package tests::ReportSubreportTest;

use strict;

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

use Lire::Report::Subreport;
use Lire::Report::TableInfo;
use Lire::Test::Mock;

sub new {
    my $self = shift->SUPER::new( @_ );

    return $self;
}

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

    return $self;
}

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

    return $self;
}

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

    my $subreport = new Lire::Report::Subreport( 'test-extended', "top-dirs" );
    $self->assert_isa( 'Lire::Report::Subreport', $subreport );
    $self->assert_str_equals( "test-extended", $subreport->superservice() );
    $self->assert_str_equals( "top-dirs", $subreport->type() );
}

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

    my $subreport =
      new_missing Lire::Report::Subreport( 'test-extended', "top-dirs",
                                           "error" );
    $self->assert_isa( 'Lire::Report::Subreport', $subreport );
    $self->assert_equals( "test-extended", $subreport->superservice() );
    $self->assert_equals( "top-dirs", $subreport->type() );
    $self->assert_equals( "error", $subreport->missing_reason() );

}

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

    my $subreport = new Lire::Report::Subreport( 'test-extended', "top-dirs" );
    $self->assert_isa( 'Lire::Report::Subreport', $subreport );
    $subreport->delete();
    $self->assert_null( $subreport->{'table_info'},
                        "reference to table_info wasn't removed" );
}

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

    my $subreport =
      new_missing Lire::Report::Subreport( 'test-extended', "top-dirs",
                                           "error" );
    $self->assert_isa( 'Lire::Report::Subreport', $subreport );
    $subreport->delete();
    $self->assert_null( $subreport->{'report'},
                        "reference to report wasn't removed" );
}

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

    my $subreport = new Lire::Report::Subreport( "test", "top-dirs" );
    my $table_info = new Lire::Report::TableInfo();
    $table_info->create_column_info( 'cell1', 'categorical', 'string' );
    my $group_info1 = $table_info->create_group_info( 'nested1' );
    $group_info1->create_column_info( 'cell2', 'categorical', 'string' );
    $group_info1->create_column_info( 'cell3', 'numerical', 'int' );
    my $group_info2 = $table_info->create_group_info( 'nested2' );
    $group_info2->create_column_info( 'cell4', 'categorical', 'string' );
    $group_info2->create_column_info( 'cell5', 'numerical', 'int' );

    $subreport->table_info( $table_info );
    my $entry = $subreport->create_entry();
    my $idx = $subreport->assign_row_indices();
    $self->assert_null( $subreport->{'row_idx'},
                        "'row_idx' attribute of Subreport should always be undef" );
    $self->assert_equals( 0, $idx );
    $self->assert_equals( 0, $entry->row_idx() );

    return;
}

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

    my @calls = ();
    my $subreport = new_proxy Lire::Test::Mock( 'Lire::Report::Subreport',
                                                'test', 'top-dirs' );
    $subreport->set_result( 'assign_row_indices' =>
                            sub { push @calls, 'assign' },
                            'compute_column_info_stats' => 
                            sub { push @calls, 'compute_stats' } );

    my $mock_table_info =
      new_proxy Lire::Test::Mock ( 'Lire::Report::TableInfo' );
    $mock_table_info->set_result( 'compute_columns_width' =>
                                  sub { push @calls, 'compute_width' } );
    $subreport->table_info( $mock_table_info );
    $subreport->finalize();

    $self->assert_num_equals( 3, scalar @calls );
    $self->assert_str_equals( 'assign', $calls[0] );
    $self->assert_str_equals( 'compute_stats', $calls[1] );
    $self->assert_str_equals( 'compute_width', $calls[2] );

    return;
}

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

    my $table = new Lire::Report::Subreport( 'test', 'top-dirs' );
    $self->assert_equals( $table, $table->subreport() );
}

