package tests::TimegroupTest;
use strict;
use base qw/Lire::Test::TestCase tests::TestStoreFixture/;
use Lire::Timegroup;
use Lire::ReportSpec;
use Lire::Param;
use Lire::Report::Group;
use Lire::Report::TableInfo;
use Lire::DlfQuery;
use Lire::Test::Mock;
use Time::Local;
#our @TESTS = qw/ /;
sub new {
my $self = shift()->SUPER::new( @_ );
$self->init();
return $self;
}
sub set_up {
my $self = $_[0];
$self->SUPER::set_up();
$self->set_up_test_schema();
$self->set_up_tz( 'UTC' );
$self->{'spec'} = new Lire::ReportSpec();
$self->{'spec'}->superservice( 'test' );
$self->{'spec'}->id( 'timegroup-test' );
foreach my $p ( qw/4h 1d 1w 3M 1y/ ) {
$self->{ $p . '_timegroup'} =
new Lire::Timegroup( 'report_spec' => $self->{'spec'},
'period' => $p,
'label' => 'Period',
);
}
return;
}
sub tear_down {
my $self = $_[0];
$self->SUPER::tear_down();
return;
}
sub test_name {
my $self = $_[0];
$self->assert_equals( 'timegroup:time_start',
$self->{'1d_timegroup'}->name() );
}
sub test_create_categorical_info {
my $self = $_[0];
my $info = new Lire::Report::TableInfo();
$self->{'1d_timegroup'}->create_categorical_info( $info );
my @cols = $info->children();
$self->assert_equals( 1, scalar @cols );
my $col = $cols[0];
$self->assert_equals( 'categorical', $col->class() );
$self->assert_equals( 'timegroup:time_start', $col->name() );
$self->assert_equals( 'timestamp', $col->type() );
$self->assert_equals( 'Period', $col->label() );
}
sub test_period {
my $self = $_[0];
$self->{'spec'}->param( 'dur', new Lire::Param( 'name' => 'dur',
'type' => 'duration',
'default' => '1d' ) );
$self->{'spec'}->param( 'int', new Lire::Param( 'name' => 'int',
'type' => 'int',
'default' => '100' ) );
my $timegroup = $self->{'1d_timegroup'};
$self->assert_equals( '1d', $timegroup->period() );
$self->assert_died( sub { $timegroup->period( undef ) },
qr/missing 'period' parameter/ );
$self->assert_died( sub { $timegroup->period( 'wawa' ) },
qr/'period' parameter isn't a valid duration: 'wawa'/);
$self->assert_died( sub { $timegroup->period( '$wawa' ) },
qr/parameter 'wawa' isn't defined/ );
$self->assert_died( sub { $timegroup->period( '2d' ) },
qr/can't use multiple with period of type 'd'/ );
$self->assert_died( sub { $timegroup->period( '$int' ) },
qr/parameter 'int' isn't a 'duration' parameter: 'int'/ );
$timegroup->period( '$dur' );
$self->assert_equals( '$dur', $timegroup->{'period'} );
$timegroup->period( '2h' );
$self->assert_equals( '2h', $timegroup->{'period'} );
}
sub test_build_query {
my $self = $_[0];
foreach my $t ( [ '4h', 'lr_timegroup_sec("time-start",14400)' ],
[ '1d', 'lr_timegroup_day("time-start")' ],
[ '1w', 'lr_timegroup_week("time-start",1)' ],
[ '3M', 'lr_timegroup_month("time-start",3)' ],
[ '1y', 'lr_timegroup_year("time-start",1)' ] )
{
my $timegroup = $self->{ $t->[0] . '_timegroup' };
$timegroup->{'field'} = 'time-start';
my $e_query = new Lire::DlfQuery( 'test' );
$e_query->add_aggr_field( '_lr_nrecords', 'count(*)' );
$e_query->add_group_field( "timegroup:time-start", $t->[1] );
$e_query->set_sort_spec( "timegroup:time-start" );
my $query = new Lire::DlfQuery( 'test' );
$timegroup->build_query( $query );
$self->assert_deep_equals( $e_query, $query );
}
}
sub test_create_entry {
my $self = $_[0];
$self->{'cfg'}{'lr_week_numbering'} = 'ISO';
my $info = new Lire::Report::TableInfo();
$self->{'1d_timegroup'}->create_categorical_info( $info );
foreach my $t ( [ '4h', '2003-10-14 20:00', 1066161600, 4*3600 ],
[ '1d', '2003-10-14', 1066089600, 24*3600 ],
[ '1w', '2003-W42', 1064966400, 7*24*3600 ],
[ '3M', 'April 2003', 1049155200, 30*24*3600*3 ],
[ '1y', '2003', 1041379200, 365*24*3600 ], )
{
my ( $period, $fmt_value, $value, $period_sec ) = @$t;
my $timegroup = $self->{$period . '_timegroup'};
my $group = new Lire::Report::Group( bless( {}, 'Lire::Report::Entry'),
$info );
my $dlf = { 'timegroup:time_start' => $value };
my $entry = $timegroup->create_entry( $group, $dlf );
$self->assert_not_null( $entry, "create_entry() returned undef" );
my @data = $entry->data();
$self->assert_equals( 1, scalar @data );
$self->assert_equals( $fmt_value, $data[0]->{'content'} );
$self->assert_equals( $value, $data[0]->{'value'} );
$self->assert_equals( $period_sec, $data[0]->{'range'} );
}
}
sub test_create_entry_mc {
my $self = $_[0];
my $timegroup = $self->{'1d_timegroup'};
my $info = new Lire::Report::TableInfo();
$self->{'1d_timegroup'}->create_categorical_info( $info );
my $group = new Lire::Report::Group( bless( {}, 'Lire::Report::Entry'),
$info );
my $entry = $timegroup->create_entry( $group,
{ 'timegroup:time_start' => undef,
'_lr_nrecords' => 24 } );
$self->assert_null( $entry, "create_entry() should have returned undef" );
$self->assert_equals( 24, $group->missing_cases() );
}
sub test_create_entry_day_change {
my $self = $_[0];
my $info = new Lire::Report::TableInfo();
$self->{'1d_timegroup'}->create_categorical_info( $info );
my $group = new Lire::Report::Group( bless( {}, 'Lire::Report::Entry'),
$info );
foreach my $t ( [ '2003-10-14 16:00', 1066147200 ],
[ ' 20:00', 1066161600 ],
[ '2003-10-15 00:00', 1066176000 ],
)
{
my $timegroup = $self->{'4h_timegroup'};
my $dlf = { 'timegroup:time_start' => $t->[1] };
my $entry = $timegroup->create_entry( $group, $dlf );
$self->assert_not_null( $entry, "create_entry() returned undef" );
$self->assert_str_equals( $t->[0], ($entry->data())[0]->{'content'} );
}
}
sub set_up_merge_fixture {
my $self = $_[0];
my $spec = new Lire::ReportSpec();
$spec->superservice( 'test' );
$spec->param( 'period', new Lire::Param( 'name' => 'period',
'type' => 'duration',
'value' => '1d' ) );
$self->{'timegroup'} = new Lire::Timegroup( 'report_spec' => $spec,
'period' => '$period' );
$self->{'aggregate'} = new Lire::Test::Mock( 'Lire::Aggregate',
'name' => 'aggr' );
$self->{'timegroup'}->ops( [ $self->{'aggregate'} ] );
return;
}
sub test_init_merge {
my $self = $_[0];
$self->set_up_merge_fixture();
$self->{'timegroup'}->init_merge();
$self->assert_num_equals( 86400, $self->{'timegroup'}{'period_sec'} );
$self->assert_isa( 'Lire::Timegroup::SecHelper',
$self->{'timegroup'}{'helper'} );
$self->assert_num_equals( 86400, $self->{'timegroup'}{'helper'}{'period'});
$self->assert_num_equals( 1, $self->{'timegroup'}{'helper'}{'multiple'} );
$self->assert_num_equals( 1, $self->{'aggregate'}->invocation_count( 'init_merge' ) );
$self->assert_num_equals( 0, $self->{'timegroup'}{'_merge_started'} );
$self->{'timegroup'}{'period'} = '4w';
$self->{'timegroup'}->init_merge();
$self->assert_isa( 'Lire::Timegroup::WeekHelper',
$self->{'timegroup'}{'helper'} );
$self->assert_num_equals( 4, $self->{'timegroup'}{'helper'}{'multiple'} );
$self->{'timegroup'}{'period'} = '1M';
$self->{'timegroup'}->init_merge();
$self->assert_isa( 'Lire::Timegroup::MonthHelper',
$self->{'timegroup'}{'helper'} );
$self->{'timegroup'}{'period'} = '4y';
$self->{'timegroup'}->init_merge();
$self->assert_isa( 'Lire::Timegroup::YearHelper',
$self->{'timegroup'}{'helper'} );
}
sub test_merge_aggregator_data {
my $self = $_[0];
$self->set_up_merge_fixture();
my $entry = new Lire::Test::Mock( 'Lire::Report::Entry' );
my $group = new Lire::Test::Mock( 'Lire::Report::Group',
'entries' => sub { return ( $entry ) } );
$self->{'timegroup'}->init_merge();
$self->_test_merge_aggregator_data_errors( $group, $entry );
my $timeslices = [];
$self->{'aggregate'}->set_result( 'init_group_data' => [] );
my $data = { 'aggr' => {} };
$entry->set_result( 'names' =>
{ 'range' => 3600,
'value' => timelocal( 0, 0, 11, 1, 0, 2004 ) },
'data_by_name' => sub { $data->{$_[1]} } );
$self->{'timegroup'}->merge_aggregator_data( $group, $timeslices );
$self->assert_num_equals( 1, $self->{'timegroup'}{'_merge_started'} );
$self->assert_deep_equals( [ $self->{'aggregate'}, {}, [] ],
$self->{'aggregate'}->get_invocation( 'merge_group_data' ) );
$self->assert_deep_equals( [ [ timelocal( 0, 0, 0, 1, 0, 2004 ), [] ] ],
$timeslices );
$entry->set_result( 'names' =>
{ 'range' => 3600,
'value' => timelocal( 0, 0, 11, 3, 0, 2004 ) } );
$self->{'timegroup'}->merge_aggregator_data( $group, $timeslices );
$self->assert_deep_equals( [ [ timelocal( 0, 0, 0, 1, 0, 2004 ), [] ],
undef,
[ timelocal( 0, 0, 0, 3, 0, 2004 ), [] ] ],
$timeslices );
$self->assert_num_equals( 2, $self->{'aggregate'}->invocation_count( 'merge_group_data' ) );
$entry->set_result( 'names' =>
{ 'range' => 3600,
'value' => timelocal( 0, 0, 11, 30, 11, 2003 ) } );
$self->{'timegroup'}->merge_aggregator_data( $group, $timeslices );
$self->assert_deep_equals( [ [ timelocal( 0, 0, 0, 30, 11, 2003 ), [] ],
undef,
[ timelocal( 0, 0, 0, 1, 0, 2004 ), [] ],
undef,
[ timelocal( 0, 0, 0, 3, 0, 2004 ), [] ] ],
$timeslices );
$entry->set_result( 'names' =>
{ 'range' => 3600,
'value' => timelocal( 0, 0, 11, 31, 11, 2003 ) } );
$self->{'timegroup'}->merge_aggregator_data( $group, $timeslices );
$self->assert_deep_equals( [ [ timelocal( 0, 0, 0, 30, 11, 2003 ), [] ],
[ timelocal( 0, 0, 0, 31, 11, 2003 ), [] ],
[ timelocal( 0, 0, 0, 1, 0, 2004 ), [] ],
undef,
[ timelocal( 0, 0, 0, 3, 0, 2004 ), [] ] ],
$timeslices );
}
sub _test_merge_aggregator_data_errors {
my ( $self, $group, $entry ) = @_;
$entry->set_result( 'names' => { 'range' => 86400 * 2, 'value' => 0 } );
$self->assert_dies( qr/incompatible merge:/,
sub { $self->{'timegroup'}->merge_aggregator_data( $group, [] ) } );
$entry->set_result( 'names' => { 'range' => 3601, 'value' => 0 } );
$self->assert_dies( qr/incompatible merge:/,
sub { $self->{'timegroup'}->merge_aggregator_data( $group, [] ) } );
}
sub test_WeekHelper_init {
my $self = $_[0];
$self->{'cfg'}{'lr_week_numbering'} = 'ISO';
my $helper = new Lire::Timegroup::WeekHelper( 7*86400, 1 );
$helper->init( timelocal( 0, 0, 0, 1, 0, 2004 ) );
$self->assert_num_equals( 0, $helper->{'week_start'} );
$self->assert_num_equals( 2004, $helper->{'year_start'} );
$helper->init( timelocal( 0, 0, 0, 31, 11, 2003 ) );
$self->assert_num_equals( 0, $helper->{'week_start'} );
$self->assert_num_equals( 2004, $helper->{'year_start'} );
$helper->init( timelocal( 0, 0, 0, 1, 1, 2004 ) );
$self->assert_num_equals( 4, $helper->{'week_start'} );
$self->assert_num_equals( 2004, $helper->{'year_start'} );
$helper->init( timelocal( 0, 0, 0, 1, 0, 2005 ) );
$self->assert_num_equals( 52, $helper->{'week_start'} );
$self->assert_num_equals( 2004, $helper->{'year_start'} );
$self->{'cfg'}{'lr_week_numbering'} = 'U';
$helper->init( timelocal( 0, 0, 0, 1, 0, 2004 ) );
$self->assert_num_equals( 51, $helper->{'week_start'} );
$self->assert_num_equals( 2003, $helper->{'year_start'} );
$helper->init( timelocal( 0, 0, 0, 1, 1, 2004 ) );
$self->assert_num_equals( 4, $helper->{'week_start'} );
$self->assert_num_equals( 2004, $helper->{'year_start'} );
}
sub test_WeekHelper_find_idx {
my $self = $_[0];
$self->{'cfg'}{'lr_week_numbering'} = 'ISO';
my $helper = new Lire::Timegroup::WeekHelper( 7*86400, 1 );
$helper->init( timelocal( 0, 0, 0, 1, 0, 2004 ) );
$self->assert_num_equals( 0, $helper->find_idx( timelocal(0,0,0,1,0,2004)));
$self->assert_num_equals( 0, $helper->find_idx( timelocal(0,0,0,31,11,2003)));
$self->assert_num_equals( 4, $helper->find_idx( timelocal(0,0,0,1,1,2004)));
$self->assert_num_equals( 52, $helper->find_idx( timelocal(0,0,0,1,0,2005)));
$self->assert_num_equals( -1, $helper->find_idx( timelocal(0,0,0,25,11,2003)));
$self->assert_num_equals( -52, $helper->find_idx( timelocal(0,0,0,1,0,2003)));
$self->assert_num_equals( -53, $helper->find_idx( timelocal(0,0,0,25,11,2002)));
$helper->{'week_start'} = 4;
$self->assert_num_equals( 0, $helper->find_idx( timelocal(0,0,0,1,1,2004)));
$self->assert_num_equals( 0, $helper->find_idx( timelocal(0,0,0,31,0,2004)));
$self->assert_num_equals( 1, $helper->find_idx( timelocal(0,0,0,2,1,2004)));
$self->assert_num_equals( 48, $helper->find_idx( timelocal(0,0,0,1,0,2005)));
$self->assert_num_equals( -4, $helper->find_idx( timelocal(0,0,0,1,0,2004)));
$self->assert_num_equals( -5, $helper->find_idx( timelocal(0,0,0,25,11,2003)));
$helper->{'multiple'} = 4;
$self->assert_num_equals( 0, $helper->find_idx( timelocal(0,0,0,1,1,2004)));
$self->assert_num_equals( 0, $helper->find_idx( timelocal(0,0,0,2,1,2004)));
$self->assert_num_equals( 12, $helper->find_idx( timelocal(0,0,0,1,0,2005)));
$self->assert_num_equals( -2, $helper->find_idx( timelocal(0,0,0,25,11,2003)));
$self->assert_num_equals( -13, $helper->find_idx( timelocal(0,0,0,1,1,2003)));
$self->assert_num_equals( -14, $helper->find_idx( timelocal(0,0,0,1,0,2003)));
}
sub test_WeekHelper_slice_start {
my $self = $_[0];
$self->{'cfg'}{'lr_week_numbering'} = 'ISO';
my $helper = new Lire::Timegroup::WeekHelper( 7*86400, 1 );
$helper->init( timelocal( 0, 0, 0, 1, 0, 2004 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 29, 11, 2003 ),
$helper->slice_start( 0 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 26, 0, 2004 ),
$helper->slice_start( 4 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 27, 11, 2004 ),
$helper->slice_start( 52 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 3, 0, 2005 ),
$helper->slice_start( 53 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 31, 0, 2005 ),
$helper->slice_start( 57 ) );
$helper->{'week_start'} = 4;
$self->assert_num_equals( timelocal( 0, 0, 0, 26, 0, 2004 ),
$helper->slice_start( 0 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 20, 11, 2004 ),
$helper->slice_start( 47 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 27, 11, 2004 ),
$helper->slice_start( 48 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 24, 0, 2005 ),
$helper->slice_start( 52 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 26, 11, 2005 ),
$helper->slice_start( 100 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 23, 0, 2006 ),
$helper->slice_start( 104 ) );
$helper->{'multiple'} = 4;
$self->assert_num_equals( timelocal( 0, 0, 0, 26, 0, 2004 ),
$helper->slice_start( 0 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 23, 1, 2004 ),
$helper->slice_start( 1 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 27, 11, 2004 ),
$helper->slice_start( 12 ) );
}
sub test_MonthHelper_find_idx {
my $self = $_[0];
my $helper = new Lire::Timegroup::MonthHelper( 7*86400, 1 );
$helper->init( timelocal( 0, 0, 0, 1, 0, 2004 ) );
$self->assert_num_equals( 104, $helper->{'year_start'} );
$self->assert_num_equals( 0, $helper->{'month_start'} );
$self->assert_num_equals( 0, $helper->find_idx( timelocal( 0, 0, 0, 15, 0, 2004 ) ) );
$self->assert_num_equals( 11, $helper->find_idx( timelocal( 0, 0, 0, 15, 11, 2004 ) ) );
$self->assert_num_equals( 12, $helper->find_idx( timelocal( 0, 0, 0, 15, 0, 2005 ) ) );
$self->assert_num_equals( -1, $helper->find_idx( timelocal( 0, 0, 0, 31, 11, 2003 ) ) );
$self->assert_num_equals( -13, $helper->find_idx( timelocal( 0, 0, 0, 31, 11, 2002 ) ) );
$helper->{'month_start'} = 2;
$self->assert_num_equals( 9, $helper->find_idx( timelocal( 0, 0, 0, 15, 11, 2004 ) ) );
$self->assert_num_equals( -2, $helper->find_idx( timelocal( 0, 0, 0, 15, 0, 2004 ) ) );
$helper->{'multiple'} = 3;
$self->assert_num_equals( -1, $helper->find_idx( timelocal( 0, 0, 0, 15, 0, 2004 ) ) );
$self->assert_num_equals( 0, $helper->find_idx( timelocal( 0, 0, 0, 15, 2, 2004 ) ) );
$self->assert_num_equals( 3, $helper->find_idx( timelocal( 0, 0, 0, 15, 0, 2005 ) ) );
$self->assert_num_equals( -1, $helper->find_idx( timelocal( 0, 0, 0, 31, 11, 2003 ) ) );
$self->assert_num_equals( -5, $helper->find_idx( timelocal( 0, 0, 0, 31, 11, 2002 ) ) );
}
sub test_MonthHelper_slice_start {
my $self = $_[0];
my $helper = new Lire::Timegroup::MonthHelper( 7*86400, 1 );
$helper->{'year_start'} = 104;
$helper->{'month_start'} = 2;
$self->assert_num_equals( timelocal( 0, 0, 0, 1, 2, 2004 ),
$helper->slice_start( 0 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 1, 11, 2004 ),
$helper->slice_start( 9 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 1, 2, 2005 ),
$helper->slice_start( 12 ) );
$helper->{'multiple'} = 3 ;
$self->assert_num_equals( timelocal( 0, 0, 0, 1, 2, 2004 ),
$helper->slice_start( 0 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 1, 11, 2004 ),
$helper->slice_start( 3 ) );
$self->assert_num_equals( timelocal( 0, 0, 0, 1, 2, 2005 ),
$helper->slice_start( 4 ) );
}
1;
syntax highlighted by Code2HTML, v. 0.9.1