specified type name is a known role, and constrain with 'does' instead
of 'isa' if it is. This brings Mouse in line with how Moose behaves
for this case. Testcase added to t/025-more-isa.t.
} else {
$code = $TYPE{ $spec };
if (! $code) {
+ # is $spec a known role? If so, constrain with 'does' instead of 'isa'
+ require Mouse::Meta::Role;
+ my $check = Mouse::Meta::Role->_metaclass_cache($spec)?
+ 'does' : 'isa';
my $code_str =
"#line " . __LINE__ . ' "' . __FILE__ . "\"\n" .
"sub {\n" .
- " Scalar::Util::blessed(\$_[0]) && \$_[0]->isa('$spec');\n" .
+ " Scalar::Util::blessed(\$_[0]) && \$_[0]->$check('$spec');\n" .
"}"
;
$code = eval $code_str or Carp::confess($@);
#!/usr/bin/env perl
use strict;
use warnings;
-use Test::More tests => 30;
+use Test::More tests => 34;
use Test::Exception;
do {
} qr/Attribute \(class\) does not pass the type constraint because: Validation failed for 'ClassName' failed with value $_/;
};
+
+# Check that Roles can be used in 'isa' and they are constrained with
+# 'does'
+do {
+ package SausageRole;
+ use Mouse::Role;
+
+ package DoesSausage;
+ use Mouse;
+ with 'SausageRole';
+
+ package HasSausage;
+ use Mouse;
+
+ has sausage =>
+ (isa => 'SausageRole',
+ is => 'rw');
+
+};
+
+my $hs;
+lives_ok {
+ $hs = HasSausage->new(sausage => DoesSausage->new);
+};
+lives_ok {
+ $hs->sausage(DoesSausage->new);
+};
+throws_ok {
+ HasSausage->new(sausage => Class->new);
+} qr/^Attribute \(sausage\) does not pass the type constraint because: Validation failed for 'SausageRole' failed with value Class=/;
+throws_ok {
+ $hs->sausage(Class->new);
+} qr/^Attribute \(sausage\) does not pass the type constraint because: Validation failed for 'SausageRole' failed with value Class=/;
+