From: wu-lee Date: Wed, 1 Apr 2009 17:23:30 +0000 (+0100) Subject: Adjusted default 'isa' typeconstraint construction to check if the X-Git-Tag: 0.20~20 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5c5a61e0daea184cff679a815d6fc4cdbe08bc33;p=gitmo%2FMouse.git Adjusted default 'isa' typeconstraint construction to check if the 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. --- diff --git a/lib/Mouse/Util/TypeConstraints.pm b/lib/Mouse/Util/TypeConstraints.pm index 6a9ee57..3ed075d 100644 --- a/lib/Mouse/Util/TypeConstraints.pm +++ b/lib/Mouse/Util/TypeConstraints.pm @@ -282,10 +282,14 @@ sub _build_type_constraint { } 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($@); diff --git a/t/025-more-isa.t b/t/025-more-isa.t old mode 100644 new mode 100755 index 0be7603..576d5e1 --- a/t/025-more-isa.t +++ b/t/025-more-isa.t @@ -1,7 +1,7 @@ #!/usr/bin/env perl use strict; use warnings; -use Test::More tests => 30; +use Test::More tests => 34; use Test::Exception; do { @@ -138,3 +138,37 @@ for ('F', 'G', 'I', 'Z') { } 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=/; +