Commit | Line | Data |
db1ab48d |
1 | #!/usr/bin/perl |
2 | |
3 | use strict; |
4 | use warnings; |
5 | |
6 | use Test::More no_plan => 1; |
7 | use Test::Exception; |
8 | |
9 | BEGIN { |
10 | use_ok('Moose'); |
11 | use_ok('Moose::Role'); |
12 | } |
13 | |
14 | =pod |
15 | |
16 | Mutually recursive roles. |
17 | |
18 | =cut |
19 | |
20 | { |
21 | package Role::Foo; |
22 | use strict; |
23 | use warnings; |
24 | use Moose::Role; |
25 | |
26 | requires 'foo'; |
27 | |
28 | sub bar { 'Role::Foo::bar' } |
29 | |
30 | package Role::Bar; |
31 | use strict; |
32 | use warnings; |
33 | use Moose::Role; |
34 | |
35 | requires 'bar'; |
36 | |
37 | sub foo { 'Role::Bar::foo' } |
38 | } |
39 | |
40 | { |
41 | package My::Test1; |
42 | use strict; |
43 | use warnings; |
44 | use Moose; |
45 | |
46 | ::lives_ok { |
47 | with 'Role::Foo', 'Role::Bar'; |
48 | } '... our mutually recursive roles combine okay'; |
49 | |
50 | package My::Test2; |
51 | use strict; |
52 | use warnings; |
53 | use Moose; |
54 | |
55 | ::lives_ok { |
56 | with 'Role::Bar', 'Role::Foo'; |
57 | } '... our mutually recursive roles combine okay (no matter what order)'; |
58 | } |
59 | |
60 | my $test1 = My::Test1->new; |
61 | isa_ok($test1, 'My::Test1'); |
62 | |
63 | ok($test1->does('Role::Foo'), '... $test1 does Role::Foo'); |
64 | ok($test1->does('Role::Bar'), '... $test1 does Role::Bar'); |
65 | |
66 | can_ok($test1, 'foo'); |
67 | can_ok($test1, 'bar'); |
68 | |
69 | is($test1->foo, 'Role::Bar::foo', '... $test1->foo worked'); |
70 | is($test1->bar, 'Role::Foo::bar', '... $test1->bar worked'); |
71 | |
72 | my $test2 = My::Test2->new; |
73 | isa_ok($test2, 'My::Test2'); |
74 | |
75 | ok($test2->does('Role::Foo'), '... $test2 does Role::Foo'); |
76 | ok($test2->does('Role::Bar'), '... $test2 does Role::Bar'); |
77 | |
78 | can_ok($test2, 'foo'); |
79 | can_ok($test2, 'bar'); |
80 | |
81 | is($test2->foo, 'Role::Bar::foo', '... $test2->foo worked'); |
82 | is($test2->bar, 'Role::Foo::bar', '... $test2->bar worked'); |
83 | |
84 | # check some meta-stuff |
85 | |
86 | ok(Role::Foo->meta->has_method('bar'), '... it still has the bar method'); |
87 | ok(Role::Foo->meta->requires_method('foo'), '... it still has the required foo method'); |
88 | |
89 | ok(Role::Bar->meta->has_method('foo'), '... it still has the foo method'); |
90 | ok(Role::Bar->meta->requires_method('bar'), '... it still has the required bar method'); |
91 | |
92 | =pod |
93 | |
94 | Role method conflicts |
95 | |
96 | =cut |
97 | |
98 | { |
99 | package Role::Bling; |
100 | use strict; |
101 | use warnings; |
102 | use Moose::Role; |
103 | |
104 | sub bling { 'Role::Bling::bling' } |
105 | |
106 | package Role::Bling::Bling; |
107 | use strict; |
108 | use warnings; |
109 | use Moose::Role; |
110 | |
111 | sub bling { 'Role::Bling::Bling::bling' } |
112 | } |
113 | |
114 | { |
115 | package My::Test3; |
116 | use strict; |
117 | use warnings; |
118 | use Moose; |
119 | |
120 | ::throws_ok { |
121 | with 'Role::Bling', 'Role::Bling::Bling'; |
122 | } qr/requires the method \'bling\' to be implemented/, '... role methods conflicted and method was required'; |
123 | |
124 | package My::Test4; |
125 | use strict; |
126 | use warnings; |
127 | use Moose; |
128 | |
129 | ::lives_ok { |
130 | with 'Role::Bling'; |
131 | with 'Role::Bling::Bling'; |
132 | } '... role methods didnt conflict when manually combined'; |
133 | |
134 | package My::Test5; |
135 | use strict; |
136 | use warnings; |
137 | use Moose; |
138 | |
139 | ::lives_ok { |
140 | with 'Role::Bling::Bling'; |
141 | with 'Role::Bling'; |
142 | } '... role methods didnt conflict when manually combined (in opposite order)'; |
143 | |
144 | package My::Test6; |
145 | use strict; |
146 | use warnings; |
147 | use Moose; |
148 | |
149 | ::lives_ok { |
150 | with 'Role::Bling::Bling', 'Role::Bling'; |
151 | } '... role methods didnt conflict when manually resolved'; |
152 | |
153 | sub bling { 'My::Test6::bling' } |
154 | } |
155 | |
156 | ok(!My::Test3->meta->has_method('bling'), '... we didnt get any methods in the conflict'); |
157 | ok(My::Test4->meta->has_method('bling'), '... we did get the method when manually dealt with'); |
158 | ok(My::Test5->meta->has_method('bling'), '... we did get the method when manually dealt with'); |
159 | ok(My::Test6->meta->has_method('bling'), '... we did get the method when manually dealt with'); |
160 | |
161 | is(My::Test4->bling, 'Role::Bling::bling', '... and we got the first method that was added'); |
162 | is(My::Test5->bling, 'Role::Bling::Bling::bling', '... and we got the first method that was added'); |
163 | is(My::Test6->bling, 'My::Test6::bling', '... and we got the local method'); |
164 | |
165 | # check how this affects role compostion |
166 | |
167 | { |
168 | package Role::Bling::Bling::Bling; |
169 | use strict; |
170 | use warnings; |
171 | use Moose::Role; |
172 | |
173 | with 'Role::Bling::Bling'; |
174 | |
175 | sub bling { 'Role::Bling::Bling::Bling::bling' } |
176 | } |
177 | |
178 | ok(Role::Bling::Bling->meta->has_method('bling'), '... still got the bling method in Role::Bling::Bling'); |
179 | ok(Role::Bling::Bling::Bling->meta->has_method('bling'), '... still got the bling method in Role::Bling::Bling::Bling'); |
180 | |
181 | =pod |
182 | |
183 | Role attribute conflicts |
184 | |
185 | =cut |
186 | |
187 | { |
188 | package Role::Boo; |
189 | use strict; |
190 | use warnings; |
191 | use Moose::Role; |
192 | |
193 | has 'ghost' => (is => 'ro', default => 'Role::Boo::ghost'); |
194 | |
195 | package Role::Boo::Hoo; |
196 | use strict; |
197 | use warnings; |
198 | use Moose::Role; |
199 | |
200 | has 'ghost' => (is => 'ro', default => 'Role::Boo::Hoo::ghost'); |
201 | } |
202 | |
203 | { |
204 | package My::Test7; |
205 | use strict; |
206 | use warnings; |
207 | use Moose; |
208 | |
209 | ::throws_ok { |
210 | with 'Role::Boo', 'Role::Boo::Hoo'; |
211 | } qr/Role \'Role::Boo::Hoo\' has encountered an attribute conflict/, |
212 | '... role attrs conflicted and method was required'; |
213 | |
214 | package My::Test8; |
215 | use strict; |
216 | use warnings; |
217 | use Moose; |
218 | |
219 | ::lives_ok { |
220 | with 'Role::Boo'; |
221 | with 'Role::Boo::Hoo'; |
222 | } '... role attrs didnt conflict when manually combined'; |
223 | |
224 | package My::Test9; |
225 | use strict; |
226 | use warnings; |
227 | use Moose; |
228 | |
229 | ::lives_ok { |
230 | with 'Role::Boo::Hoo'; |
231 | with 'Role::Boo'; |
232 | } '... role attrs didnt conflict when manually combined'; |
233 | |
234 | package My::Test10; |
235 | use strict; |
236 | use warnings; |
237 | use Moose; |
238 | |
239 | has 'ghost' => (is => 'ro', default => 'My::Test10::ghost'); |
240 | |
241 | ::throws_ok { |
242 | with 'Role::Boo', 'Role::Boo::Hoo'; |
243 | } qr/Role \'Role::Boo::Hoo\' has encountered an attribute conflict/, |
244 | '... role attrs conflicted and cannot be manually disambiguted'; |
245 | |
246 | } |
247 | |
248 | ok(!My::Test7->meta->has_attribute('ghost'), '... we didnt get any attributes in the conflict'); |
249 | ok(My::Test8->meta->has_attribute('ghost'), '... we did get an attributes when manually composed'); |
250 | ok(My::Test9->meta->has_attribute('ghost'), '... we did get an attributes when manually composed'); |
251 | ok(My::Test10->meta->has_attribute('ghost'), '... we did still have an attribute ghost (conflict does not mess with class)'); |
252 | |
253 | can_ok('My::Test8', 'ghost'); |
254 | can_ok('My::Test9', 'ghost'); |
255 | can_ok('My::Test10', 'ghost'); |
256 | |
257 | is(My::Test8->new->ghost, 'Role::Boo::ghost', '... got the expected default attr value'); |
258 | is(My::Test9->new->ghost, 'Role::Boo::Hoo::ghost', '... got the expected default attr value'); |
259 | is(My::Test10->new->ghost, 'My::Test10::ghost', '... got the expected default attr value'); |
260 | |
261 | |
262 | |