Stop making $class_tc->is_subtype_of behave like ->is_type_of
Florian Ragwitz [Fri, 30 Apr 2010 20:33:22 +0000 (22:33 +0200)]
Calling is_subtype_of on a Moose::Meta::TypeConstraint::Class with itself or
the class the TC represents as an argument incorrectly returned true. This
behavior is correct for is_type_of, not is_subtype_of.

Changes
lib/Moose/Manual/Delta.pod
lib/Moose/Meta/TypeConstraint/Class.pm
t/040_type_constraints/020_class_type_constraint.t

diff --git a/Changes b/Changes
index addc0cb..bb30ef5 100644 (file)
--- a/Changes
+++ b/Changes
@@ -9,6 +9,10 @@ for, noteworthy changes.
   * Make Moose::Meta::TypeConstraint::Class correctly reject RegexpRefs.
     (Florian Ragwitz)
 
+  * Calling is_subtype_of on a Moose::Meta::TypeConstraint::Class with itself or
+    the class the TC represents as an argument incorrectly returned true. This
+    behavior is correct for is_type_of, not is_subtype_of. (Guillermo Roditi)
+
   * Use File::Temp for temp files created during tests. Previously, files were
     written to the t/ dir, which could cause problems of the user running the
     tests did not have write access to that directory.. (Chris Weyl, Ævar
index b9f747e..2aef081 100644 (file)
@@ -16,6 +16,20 @@ feature.  If you encounter a problem and have a solution but don't see
 it documented here, or think we missed an important feature, please
 send us a patch.
 
+=head1 1.02
+
+=over 4
+
+=item Moose::Meta::TypeConstraint::Class is_subtype_of behavior
+
+Earlier versions of L<is_subtype_of|Moose::Meta::TypeConstraint::Class/is_subtype_of>
+would incorrectly return true when called with itself, its own TC name or
+its class name as an argument. (i.e. $foo_tc->is_subtype_of('Foo') == 1) This
+behavior was a caused by C<isa> being checked before the class name. The old
+behavior can be accessed with L<is_type_of|Moose::Meta::TypeConstraint::Class/is_type_of>
+
+=back
+
 =head1 1.00
 
 =over 4
index 397e3d9..f263436 100644 (file)
@@ -78,16 +78,17 @@ sub is_a_type_of {
 sub is_subtype_of {
     my ($self, $type_or_name_or_class ) = @_;
 
-    if ( not ref $type_or_name_or_class ) {
-        # it might be a class
-        return 1 if $self->class->isa( $type_or_name_or_class );
-    }
-
     my $type = Moose::Util::TypeConstraints::find_type_constraint($type_or_name_or_class);
 
-    return unless defined $type;
+    if ( not defined $type ) {
+        if ( not ref $type_or_name_or_class ) {
+            # it might be a class
+            return 1 if $self->class->isa( $type_or_name_or_class );
+        }
+        return;
+    }
 
-    if ( $type->isa(__PACKAGE__) ) {
+    if ( $type->isa(__PACKAGE__) && $type->class ne $self->class) {
         # if $type_or_name_or_class isn't a class, it might be the TC name of another ::Class type
         # or it could also just be a type object in this branch
         return $self->class->isa( $type->class );
index 0ae1348..f91ddf5 100644 (file)
@@ -32,6 +32,9 @@ my $type = find_type_constraint("Foo");
 
 is( $type->class, "Foo", "class attribute" );
 
+ok( !$type->is_subtype_of('Foo'), "Foo is not subtype of Foo" );
+ok( !$type->is_subtype_of($type), '$foo_type is not subtype of $foo_type' );
+
 ok( $type->is_subtype_of("Gorch"), "subtype of gorch" );
 
 ok( $type->is_subtype_of("Bar"), "subtype of bar" );