Don't import Test::Exception into classes we are testing
[gitmo/Moose.git] / t / 030_roles / 013_method_aliasing_in_composition.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::More;
7 use Test::Exception;
8
9
10 {
11     package My::Role;
12     use Moose::Role;
13
14     sub foo { 'Foo::foo' }
15     sub bar { 'Foo::bar' }
16     sub baz { 'Foo::baz' }
17
18     requires 'role_bar';
19
20     package My::Class;
21     use Moose;
22
23     ::lives_ok {
24         with 'My::Role' => { -alias => { bar => 'role_bar' } };
25     } '... this succeeds';
26
27     package My::Class::Failure;
28     use Moose;
29
30     ::throws_ok {
31         with 'My::Role' => { -alias => { bar => 'role_bar' } };
32     } qr/Cannot create a method alias if a local method of the same name exists/, '... this succeeds';
33
34     sub role_bar { 'FAIL' }
35 }
36
37 ok(My::Class->meta->has_method($_), "we have a $_ method") for qw(foo baz bar role_bar);
38
39 {
40     package My::OtherRole;
41     use Moose::Role;
42
43     ::lives_ok {
44         with 'My::Role' => { -alias => { bar => 'role_bar' } };
45     } '... this succeeds';
46
47     sub bar { 'My::OtherRole::bar' }
48
49     package My::OtherRole::Failure;
50     use Moose::Role;
51
52     ::throws_ok {
53         with 'My::Role' => { -alias => { bar => 'role_bar' } };
54     } qr/Cannot create a method alias if a local method of the same name exists/, '... cannot alias to a name that exists';
55
56     sub role_bar { 'FAIL' }
57 }
58
59 ok(My::OtherRole->meta->has_method($_), "we have a $_ method") for qw(foo baz role_bar);
60 ok(My::OtherRole->meta->requires_method('bar'), '... and the &bar method is required');
61 ok(!My::OtherRole->meta->requires_method('role_bar'), '... and the &role_bar method is not required');
62
63 {
64     package My::AliasingRole;
65     use Moose::Role;
66
67     ::lives_ok {
68         with 'My::Role' => { -alias => { bar => 'role_bar' } };
69     } '... this succeeds';
70 }
71
72 ok(My::AliasingRole->meta->has_method($_), "we have a $_ method") for qw(foo baz role_bar);
73 ok(!My::AliasingRole->meta->requires_method('bar'), '... and the &bar method is not required');
74
75 {
76     package Foo::Role;
77     use Moose::Role;
78
79     sub foo { 'Foo::Role::foo' }
80
81     package Bar::Role;
82     use Moose::Role;
83
84     sub foo { 'Bar::Role::foo' }
85
86     package Baz::Role;
87     use Moose::Role;
88
89     sub foo { 'Baz::Role::foo' }
90
91     package My::Foo::Class;
92     use Moose;
93
94     ::lives_ok {
95         with 'Foo::Role' => { -alias => { 'foo' => 'foo_foo' }, -excludes => 'foo' },
96              'Bar::Role' => { -alias => { 'foo' => 'bar_foo' }, -excludes => 'foo' },
97              'Baz::Role';
98     } '... composed our roles correctly';
99
100     package My::Foo::Class::Broken;
101     use Moose;
102
103     ::throws_ok {
104         with 'Foo::Role' => { -alias => { 'foo' => 'foo_foo' }, -excludes => 'foo' },
105              'Bar::Role' => { -alias => { 'foo' => 'foo_foo' }, -excludes => 'foo' },
106              'Baz::Role';
107     } qr/Due to a method name conflict in roles 'Bar::Role' and 'Foo::Role', the method 'foo_foo' must be implemented or excluded by 'My::Foo::Class::Broken'/,
108       '... composed our roles correctly';
109 }
110
111 {
112     my $foo = My::Foo::Class->new;
113     isa_ok($foo, 'My::Foo::Class');
114     can_ok($foo, $_) for qw/foo foo_foo bar_foo/;
115     is($foo->foo, 'Baz::Role::foo', '... got the right method');
116     is($foo->foo_foo, 'Foo::Role::foo', '... got the right method');
117     is($foo->bar_foo, 'Bar::Role::foo', '... got the right method');
118 }
119
120 {
121     package My::Foo::Role;
122     use Moose::Role;
123
124     ::lives_ok {
125         with 'Foo::Role' => { -alias => { 'foo' => 'foo_foo' }, -excludes => 'foo' },
126              'Bar::Role' => { -alias => { 'foo' => 'bar_foo' }, -excludes => 'foo' },
127              'Baz::Role';
128     } '... composed our roles correctly';
129 }
130
131 ok(My::Foo::Role->meta->has_method($_), "we have a $_ method") for qw/foo foo_foo bar_foo/;;
132 ok(!My::Foo::Role->meta->requires_method('foo'), '... and the &foo method is not required');
133
134
135 {
136     package My::Foo::Role::Other;
137     use Moose::Role;
138
139     ::lives_ok {
140         with 'Foo::Role' => { -alias => { 'foo' => 'foo_foo' }, -excludes => 'foo' },
141              'Bar::Role' => { -alias => { 'foo' => 'foo_foo' }, -excludes => 'foo' },
142              'Baz::Role';
143     } '... composed our roles correctly';
144 }
145
146 ok(!My::Foo::Role::Other->meta->has_method('foo_foo'), "we dont have a foo_foo method");
147 ok(My::Foo::Role::Other->meta->requires_method('foo_foo'), '... and the &foo method is required');
148
149 {
150     package My::Foo::AliasOnly;
151     use Moose;
152
153     ::lives_ok {
154         with 'Foo::Role' => { -alias => { 'foo' => 'foo_foo' } },
155     } '... composed our roles correctly';
156 }
157
158 ok(My::Foo::AliasOnly->meta->has_method('foo'), 'we have a foo method');
159 ok(My::Foo::AliasOnly->meta->has_method('foo_foo'), '.. and the aliased foo_foo method');
160
161 {
162     package Role::Foo;
163     use Moose::Role;
164
165     sub x1 {}
166     sub y1 {}
167 }
168
169 {
170     package Role::Bar;
171     use Moose::Role;
172
173     ::lives_ok {
174         with 'Role::Foo' => {
175             -alias    => { x1 => 'foo_x1' },
176             -excludes => ['y1'],
177         };
178     }
179     'Compose Role::Foo into Role::Bar with alias and exclude';
180
181     sub x1 {}
182     sub y1 {}
183 }
184
185 {
186     my $bar = Role::Bar->meta;
187     ok( $bar->has_method($_), "has $_ method" )
188         for qw( x1 y1 foo_x1 );
189 }
190
191 {
192     package Role::Baz;
193     use Moose::Role;
194
195     ::lives_ok {
196         with 'Role::Foo' => {
197             -alias    => { x1 => 'foo_x1' },
198             -excludes => ['y1'],
199         };
200     }
201     'Compose Role::Foo into Role::Baz with alias and exclude';
202 }
203
204 {
205     my $baz = Role::Baz->meta;
206     ok( $baz->has_method($_), "has $_ method" )
207         for qw( x1 foo_x1 );
208     ok( ! $baz->has_method('y1'), 'Role::Baz has no y1 method' );
209 }
210
211 done_testing;