Test coercion of lazy defaults
[gitmo/Moose.git] / t / 050_metaclasses / 015_metarole.t
index cd0c7d2..1bdde3e 100644 (file)
@@ -5,8 +5,8 @@ use warnings;
 
 use lib 't/lib', 'lib';
 
-use Test::More tests => 78;
-use Test::Exception;
+use Test::More;
+use Test::Fatal;
 
 use Moose::Util::MetaRole;
 
@@ -30,9 +30,14 @@ use Moose::Util::MetaRole;
 }
 
 {
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class       => 'My::Class',
-        metaclass_roles => ['Role::Foo'],
+    package My::Role;
+    use Moose::Role;
+}
+
+{
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => My::Class->meta,
+        class_metaroles => { class => ['Role::Foo'] },
     );
 
     ok( My::Class->meta()->meta()->does_role('Role::Foo'),
@@ -42,9 +47,9 @@ use Moose::Util::MetaRole;
 }
 
 {
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class                 => 'My::Class',
-        attribute_metaclass_roles => ['Role::Foo'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class',
+        class_metaroles => { attribute => ['Role::Foo'] },
     );
 
     ok( My::Class->meta()->attribute_metaclass()->meta()->does_role('Role::Foo'),
@@ -58,9 +63,9 @@ use Moose::Util::MetaRole;
 }
 
 {
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class              => 'My::Class',
-        method_metaclass_roles => ['Role::Foo'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class',
+        class_metaroles => { method => ['Role::Foo'] },
     );
 
     ok( My::Class->meta()->method_metaclass()->meta()->does_role('Role::Foo'),
@@ -76,9 +81,9 @@ use Moose::Util::MetaRole;
 }
 
 {
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class                      => 'My::Class',
-        wrapped_method_metaclass_roles => ['Role::Foo'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class',
+        class_metaroles => { wrapped_method => ['Role::Foo'] },
     );
 
     ok( My::Class->meta()->wrapped_method_metaclass()->meta()->does_role('Role::Foo'),
@@ -96,9 +101,9 @@ use Moose::Util::MetaRole;
 }
 
 {
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class              => 'My::Class',
-        instance_metaclass_roles => ['Role::Foo'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class',
+        class_metaroles => { instance => ['Role::Foo'] },
     );
 
     ok( My::Class->meta()->instance_metaclass()->meta()->does_role('Role::Foo'),
@@ -115,9 +120,9 @@ use Moose::Util::MetaRole;
 }
 
 {
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class               => 'My::Class',
-        constructor_class_roles => ['Role::Foo'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class',
+        class_metaroles => { constructor => ['Role::Foo'] },
     );
 
     ok( My::Class->meta()->constructor_class()->meta()->does_role('Role::Foo'),
@@ -137,9 +142,9 @@ use Moose::Util::MetaRole;
 }
 
 {
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class              => 'My::Class',
-        destructor_class_roles => ['Role::Foo'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class',
+        class_metaroles => { destructor => ['Role::Foo'] },
     );
 
     ok( My::Class->meta()->destructor_class()->meta()->does_role('Role::Foo'),
@@ -161,9 +166,54 @@ use Moose::Util::MetaRole;
 }
 
 {
+    Moose::Util::MetaRole::apply_metaroles(
+        for            => 'My::Role',
+        role_metaroles => { application_to_class => ['Role::Foo'] },
+    );
+
+    ok( My::Role->meta->application_to_class_class->meta->does_role('Role::Foo'),
+        q{apply Role::Foo to My::Role->meta's application_to_class class} );
+
+    is( My::Role->meta->application_to_class_class->new->foo, 10,
+        q{... call foo() on an application_to_class instance} );
+}
+
+{
+    Moose::Util::MetaRole::apply_metaroles(
+        for            => 'My::Role',
+        role_metaroles => { application_to_role => ['Role::Foo'] },
+    );
+
+    ok( My::Role->meta->application_to_role_class->meta->does_role('Role::Foo'),
+        q{apply Role::Foo to My::Role->meta's application_to_role class} );
+    ok( My::Role->meta->application_to_class_class->meta->does_role('Role::Foo'),
+        q{... My::Role->meta's application_to_class class still does Role::Foo} );
+
+    is( My::Role->meta->application_to_role_class->new->foo, 10,
+        q{... call foo() on an application_to_role instance} );
+}
+
+{
+    Moose::Util::MetaRole::apply_metaroles(
+        for            => 'My::Role',
+        role_metaroles => { application_to_instance => ['Role::Foo'] },
+    );
+
+    ok( My::Role->meta->application_to_instance_class->meta->does_role('Role::Foo'),
+        q{apply Role::Foo to My::Role->meta's application_to_instance class} );
+    ok( My::Role->meta->application_to_role_class->meta->does_role('Role::Foo'),
+        q{... My::Role->meta's application_to_role class still does Role::Foo} );
+    ok( My::Role->meta->application_to_class_class->meta->does_role('Role::Foo'),
+        q{... My::Role->meta's application_to_class class still does Role::Foo} );
+
+    is( My::Role->meta->application_to_instance_class->new->foo, 10,
+        q{... call foo() on an application_to_instance instance} );
+}
+
+{
     Moose::Util::MetaRole::apply_base_class_roles(
-        for_class => 'My::Class',
-        roles     => ['Role::Foo'],
+        for   => 'My::Class',
+        roles => ['Role::Foo'],
     );
 
     ok( My::Class->meta()->does_role('Role::Foo'),
@@ -179,14 +229,16 @@ use Moose::Util::MetaRole;
 }
 
 {
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class                 => 'My::Class2',
-        metaclass_roles           => ['Role::Foo'],
-        attribute_metaclass_roles => ['Role::Foo'],
-        method_metaclass_roles    => ['Role::Foo'],
-        instance_metaclass_roles  => ['Role::Foo'],
-        constructor_class_roles   => ['Role::Foo'],
-        destructor_class_roles    => ['Role::Foo'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class2',
+        class_metaroles => {
+            class       => ['Role::Foo'],
+            attribute   => ['Role::Foo'],
+            method      => ['Role::Foo'],
+            instance    => ['Role::Foo'],
+            constructor => ['Role::Foo'],
+            destructor  => ['Role::Foo'],
+        },
     );
 
     ok( My::Class2->meta()->meta()->does_role('Role::Foo'),
@@ -246,9 +298,9 @@ use Moose::Util::MetaRole;
 
 
 {
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class                 => 'My::Class3',
-        metaclass_roles           => ['Role::Foo'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class3',
+        class_metaroles => { class => ['Role::Foo'] },
     );
 
     ok( My::Class3->meta()->meta()->does_role('Role::Foo'),
@@ -256,7 +308,7 @@ use Moose::Util::MetaRole;
     is( My::Class3->meta()->foo(), 10,
         '... and call foo() on that meta object' );
     ok( ( grep { $_ eq 'My::Meta::Class' } My::Class3->meta()->meta()->superclasses() ),
-        'apply_metaclass_roles() does not interfere with metaclass set via Moose->init_meta()' );
+        'apply_metaroles() does not interfere with metaclass set via Moose->init_meta()' );
 }
 
 {
@@ -271,17 +323,17 @@ use Moose::Util::MetaRole;
 }
 
 {
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class                 => 'My::Class4',
-        metaclass_roles           => ['Role::Foo'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class4',
+        class_metaroles => { class => ['Role::Foo'] },
     );
 
     ok( My::Class4->meta()->meta()->does_role('Role::Foo'),
         'apply Role::Foo to My::Class4->meta()' );
 
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class                 => 'My::Class4',
-        metaclass_roles           => ['Role::Bar'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class4',
+        class_metaroles => { class => ['Role::Bar'] },
     );
 
     ok( My::Class4->meta()->meta()->does_role('Role::Bar'),
@@ -313,9 +365,9 @@ use Moose::Util::MetaRole;
 }
 
 {
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class       => 'My::Class5',
-        metaclass_roles => ['Role::Bar'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class5',
+        class_metaroles => { class => ['Role::Bar'] },
     );
 
     ok( My::Class5->meta()->meta()->does_role('Role::Bar'),
@@ -328,9 +380,9 @@ use Moose::Util::MetaRole;
     package My::Class6;
     use Moose;
 
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class       => 'My::Class6',
-        metaclass_roles => ['Role::Bar'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class6',
+        class_metaroles => { class => ['Role::Bar'] },
     );
 
     extends 'My::Class';
@@ -353,12 +405,12 @@ use Moose::Util::MetaRole;
     use Moose;
 
     # In real usage this would go in a BEGIN block so it happened
-    # before apply_metaclass_roles was called by an extension.
+    # before apply_metaroles was called by an extension.
     extends 'My::Class';
 
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class       => 'My::Class7',
-        metaclass_roles => ['Role::Bar'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class7',
+        class_metaroles => { class => ['Role::Bar'] },
     );
 }
 
@@ -373,10 +425,12 @@ use Moose::Util::MetaRole;
     package My::Class8;
     use Moose;
 
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class                 => 'My::Class8',
-        metaclass_roles           => ['Role::Bar'],
-        attribute_metaclass_roles => ['Role::Bar'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class8',
+        class_metaroles => {
+            class     => ['Role::Bar'],
+            attribute => ['Role::Bar'],
+        },
     );
 
     extends 'My::Class';
@@ -398,9 +452,9 @@ use Moose::Util::MetaRole;
     package My::Class9;
     use Moose;
 
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class                 => 'My::Class9',
-        attribute_metaclass_roles => ['Role::Bar'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class9',
+        class_metaroles => { attribute => ['Role::Bar'] },
     );
 
     extends 'My::Class';
@@ -429,9 +483,9 @@ use Moose::Util::MetaRole;
     use Moose;
     extends 'Moose::Meta::Class';
 
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class       => 'My::Meta::Class2',
-        metaclass_roles => ['Role::Foo'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Meta::Class2',
+        class_metaroles => { class => ['Role::Foo'] },
     );
 }
 
@@ -463,9 +517,9 @@ use Moose::Util::MetaRole;
     package My::Class10;
     My::Meta2->import;
 
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class       => 'My::Class10',
-        metaclass_roles => ['Role::Bar'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class10',
+        class_metaroles => { class => ['Role::Bar'] },
     );
 }
 
@@ -493,9 +547,9 @@ use Moose::Util::MetaRole;
 
     __PACKAGE__->meta->constructor_class('My::Constructor');
 
-    Moose::Util::MetaRole::apply_metaclass_roles(
-        for_class       => 'My::Class11',
-        metaclass_roles => ['Role::Foo'],
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => 'My::Class11',
+        class_metaroles => { class => ['Role::Foo'] },
     );
 }
 
@@ -510,24 +564,112 @@ use Moose::Util::MetaRole;
     package ExportsMoose;
 
     Moose::Exporter->setup_import_methods(
-        also        => 'Moose',
+        also => 'Moose',
     );
 
     sub init_meta {
         shift;
         my %p = @_;
         Moose->init_meta(%p);
-        return Moose::Util::MetaRole::apply_metaclass_roles( 
-            for_class       => $p{for_class},
+        return Moose::Util::MetaRole::apply_metaroles(
+            for => $p{for_class},
             # Causes us to recurse through init_meta, as we have to
             # load MyMetaclassRole from disk.
-           metaclass_roles => [qw/MyMetaclassRole/],
+            class_metaroles => { class => [qw/MyMetaclassRole/] },
         );
     }
 }
 
-lives_ok {
+is( exception {
     package UsesExportedMoose;
     ExportsMoose->import;
-} 'import module which loads a role from disk during init_meta';
+}, undef, 'import module which loads a role from disk during init_meta' );
+
+{
+    package Foo::Meta::Role;
+
+    use Moose::Role;
+}
+
+{
+    package Foo::Role;
+
+    Moose::Exporter->setup_import_methods(
+        also => 'Moose::Role',
+    );
+
+    sub init_meta {
+        shift;
+        my %p = @_;
+
+        Moose::Role->init_meta(%p);
+
+        return Moose::Util::MetaRole::apply_metaroles(
+            for            => $p{for_class},
+            role_metaroles => { method => ['Foo::Meta::Role'] },
+        );
+    }
+}
+
+{
+    package Role::Baz;
+
+    Foo::Role->import;
+
+    sub bla {}
+}
+
+{
+    package My::Class12;
+
+    use Moose;
+
+    with( 'Role::Baz' );
+}
+
+{
+    ok(
+        My::Class12->meta->does_role( 'Role::Baz' ),
+        'role applied'
+    );
+
+    my $method = My::Class12->meta->get_method( 'bla' );
+    ok(
+        $method->meta->does_role( 'Foo::Meta::Role' ),
+        'method_metaclass_role applied'
+    );
+}
+
+{
+    package Parent;
+    use Moose;
+
+    Moose::Util::MetaRole::apply_metaroles(
+        for             => __PACKAGE__,
+        class_metaroles => { constructor => ['Role::Foo'] },
+    );
+}
+
+{
+    package Child;
+
+    use Moose;
+    extends 'Parent';
+}
+
+{
+    ok(
+        Parent->meta->constructor_class->meta->can('does_role')
+            && Parent->meta->constructor_class->meta->does_role('Role::Foo'),
+        'Parent constructor class has metarole from Parent'
+    );
+
+    ok(
+        Child->meta->constructor_class->meta->can('does_role')
+            && Child->meta->constructor_class->meta->does_role(
+            'Role::Foo'),
+        'Child constructor class has metarole from Parent'
+    );
+}
 
+done_testing;