package tests::WeekCalculatorTest;

use strict;

use base qw/Lire::Test::TestCase/;

use Lire::WeekCalculator;
use Time::Local;

my @week_no_data =
  (
   [788961600, '01', '52', '00'],
   [789048000, '01', '01', '01'],
   [789134400, '01', '01', '01'],
   [789220800, '01', '01', '01'],
   [789307200, '01', '01', '01'],
   [789393600, '01', '01', '01'],
   [789480000, '01', '01', '01'],
   [789566400, '02', '01', '01'],
   [819720000, '51', '51', '51'],
   [819806400, '52', '51', '51'],
   [819892800, '52', '52', '52'],
   [819979200, '52', '52', '52'],
   [820065600, '52', '52', '52'],
   [820152000, '52', '52', '52'],
   [820238400, '52', '52', '52'],
   [820324800, '52', '52', '52'],
   [820411200, '53', '52', '52'],
   [820497600, '00', '01', '01'],
   [820584000, '00', '01', '01'],
   [820670400, '00', '01', '01'],
   [820756800, '00', '01', '01'],
   [820843200, '00', '01', '01'],
   [820929600, '00', '01', '01'],
   [821016000, '01', '01', '01'],
   [821102400, '01', '02', '02'],
   [851342400, '51', '52', '52'],
   [851428800, '51', '52', '52'],
   [851515200, '51', '52', '52'],
   [851601600, '51', '52', '52'],
   [851688000, '51', '52', '52'],
   [851774400, '51', '52', '52'],
   [851860800, '52', '52', '52'],
   [851947200, '52', '01', '53'],
   [852033600, '52', '01', '53'],
   [852120000, '00', '01', '00'],
   [852206400, '00', '01', '00'],
   [852292800, '00', '01', '00'],
   [852379200, '00', '01', '00'],
   [852465600, '01', '01', '00'],
   [852552000, '01', '02', '01'],
   [852638400, '01', '02', '01'],
   [852724800, '01', '02', '01'],
   [882878400, '51', '52', '51'],
   [882964800, '51', '52', '51'],
   [883051200, '51', '52', '51'],
   [883137600, '51', '52', '51'],
   [883224000, '51', '52', '51'],
   [883310400, '52', '52', '51'],
   [883396800, '52', '01', '52'],
   [883483200, '52', '01', '52'],
   [883569600, '52', '01', '52'],
   [883656000, '00', '01', '00'],
   [883742400, '00', '01', '00'],
   [883828800, '00', '01', '00'],
   [883915200, '01', '01', '00'],
   [884001600, '01', '02', '01'],
   [884088000, '01', '02', '01'],
   [884174400, '01', '02', '01'],
   [884260800, '01', '02', '01'],
   [914414400, '51', '52', '51'],
   [914500800, '51', '52', '51'],
   [914587200, '51', '52', '51'],
   [914673600, '51', '52', '51'],
   [914760000, '52', '52', '51'],
   [914846400, '52', '53', '52'],
   [914932800, '52', '53', '52'],
   [915019200, '52', '53', '52'],
   [915105600, '52', '53', '52'],
   [915192000, '00', '53', '00'],
   [915278400, '00', '53', '00'],
   [915364800, '01', '53', '00'],
   [915451200, '01', '01', '01'],
   [915537600, '01', '01', '01'],
   [915624000, '01', '01', '01'],
   [915710400, '01', '01', '01'],
   [915796800, '01', '01', '01'],
   [945950400, '51', '51', '51'],
   [946036800, '51', '51', '51'],
   [946123200, '51', '51', '51'],
   [946209600, '52', '51', '51'],
   [946296000, '52', '52', '52'],
   [946382400, '52', '52', '52'],
   [946468800, '52', '52', '52'],
   [946555200, '52', '52', '52'],
   [946641600, '52', '52', '52'],
   [946728000, '00', '52', '00'],
   [946814400, '01', '52', '00'],
   [946900800, '01', '01', '01'],
   [946987200, '01', '01', '01'],
   [947073600, '01', '01', '01'],
   [947160000, '01', '01', '01'],
   [947246400, '01', '01', '01'],
   [947332800, '01', '01', '01'],
   [977572800, '51', '51', '51'],
   [977659200, '52', '51', '51'],
   [977745600, '52', '52', '52'],
   [977832000, '52', '52', '52'],
   [977918400, '52', '52', '52'],
   [978004800, '52', '52', '52'],
   [978091200, '52', '52', '52'],
   [978177600, '52', '52', '52'],
   [978264000, '53', '52', '52'],
   [978350400, '00', '01', '01'],
   [978436800, '00', '01', '01'],
   [978523200, '00', '01', '01'],
   [978609600, '00', '01', '01'],
   [978696000, '00', '01', '01'],
   [978782400, '00', '01', '01'],
   [978868800, '01', '01', '01'],
   [978955200, '01', '02', '02'],
   [1009108800, '51', '51', '51'],
   [1009195200, '51', '52', '52'],
   [1009281600, '51', '52', '52'],
   [1009368000, '51', '52', '52'],
   [1009454400, '51', '52', '52'],
   [1009540800, '51', '52', '52'],
   [1009627200, '51', '52', '52'],
   [1009713600, '52', '52', '52'],
   [1009800000, '52', '01', '53'],
   [1009886400, '00', '01', '00'],
   [1009972800, '00', '01', '00'],
   [1010059200, '00', '01', '00'],
   [1010145600, '00', '01', '00'],
   [1010232000, '00', '01', '00'],
   [1010318400, '01', '01', '00'],
   [1010404800, '01', '02', '01'],
   [1010491200, '01', '02', '01'],
   [1040644800, '51', '52', '51'],
   [1040731200, '51', '52', '51'],
   [1040817600, '51', '52', '51'],
   [1040904000, '51', '52', '51'],
   [1040990400, '51', '52', '51'],
   [1041076800, '51', '52', '51'],
   [1041163200, '52', '52', '51'],
   [1041249600, '52', '01', '52'],
   [1041336000, '52', '01', '52'],
   [1041422400, '00', '01', '00'],
   [1041508800, '00', '01', '00'],
   [1041595200, '00', '01', '00'],
   [1041681600, '00', '01', '00'],
   [1041768000, '01', '01', '00'],
   [1041854400, '01', '02', '01'],
   [1041940800, '01', '02', '01'],
   [1042027200, '01', '02', '01'],
   [1072180800, '51', '52', '51'],
   [1072267200, '51', '52', '51'],
   [1072353600, '51', '52', '51'],
   [1072440000, '51', '52', '51'],
   [1072526400, '51', '52', '51'],
   [1072612800, '52', '52', '51'],
   [1072699200, '52', '01', '52'],
   [1072785600, '52', '01', '52'],
   [1072872000, '52', '01', '52'],
   [1072958400, '00', '01', '00'],
   [1073044800, '00', '01', '00'],
   [1073131200, '00', '01', '00'],
   [1073217600, '01', '01', '00'],
   [1073304000, '01', '02', '01'],
   [1073390400, '01', '02', '01'],
   [1073476800, '01', '02', '01'],
   [1073563200, '01', '02', '01'],
   [1103803200, '51', '52', '51'],
   [1103889600, '51', '52', '51'],
   [1103976000, '51', '52', '51'],
   [1104062400, '52', '52', '51'],
   [1104148800, '52', '53', '52'],
   [1104235200, '52', '53', '52'],
   [1104321600, '52', '53', '52'],
   [1104408000, '52', '53', '52'],
   [1104494400, '52', '53', '52'],
   [1104580800, '00', '53', '00'],
   [1104667200, '01', '53', '00'],
   [1104753600, '01', '01', '01'],
   [1104840000, '01', '01', '01'],
   [1104926400, '01', '01', '01'],
   [1105012800, '01', '01', '01'],
   [1105099200, '01', '01', '01'],
   [1105185600, '01', '01', '01'],
   [1135339200, '51', '51', '51'],
   [1135425600, '51', '51', '51'],
   [1135512000, '52', '51', '51'],
   [1135598400, '52', '52', '52'],
   [1135684800, '52', '52', '52'],
   [1135771200, '52', '52', '52'],
   [1135857600, '52', '52', '52'],
   [1135944000, '52', '52', '52'],
   [1136030400, '52', '52', '52'],
  );

