package tests::DlfResultTest;

use strict;

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

use Lire::DlfQuery;
use Lire::DlfResult;

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

    $self->init();

    return $self;
}

sub set_up {
    my $self = shift->SUPER::set_up();

    $self->set_up_test_store();
    $self->set_up_simple_query();
}

sub set_up_simple_query {
    my $self = $_[0];
    my $query = new Lire::DlfQuery( 'test' );
    foreach my $f ( qw/time_start user file/ ) {
        $query->add_field( $f );
    }
    $query->set_filter_clause( 'user = ?', 'flacoste' );
    $query->set_order_by_clause( 'time_start' );
    $self->{'simple_query'} = $query;
}

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

    $self->{'uni_string'} = "ISO eacute: \xe9";
    my $utf8_string = "ISO eacute: \x{c3}\x{a9}";
    $self->{'store'}{'_dbh'}->do( 'INSERT INTO dlf_test ( user, file ) VALUES( ?, ? )',
                                  {}, 'utf8_test', $utf8_string );
    my $query = new Lire::DlfQuery( 'test' );
    $query->add_field( 'file' );
    $query->set_filter_clause( 'user = ?', 'utf8_test' );
    $self->{'utf8_query'} = $query;

    return;
}

sub tear_down {
    my $self = shift->SUPER::tear_down();

    $self->tear_down_test_store();
    $self->{'simple_query'}->release();
}

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

    $self->assert_died( sub { new Lire::DlfResult() },
                        qr/missing 'query' parameter/ );

    $self->assert_died( sub { new Lire::DlfResult( $self->{'simple_query'} ) },
                        qr/missing 'sql' parameter/ );

    $self->assert_died( sub { new Lire::DlfResult( $self->{'simple_query'},
                                                   $self->{'simple_query'}->_as_sql()
                                                 ) },
                        qr/missing 'store' parameter/ );

    my $result = new Lire::DlfResult( $self->{'simple_query'},
                                      $self->{'simple_query'}->_as_sql(),
                                      $self->{'store'} );
    $self->assert_not_null( $result, "new() returned undef" );
    $self->assert( UNIVERSAL::isa( $result, 'Lire::DlfResult' ),
                   "new() didn't return a Lire::DlfResult instance: $result" );
    $self->assert_deep_equals( $self->{'simple_query'},
                               $result->{'_query'} );
    $self->assert_not_null( $result->{'_sth'},
                            "'_sth' attribute wasn't initialized" );
    $self->assert( defined UNIVERSAL::can( $result->{'_sth'}, 'fetchrow_arrayref' ),
                   "'_sth' attribute doesn't seem to be a DBI statement handle: $result->{'_sth'}"
                 );
}

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

    my $result = $self->{'simple_query'}->execute( $self->{'store'} );

    my @rows = ( { 'time_start' => 1043514300,
                   'user' => 'flacoste',
                   'file' => '/movies/000002.mpg',
                 },
                 { 'time_start' => 1043515075,
                   'user' => 'flacoste',
                   'file' => '/movies/000003.mpg',
                 },
               );

    my $row1 = $result->next_row();
    $self->assert_deep_equals( $rows[0], $row1 );
    my $row2 = $result->next_row();
    $self->assert_deep_equals( $rows[1], $row2 );
    $self->assert_not_equals( $row1, $row2 );

    $self->assert_null( $result->next_row(),
                        "next_row() should return undef when there is no more data" );

    $self->assert_died( sub { $result->next_row() },
                        qr/next_row\(\) called after undef was returned by previous call/ );
}

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

    my $query = new Lire::DlfQuery( 'test', $self->{'store'} );
    foreach my $f ( qw/time_start transfer-complete/ ) {
        $query->add_field( $f );
    }
    $query->set_order_by_clause( 'time_start' );

    my $result = $query->execute( $self->{'store'} );
    $self->assert_deep_equals( { 'time_start' => 1043514000,
                                 'transfer-complete' => 1 },
                               $result->next_row() );
}

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

    # Under 5.6, DlfStore should only contain ASCII
    return unless $Lire::I18N::USE_ENCODING;

    $self->set_up_utf8_query();

    my $result = $self->{'utf8_query'}->execute( $self->{'store'} );
    my $row = $result->next_row();
    $self->assert_str_equals( $self->{'uni_string'},
                              $row->{'file'} );
}

sub test_next_row_aref {
    my $self = $_[0];
    my $result = $self->{'simple_query'}->execute( $self->{'store'} );

    my @rows = ( [ 1043514300, 'flacoste', '/movies/000002.mpg', ],
                 [ 1043515075, 'flacoste', '/movies/000003.mpg' ],
               );

    my $row1 = $result->next_row_aref();
    $self->assert_deep_equals( $rows[0], $row1 );
    my $row2 = $result->next_row_aref();
    $self->assert_deep_equals( $rows[1], $row2 );
    $self->assert_not_equals( $row1, $row2 );

    $self->assert_null( $result->next_row_aref(),
                        "next_row_aref() should return undef when there is no more data" );

    $self->assert_died( sub { $result->next_row_aref() },
                        qr/next_row_aref\(\) called after undef was returned by previous call/ );
}

sub test_next_row_and_next_row_aref_mix {
    my $self = $_[0];
    my $result = $self->{'simple_query'}->execute( $self->{'store'} );

    $result->next_row();
    $result->next_row_aref();
    $self->assert_null( $result->next_row(),
                        "next_row() should return undef when there is no more data" );

    $self->assert_died( sub { $result->next_row_aref() },
                        qr/next_row_aref\(\) called after undef was returned by previous call/ );

    $self->assert_died( sub { $result->next_row() },
                        qr/next_row\(\) called after undef was returned by previous call/ );
}

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

    # Under 5.6, DlfStore should only contain ASCII
    return unless $Lire::I18N::USE_ENCODING;

    $self->set_up_utf8_query();

    my $result = $self->{'utf8_query'}->execute( $self->{'store'} );
    my $row = $result->next_row_aref();
    $self->assert_str_equals( $self->{'uni_string'},
                              $row->[0] );
}

1;


syntax highlighted by Code2HTML, v. 0.9.1