use strict;
use warnings;
-use Test::More tests => 87; # it's really 124 with kolibre's tests;
+use Test::More;
use Test::Exception;
=pod
use Moose::Role;
requires 'foo';
-
+
sub bar { 'Role::Foo::bar' }
-
+
package Role::Bar;
use Moose::Role;
-
+
requires 'bar';
-
- sub foo { 'Role::Bar::foo' }
+
+ sub foo { 'Role::Bar::foo' }
}
{
package My::Test1;
use Moose;
-
+
::lives_ok {
with 'Role::Foo', 'Role::Bar';
} '... our mutually recursive roles combine okay';
-
+
package My::Test2;
use Moose;
-
+
::lives_ok {
with 'Role::Bar', 'Role::Foo';
- } '... our mutually recursive roles combine okay (no matter what order)';
+ } '... our mutually recursive roles combine okay (no matter what order)';
}
my $test1 = My::Test1->new;
{
package Role::Bling;
use Moose::Role;
-
+
sub bling { 'Role::Bling::bling' }
-
+
package Role::Bling::Bling;
use Moose::Role;
-
- sub bling { 'Role::Bling::Bling::bling' }
+
+ sub bling { 'Role::Bling::Bling::bling' }
}
{
package My::Test3;
use Moose;
-
+
::throws_ok {
with 'Role::Bling', 'Role::Bling::Bling';
- } qr/requires the method \'bling\' to be implemented/, '... role methods conflicted and method was required';
-
+ } qr/Due to a method name conflict in roles 'Role::Bling' and 'Role::Bling::Bling', the method 'bling' must be implemented or excluded by 'My::Test3'/, '... role methods conflict and method was required';
+
package My::Test4;
use Moose;
-
+
::lives_ok {
with 'Role::Bling';
with 'Role::Bling::Bling';
- } '... role methods didnt conflict when manually combined';
-
+ } '... role methods didnt conflict when manually combined';
+
package My::Test5;
use Moose;
-
+
::lives_ok {
with 'Role::Bling::Bling';
with 'Role::Bling';
- } '... role methods didnt conflict when manually combined (in opposite order)';
-
+ } '... role methods didnt conflict when manually combined (in opposite order)';
+
package My::Test6;
use Moose;
-
+
::lives_ok {
with 'Role::Bling::Bling', 'Role::Bling';
- } '... role methods didnt conflict when manually resolved';
-
+ } '... role methods didnt conflict when manually resolved';
+
sub bling { 'My::Test6::bling' }
}
{
package Role::Bling::Bling::Bling;
use Moose::Role;
-
+
with 'Role::Bling::Bling';
-
- sub bling { 'Role::Bling::Bling::Bling::bling' }
+
+ sub bling { 'Role::Bling::Bling::Bling::bling' }
}
ok(Role::Bling::Bling->meta->has_method('bling'), '... still got the bling method in Role::Bling::Bling');
ok(Role::Bling::Bling->meta->does_role('Role::Bling::Bling'), '... our role correctly does() the other role');
ok(Role::Bling::Bling::Bling->meta->has_method('bling'), '... dont have the bling method in Role::Bling::Bling::Bling');
-is(Role::Bling::Bling::Bling->meta->get_method('bling')->(),
+is(Role::Bling::Bling::Bling->meta->get_method('bling')->(),
'Role::Bling::Bling::Bling::bling',
'... still got the bling method in Role::Bling::Bling::Bling');
{
package Role::Boo;
use Moose::Role;
-
+
has 'ghost' => (is => 'ro', default => 'Role::Boo::ghost');
-
+
package Role::Boo::Hoo;
use Moose::Role;
-
+
has 'ghost' => (is => 'ro', default => 'Role::Boo::Hoo::ghost');
}
{
package My::Test7;
use Moose;
-
+
::throws_ok {
with 'Role::Boo', 'Role::Boo::Hoo';
- } qr/We have encountered an attribute conflict/,
- '... role attrs conflicted and method was required';
+ } qr/We have encountered an attribute conflict/,
+ '... role attrs conflict and method was required';
package My::Test8;
use Moose;
with 'Role::Boo';
with 'Role::Boo::Hoo';
} '... role attrs didnt conflict when manually combined';
-
+
package My::Test9;
use Moose;
::lives_ok {
with 'Role::Boo::Hoo';
with 'Role::Boo';
- } '... role attrs didnt conflict when manually combined';
+ } '... role attrs didnt conflict when manually combined';
package My::Test10;
use Moose;
-
- has 'ghost' => (is => 'ro', default => 'My::Test10::ghost');
-
+
+ has 'ghost' => (is => 'ro', default => 'My::Test10::ghost');
+
::throws_ok {
with 'Role::Boo', 'Role::Boo::Hoo';
- } qr/We have encountered an attribute conflict/,
- '... role attrs conflicted and cannot be manually disambiguted';
+ } qr/We have encountered an attribute conflict/,
+ '... role attrs conflict and cannot be manually disambiguted';
}
{
package Role::Plot;
use Moose::Role;
-
+
override 'twist' => sub {
super() . ' -> Role::Plot::twist';
};
-
+
package Role::Truth;
use Moose::Role;
-
+
override 'twist' => sub {
super() . ' -> Role::Truth::twist';
};
{
package My::Test::Base;
use Moose;
-
+
sub twist { 'My::Test::Base::twist' }
-
+
package My::Test11;
use Moose;
-
+
extends 'My::Test::Base';
::lives_ok {
with 'Role::Truth';
} '... composed the role with override okay';
-
+
package My::Test12;
use Moose;
extends 'My::Test::Base';
- ::lives_ok {
+ ::lives_ok {
with 'Role::Plot';
} '... composed the role with override okay';
-
+
package My::Test13;
use Moose;
::dies_ok {
- with 'Role::Plot';
+ with 'Role::Plot';
} '... cannot compose it because we have no superclass';
-
+
package My::Test14;
use Moose;
extends 'My::Test::Base';
::throws_ok {
- with 'Role::Plot', 'Role::Truth';
- } qr/Two \'override\' methods of the same name encountered/,
- '... cannot compose it because we have no superclass';
+ with 'Role::Plot', 'Role::Truth';
+ } qr/Two \'override\' methods of the same name encountered/,
+ '... cannot compose it because we have no superclass';
}
ok(My::Test11->meta->has_method('twist'), '... the twist method has been added');
package Role::Reality;
use Moose::Role;
- ::throws_ok {
+ ::throws_ok {
with 'Role::Plot';
- } qr/A local method of the same name as been found/,
+ } qr/A local method of the same name as been found/,
'... could not compose roles here, it dies';
sub twist {
'Role::Reality::twist';
}
-}
+}
ok(Role::Reality->meta->has_method('twist'), '... the twist method has not been added');
#ok(!Role::Reality->meta->does_role('Role::Plot'), '... our role does() the correct roles');
-is(Role::Reality->meta->get_method('twist')->(),
- 'Role::Reality::twist',
+is(Role::Reality->meta->get_method('twist')->(),
+ 'Role::Reality::twist',
'... the twist method returns the right value');
+# Ovid's test case from rt.cpan.org #44
+{
+ package Role1;
+ use Moose::Role;
+
+ sub foo {}
+}
+{
+ package Role2;
+ use Moose::Role;
+
+ sub foo {}
+}
+{
+ package Conflicts;
+ use Moose;
+
+ ::throws_ok {
+ with qw(Role1 Role2);
+ } qr/Due to a method name conflict in roles 'Role1' and 'Role2', the method 'foo' must be implemented or excluded by 'Conflicts'/;
+}
+
=pod
Role conflicts between attributes and methods
[15:24] <kolibrie> when class 'has' method and role defines method, class wins
[15:24] <kolibrie> when class defines method and role 'has' method, role wins
[15:24] <kolibrie> when class 'has' method and role 'has' method, role wins
-[15:24] <kolibrie> which means when class 'has' method and two roles 'has' method, no tiebreak is d
-[15:24] <kolibrie> etected
+[15:24] <kolibrie> which means when class 'has' method and two roles 'has' method, no tiebreak is detected
[15:24] <perigrin> this is with role and has declaration in the exact same order in every case?
[15:25] <kolibrie> yes
[15:25] <perigrin> interesting
{
package Role::Method;
use Moose::Role;
-
+
sub ghost { 'Role::Method::ghost' }
package Role::Method2;
use Moose::Role;
-
+
sub ghost { 'Role::Method2::ghost' }
package Role::Attribute;
use Moose::Role;
-
+
has 'ghost' => (is => 'ro', default => 'Role::Attribute::ghost');
package Role::Attribute2;
use Moose::Role;
-
+
has 'ghost' => (is => 'ro', default => 'Role::Attribute2::ghost');
}
package My::Test15;
use Moose;
- ::lives_ok {
+ ::lives_ok {
with 'Role::Method';
} '... composed the method role into the method class';
is($test26->ghost, 'My::Test26::ghost', '... we access the attribute from the class and ignore the role attribute and method');
=cut
+
+done_testing;