my @last_week_data =
  (
   [1990, 52, 52, 53],
   [1991, 52, 52, 52],
   [1992, 52, 53, 52],
   [1993, 52, 52, 52],
   [1994, 52, 52, 52],
   [1995, 53, 52, 52],
   [1996, 52, 52, 53],
   [1997, 52, 52, 52],
   [1998, 52, 53, 52],
   [1999, 52, 52, 52],
   [2000, 53, 52, 52],
   [2001, 52, 52, 53],
   [2002, 52, 52, 52],
   [2003, 52, 52, 52],
   [2004, 52, 53, 52],
   [2005, 52, 52, 52],
   [2006, 53, 52, 52],
   [2007, 52, 52, 53],
   [2008, 52, 52, 52],
   [2009, 52, 53, 52],
   [2010, 52, 52, 52],
  );

my @first_week_data =
  (
   [1990, 631670400, 631152000, 631152000],
   [1991, 663120000, 662601600, 663206400],
   [1992, 694569600, 694051200, 694656000],
   [1993, 726019200, 726105600, 726105600],
   [1994, 757468800, 757555200, 757555200],
   [1995, 788918400, 789004800, 789004800],
   [1996, 820972800, 820454400, 820454400],
   [1997, 852422400, 851904000, 852508800],
   [1998, 883872000, 883353600, 883958400],
   [1999, 915321600, 915408000, 915408000],
   [2000, 946771200, 946857600, 946857600],
   [2001, 978825600, 978307200, 978307200],
   [2002, 1010275200, 1009756800, 1010361600],
   [2003, 1041724800, 1041206400, 1041811200],
   [2004, 1073174400, 1072656000, 1073260800],
   [2005, 1104624000, 1104710400, 1104710400],
   [2006, 1136073600, 1136160000, 1136160000],
   [2007, 1168128000, 1167609600, 1167609600],
   [2008, 1199577600, 1199059200, 1199664000],
   [2009, 1231027200, 1230508800, 1231113600],
   [2010, 1262476800, 1262563200, 1262563200],
  );


