more doc tweaks and test cases
John Napiorkowski [Fri, 25 Jun 2010 12:14:40 +0000 (08:14 -0400)]
lib/MooseX/Types/Parameterizable.pm
t/05-pod-examples.t

index d62d7fe..78a75a4 100644 (file)
@@ -36,6 +36,8 @@ The follow is example usage.
       },
       message { "'$_' is too long"  };
 
+    ## Coerce an ArrayRef to a string via concatenation.
+
     coerce Varchar,
       from ArrayRef,
       via { 
@@ -130,14 +132,14 @@ This is the preferred syntax, as it improve readability and adds to the
 conciseness of your type constraint declarations.  An exception wil be thrown if
 your type parameters don't match the required reference type.
 
-Also not that if you 'chain' parameterization results with a method call like:
+Also note that if you 'chain' parameterization results with a method call like:
 
     TypeConstraint([$ob])->method;
     
 You need to have the "(...)" around the ArrayRef in the Type Constraint
-parameters.  This seems to have something to do with the precendent level of
-"->".  Patches or thoughts welcomed.  You only need to do this in the above
-case which I imagine is not a very common case.
+parameters.  You can skip the wrapping parenthesis in the most common cases,
+such as when you use the type constraint in the options section of a L<Moose>
+attribute declaration, or when defining type libraries.
 
 ==head2 Subtyping a Parameterizable type constraints
 
@@ -161,7 +163,18 @@ Example subtype with additional constraints:
             shift >= 0;              
         };
         
-Or you could have done the following instead:
+In this case you'd now have a parameterizable type constraint called which
+would work like:
+
+    Test::More::ok PositiveRangedInt([{min=>-10, max=>75}])->check(5);
+    Test::More::ok !PositiveRangedInt([{min=>-10, max=>75}])->check(-5);
+
+Of course the above is somewhat counter-intuitive to the reader, since we have
+defined our 'RangedInt' in such as way as to let you declare negative ranges.
+For the moment each type constraint rule is apply without knowledge of any
+other rule, nor can a rule 'inform' existing rules.  This is a limitation of
+the current system.  However, you could instead do the following:
+
 
     ## Subtype of Int for positive numbers
     subtype PositiveInt,
@@ -179,6 +192,13 @@ Or you could have done the following instead:
     subtype PositiveRangedInt,
         as RangedInt[PositiveRange];
 
+This would constrain values in the same way as the previous type constraint but
+have the bonus that you'd throw a hard exception if you try to use an incorrect
+range:
+
+    Test::More::ok PositiveRangedInt([{min=>10, max=>75}])->check(15); ## OK
+    Test::More::ok !PositiveRangedInt([{min=>-10, max=>75}])->check(-5); ## Dies
+
 Notice how re-parameterizing the parameterizable type 'RangedInt' works slightly
 differently from re-parameterizing 'PositiveRange'  Although it initially takes
 two type constraint values to declare a parameterizable type, should you wish to
index 1810599..e16a7b0 100644 (file)
@@ -111,6 +111,94 @@ use Test::More;
 
 }
 
+{
+    package Test::MooseX::Types::Parameterizable::Subtypes;
+
+    use Moose;
+    use MooseX::Types::Parameterizable qw(Parameterizable);
+    use MooseX::Types::Moose qw(HashRef Int);
+    use MooseX::Types -declare=>[qw(Range RangedInt PositiveRangedInt 
+        PositiveInt PositiveRange PositiveRangedInt2 )];
+
+    ## Minor change from docs to avoid additional test dependencies
+    subtype Range,
+        as HashRef[Int],
+        where {
+            my ($range) = @_;
+            return $range->{max} > $range->{min};
+        },
+        message { "Not a Valid range [ $_->{max} not > $_->{min} ] " };
+
+    subtype RangedInt,
+        as Parameterizable[Int, Range],
+        where {
+            my ($value, $range) = @_;
+            return ($value >= $range->{min} &&
+             $value <= $range->{max});
+        };
+        
+    subtype PositiveRangedInt,
+        as RangedInt,
+        where {
+            shift >= 0;              
+        };
+
+    Test::More::ok PositiveRangedInt([{min=>10,max=>100}])->check(50);
+    Test::More::ok !PositiveRangedInt([{min=>50, max=>75}])->check(99);
+
+    eval {
+        Test::More::ok !PositiveRangedInt([{min=>99, max=>10}])->check(10); 
+    }; 
+
+    Test::More::ok $@, 'There was an error';
+    Test::More::like $@, qr(Not a Valid range), 'Correct custom error';
+
+    Test::More::ok PositiveRangedInt([min=>10,max=>100])->check(50);
+    Test::More::ok ! PositiveRangedInt([min=>50, max=>75])->check(99);
+
+    eval {
+        PositiveRangedInt([min=>99, max=>10])->check(10); 
+    }; 
+
+    Test::More::ok $@, 'There was an error';
+    Test::More::like $@, qr(Not a Valid range), 'Correct custom error';
+
+    Test::More::ok !PositiveRangedInt([{min=>-10, max=>75}])->check(-5);
+
+    ## Subtype of Int for positive numbers
+    subtype PositiveInt,
+        as Int,
+        where {
+            my ($value, $range) = @_;
+            return $value >= 0;
+        };
+
+    ## subtype Range to re-parameterize Range with subtypes.  Minor change from
+    ## docs to reduce test dependencies
+
+    subtype PositiveRange,
+      as Range[PositiveInt],
+      message { "[ $_->{max} not > $_->{min} ] is not a positive range " };
+    
+    ## create subtype via reparameterizing
+    subtype PositiveRangedInt2,
+        as RangedInt[PositiveRange];
+
+    Test::More::ok PositiveRangedInt2([{min=>10,max=>100}])->check(50);
+    Test::More::ok !PositiveRangedInt2([{min=>50, max=>75}])->check(99);
+
+    eval {
+        Test::More::ok !PositiveRangedInt2([{min=>99, max=>10}])->check(10); 
+    }; 
+
+    Test::More::ok $@, 'There was an error';
+    Test::More::like $@, qr(not a positive range), 'Correct custom error';
+
+    Test::More::ok !PositiveRangedInt2([{min=>10, max=>75}])->check(-5);
+
+    ## See t/02-types-parameterizable-extended.t for remaining examples tests
+}
+
 
 done_testing;