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