DateTime::Duration + other new coercions
Yuval Kogman [Fri, 18 Apr 2008 16:31:01 +0000 (16:31 +0000)]
lib/MooseX/Types/DateTime.pm
t/01_basic.t

index c1e7c19..2d50d72 100644 (file)
@@ -14,12 +14,29 @@ use DateTime::TimeZone ();
 use Moose::Util::TypeConstraints;
 
 class_type "DateTime";
+class_type "DateTime::Duration";
 class_type "DateTime::TimeZone";
 class_type "DateTime::Locale::root" => { name => "DateTime::Locale" };
 
 coerce "DateTime" => (
-    from "Int",
+    from "Num",
     via { DateTime->from_epoch( epoch => $_ ) },
+    from "HashRef",
+    via { DateTime->new( %$_ ) },
+    Moose::Meta::TypeConstraint->new(
+        name => "__ANON__",
+        parent => find_type_constraint("Str"),
+        constraint => sub { $_ eq 'now' },
+        optimise_as => sub { no warnings 'uninitialized'; !ref($_[0]) and $_[0] eq 'now' },
+    ),
+    via { DateTime->now },
+);
+
+coerce "DateTime::Duration" => (
+    from "Num",
+    via { DateTime::Duration->new( seconds => $_ ) },
+    from "HashRef",
+    via { DateTime::Duration->new( %$_ ) },
 );
 
 coerce "DateTime::TimeZone" => (
@@ -68,19 +85,71 @@ designed to work with the L<DateTime> suite of objects.
 
 =item L<DateTime>
 
-A coercion from C<Int> using L<DateTime/from_epoch> is defined.
+A class type for L<DateTime>.
+
+=over 4
+
+=item from C<Num>
+
+Uses L<DateTime/from_epoch>. Floating values will be used for subsecond
+percision, see L<DateTime> for details.
+
+=item from C<HashRef>
+
+Calls L<DateTime/new> with the hash entries as arguments.
+
+=back
+
+=item L<DateTime::Duration>
+
+A class type for L<DateTime::Duration>
+
+=over 4
+
+=item from C<Num>
+
+Uses L<DateTime::Duration/new> and passes the number as the C<seconds> argument.
+
+Note that due to leap seconds, DST changes etc this may not do what you expect.
+For instance passing in C<86400> is not always equivalent to one day, although
+there are that many seconds in a day. See L<DateTime/"How Date Math is Done">
+for more details.
+
+=item from C<HashRef>
+
+Calls L<DateTime::Duration/new> with the hash entries as arguments.
+
+=back
 
 =item L<DateTime::Locale>
 
-Coerces from C<Str>, where the string is the language tag, e.g. C<en> etc. See
+A class type for L<DateTime::Locale::root> with the name L<DateTime::Locale>.
+
+=over 4
+
+=item from C<Str>
+
+The string is treated as a language tag (e.g. C<en> or C<he_IL>) and given to
 L<DateTime::Locale/load>.
 
+=item from L<Locale::Maktext>
+
+The C<Locale::Maketext/language_tag> attribute will be used with L<DateTime::Locale/load>.
+
 =item L<DateTime::TimeZone>
 
-Coerces from C<Str> where the string is any time zone name.
+A class type for L<DateTime::TimeZone>.
+
+=over 4
+
+=item from C<Str>
+
+Treated as a time zone name or offset. See L<DateTime::TimeZone/USAGE> for more
+details on the allowed values.
+
+Delegates to L<DateTime::TimeZone/new> with the string as the C<name> argument.
 
-The string may also be a number of special values (C<local>, C<floating>,
-offsets, etc). See L<DateTime::TimeZone/USAGE> for details.
+=back
 
 =head1 VERSION CONTROL
 
index d137131..3a61db1 100644 (file)
@@ -32,11 +32,44 @@ isa_ok( find_type_constraint($_), "Moose::Meta::TypeConstraint" ) for qw(DateTim
 
     is( $coerced->epoch, $epoch, "epoch is correct" );
 
+    isa_ok( Foo->new( date => { year => 2000, month => 1, day => 1 } )->date, "DateTime" );
+
+    isa_ok( Foo->new( date => 'now' )->date, "DateTime" );
+
     throws_ok { Foo->new( date => "junk1!!" ) } qr/DateTime/, "constraint";
 }
 
 {
     {
+        package Quxx;
+        use Moose;
+
+        has duration => (
+            isa => "DateTime::Duration",
+            is  => "rw",
+            coerce => 1,
+        );
+    }
+
+    my $coerced = Quxx->new( duration => 10 )->duration;
+
+    isa_ok( $coerced, "DateTime::Duration", "coerced from seconds" );
+
+    my $time = time;
+
+    my $now = DateTime->from_epoch( epoch => $time );
+
+    my $future = $now + $coerced;
+
+    is( $future->epoch, ( $time + 10 ), "coerced value" );
+
+    isa_ok( Quxx->new( duration => { minutes => 2 } )->duration, "DateTime::Duration", "coerced from hash" );
+
+    throws_ok { Quxx->new( duration => "ahdstkljhat" ) } qr/DateTime/, "constraint";
+}
+
+{
+    {
         package Bar;
         use Moose;
 
@@ -70,7 +103,7 @@ isa_ok( find_type_constraint($_), "Moose::Meta::TypeConstraint" ) for qw(DateTim
 
     my $loc = Gorch->new( loc => "he_IL" )->loc;
 
-    isa_ok( $loc, "DateTime::Locale::he" );
+    isa_ok( $loc, "DateTime::Locale::he", "coerced from string" );
 
     dies_ok { Gorch->new( loc => "not_a_place_or_a_locale" ) } "bad locale name";