Add what does moose stand for section back to docs
[gitmo/Moose.git] / t / metaclasses / metarole.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use lib 't/lib', 'lib';
7
8 use Test::More;
9 use Test::Fatal;
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 {
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 {
33     package My::Role;
34     use Moose::Role;
35 }
36
37 {
38     Moose::Util::MetaRole::apply_metaroles(
39         for             => My::Class->meta,
40         class_metaroles => { class => ['Role::Foo'] },
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 {
50     Moose::Util::MetaRole::apply_metaroles(
51         for             => 'My::Class',
52         class_metaroles => { attribute => ['Role::Foo'] },
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 {
66     Moose::Util::MetaRole::apply_metaroles(
67         for             => 'My::Class',
68         class_metaroles => { method => ['Role::Foo'] },
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 {
84     Moose::Util::MetaRole::apply_metaroles(
85         for             => 'My::Class',
86         class_metaroles => { wrapped_method => ['Role::Foo'] },
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 {
104     Moose::Util::MetaRole::apply_metaroles(
105         for             => 'My::Class',
106         class_metaroles => { instance => ['Role::Foo'] },
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 {
123     Moose::Util::MetaRole::apply_metaroles(
124         for             => 'My::Class',
125         class_metaroles => { constructor => ['Role::Foo'] },
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 {
145     Moose::Util::MetaRole::apply_metaroles(
146         for             => 'My::Class',
147         class_metaroles => { destructor => ['Role::Foo'] },
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 {
169     Moose::Util::MetaRole::apply_metaroles(
170         for            => 'My::Role',
171         role_metaroles => { application_to_class => ['Role::Foo'] },
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 {
182     Moose::Util::MetaRole::apply_metaroles(
183         for            => 'My::Role',
184         role_metaroles => { application_to_role => ['Role::Foo'] },
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 {
197     Moose::Util::MetaRole::apply_metaroles(
198         for            => 'My::Role',
199         role_metaroles => { application_to_instance => ['Role::Foo'] },
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 {
214     Moose::Util::MetaRole::apply_base_class_roles(
215         for   => 'My::Class',
216         roles => ['Role::Foo'],
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 {
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         },
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 {
301     Moose::Util::MetaRole::apply_metaroles(
302         for             => 'My::Class3',
303         class_metaroles => { class => ['Role::Foo'] },
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() ),
311         'apply_metaroles() does not interfere with metaclass set via Moose->init_meta()' );
312 }
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 {
326     Moose::Util::MetaRole::apply_metaroles(
327         for             => 'My::Class4',
328         class_metaroles => { class => ['Role::Foo'] },
329     );
330
331     ok( My::Class4->meta()->meta()->does_role('Role::Foo'),
332         'apply Role::Foo to My::Class4->meta()' );
333
334     Moose::Util::MetaRole::apply_metaroles(
335         for             => 'My::Class4',
336         class_metaroles => { class => ['Role::Bar'] },
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 }
344
345 {
346     package My::Class5;
347     use Moose;
348
349     extends 'My::Class';
350 }
351
352 {
353     ok( My::Class5->meta()->meta()->does_role('Role::Foo'),
354         q{My::Class5->meta()'s does Role::Foo because it extends My::Class} );
355     ok( My::Class5->meta()->attribute_metaclass()->meta()->does_role('Role::Foo'),
356         q{My::Class5->meta()'s attribute metaclass also does Role::Foo} );
357     ok( My::Class5->meta()->method_metaclass()->meta()->does_role('Role::Foo'),
358         q{My::Class5->meta()'s method metaclass also does Role::Foo} );
359     ok( My::Class5->meta()->instance_metaclass()->meta()->does_role('Role::Foo'),
360         q{My::Class5->meta()'s instance metaclass also does Role::Foo} );
361     ok( My::Class5->meta()->constructor_class()->meta()->does_role('Role::Foo'),
362         q{My::Class5->meta()'s constructor class also does Role::Foo} );
363     ok( My::Class5->meta()->destructor_class()->meta()->does_role('Role::Foo'),
364         q{My::Class5->meta()'s destructor class also does Role::Foo} );
365 }
366
367 {
368     Moose::Util::MetaRole::apply_metaroles(
369         for             => 'My::Class5',
370         class_metaroles => { class => ['Role::Bar'] },
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
379 {
380     package My::Class6;
381     use Moose;
382
383     Moose::Util::MetaRole::apply_metaroles(
384         for             => 'My::Class6',
385         class_metaroles => { class => ['Role::Bar'] },
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'),
395         q{... and My::Class6->meta() does Role::Foo because My::Class6 extends My::Class} );
396 }
397
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.
403 {
404     package My::Class7;
405     use Moose;
406
407     # In real usage this would go in a BEGIN block so it happened
408     # before apply_metaroles was called by an extension.
409     extends 'My::Class';
410
411     Moose::Util::MetaRole::apply_metaroles(
412         for             => 'My::Class7',
413         class_metaroles => { class => ['Role::Bar'] },
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'),
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
428     Moose::Util::MetaRole::apply_metaroles(
429         for             => 'My::Class8',
430         class_metaroles => {
431             class     => ['Role::Bar'],
432             attribute => ['Role::Bar'],
433         },
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
455     Moose::Util::MetaRole::apply_metaroles(
456         for             => 'My::Class9',
457         class_metaroles => { attribute => ['Role::Bar'] },
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} );
470 }
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
486     Moose::Util::MetaRole::apply_metaroles(
487         for             => 'My::Meta::Class2',
488         class_metaroles => { class => ['Role::Foo'] },
489     );
490 }
491
492 {
493     package My::Object;
494     use Moose;
495     extends 'Moose::Object';
496 }
497
498 {
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
508         Moose->init_meta(
509             %p,
510             metaclass  => 'My::Meta::Class2',
511             base_class => 'My::Object',
512         );
513     }
514 }
515
516 {
517     package My::Class10;
518     My::Meta2->import;
519
520     Moose::Util::MetaRole::apply_metaroles(
521         for             => 'My::Class10',
522         class_metaroles => { class => ['Role::Bar'] },
523     );
524 }
525
526 {
527     ok( My::Class10->meta()->meta()->meta()->does_role('Role::Foo'),
528         q{My::Class10->meta()->meta() does Role::Foo } );
529     ok( My::Class10->meta()->meta()->does_role('Role::Bar'),
530         q{My::Class10->meta()->meta() does Role::Bar } );
531     ok( My::Class10->meta()->isa('My::Meta::Class2'),
532         q{... and My::Class10->meta still isa(My::Meta::Class2)} );
533     ok( My::Class10->isa('My::Object'),
534         q{... and My::Class10 still isa(My::Object)} );
535 }
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
550     Moose::Util::MetaRole::apply_metaroles(
551         for             => 'My::Class11',
552         class_metaroles => { class => ['Role::Foo'] },
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 }
562
563 {
564     package ExportsMoose;
565
566     Moose::Exporter->setup_import_methods(
567         also => 'Moose',
568     );
569
570     sub init_meta {
571         shift;
572         my %p = @_;
573         Moose->init_meta(%p);
574         return Moose::Util::MetaRole::apply_metaroles(
575             for => $p{for_class},
576             # Causes us to recurse through init_meta, as we have to
577             # load MyMetaclassRole from disk.
578             class_metaroles => { class => [qw/MyMetaclassRole/] },
579         );
580     }
581 }
582
583 is( exception {
584     package UsesExportedMoose;
585     ExportsMoose->import;
586 }, undef, 'import module which loads a role from disk during init_meta' );
587
588 {
589     package Foo::Meta::Role;
590
591     use Moose::Role;
592 }
593
594 {
595     package Foo::Role;
596
597     Moose::Exporter->setup_import_methods(
598         also => 'Moose::Role',
599     );
600
601     sub init_meta {
602         shift;
603         my %p = @_;
604
605         Moose::Role->init_meta(%p);
606
607         return Moose::Util::MetaRole::apply_metaroles(
608             for            => $p{for_class},
609             role_metaroles => { method => ['Foo::Meta::Role'] },
610         );
611     }
612 }
613
614 {
615     package Role::Baz;
616
617     Foo::Role->import;
618
619     sub bla {}
620 }
621
622 {
623     package My::Class12;
624
625     use Moose;
626
627     with( 'Role::Baz' );
628 }
629
630 {
631     ok(
632         My::Class12->meta->does_role( 'Role::Baz' ),
633         'role applied'
634     );
635
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 }
642
643 {
644     package Parent;
645     use Moose;
646
647     Moose::Util::MetaRole::apply_metaroles(
648         for             => __PACKAGE__,
649         class_metaroles => { constructor => ['Role::Foo'] },
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
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     );
673 }
674
675 {
676     package NotMoosey;
677
678     use metaclass;
679 }
680
681 {
682     like(
683         exception {
684             Moose::Util::MetaRole::apply_metaroles(
685                 for             => 'Does::Not::Exist',
686                 class_metaroles => { class => ['Role::Foo'] },
687             );
688         },
689         qr/When using Moose::Util::MetaRole.+You passed Does::Not::Exist.+Maybe you need to call.+/,
690         'useful error when apply metaroles to a class without a metaclass'
691     );
692
693     like(
694         exception {
695             Moose::Util::MetaRole::apply_metaroles(
696                 for             => 'NotMoosey',
697                 class_metaroles => { class => ['Role::Foo'] },
698             );
699         },
700         qr/When using Moose::Util::MetaRole.+You passed NotMoosey.+we resolved this to a Class::MOP::Class object.+/,
701         'useful error when using apply metaroles to a class with a Class::MOP::Class metaclass'
702     );
703
704     like(
705         exception {
706             Moose::Util::MetaRole::apply_base_class_roles(
707                 for   => 'NotMoosey',
708                 roles => { class => ['Role::Foo'] },
709             );
710         },
711         qr/When using Moose::Util::MetaRole.+You passed NotMoosey.+we resolved this to a Class::MOP::Class object.+/,
712         'useful error when applying base class to roles to a non-Moose class'
713     );
714
715     like(
716         exception {
717             Moose::Util::MetaRole::apply_base_class_roles(
718                 for   => 'My::Role',
719                 roles => { class => ['Role::Foo'] },
720             );
721         },
722         qr/You can only apply base class roles to a Moose class.+/,
723         'useful error when applying base class to roles to a non-Moose class'
724     );
725 }
726
727 done_testing;