sub set_up_table_info {
    my $self = $_[0];
    my $table = new Lire::Report::TableInfo();
    $table->create_column_info( 'period', 'categorical', 'timestamp', 'Period' );
    my $group1 = $table->create_group_info( 'by_page' );
    $group1->create_column_info( 'page', 'categorical', 'string',
                                 'Requested Page' );
    $group1->create_column_info( 'hits_by_page', 'numerical', 'int', 'Hits' );
    $group1->create_column_info( 'size_by_page', 'numerical', 'int' );

    my $group2 = $table->create_group_info( 'by_host' );
    $group2->create_column_info( 'host', 'categorical', 'string', 'Host' );
    $group2->create_column_info( 'hits_by_host', 'numerical', 'int', 'Hits' );
    $group2->create_column_info( 'size_by_host', 'numerical', 'int' );

    $table->compute_group_layout();
    $self->{'table_info'} = $table;
}

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

    $self->set_up_table_info();
    $self->{'subreport'} = new Lire::Report::Subreport( 'test', 'myreport' );
    $self->{'subreport'}->table_info( $self->{'table_info'} );

    my $data = [ [ '2003-10-12', undef, 9, 53, undef,   9, 53 ],
                 [ undef, 'page1.html', 5, 50, 'host1', 4, 25 ],
                 [ undef, 'page2.html', 4, 3,  'host2', 2, 13 ],
                 [ undef, undef, undef, undef, 'host3', 2, 10 ],
                 [ undef, undef, undef, undef, 'host4', 1,  5 ], # No row-idx
                 [ '2003-10-13', undef, 5, 10, undef,   5, 10 ],
                 [ undef, 'page3.html',  3, 6, 'host3', 3,  6 ],
                 [ undef, 'page2.html',  1, 2, 'host1', 2,  4 ],
                 [ undef, 'page4.html',  2, 4,  undef,  undef, undef ] ];
    my $e_table = [];
    my ( $page_group, $host_group );
    foreach my $r ( @$data ) {
        my ( $period, $page, $page_hits, $page_size, $host, $host_hits, $host_size  ) = @$r;
        my $row = [];
        push @$e_table, $row unless ($host || '' ) eq 'host4';
        if ( $period ) {
            my $entry = $self->{'subreport'}->create_entry();
            $entry->add_name( $period );
            $row->[0] = $entry->data_by_name( 'period' );
            $page_group = $entry->create_group();
            $host_group = $entry->create_group();
            $host_group->show( 3 );
            $page_group->set_summary_value( 'hits_by_page', 'value' => $page_hits );
            $page_group->set_summary_value( 'size_by_page', 'value' => $page_size );
            $row->[2] = $page_group->get_summary_value( 'hits_by_page' );
            $row->[3] = $page_group->get_summary_value( 'size_by_page' );
            $host_group->set_summary_value( 'hits_by_host', 'value' => $host_hits );
            $host_group->set_summary_value( 'size_by_host', 'value' => $host_size );
            $row->[5] = $host_group->get_summary_value( 'hits_by_host' );
            $row->[6] = $host_group->get_summary_value( 'size_by_host' );
        } else {
            if ( $page ) {
                my $entry = $page_group->create_entry();
                $entry->add_name( $page );
                $entry->add_value( 'value' => $page_hits );
                $entry->add_value( 'value' => $page_size );
                $row->[1] = $entry->data_by_name( 'page' );
                $row->[2] = $entry->data_by_name( 'hits_by_page' );
                $row->[3] = $entry->data_by_name( 'size_by_page' );
            }
            if ( $host ) {
                my $entry = $host_group->create_entry();
                $entry->add_name( $host );
                $entry->add_value( 'value' => $host_hits );
                $entry->add_value( 'value' => $host_size );
                $row->[4] = $entry->data_by_name( 'host' );
                $row->[5] = $entry->data_by_name( 'hits_by_host' );
                $row->[6] = $entry->data_by_name( 'size_by_host' );
            }
        }
    }
    $self->{'subreport'}->finalize();
    $self->{'e_table'} = $e_table;
}

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

    $self->set_up_subreport_with_data();
    $self->assert_num_equals( $#{$self->{'e_table'}},
                              $self->{'subreport'}->last_row_idx() );

    return;
}

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

    $self->set_up_subreport_with_data();
    $self->assert_num_equals( scalar @{$self->{'e_table'}},
                              $self->{'subreport'}->nrows() );
    $self->assert_num_equals( scalar @{$self->{'e_table'}},
                              $self->{'subreport'}{'_nrows'} );
}

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

    $self->set_up_subreport_with_data();
    $self->assert_deep_equals( $self->{'e_table'},
                               $self->{'subreport'}->getrows() );
}

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

    $self->set_up_subreport_with_data();

    $self->assert_dies( qr/index out of bounds: 8/,
                        sub { $self->{'subreport'}->getrow_by_idx( 8 ); } );
    $self->assert_dies( qr/index out of bounds: -9/,
                        sub { $self->{'subreport'}->getrow_by_idx( -9 ); } );
    my $idx = 0;
    foreach my $row ( @{$self->{'e_table'}} ) {
        $self->annotate( "Index: $idx\n" );
        $self->assert_deep_equals( $self->{'e_table'}[$idx],
                                   $self->{'subreport'}->getrow_by_idx( $idx ) );
        my $nidx = - ( @{$self->{'e_table'}} - $idx );
        $self->annotate( "Index: $nidx\n" );
        $self->assert_deep_equals( $self->{'e_table'}[$nidx],
                                   $self->{'subreport'}->getrow_by_idx( $nidx ) );
        $idx++;
    }
}

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

    my $subreport = new Lire::Report::Subreport( 'test', "top-dirs" );
    $self->assert_deep_equals( [], $subreport->{'_chart_configs'} );
    $self->assert_deep_equals( [], $subreport->chart_configs() );

    my $cfg = new Lire::Report::ChartConfig();
    $subreport->add_chart_config( $cfg );
    $self->assert_deep_equals( [ $cfg ], $subreport->chart_configs() );
}

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

    $self->init();
    $self->set_up_test_schema();
    $self->{'cfg'}{'lr_reports_path'} = [ "$self->{'testdir'}/reports" ];

    my $subreport = new Lire::Report::Subreport( 'test', 'top-dirs' );
    $self->assert_null( $subreport->{'_schemas'}, '_schemas != undef' );
    $self->assert_deep_equals( [ 'test-extended' ], $subreport->schemas() );
    $self->assert_deep_equals( [ 'test-extended' ], $subreport->{'_schemas'} );
    $subreport->schemas( 'test-extended', 'test-derived' );
    $self->assert_deep_equals( [ 'test-extended', 'test-derived' ],
                              $subreport->{'_schemas'} );
    $self->assert_deep_equals( [ 'test-extended', 'test-derived' ],
                              $subreport->schemas() );
}

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

    $self->init();
    $self->set_up_test_schema();
    $self->{'cfg'}{'lr_reports_path'} = [ "$self->{'testdir'}/reports" ];

    my $subreport = new Lire::Report::Subreport( 'test', 'top-dirs' );
    $self->assert_str_equals( 'test-extended',
                              $subreport->field_schema( 'dirname' ) );
    $self->assert_null( $subreport->field_schema( 'downloads' ) );
}

1;


syntax highlighted by Code2HTML, v. 0.9.1