Commit | Line | Data |
231be3be |
1 | #!/usr/bin/perl |
2 | |
3 | use strict; |
4 | use warnings; |
5 | |
fdeb8354 |
6 | use lib 't/lib', 'lib'; |
7 | |
a28e50e4 |
8 | use Test::More; |
fdeb8354 |
9 | use Test::Exception; |
231be3be |
10 | |
11 | use Moose::Util::MetaRole; |
12 | |
13 | |
14 | { |
15 | package My::Meta::Class; |
16 | use Moose; |
17 | extends 'Moose::Meta::Class'; |
18 | } |
19 | |
20 | { |
231be3be |
21 | package Role::Foo; |
22 | use Moose::Role; |
23 | has 'foo' => ( is => 'ro', default => 10 ); |
24 | } |
25 | |
26 | { |
27 | package My::Class; |
28 | |
29 | use Moose; |
30 | } |
31 | |
32 | { |
d401dc20 |
33 | package My::Role; |
34 | use Moose::Role; |
35 | } |
36 | |
37 | { |
f785aad8 |
38 | Moose::Util::MetaRole::apply_metaroles( |
39 | for => My::Class->meta, |
40 | class_metaroles => { class => ['Role::Foo'] }, |
231be3be |
41 | ); |
42 | |
43 | ok( My::Class->meta()->meta()->does_role('Role::Foo'), |
44 | 'apply Role::Foo to My::Class->meta()' ); |
45 | is( My::Class->meta()->foo(), 10, |
46 | '... and call foo() on that meta object' ); |
47 | } |
48 | |
49 | { |
f785aad8 |
50 | Moose::Util::MetaRole::apply_metaroles( |
51 | for => 'My::Class', |
52 | class_metaroles => { attribute => ['Role::Foo'] }, |
231be3be |
53 | ); |
54 | |
55 | ok( My::Class->meta()->attribute_metaclass()->meta()->does_role('Role::Foo'), |
56 | q{apply Role::Foo to My::Class->meta()'s attribute metaclass} ); |
57 | ok( My::Class->meta()->meta()->does_role('Role::Foo'), |
58 | '... My::Class->meta() still does Role::Foo' ); |
59 | |
60 | My::Class->meta()->add_attribute( 'size', is => 'ro' ); |
61 | is( My::Class->meta()->get_attribute('size')->foo(), 10, |
62 | '... call foo() on an attribute metaclass object' ); |
63 | } |
64 | |
65 | { |
f785aad8 |
66 | Moose::Util::MetaRole::apply_metaroles( |
67 | for => 'My::Class', |
68 | class_metaroles => { method => ['Role::Foo'] }, |
231be3be |
69 | ); |
70 | |
71 | ok( My::Class->meta()->method_metaclass()->meta()->does_role('Role::Foo'), |
72 | q{apply Role::Foo to My::Class->meta()'s method metaclass} ); |
73 | ok( My::Class->meta()->meta()->does_role('Role::Foo'), |
74 | '... My::Class->meta() still does Role::Foo' ); |
75 | ok( My::Class->meta()->attribute_metaclass()->meta()->does_role('Role::Foo'), |
76 | q{... My::Class->meta()'s attribute metaclass still does Role::Foo} ); |
77 | |
78 | My::Class->meta()->add_method( 'bar' => sub { 'bar' } ); |
79 | is( My::Class->meta()->get_method('bar')->foo(), 10, |
80 | '... call foo() on a method metaclass object' ); |
81 | } |
82 | |
83 | { |
f785aad8 |
84 | Moose::Util::MetaRole::apply_metaroles( |
85 | for => 'My::Class', |
86 | class_metaroles => { wrapped_method => ['Role::Foo'] }, |
8286fcd6 |
87 | ); |
88 | |
89 | ok( My::Class->meta()->wrapped_method_metaclass()->meta()->does_role('Role::Foo'), |
90 | q{apply Role::Foo to My::Class->meta()'s wrapped method metaclass} ); |
91 | ok( My::Class->meta()->method_metaclass()->meta()->does_role('Role::Foo'), |
92 | '... My::Class->meta() still does Role::Foo' ); |
93 | ok( My::Class->meta()->meta()->does_role('Role::Foo'), |
94 | '... My::Class->meta() still does Role::Foo' ); |
95 | ok( My::Class->meta()->attribute_metaclass()->meta()->does_role('Role::Foo'), |
96 | q{... My::Class->meta()'s attribute metaclass still does Role::Foo} ); |
97 | |
98 | My::Class->meta()->add_after_method_modifier( 'bar' => sub { 'bar' } ); |
99 | is( My::Class->meta()->get_method('bar')->foo(), 10, |
100 | '... call foo() on a wrapped method metaclass object' ); |
101 | } |
102 | |
103 | { |
f785aad8 |
104 | Moose::Util::MetaRole::apply_metaroles( |
105 | for => 'My::Class', |
106 | class_metaroles => { instance => ['Role::Foo'] }, |
231be3be |
107 | ); |
108 | |
109 | ok( My::Class->meta()->instance_metaclass()->meta()->does_role('Role::Foo'), |
110 | q{apply Role::Foo to My::Class->meta()'s instance metaclass} ); |
111 | ok( My::Class->meta()->meta()->does_role('Role::Foo'), |
112 | '... My::Class->meta() still does Role::Foo' ); |
113 | ok( My::Class->meta()->attribute_metaclass()->meta()->does_role('Role::Foo'), |
114 | q{... My::Class->meta()'s attribute metaclass still does Role::Foo} ); |
115 | ok( My::Class->meta()->method_metaclass()->meta()->does_role('Role::Foo'), |
116 | q{... My::Class->meta()'s method metaclass still does Role::Foo} ); |
117 | |
118 | is( My::Class->meta()->get_meta_instance()->foo(), 10, |
119 | '... call foo() on an instance metaclass object' ); |
120 | } |
121 | |
122 | { |
f785aad8 |
123 | Moose::Util::MetaRole::apply_metaroles( |
124 | for => 'My::Class', |
125 | class_metaroles => { constructor => ['Role::Foo'] }, |
231be3be |
126 | ); |
127 | |
128 | ok( My::Class->meta()->constructor_class()->meta()->does_role('Role::Foo'), |
129 | q{apply Role::Foo to My::Class->meta()'s constructor class} ); |
130 | ok( My::Class->meta()->meta()->does_role('Role::Foo'), |
131 | '... My::Class->meta() still does Role::Foo' ); |
132 | ok( My::Class->meta()->attribute_metaclass()->meta()->does_role('Role::Foo'), |
133 | q{... My::Class->meta()'s attribute metaclass still does Role::Foo} ); |
134 | ok( My::Class->meta()->method_metaclass()->meta()->does_role('Role::Foo'), |
135 | q{... My::Class->meta()'s method metaclass still does Role::Foo} ); |
136 | ok( My::Class->meta()->instance_metaclass()->meta()->does_role('Role::Foo'), |
137 | q{... My::Class->meta()'s instance metaclass still does Role::Foo} ); |
138 | |
139 | # Actually instantiating the constructor class is too freaking hard! |
140 | ok( My::Class->meta()->constructor_class()->can('foo'), |
141 | '... constructor class has a foo method' ); |
142 | } |
143 | |
144 | { |
f785aad8 |
145 | Moose::Util::MetaRole::apply_metaroles( |
146 | for => 'My::Class', |
147 | class_metaroles => { destructor => ['Role::Foo'] }, |
231be3be |
148 | ); |
149 | |
150 | ok( My::Class->meta()->destructor_class()->meta()->does_role('Role::Foo'), |
151 | q{apply Role::Foo to My::Class->meta()'s destructor class} ); |
152 | ok( My::Class->meta()->meta()->does_role('Role::Foo'), |
153 | '... My::Class->meta() still does Role::Foo' ); |
154 | ok( My::Class->meta()->attribute_metaclass()->meta()->does_role('Role::Foo'), |
155 | q{... My::Class->meta()'s attribute metaclass still does Role::Foo} ); |
156 | ok( My::Class->meta()->method_metaclass()->meta()->does_role('Role::Foo'), |
157 | q{... My::Class->meta()'s method metaclass still does Role::Foo} ); |
158 | ok( My::Class->meta()->instance_metaclass()->meta()->does_role('Role::Foo'), |
159 | q{... My::Class->meta()'s instance metaclass still does Role::Foo} ); |
160 | ok( My::Class->meta()->constructor_class()->meta()->does_role('Role::Foo'), |
161 | q{... My::Class->meta()'s constructor class still does Role::Foo} ); |
162 | |
163 | # same problem as the constructor class |
164 | ok( My::Class->meta()->destructor_class()->can('foo'), |
165 | '... destructor class has a foo method' ); |
166 | } |
167 | |
168 | { |
f785aad8 |
169 | Moose::Util::MetaRole::apply_metaroles( |
170 | for => 'My::Role', |
171 | role_metaroles => { application_to_class => ['Role::Foo'] }, |
d401dc20 |
172 | ); |
173 | |
174 | ok( My::Role->meta->application_to_class_class->meta->does_role('Role::Foo'), |
175 | q{apply Role::Foo to My::Role->meta's application_to_class class} ); |
176 | |
177 | is( My::Role->meta->application_to_class_class->new->foo, 10, |
178 | q{... call foo() on an application_to_class instance} ); |
179 | } |
180 | |
181 | { |
f785aad8 |
182 | Moose::Util::MetaRole::apply_metaroles( |
183 | for => 'My::Role', |
184 | role_metaroles => { application_to_role => ['Role::Foo'] }, |
d401dc20 |
185 | ); |
186 | |
187 | ok( My::Role->meta->application_to_role_class->meta->does_role('Role::Foo'), |
188 | q{apply Role::Foo to My::Role->meta's application_to_role class} ); |
189 | ok( My::Role->meta->application_to_class_class->meta->does_role('Role::Foo'), |
190 | q{... My::Role->meta's application_to_class class still does Role::Foo} ); |
191 | |
192 | is( My::Role->meta->application_to_role_class->new->foo, 10, |
193 | q{... call foo() on an application_to_role instance} ); |
194 | } |
195 | |
196 | { |
f785aad8 |
197 | Moose::Util::MetaRole::apply_metaroles( |
198 | for => 'My::Role', |
199 | role_metaroles => { application_to_instance => ['Role::Foo'] }, |
d401dc20 |
200 | ); |
201 | |
202 | ok( My::Role->meta->application_to_instance_class->meta->does_role('Role::Foo'), |
203 | q{apply Role::Foo to My::Role->meta's application_to_instance class} ); |
204 | ok( My::Role->meta->application_to_role_class->meta->does_role('Role::Foo'), |
205 | q{... My::Role->meta's application_to_role class still does Role::Foo} ); |
206 | ok( My::Role->meta->application_to_class_class->meta->does_role('Role::Foo'), |
207 | q{... My::Role->meta's application_to_class class still does Role::Foo} ); |
208 | |
209 | is( My::Role->meta->application_to_instance_class->new->foo, 10, |
210 | q{... call foo() on an application_to_instance instance} ); |
211 | } |
212 | |
213 | { |
231be3be |
214 | Moose::Util::MetaRole::apply_base_class_roles( |
f785aad8 |
215 | for => 'My::Class', |
216 | roles => ['Role::Foo'], |
231be3be |
217 | ); |
218 | |
219 | ok( My::Class->meta()->does_role('Role::Foo'), |
220 | 'apply Role::Foo to My::Class base class' ); |
221 | is( My::Class->new()->foo(), 10, |
222 | '... call foo() on a My::Class object' ); |
223 | } |
224 | |
225 | { |
226 | package My::Class2; |
227 | |
228 | use Moose; |
229 | } |
230 | |
231 | { |
f785aad8 |
232 | Moose::Util::MetaRole::apply_metaroles( |
233 | for => 'My::Class2', |
234 | class_metaroles => { |
235 | class => ['Role::Foo'], |
236 | attribute => ['Role::Foo'], |
237 | method => ['Role::Foo'], |
238 | instance => ['Role::Foo'], |
239 | constructor => ['Role::Foo'], |
240 | destructor => ['Role::Foo'], |
241 | }, |
231be3be |
242 | ); |
243 | |
244 | ok( My::Class2->meta()->meta()->does_role('Role::Foo'), |
245 | 'apply Role::Foo to My::Class2->meta()' ); |
246 | is( My::Class2->meta()->foo(), 10, |
247 | '... and call foo() on that meta object' ); |
248 | ok( My::Class2->meta()->attribute_metaclass()->meta()->does_role('Role::Foo'), |
249 | q{apply Role::Foo to My::Class2->meta()'s attribute metaclass} ); |
250 | My::Class2->meta()->add_attribute( 'size', is => 'ro' ); |
251 | |
252 | is( My::Class2->meta()->get_attribute('size')->foo(), 10, |
253 | '... call foo() on an attribute metaclass object' ); |
254 | |
255 | ok( My::Class2->meta()->method_metaclass()->meta()->does_role('Role::Foo'), |
256 | q{apply Role::Foo to My::Class2->meta()'s method metaclass} ); |
257 | |
258 | My::Class2->meta()->add_method( 'bar' => sub { 'bar' } ); |
259 | is( My::Class2->meta()->get_method('bar')->foo(), 10, |
260 | '... call foo() on a method metaclass object' ); |
261 | |
262 | ok( My::Class2->meta()->instance_metaclass()->meta()->does_role('Role::Foo'), |
263 | q{apply Role::Foo to My::Class2->meta()'s instance metaclass} ); |
264 | is( My::Class2->meta()->get_meta_instance()->foo(), 10, |
265 | '... call foo() on an instance metaclass object' ); |
266 | |
267 | ok( My::Class2->meta()->constructor_class()->meta()->does_role('Role::Foo'), |
268 | q{apply Role::Foo to My::Class2->meta()'s constructor class} ); |
269 | ok( My::Class2->meta()->constructor_class()->can('foo'), |
270 | '... constructor class has a foo method' ); |
271 | |
272 | ok( My::Class2->meta()->destructor_class()->meta()->does_role('Role::Foo'), |
273 | q{apply Role::Foo to My::Class2->meta()'s destructor class} ); |
274 | ok( My::Class2->meta()->destructor_class()->can('foo'), |
275 | '... destructor class has a foo method' ); |
276 | } |
277 | |
278 | |
279 | { |
280 | package My::Meta; |
281 | |
282 | use Moose::Exporter; |
283 | Moose::Exporter->setup_import_methods( also => 'Moose' ); |
284 | |
285 | sub init_meta { |
286 | shift; |
287 | my %p = @_; |
288 | |
289 | Moose->init_meta( %p, metaclass => 'My::Meta::Class' ); |
290 | } |
291 | } |
292 | |
293 | { |
294 | package My::Class3; |
295 | |
296 | My::Meta->import(); |
297 | } |
298 | |
299 | |
300 | { |
f785aad8 |
301 | Moose::Util::MetaRole::apply_metaroles( |
302 | for => 'My::Class3', |
303 | class_metaroles => { class => ['Role::Foo'] }, |
231be3be |
304 | ); |
305 | |
306 | ok( My::Class3->meta()->meta()->does_role('Role::Foo'), |
307 | 'apply Role::Foo to My::Class3->meta()' ); |
308 | is( My::Class3->meta()->foo(), 10, |
309 | '... and call foo() on that meta object' ); |
310 | ok( ( grep { $_ eq 'My::Meta::Class' } My::Class3->meta()->meta()->superclasses() ), |
f785aad8 |
311 | 'apply_metaroles() does not interfere with metaclass set via Moose->init_meta()' ); |
231be3be |
312 | } |
82b388d5 |
313 | |
314 | { |
315 | package Role::Bar; |
316 | use Moose::Role; |
317 | has 'bar' => ( is => 'ro', default => 200 ); |
318 | } |
319 | |
320 | { |
321 | package My::Class4; |
322 | use Moose; |
323 | } |
324 | |
325 | { |
f785aad8 |
326 | Moose::Util::MetaRole::apply_metaroles( |
327 | for => 'My::Class4', |
328 | class_metaroles => { class => ['Role::Foo'] }, |
82b388d5 |
329 | ); |
330 | |
331 | ok( My::Class4->meta()->meta()->does_role('Role::Foo'), |
332 | 'apply Role::Foo to My::Class4->meta()' ); |
333 | |
f785aad8 |
334 | Moose::Util::MetaRole::apply_metaroles( |
335 | for => 'My::Class4', |
336 | class_metaroles => { class => ['Role::Bar'] }, |
82b388d5 |
337 | ); |
338 | |
339 | ok( My::Class4->meta()->meta()->does_role('Role::Bar'), |
340 | 'apply Role::Bar to My::Class4->meta()' ); |
341 | ok( My::Class4->meta()->meta()->does_role('Role::Foo'), |
342 | '... and My::Class4->meta() still does Role::Foo' ); |
343 | } |
4fed6bbc |
344 | |
345 | { |
346 | package My::Class5; |
347 | use Moose; |
348 | |
349 | extends 'My::Class'; |
350 | } |
351 | |
352 | { |
deed2e7e |
353 | ok( My::Class5->meta()->meta()->does_role('Role::Foo'), |
63647399 |
354 | q{My::Class5->meta()'s does Role::Foo because it extends My::Class} ); |
deed2e7e |
355 | ok( My::Class5->meta()->attribute_metaclass()->meta()->does_role('Role::Foo'), |
4fed6bbc |
356 | q{My::Class5->meta()'s attribute metaclass also does Role::Foo} ); |
deed2e7e |
357 | ok( My::Class5->meta()->method_metaclass()->meta()->does_role('Role::Foo'), |
4fed6bbc |
358 | q{My::Class5->meta()'s method metaclass also does Role::Foo} ); |
deed2e7e |
359 | ok( My::Class5->meta()->instance_metaclass()->meta()->does_role('Role::Foo'), |
4fed6bbc |
360 | q{My::Class5->meta()'s instance metaclass also does Role::Foo} ); |
deed2e7e |
361 | ok( My::Class5->meta()->constructor_class()->meta()->does_role('Role::Foo'), |
4fed6bbc |
362 | q{My::Class5->meta()'s constructor class also does Role::Foo} ); |
deed2e7e |
363 | ok( My::Class5->meta()->destructor_class()->meta()->does_role('Role::Foo'), |
364 | q{My::Class5->meta()'s destructor class also does Role::Foo} ); |
4fed6bbc |
365 | } |
366 | |
367 | { |
f785aad8 |
368 | Moose::Util::MetaRole::apply_metaroles( |
369 | for => 'My::Class5', |
370 | class_metaroles => { class => ['Role::Bar'] }, |
4fed6bbc |
371 | ); |
372 | |
373 | ok( My::Class5->meta()->meta()->does_role('Role::Bar'), |
374 | q{apply Role::Bar My::Class5->meta()} ); |
375 | ok( My::Class5->meta()->meta()->does_role('Role::Foo'), |
376 | q{... and My::Class5->meta() still does Role::Foo} ); |
377 | } |
378 | |
4fed6bbc |
379 | { |
380 | package My::Class6; |
381 | use Moose; |
9f82cc33 |
382 | |
f785aad8 |
383 | Moose::Util::MetaRole::apply_metaroles( |
384 | for => 'My::Class6', |
385 | class_metaroles => { class => ['Role::Bar'] }, |
4fed6bbc |
386 | ); |
387 | |
388 | extends 'My::Class'; |
389 | } |
390 | |
391 | { |
392 | ok( My::Class6->meta()->meta()->does_role('Role::Bar'), |
393 | q{apply Role::Bar My::Class6->meta() before extends} ); |
394 | ok( My::Class6->meta()->meta()->does_role('Role::Foo'), |
f8b6827f |
395 | q{... and My::Class6->meta() does Role::Foo because My::Class6 extends My::Class} ); |
00c71b9f |
396 | } |
4fed6bbc |
397 | |
f8b6827f |
398 | # This is the hack that used to be needed to work around the |
399 | # _fix_metaclass_incompatibility problem. You called extends() (which |
400 | # in turn calls _fix_metaclass_imcompatibility) _before_ you apply |
401 | # more extensions in the subclass. We wabt to make sure this continues |
402 | # to work in the future. |
4fed6bbc |
403 | { |
404 | package My::Class7; |
405 | use Moose; |
406 | |
407 | # In real usage this would go in a BEGIN block so it happened |
f785aad8 |
408 | # before apply_metaroles was called by an extension. |
4fed6bbc |
409 | extends 'My::Class'; |
410 | |
f785aad8 |
411 | Moose::Util::MetaRole::apply_metaroles( |
412 | for => 'My::Class7', |
413 | class_metaroles => { class => ['Role::Bar'] }, |
4fed6bbc |
414 | ); |
415 | } |
416 | |
417 | { |
418 | ok( My::Class7->meta()->meta()->does_role('Role::Bar'), |
419 | q{apply Role::Bar My::Class7->meta() before extends} ); |
420 | ok( My::Class7->meta()->meta()->does_role('Role::Foo'), |
f8b6827f |
421 | q{... and My::Class7->meta() does Role::Foo because My::Class7 extends My::Class} ); |
422 | } |
423 | |
424 | { |
425 | package My::Class8; |
426 | use Moose; |
427 | |
f785aad8 |
428 | Moose::Util::MetaRole::apply_metaroles( |
429 | for => 'My::Class8', |
430 | class_metaroles => { |
431 | class => ['Role::Bar'], |
432 | attribute => ['Role::Bar'], |
433 | }, |
f8b6827f |
434 | ); |
435 | |
436 | extends 'My::Class'; |
437 | } |
438 | |
439 | { |
440 | ok( My::Class8->meta()->meta()->does_role('Role::Bar'), |
441 | q{apply Role::Bar My::Class8->meta() before extends} ); |
442 | ok( My::Class8->meta()->meta()->does_role('Role::Foo'), |
443 | q{... and My::Class8->meta() does Role::Foo because My::Class8 extends My::Class} ); |
444 | ok( My::Class8->meta()->attribute_metaclass->meta()->does_role('Role::Bar'), |
445 | q{apply Role::Bar to My::Class8->meta()->attribute_metaclass before extends} ); |
446 | ok( My::Class8->meta()->attribute_metaclass->meta()->does_role('Role::Foo'), |
447 | q{... and My::Class8->meta()->attribute_metaclass does Role::Foo because My::Class8 extends My::Class} ); |
448 | } |
449 | |
450 | |
451 | { |
452 | package My::Class9; |
453 | use Moose; |
454 | |
f785aad8 |
455 | Moose::Util::MetaRole::apply_metaroles( |
456 | for => 'My::Class9', |
457 | class_metaroles => { attribute => ['Role::Bar'] }, |
f8b6827f |
458 | ); |
459 | |
460 | extends 'My::Class'; |
461 | } |
462 | |
463 | { |
464 | ok( My::Class9->meta()->meta()->does_role('Role::Foo'), |
465 | q{... and My::Class9->meta() does Role::Foo because My::Class9 extends My::Class} ); |
466 | ok( My::Class9->meta()->attribute_metaclass->meta()->does_role('Role::Bar'), |
467 | q{apply Role::Bar to My::Class9->meta()->attribute_metaclass before extends} ); |
468 | ok( My::Class9->meta()->attribute_metaclass->meta()->does_role('Role::Foo'), |
469 | q{... and My::Class9->meta()->attribute_metaclass does Role::Foo because My::Class9 extends My::Class} ); |
4fed6bbc |
470 | } |
dd37a5be |
471 | |
472 | # This tests applying meta roles to a metaclass's metaclass. This is |
473 | # completely insane, but is exactly what happens with |
474 | # Fey::Meta::Class::Table. It's a subclass of Moose::Meta::Class |
475 | # itself, and then it _uses_ MooseX::ClassAttribute, so the metaclass |
476 | # for Fey::Meta::Class::Table does a role. |
477 | # |
478 | # At one point this caused a metaclass incompatibility error down |
479 | # below, when we applied roles to the metaclass of My::Class10. It's |
480 | # all madness but as long as the tests pass we're happy. |
481 | { |
482 | package My::Meta::Class2; |
483 | use Moose; |
484 | extends 'Moose::Meta::Class'; |
485 | |
f785aad8 |
486 | Moose::Util::MetaRole::apply_metaroles( |
487 | for => 'My::Meta::Class2', |
488 | class_metaroles => { class => ['Role::Foo'] }, |
dd37a5be |
489 | ); |
490 | } |
491 | |
492 | { |
896e6f85 |
493 | package My::Object; |
494 | use Moose; |
495 | extends 'Moose::Object'; |
496 | } |
497 | |
498 | { |
dd37a5be |
499 | package My::Meta2; |
500 | |
501 | use Moose::Exporter; |
502 | Moose::Exporter->setup_import_methods( also => 'Moose' ); |
503 | |
504 | sub init_meta { |
505 | shift; |
506 | my %p = @_; |
507 | |
896e6f85 |
508 | Moose->init_meta( |
509 | %p, |
510 | metaclass => 'My::Meta::Class2', |
511 | base_class => 'My::Object', |
512 | ); |
dd37a5be |
513 | } |
514 | } |
515 | |
516 | { |
517 | package My::Class10; |
518 | My::Meta2->import; |
519 | |
f785aad8 |
520 | Moose::Util::MetaRole::apply_metaroles( |
521 | for => 'My::Class10', |
522 | class_metaroles => { class => ['Role::Bar'] }, |
dd37a5be |
523 | ); |
524 | } |
525 | |
526 | { |
527 | ok( My::Class10->meta()->meta()->meta()->does_role('Role::Foo'), |
528 | q{My::Class10->meta()->meta() does Role::Foo } ); |
b72373c4 |
529 | ok( My::Class10->meta()->meta()->does_role('Role::Bar'), |
530 | q{My::Class10->meta()->meta() does Role::Bar } ); |
dd37a5be |
531 | ok( My::Class10->meta()->isa('My::Meta::Class2'), |
532 | q{... and My::Class10->meta still isa(My::Meta::Class2)} ); |
896e6f85 |
533 | ok( My::Class10->isa('My::Object'), |
534 | q{... and My::Class10 still isa(My::Object)} ); |
dd37a5be |
535 | } |
8f05895e |
536 | |
537 | { |
538 | package My::Constructor; |
539 | |
540 | use base 'Moose::Meta::Method::Constructor'; |
541 | } |
542 | |
543 | { |
544 | package My::Class11; |
545 | |
546 | use Moose; |
547 | |
548 | __PACKAGE__->meta->constructor_class('My::Constructor'); |
549 | |
f785aad8 |
550 | Moose::Util::MetaRole::apply_metaroles( |
551 | for => 'My::Class11', |
552 | class_metaroles => { class => ['Role::Foo'] }, |
8f05895e |
553 | ); |
554 | } |
555 | |
556 | { |
557 | ok( My::Class11->meta()->meta()->does_role('Role::Foo'), |
558 | q{My::Class11->meta()->meta() does Role::Foo } ); |
559 | is( My::Class11->meta()->constructor_class, 'My::Constructor', |
560 | q{... and explicitly set constructor_class value is unchanged)} ); |
561 | } |
fdeb8354 |
562 | |
563 | { |
564 | package ExportsMoose; |
565 | |
566 | Moose::Exporter->setup_import_methods( |
f785aad8 |
567 | also => 'Moose', |
fdeb8354 |
568 | ); |
569 | |
570 | sub init_meta { |
571 | shift; |
572 | my %p = @_; |
573 | Moose->init_meta(%p); |
f785aad8 |
574 | return Moose::Util::MetaRole::apply_metaroles( |
3b400403 |
575 | for => $p{for_class}, |
fdeb8354 |
576 | # Causes us to recurse through init_meta, as we have to |
577 | # load MyMetaclassRole from disk. |
3b400403 |
578 | class_metaroles => { class => [qw/MyMetaclassRole/] }, |
fdeb8354 |
579 | ); |
580 | } |
581 | } |
582 | |
583 | lives_ok { |
584 | package UsesExportedMoose; |
585 | ExportsMoose->import; |
586 | } 'import module which loads a role from disk during init_meta'; |
587 | |
b05518b2 |
588 | { |
589 | package Foo::Meta::Role; |
590 | |
591 | use Moose::Role; |
592 | } |
f785aad8 |
593 | |
b05518b2 |
594 | { |
595 | package Foo::Role; |
596 | |
597 | Moose::Exporter->setup_import_methods( |
f785aad8 |
598 | also => 'Moose::Role', |
b05518b2 |
599 | ); |
600 | |
601 | sub init_meta { |
602 | shift; |
603 | my %p = @_; |
f785aad8 |
604 | |
b05518b2 |
605 | Moose::Role->init_meta(%p); |
f785aad8 |
606 | |
607 | return Moose::Util::MetaRole::apply_metaroles( |
608 | for => $p{for_class}, |
609 | role_metaroles => { method => ['Foo::Meta::Role'] }, |
b05518b2 |
610 | ); |
611 | } |
612 | } |
f785aad8 |
613 | |
b05518b2 |
614 | { |
615 | package Role::Baz; |
616 | |
617 | Foo::Role->import; |
618 | |
619 | sub bla {} |
620 | } |
f785aad8 |
621 | |
b05518b2 |
622 | { |
623 | package My::Class12; |
624 | |
625 | use Moose; |
626 | |
627 | with( 'Role::Baz' ); |
628 | } |
f785aad8 |
629 | |
b05518b2 |
630 | { |
631 | ok( |
632 | My::Class12->meta->does_role( 'Role::Baz' ), |
633 | 'role applied' |
634 | ); |
f785aad8 |
635 | |
b05518b2 |
636 | my $method = My::Class12->meta->get_method( 'bla' ); |
637 | ok( |
638 | $method->meta->does_role( 'Foo::Meta::Role' ), |
639 | 'method_metaclass_role applied' |
640 | ); |
641 | } |
629ba321 |
642 | |
643 | { |
644 | package Parent; |
645 | use Moose; |
646 | |
f785aad8 |
647 | Moose::Util::MetaRole::apply_metaroles( |
648 | for => __PACKAGE__, |
649 | class_metaroles => { constructor => ['Role::Foo'] }, |
629ba321 |
650 | ); |
651 | } |
652 | |
653 | { |
654 | package Child; |
655 | |
656 | use Moose; |
657 | extends 'Parent'; |
658 | } |
659 | |
660 | { |
661 | ok( |
662 | Parent->meta->constructor_class->meta->can('does_role') |
663 | && Parent->meta->constructor_class->meta->does_role('Role::Foo'), |
664 | 'Parent constructor class has metarole from Parent' |
665 | ); |
666 | |
63eeb72b |
667 | ok( |
668 | Child->meta->constructor_class->meta->can('does_role') |
669 | && Child->meta->constructor_class->meta->does_role( |
670 | 'Role::Foo'), |
671 | 'Child constructor class has metarole from Parent' |
672 | ); |
629ba321 |
673 | } |
a28e50e4 |
674 | |
675 | done_testing; |