sub set_up {
    my $self = $_[0];
    $self->SUPER::set_up();

    $self->{'cfg'}{'lr_week_numbering'} = 'ISO';

    $self->set_up_tz( 'UTC' );

    return;
}

sub tear_down {
    my $self = $_[0];
    $self->SUPER::tear_down();

    return;
}

sub test_new {
    my $self = $_[0];

    for my $style ( [ undef, '%V' ], [ 'U', '%U' ],
                    [ 'W', '%W' ], [ 'ISO', '%V' ] )
    {
        my $calc = new Lire::WeekCalculator( 'style' => $style->[0] );
        $self->assert( UNIVERSAL::isa( $calc, 'Lire::WeekCalculator' ),
                       "new() returned wrong instance" );
        $self->assert_equals( $style->[1], $calc->{'fmt'} );
    }

    $self->assert_died( sub { new Lire::WeekCalculator( 'style' => 'wrong' )},
                        qr/invalid week numbering style/
                      );

    $self->assert_not_null( $Lire::WeekCalculator::haveV,
                            "haveV wasn't set" );
}

sub run_test_on_method {
    my ( $self, $method, $data ) = @_;

    no strict 'refs';

    my $u = new Lire::WeekCalculator( 'style' => 'U' );
    my $v = new Lire::WeekCalculator( 'style' => 'ISO' );
    my $w = new Lire::WeekCalculator( 'style' => 'W' );

    foreach ( @$data ) {
        $self->assert_equals($_->[1], $u->$method($_->[0]));
        $self->assert_equals($_->[2], $v->$method($_->[0]));
        $self->assert_equals($_->[3], $w->$method($_->[0]));
    }
}

sub test_week_number {
    my $self = $_[0];

    $self->run_test_on_method( 'week_number', \@week_no_data );
}

sub test_week_number_own_V {
    my $self = $_[0];

    local $Lire::WeekCalculator::haveV = 0;
    $self->run_test_on_method( 'week_number', \@week_no_data );
}

sub test_last_week_of_year {
    my $self = $_[0];

    $self->run_test_on_method( 'last_week_of_year', \@last_week_data );
}

sub test_last_week_of_year_V {
    my $self = $_[0];

    local $Lire::WeekCalculator::haveV = 0;
    $self->run_test_on_method( 'last_week_of_year', \@last_week_data );
}

sub test_find_year_week1_start_date {
    my $self = $_[0];

    $self->run_test_on_method( 'find_year_week1_start_date',
                               \@first_week_data );
}

sub test_find_year_week1_start_date_V {
    my $self = $_[0];

    local $Lire::WeekCalculator::haveV = 0;
    $self->run_test_on_method( 'find_year_week1_start_date',
                               \@first_week_data );
}

sub test_week_idx {
    my $self = $_[0];

    my $calc = new Lire::WeekCalculator( 'style' => 'ISO' );
    $self->assert_num_equals( 0, $calc->week_idx( timelocal( 0, 0, 0, 1, 0, 2004 ) ) );
    $self->assert_num_equals( 0, $calc->week_idx( timelocal( 0, 0, 0, 31, 11, 2003 ) ) );
    $self->assert_num_equals( 4, $calc->week_idx( timelocal( 0, 0, 0, 1, 1, 2004 ) ) );

    $calc = new Lire::WeekCalculator( 'style' => 'U' );
    $self->assert_num_equals( 51, $calc->week_idx( timelocal( 0, 0, 0, 1, 0, 2004 ) ) );
    $self->assert_num_equals( 51, $calc->week_idx( timelocal( 0, 0, 0, 31, 11, 2003 ) ) );
    $self->assert_num_equals( 4, $calc->week_idx( timelocal( 0, 0, 0, 1, 1, 2004 ) ) );

    $calc = new Lire::WeekCalculator( 'style' => 'W' );
    $self->assert_num_equals( 51, $calc->week_idx( timelocal( 0, 0, 0, 1, 0, 2004 ) ) );
    $self->assert_num_equals( 51, $calc->week_idx( timelocal( 0, 0, 0, 31, 11, 2003 ) ) );
    $self->assert_num_equals( 3, $calc->week_idx( timelocal( 0, 0, 0, 1, 1, 2004 ) ) );
}

1;


syntax highlighted by Code2HTML, v. 0.9.1