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;