#!/usr/bin/perl -w
use strict;
use Test::More tests => 15;
use DateTime::Format::ICal;
use DateTime::Span;
my $ical = 'DateTime::Format::ICal';
{
# this is an example from rfc2445
my $recur =
$ical->parse_recurrence( recurrence => 'freq=monthly;count=10;byday=1fr',
dtstart => $ical->parse_datetime( '19970905T090000' )
);
my @r;
while ( my $dt = $recur->next )
{
push @r, $ical->format_datetime( $dt );
}
my $s1 = join ',', @r;
my $s2 = join ',', qw( 1997-09-05T09:00:00
1997-10-03T09:00:00
1997-11-07T09:00:00
1997-12-05T09:00:00
1998-01-02T09:00:00
1998-02-06T09:00:00
1998-03-06T09:00:00
1998-04-03T09:00:00
1998-05-01T09:00:00
1998-06-05T09:00:00
);
$s2 =~ s/[-:]//g;
is( $s1, $s2, "recurrence parser is ok" );
}
{
# DTSTART;TZID=US-Eastern:19980101T090000
# RRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA
my $recur =
$ical->parse_recurrence
( recurrence => 'FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA',
dtstart => $ical->parse_datetime( '19980101T090000' )
);
my @str = $ical->format_recurrence( $recur );
is( "@str", 'RRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA',
'unbounded recurrence formats ok' );
my $union = $recur->union(
$ical->parse_datetime( '19980303T030303' )
);
@str = $ical->format_recurrence( $union );
is( "@str", 'RRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA '.
'RDATE:19980303T030303',
'unbounded recurrence union formats ok' );
my $recur2 =
$ical->parse_recurrence
( recurrence => 'FREQ=YEARLY;BYMONTH=2;BYDAY=SU,MO,TU,WE,TH,FR,SA',
dtstart => $ical->parse_datetime( '19980101T090000' )
);
my $union2 = $recur->union( $recur2 );
@str = $ical->format_recurrence( $union2 );
is( "@str", 'RRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA '.
'RRULE:FREQ=YEARLY;BYMONTH=2;BYDAY=SU,MO,TU,WE,TH,FR,SA',
'union of unbounded recurrences formats ok' );
my $union3 = $union2->union(
$ical->parse_datetime( '19980303T030303' )
);
@str = $ical->format_recurrence( $union3 );
is( "@str", 'RRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA '.
'RRULE:FREQ=YEARLY;BYMONTH=2;BYDAY=SU,MO,TU,WE,TH,FR,SA '.
'RDATE:19980303T030303',
'deep union of unbounded recurrences formats ok' );
# exclude date
my $exclude = $union2->union(
$ical->parse_datetime( '19980303T030303' )
)->complement(
$ical->parse_datetime( '19980404T040404' )
);
@str = $ical->format_recurrence( $exclude );
is( "@str", 'RRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA '.
'RRULE:FREQ=YEARLY;BYMONTH=2;BYDAY=SU,MO,TU,WE,TH,FR,SA '.
'RDATE:19980303T030303 '.
'EXDATE:19980404T040404',
'complement of date formats ok' );
# clone keeps formatting
@str = $ical->format_recurrence( $exclude->clone );
is( "@str", 'RRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA '.
'RRULE:FREQ=YEARLY;BYMONTH=2;BYDAY=SU,MO,TU,WE,TH,FR,SA '.
'RDATE:19980303T030303 '.
'EXDATE:19980404T040404',
'clone formats ok' );
# exclude rule
# exclude date + exclude rule
my $exclude2 = $exclude->complement( $recur );
@str = $ical->format_recurrence( $exclude2 );
is( "@str", 'RRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA '.
'RRULE:FREQ=YEARLY;BYMONTH=2;BYDAY=SU,MO,TU,WE,TH,FR,SA '.
'RDATE:19980303T030303 '.
'EXDATE:19980404T040404 '.
'EXRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA',
'complement of rule formats ok' );
# exclude date + add date should die
# exclude rule + add date should die
my $mixed = $exclude->union(
$ical->parse_datetime( '19980303T030303' )
);
@str = ('Error');
eval { @str = $ical->format_recurrence( $mixed ); }; # should die!
is( "@str", 'Error',
'exclude + complement of date cannot format' );
# date + exclude rule -- should fail
my $mixed2 = DateTime::Set->from_datetimes(
dates => [
$ical->parse_datetime( '19980303T030303')
] )
->union ( $recur );
@str = ('Error');
eval { @str = $ical->format_recurrence( $mixed2 ); }; # should die!
is( "@str", 'Error',
'unblessed date + recurrence cannot format' );
# blessed date + rule
my $mixed3 = DateTime::Set::ICal->from_datetimes(
dates => [
$ical->parse_datetime( '19980303T030303')
] )
->union ( $recur );
@str = ('Error');
eval { @str = $ical->format_recurrence( $mixed3 ); }; # should not die!
is( "@str", 'RDATE:19980303T030303 '.
'RRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA',
'blessed date + recurrence formats ok' );
# blessed date + exclude rule
# NOTE: this test was removed because the result of
# complement is not unbounded!
#
# my $mixed4 = DateTime::Set::ICal->from_datetimes(
# dates => [
# $ical->parse_datetime( '19980303T030303')
# ] )
# ->complement ( $recur );
# @str = ('Error');
# eval { @str = $ical->format_recurrence( $mixed4 ); }; # should not die!
# is( "@str", 'RDATE:19980303T030303 '.
# 'EXRULE:FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA',
# 'blessed date + exclude recurrence formats ok' );
}
{
# another example from rfc2445
# DTSTART;TZID=US-Eastern:19980101T090000
# RRULE:FREQ=YEARLY;UNTIL=2000-01-31T09:00:00;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA
my $recur =
$ical->parse_recurrence
( recurrence => 'FREQ=YEARLY;UNTIL=20000131T090000Z;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA',
dtstart => $ical->parse_datetime( '19980101T090000' )
);
my @r;
my @dt;
for ( 1 .. 2 )
{
my $dt = $recur->next;
push @dt, $dt;
push @r, $ical->format_datetime( $dt );
}
my $s1 = join ',', @r;
my $s2 = join ',', ( '1998-01-01T09:00:00',
'1998-01-02T09:00:00'
);
$s2 =~ s/[-:]//g;
is( $s1, $s2, "recurrence parser with 'until' is ok" );
# recurrence formatter
my @str = $ical->format_recurrence( @dt );
is( "@str", 'RDATE:19980101T090000,19980102T090000',
'datetime recurrence formats ok' );
# recurrence formatter - with mixed timezones
$dt[0]->set_time_zone( 'UTC' );
$dt[1]->set_time_zone( 'America/Chicago' );
@str = $ical->format_recurrence( @dt );
is( "@str", 'RDATE:19980101T090000Z '.
'RDATE;TZID=America/Chicago:19980102T090000',
'datetime with time zones recurrence formats ok' );
# recurrence formatter - with spans
push @dt, $recur->next;
# the end time zone will be translated to
# the start time zone (America/Chicago)
$dt[2]->set_time_zone( 'America/New-York' );
my $spanset = DateTime::SpanSet->from_spans(
spans => [
DateTime::Span->from_datetimes( start => $dt[0], end => $dt[0] ),
DateTime::Span->from_datetimes( start => $dt[1], before => $dt[2]),
]
);
@str = $ical->format_recurrence( $spanset );
is( "@str",
'RDATE:19980101T090000Z '.
'RDATE;VALUE=PERIOD;TZID=America/Chicago:19980102T090000/19980103T080000',
'datetime spans with time zones recurrence formats ok' );
}
1;