diff options
Diffstat (limited to 't/exceptions/moose-meta-role-application-toclass.t')
-rw-r--r-- | t/exceptions/moose-meta-role-application-toclass.t | 432 |
1 files changed, 432 insertions, 0 deletions
diff --git a/t/exceptions/moose-meta-role-application-toclass.t b/t/exceptions/moose-meta-role-application-toclass.t new file mode 100644 index 0000000..2a32e38 --- /dev/null +++ b/t/exceptions/moose-meta-role-application-toclass.t @@ -0,0 +1,432 @@ +use strict; +use warnings; + +use Test::More; +use Test::Fatal; + +use Moose(); + +use Moose::Util 'find_meta'; + +{ + { + package BarRole; + use Moose::Role; + } + + { + package RoleExcludingBarRole; + use Moose::Role; + excludes 'BarRole'; + } + + my $exception = exception { + { + package FooClass; + use Moose; + + with 'RoleExcludingBarRole'; + with 'BarRole'; + } + }; + + like( + $exception, + qr/\QConflict detected: FooClass excludes role 'BarRole'/, + 'class FooClass excludes Role BarRole'); + + isa_ok( + $exception, + "Moose::Exception::ConflictDetectedInCheckRoleExclusionsInToClass", + 'class FooClass excludes Role BarRole'); + + is( + $exception->class_name, + "FooClass", + 'class FooClass excludes Role BarRole'); + + is( + find_meta($exception->class_name), + FooClass->meta, + 'class FooClass excludes Role BarRole'); + + is( + $exception->role_name, + "BarRole", + 'class FooClass excludes Role BarRole'); + + is( + find_meta($exception->role_name), + BarRole->meta, + 'class FooClass excludes Role BarRole'); +} + +{ + { + package BarRole2; + use Moose::Role; + excludes 'ExcludedRole2'; + } + + { + package ExcludedRole2; + use Moose::Role; + } + + my $exception = exception { + { + package FooClass2; + use Moose; + + with 'ExcludedRole2'; + with 'BarRole2'; + } + }; + + like( + $exception, + qr/\QThe class FooClass2 does the excluded role 'ExcludedRole2'/, + 'Class FooClass2 does Role ExcludedRole2'); + + isa_ok( + $exception, + "Moose::Exception::ClassDoesTheExcludedRole", + 'Class FooClass2 does Role ExcludedRole2'); + + is( + $exception->role_name, + "BarRole2", + 'Class FooClass2 does Role ExcludedRole2'); + + is( + find_meta($exception->role_name), + BarRole2->meta, + 'Class FooClass2 does Role ExcludedRole2'); + + is( + $exception->excluded_role_name, + "ExcludedRole2", + 'Class FooClass2 does Role ExcludedRole2'); + + is( + find_meta($exception->excluded_role_name), + ExcludedRole2->meta, + 'Class FooClass2 does Role ExcludedRole2'); + + is( + $exception->class_name, + "FooClass2", + 'Class FooClass2 does Role ExcludedRole2'); + + is( + find_meta($exception->class_name), + FooClass2->meta, + 'Class FooClass2 does Role ExcludedRole2'); +} + +{ + { + package Foo5; + use Moose::Role; + + sub foo5 { "foo" } + } + + my $exception = exception { + { + package Bar5; + use Moose; + with 'Foo5' => { + -alias => { foo5 => 'foo_in_bar' } + }; + + sub foo_in_bar { "test in foo" } + } + }; + + like( + $exception, + qr/\QCannot create a method alias if a local method of the same name exists/, + "Class Bar5 already has a method named foo_in_bar"); + + isa_ok( + $exception, + "Moose::Exception::CannotCreateMethodAliasLocalMethodIsPresentInClass", + "Class Bar5 already has a method named foo_in_bar"); + + is( + $exception->role_name, + "Foo5", + "Class Bar5 already has a method named foo_in_bar"); + + is( + find_meta($exception->role_name), + Foo5->meta, + "Class Bar5 already has a method named foo_in_bar"); + + is( + $exception->class_name, + "Bar5", + "Class Bar5 already has a method named foo_in_bar"); + + is( + find_meta($exception->class_name), + Bar5->meta, + "Class Bar5 already has a method named foo_in_bar"); + + is( + $exception->aliased_method_name, + "foo_in_bar", + "Class Bar5 already has a method named foo_in_bar"); + + is( + $exception->method->name, + "foo5", + "Class Bar5 already has a method named foo_in_bar"); +} + +{ + { + package Foo::Role; + use Moose::Role; + + sub foo { 'Foo::Role::foo' } + } + + { + package Bar::Role; + use Moose::Role; + + sub foo { 'Bar::Role::foo' } + } + + { + package Baz::Role; + use Moose::Role; + + sub foo { 'Baz::Role::foo' } + } + + my $exception = exception { + { + package My::Foo::Class::Broken; + use Moose; + + with 'Foo::Role', + 'Bar::Role', + 'Baz::Role' => { -excludes => 'foo' }; + } + }; + + like( + $exception, + qr/\QDue to a method name conflict in roles 'Bar::Role' and 'Foo::Role', the method 'foo' must be implemented or excluded by 'My::Foo::Class::Broken'/, + 'Foo::Role, Bar::Role & Baz::Role, all three has a method named foo'); + + isa_ok( + $exception, + "Moose::Exception::MethodNameConflictInRoles", + 'Foo::Role, Bar::Role & Baz::Role, all three has a method named foo'); + + is( + $exception->class_name, + "My::Foo::Class::Broken", + 'Foo::Role, Bar::Role & Baz::Role, all three has a method named foo'); + + is( + find_meta($exception->class_name), + My::Foo::Class::Broken->meta, + 'Foo::Role, Bar::Role & Baz::Role, all three has a method named foo'); + + is( + $exception->get_method_at(0)->name, + "foo", + 'Foo::Role, Bar::Role & Baz::Role, all three has a method named foo'); + + is( + $exception->get_method_at(0)->roles_as_english_list, + "'Bar::Role' and 'Foo::Role'", + 'Foo::Role, Bar::Role & Baz::Role, all three has a method named foo'); +} + +{ + { + package Foo2::Role; + use Moose::Role; + + sub foo { 'Foo2::Role::foo' } + sub bar { 'Foo2::Role::bar' } + } + + { + package Bar2::Role; + use Moose::Role; + + sub foo { 'Bar2::Role::foo' } + sub bar { 'Bar2::Role::bar' } + } + + { + package Baz2::Role; + use Moose::Role; + + sub foo { 'Baz2::Role::foo' } + sub bar { 'Baz2::Role::bar' } + } + + my $exception = exception { + { + package My::Foo::Class::Broken2; + use Moose; + + with 'Foo2::Role', + 'Bar2::Role', + 'Baz2::Role'; + } + }; + + like( + $exception, + qr/\QDue to method name conflicts in roles 'Bar2::Role' and 'Foo2::Role', the methods 'bar' and 'foo' must be implemented or excluded by 'My::Foo::Class::Broken2'/, + 'Foo2::Role, Bar2::Role & Baz2::Role, all three has a methods named foo & bar'); + + isa_ok( + $exception, + "Moose::Exception::MethodNameConflictInRoles", + 'Foo2::Role, Bar2::Role & Baz2::Role, all three has a methods named foo & bar'); + + is( + $exception->class_name, + "My::Foo::Class::Broken2", + 'Foo2::Role, Bar2::Role & Baz2::Role, all three has a methods named foo & bar'); + + is( + find_meta($exception->class_name), + My::Foo::Class::Broken2->meta, + 'Foo2::Role, Bar2::Role & Baz2::Role, all three has a methods named foo & bar'); + + is( + $exception->get_method_at(0)->roles_as_english_list, + "'Bar2::Role' and 'Foo2::Role'", + 'Foo2::Role, Bar2::Role & Baz2::Role, all three has a methods named foo & bar'); +} + +{ + { + package Foo3::Role; + use Moose::Role; + requires 'foo'; + } + + { + package Bar3::Role; + use Moose::Role; + } + + { + package Baz3::Role; + use Moose::Role; + } + + my $exception = exception { + { + package My::Foo::Class::Broken3; + use Moose; + with 'Foo3::Role', + 'Bar3::Role', + 'Baz3::Role'; + } + }; + + like( + $exception, + qr/\Q'Foo3::Role|Bar3::Role|Baz3::Role' requires the method 'foo' to be implemented by 'My::Foo::Class::Broken3'/, + "foo is required by Foo3::Role, but it's not implemented by My::Foo::Class::Broken3"); + + isa_ok( + $exception, + "Moose::Exception::RequiredMethodsNotImplementedByClass", + "foo is required by Foo3::Role, but it's not implemented by My::Foo::Class::Broken3"); + + is( + $exception->class_name, + "My::Foo::Class::Broken3", + "foo is required by Foo3::Role, but it's not implemented by My::Foo::Class::Broken3"); + + is( + find_meta($exception->class_name), + My::Foo::Class::Broken3->meta, + "foo is required by Foo3::Role, but it's not implemented by My::Foo::Class::Broken3"); + + is( + $exception->role_name, + 'Foo3::Role|Bar3::Role|Baz3::Role', + "foo is required by Foo3::Role, but it's not implemented by My::Foo::Class::Broken3"); + + is( + $exception->get_method_at(0)->name, + "foo", + "foo is required by Foo3::Role, but it's not implemented by My::Foo::Class::Broken3"); +} + +{ + BEGIN { + package ExportsFoo; + use Sub::Exporter -setup => { + exports => ['foo'], + }; + + sub foo { 'FOO' } + + $INC{'ExportsFoo.pm'} = 1; + } + + { + package Foo4::Role; + use Moose::Role; + requires 'foo'; + } + + my $exception = exception { + { + package Class; + use Moose; + use ExportsFoo 'foo'; + with 'Foo4::Role'; + } + }; + + my $methodName = "\\&foo"; + + like( + $exception, + qr/\Q'Foo4::Role' requires the method 'foo' to be implemented by 'Class'. If you imported functions intending to use them as methods, you need to explicitly mark them as such, via Class->meta->add_method(foo => $methodName)/, + "foo is required by Foo4::Role and imported by Class"); + + isa_ok( + $exception, + "Moose::Exception::RequiredMethodsImportedByClass", + "foo is required by Foo4::Role and imported by Class"); + + is( + $exception->class_name, + "Class", + "foo is required by Foo4::Role and imported by Class"); + + is( + find_meta($exception->class_name), + Class->meta, + "foo is required by Foo4::Role and imported by Class"); + + is( + $exception->role_name, + 'Foo4::Role', + "foo is required by Foo4::Role and imported by Class"); + + is( + $exception->get_method_at(0)->name, + "foo", + "foo is required by Foo4::Role and imported by Class"); +} + +done_testing; |