For class_types, explicitly state that the value is not an instance of
Shawn M Moore [Fri, 24 Apr 2009 23:18:29 +0000 (19:18 -0400)]
the class

Changes
lib/Moose/Meta/TypeConstraint/Class.pm
t/040_type_constraints/030_class_subtypes.t

diff --git a/Changes b/Changes
index dfc6e29..f97b3fa 100644 (file)
--- a/Changes
+++ b/Changes
@@ -6,6 +6,11 @@ for, noteworthy changes.
       - Do not run coercions in coerce() if the value already passes the type
         constraint (hdp)
 
+    * Moose::Meta::TypeConstraint::Class
+      - In validation error messages, specifically say that the value is not
+        an instance of the class. This should alleviate some frustrating
+        forgot-to-load-my-type bugs. rt.cpan.org #44639 (Sartak)
+
 0.75_01 Thu, April 23, 2009
     * Moose::Meta::Role::Application::ToClass
       - Moose now warns about each class overriding methods from roles it
index 4af6472..a128acc 100644 (file)
@@ -106,6 +106,18 @@ sub create_child_type {
     return Moose::Meta::TypeConstraint->new(@args, parent => $self);
 }
 
+sub get_message {
+    my $self = shift;
+    my ($value) = @_;
+
+    if ($self->has_message) {
+        return $self->SUPER::get_message(@_);
+    }
+
+    $value = (defined $value ? overload::StrVal($value) : 'undef');
+    return "Validation failed for '" . $self->name . "' failed with value $value (not isa " . $self->class . ")";
+}
+
 1;
 
 __END__
index 4eb88b5..196fdf2 100644 (file)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 18;
+use Test::More tests => 26;
 use Test::Exception;
 
 use Moose::Util::TypeConstraints;
@@ -80,3 +80,60 @@ ok $isa_foo, 'Created subtype of Foo type';
 ok $isa_foo->check( Foo->new ), 'Foo passes check';
 ok $isa_foo->check( Bar->new ), 'Bar passes check';
 ok ! $isa_foo->check( Baz->new ), 'Baz does not pass check';
+like $foo->get_message( Baz->new ), qr/^Validation failed for 'Foo' failed with value Baz=HASH\(0x\w+\) \(not isa Foo\)/, 'Better validation message';
+
+# Maybe in the future this *should* inherit?
+like $isa_foo->get_message( Baz->new ), qr/^Validation failed for 'IsaFoo' failed with value Baz=HASH\(0x\w+\)$/, "Subtypes do not automatically inherit parent type's message";
+
+
+# Implicit types
+{
+    package Quux;
+
+    use Moose;
+
+    has age => (
+        isa => 'Positive',
+    );
+}
+
+throws_ok {
+    Quux->new(age => 3)
+} qr/^Attribute \(age\) does not pass the type constraint because: Validation failed for 'Positive' failed with value 3 \(not isa Positive\)/;
+
+lives_ok {
+    Quux->new(age => (bless {}, 'Positive'));
+};
+
+eval "
+    package Positive;
+    use Moose;
+";
+
+throws_ok {
+    Quux->new(age => 3)
+} qr/^Attribute \(age\) does not pass the type constraint because: Validation failed for 'Positive' failed with value 3 \(not isa Positive\)/;
+
+lives_ok {
+    Quux->new(age => Positive->new)
+};
+
+class_type 'Negative' => message { "$_ is not a Negative Nancy" };
+
+{
+    package Quux::Ier;
+
+    use Moose;
+
+    has age => (
+        isa => 'Negative',
+    );
+}
+
+throws_ok {
+    Quux::Ier->new(age => 3)
+} qr/^Attribute \(age\) does not pass the type constraint because: 3 is not a Negative Nancy /;
+
+lives_ok {
+    Quux::Ier->new(age => (bless {}, 'Negative'))
+};