From: Shawn M Moore Date: Fri, 24 Apr 2009 23:18:29 +0000 (-0400) Subject: For class_types, explicitly state that the value is not an instance of X-Git-Tag: 0.76~10 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=d414e17c1964192a17121570a9e0ccbd9190bde8;p=gitmo%2FMoose.git For class_types, explicitly state that the value is not an instance of the class --- diff --git a/Changes b/Changes index dfc6e29..f97b3fa 100644 --- 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 diff --git a/lib/Moose/Meta/TypeConstraint/Class.pm b/lib/Moose/Meta/TypeConstraint/Class.pm index 4af6472..a128acc 100644 --- a/lib/Moose/Meta/TypeConstraint/Class.pm +++ b/lib/Moose/Meta/TypeConstraint/Class.pm @@ -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__ diff --git a/t/040_type_constraints/030_class_subtypes.t b/t/040_type_constraints/030_class_subtypes.t index 4eb88b5..196fdf2 100644 --- a/t/040_type_constraints/030_class_subtypes.t +++ b/t/040_type_constraints/030_class_subtypes.t @@ -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')) +};