Much better error message for role conflicts
Shawn M Moore [Sun, 31 May 2009 02:13:53 +0000 (22:13 -0400)]
lib/Moose/Meta/Role/Application/ToClass.pm
t/030_roles/005_role_conflict_detection.t
t/030_roles/011_overriding.t
t/030_roles/012_method_exclusion_in_composition.t
t/030_roles/013_method_aliasing_in_composition.t

index 69d7bc0..f7573ab 100644 (file)
@@ -77,15 +77,16 @@ sub check_required_methods {
 
     if (@conflicts) {
         my $conflict = $conflicts[0];
+        my $roles = Moose::Util::english_list( map { q{'} . $_ . q{'} } @{ $conflict->roles } );
 
         $error
-            .= q{'}
-            . $role->name
-            . "' requires the method '"
+            .= "Due to a method name conflict in roles "
+            .  $roles
+            . ", the method '"
             . $conflict->name
-            . "' to be implemented by '"
+            . "' must be implemented by '"
             . $class->name
-            . "' due to a method conflict"
+            . q{'};
     }
     elsif (@missing) {
         my $noun = @missing == 1 ? 'method' : 'methods';
index 800bdda..9382a2a 100644 (file)
@@ -100,7 +100,7 @@ Role method conflicts
 
     ::throws_ok {
         with 'Role::Bling', 'Role::Bling::Bling';
-    } qr/requires the method \'bling\' to be implemented/, '... role methods conflicted and method was required';
+    } qr/Due to a method name conflict in roles 'Role::Bling' and 'Role::Bling::Bling', the method 'bling' must be implemented by 'My::Test3'/, '... role methods conflicted and method was required';
 
     package My::Test4;
     use Moose;
index 7dd2dac..01f578a 100644 (file)
@@ -64,7 +64,7 @@ is( Class::A->new->xxy, "Role::B::xxy",  "... got the right xxy method" );
 
     ::throws_ok {
         with 'Role::A::Conflict';
-    }  qr/requires.*'bar'/, '... did not fufill the requirement of &bar method';
+    }  qr/Due to a method name conflict in roles 'Role::A' and 'Role::A::Conflict', the method 'bar' must be implemented by 'Class::A::Conflict'/, '... did not fufill the requirement of &bar method';
 
     package Class::A::Resolved;
     use Moose;
@@ -181,7 +181,7 @@ ok(Role::D::And::E::Conflict->meta->requires_method('bar'), '... Role::D::And::E
 
     ::throws_ok {
         with qw(Role::I);
-    } qr/requires.*'foo'/, "defining class Class::C fails";
+    } qr/Due to a method name conflict in roles 'Role::H' and 'Role::J', the method 'foo' must be implemented by 'Class::C'/, "defining class Class::C fails";
 
     sub zot { 'Class::C::zot' }
 
index 683dedd..93557f4 100644 (file)
@@ -72,7 +72,7 @@ ok(My::OtherRole->meta->requires_method('bar'), '... and the &bar method is requ
         with 'Foo::Role',
              'Bar::Role' => { excludes => 'foo' },
              'Baz::Role';
-    } qr/\'Foo::Role\|Bar::Role\|Baz::Role\' requires the method \'foo\' to be implemented by \'My::Foo::Class::Broken\'/,
+    } qr/Due to a method name conflict in roles 'Baz::Role' and 'Foo::Role', the method 'foo' must be implemented by 'My::Foo::Class::Broken'/,
       '... composed our roles correctly';
 }
 
index 4e5c25a..f29a4be 100644 (file)
@@ -105,7 +105,7 @@ ok(My::AliasingRole->meta->requires_method('bar'), '... and the &bar method is r
         with 'Foo::Role' => { alias => { 'foo' => 'foo_foo' }, excludes => 'foo' },
              'Bar::Role' => { alias => { 'foo' => 'foo_foo' }, excludes => 'foo' },
              'Baz::Role';
-    } qr/\'Foo::Role\|Bar::Role\|Baz::Role\' requires the method \'foo_foo\' to be implemented by \'My::Foo::Class::Broken\'/,
+    } qr/Due to a method name conflict in roles 'Bar::Role' and 'Foo::Role', the method 'foo_foo' must be implemented by 'My::Foo::Class::Broken'/,
       '... composed our roles correctly';
 }