Add OrZero types for numbers
Dave Rolsky [Wed, 31 Aug 2011 15:17:34 +0000 (10:17 -0500)]
lib/MooseX/Types/Common/Numeric.pm
t/02-numeric.t

index af9e01a..9a30631 100644 (file)
@@ -6,7 +6,11 @@ use warnings;
 our $VERSION = '0.001001';
 
 use MooseX::Types -declare => [
-  qw(PositiveNum PositiveInt NegativeNum NegativeInt SingleDigit)
+  qw(PositiveNum PositiveOrZeroNum
+     PositiveInt PositiveOrZeroInt
+     NegativeNum NegativeOrZeroNum
+     NegativeInt NegativeOrZeroInt
+     SingleDigit)
 ];
 
 use MooseX::Types::Moose qw/Num Int/;
@@ -23,6 +27,18 @@ subtype PositiveNum,
         : ()
     );
 
+subtype PositiveOrZeroNum,
+  as Num,
+  where { $_ >= 0 },
+  message { "Must be a number greater than or equal to zero" },
+    ( $Moose::VERSION >= 2.0200
+        ? inline_as {
+            $_[0]->parent()->_inline_check( $_[1] ) . ' && '
+                . qq{ ($_[1] >= 0) };
+        }
+        : ()
+    );
+
 subtype PositiveInt,
   as Int,
   where { $_ > 0 },
@@ -35,6 +51,18 @@ subtype PositiveInt,
         : ()
     );
 
+subtype PositiveOrZeroInt,
+  as Int,
+  where { $_ >= 0 },
+  message { "Must be an integer greater than or equal to zero" },
+    ( $Moose::VERSION >= 2.0200
+        ? inline_as {
+            $_[0]->parent()->_inline_check( $_[1] ) . ' && '
+                . qq{ ($_[1] >= 0) };
+        }
+        : ()
+    );
+
 subtype NegativeNum,
   as Num,
   where { $_ < 0 },
@@ -47,6 +75,18 @@ subtype NegativeNum,
         : ()
     );
 
+subtype NegativeOrZeroNum,
+  as Num,
+  where { $_ <= 0 },
+  message { "Must be a number less than or equal to zero" },
+    ( $Moose::VERSION >= 2.0200
+        ? inline_as {
+            $_[0]->parent()->_inline_check( $_[1] ) . ' && '
+                . qq{ ($_[1] <= 0) };
+        }
+        : ()
+    );
+
 subtype NegativeInt,
   as Int,
   where { $_ < 0 },
@@ -59,6 +99,18 @@ subtype NegativeInt,
         : ()
     );
 
+subtype NegativeOrZeroInt,
+  as Int,
+  where { $_ <= 0 },
+  message { "Must be an integer less than or equal to zero" },
+    ( $Moose::VERSION >= 2.0200
+        ? inline_as {
+            $_[0]->parent()->_inline_check( $_[1] ) . ' && '
+                . qq{ ($_[1] <= 0) };
+        }
+        : ()
+    );
+
 subtype SingleDigit,
   as PositiveInt,
   where { $_ <= 9 },
@@ -97,11 +149,19 @@ default.
 
 =item * PositiveNum
 
+=item * PositiveOrZeroNum
+
 =item * PositiveInt
 
+=item * PositiveOrZeroInt
+
 =item * NegativeNum
 
-=item * Int
+=item * NegativeOrZeroNum
+
+=item * NegativeInt
+
+=item * NegativeOrZeroInt
 
 =item * SingleDigit
 
index aed9aa7..4908d04 100644 (file)
@@ -2,14 +2,18 @@
 
 use strict;
 use warnings;
-use Test::More tests => 18;
+use Test::More tests => 34;
 use Test::Exception;
 
 {
   package FooTest;
   use Moose;
   use MooseX::Types::Common::Numeric (
-    qw(PositiveNum PositiveInt NegativeInt NegativeNum SingleDigit)
+    qw(PositiveNum PositiveOrZeroNum
+       PositiveInt PositiveOrZeroInt
+       NegativeNum NegativeOrZeroNum
+       NegativeInt NegativeOrZeroInt
+       SingleDigit)
   );
 
   has digit => ( is => 'rw', isa => SingleDigit);
@@ -17,6 +21,10 @@ use Test::Exception;
   has posint => ( is => 'rw', isa => PositiveInt);
   has negnum => ( is => 'rw', isa => NegativeNum);
   has negint => ( is => 'rw', isa => NegativeInt);
+  has posorzeronum => ( is => 'rw', isa => PositiveOrZeroNum);
+  has posorzeroint => ( is => 'rw', isa => PositiveOrZeroInt);
+  has negorzeronum => ( is => 'rw', isa => NegativeOrZeroNum);
+  has negorzeroint => ( is => 'rw', isa => NegativeOrZeroInt);
 }
 
 my $ins = FooTest->new;
@@ -33,6 +41,15 @@ lives_ok { $ins->posnum(100.885); } 'PositiveNum (100.885)';
 dies_ok { $ins->posnum(-100.885); } 'PositiveNum (-100.885)';
 lives_ok { $ins->posnum(0.0000000001); } 'PositiveNum (0.0000000001)';
 
+dies_ok { $ins->posorzeroint(-100); } 'PositiveOrZeroInt (-100)';
+lives_ok { $ins->posorzeroint(0); } 'PositiveOrZeroInt (0)';
+dies_ok { $ins->posorzeroint(100.885); } 'PositiveOrZeroInt (100.885)';
+lives_ok { $ins->posorzeroint(100); } 'PositiveOrZeroInt (100)';
+lives_ok { $ins->posorzeronum(0); } 'PositiveOrZeroNum (0)';
+lives_ok { $ins->posorzeronum(100.885); } 'PositiveOrZeroNum (100.885)';
+dies_ok { $ins->posorzeronum(-100.885); } 'PositiveOrZeroNum (-100.885)';
+lives_ok { $ins->posorzeronum(0.0000000001); } 'PositiveOrZeroNum (0.0000000001)';
+
 dies_ok { $ins->negint(100); } 'NegativeInt (100)';
 dies_ok { $ins->negint(-100.885); } 'NegativeInt (-100.885)';
 lives_ok { $ins->negint(-100); } 'NegativeInt (-100)';
@@ -41,3 +58,12 @@ lives_ok { $ins->negnum(-100.885); } 'NegativeNum (-100.885)';
 dies_ok { $ins->negnum(100.885); } 'NegativeNum (100.885)';
 dies_ok { $ins->negnum(0); } 'NegativeNum (0)';
 lives_ok { $ins->negnum(-0.0000000001); } 'NegativeNum (-0.0000000001)';
+
+dies_ok { $ins->negorzeroint(100); } 'NegativeOrZeroInt (100)';
+dies_ok { $ins->negorzeroint(-100.885); } 'NegativeOrZeroInt (-100.885)';
+lives_ok { $ins->negorzeroint(-100); } 'NegativeOrZeroInt (-100)';
+lives_ok { $ins->negorzeroint(0); } 'NegativeOrZeroInt (0)';
+lives_ok { $ins->negorzeronum(-100.885); } 'NegativeOrZeroNum (-100.885)';
+dies_ok { $ins->negorzeronum(100.885); } 'NegativeOrZeroNum (100.885)';
+lives_ok { $ins->negorzeronum(0); } 'NegativeOrZeroNum (0)';
+lives_ok { $ins->negorzeronum(-0.0000000001); } 'NegativeOrZeroNum (-0.0000000001)';