package tests::DlfConverterProcessFixture; use strict; use base qw/ Lire::Test::TestCase /; use Cwd qw/ realpath /; use File::Basename qw/ dirname /; use File::Temp qw/ :mktemp tempdir /; use Lire::PluginManager; use Lire::DlfConverterProcess; use Lire::DlfStore; use Lire::ImportJob; use Lire::DlfSchema; use Lire::Utils qw/ check_param /; use Lire::Test::Mock; =pod =head1 NAME Lire::Test::DlfConverterTestCase - Base class for writing DLfConverter unit tests =head1 SYNOPSIS use base qw/ Lire::Test::DlfConverterTestCase /; sub schema_fixtures { { 'test' => "...", 'test2' => "...", }, } sub import_job_fixtures { { log }, } =head1 DESCRIPTION This is a Test::Unit::TestCase subclass which can be used to easily write tests for DlfConverters. This class implements what is needed to provide the necessary fixture in the set_up() and tear_down(). =head1 FIXTURES These are the methods that subclasses will usually override to provide the necessary data so that the DlfConverter test fixtures be setup. =head2 schema_fixtures() Should return an hash reference. Keys are schema names and the value should be the schema in XML. The class will make sure that these schemas can be loaded using load_schema(). =cut sub schema_fixtures { return {}; } =pod =head2 import_job_fixtures() Should return an hash reference. Keys are the ImportJob name and the value should the log file's content. Appropriate Lire::ImportJob can then be acessed using the import_job() method. =cut sub import_job_fixtures { return {}; } =pod =head2 converter_fixtures() Should return an array reference containing the Lire::DlfConverter object which should be registered with the Lire::PluginManager. =cut sub converter_fixtures { return []; } sub new { my $self = shift()->SUPER::new( @_ ); my $tmpl = ref($self) . "_XXXXXX"; $tmpl =~ s/::/__/; $self->{'_tmpdir'} = tempdir( $tmpl, 'TMPDIR' => 1, 'CLEANUP' => 1 ); my $schemas = $self->schema_fixtures(); $self->error( "schema_fixtures() didn't return an hash reference: $schemas" ) unless ref $schemas eq 'HASH'; foreach my $s ( keys %$schemas ) { open FH, "> $self->{'_tmpdir'}/$s.xml" or $self->error( "error creating $s schema: $!" ); print FH $schemas->{$s}; close FH; } my $logs = $self->import_job_fixtures(); $self->error( "import_job_fixtures() didn't return an hash reference: $logs" ) unless ref $logs eq 'HASH'; foreach my $l ( keys %$logs ) { open FH, "> $self->{'_tmpdir'}/$l.log" or $self->error( "can' create log file $l: $!" ); print FH $logs->{$l}; close FH; $self->{'_jobs'}{$l} = new Lire::ImportJob( $l ); $self->{'_jobs'}{$l}->pattern( "$self->{'_tmpdir'}/$l.log" ); } $self->{'_test_count'} = 0; return $self; } =pod =head1 UTILITY METHODS =head2 dlf_store() Return the Lire::DlfStore instance that should be used for the test. A new Lire::DlfStore is created before each test. =cut sub dlf_store { return $_[0]{'_store'}; } =pod =head2 import_job( $name ) Returns the Lire::ImportJob named $name which points to the corresponding log file content as returned by import_job_fixtures(). =cut sub import_job { check_param( $_[1], 'name', qr/^.+$/ ); return $_[0]{'_jobs'}{$_[1]}; } sub set_up { my $self = $_[0]; $self->SUPER::set_up(); $self->{'old_cache'} = { %Lire::DlfSchema::SCHEMA_CACHE }; %Lire::DlfSchema::SCHEMA_CACHE = (); $self->{'cfg'}{'_lr_config_spec'} = $self->lire_default_config_spec(); $self->{'_store'} = Lire::DlfStore->open( "$self->{'_tmpdir'}/store" . $self->{'_test_count'}++, 1 ); my $lire_schemas_dir = realpath( dirname( __FILE__ ) . '/../../schemas' ); $self->{'cfg'}{'lr_schemas_path'} = [ $lire_schemas_dir, $self->{'_tmpdir'} ]; $self->{'_converter_fixtures'} = $self->converter_fixtures(); $self->set_up_plugin_mgr(); foreach my $converter ( @{$self->{'_converter_fixtures'}} ) { Lire::PluginManager->register_plugin( $converter ); } return; } sub tear_down { my $self = $_[0]; $self->SUPER::tear_down(); delete $self->{'_converter_fixtures'}; %Lire::DlfSchema::SCHEMA_CACHE = %{$self->{'old_cache'}}; return; } =pod =head2 create_dlf_converter_process( $job_name, $converter_name ) Returns a Lire::DlfConverterProcess to process the ImportJob $job_name using the DLF converter $converter_name. =cut sub create_dlf_converter_process { my ( $self, $job_name, $converter_name ) = @_; $self->import_job( $job_name )->converter( $converter_name ); my $p = new_proxy Lire::Test::Mock( 'Lire::DlfConverterProcess', $self->import_job( $job_name ), $self->dlf_store() ); $p->set_result( 'error', sub { $self->annotate( $_[1] ); shift->Lire::DlfConverterProcess::error( @_ ) } ); $self->assert_not_null( $p, "new() returned undef" ); return $p; } =pod =head2 assert_store_contains_expected_results( $expected, $process ) This is method can be use to validate the results of a Lire::DlfConverterProcess. The expected results are specified in the $expected structure. The $process parameter should contains the Lire::DlfConverterProcess for which the results should be checked. The $expected data structure is an hash reference which contains the expected results. The following keys will be checked: =over =item line_count This is checked against the value returned by line_count() from the DlfConverterProcess. =item dlf_count This value is checked against the value returned by dlf_count() from the DlfConverterProcess. =item error_count This value is checked against the value returned by error_count() from the DlfConverterProcess. =item saved_count This value is checked against the value returned by saved_count() from the DlfConverterProcess. =item ignored_count This value is checked against the value returned by ignored_count() from the DlfConverterProcess. =item dlf This should contains another hash reference. For each keys in this hash, the DlfStore will be checked for DlfStream of the same name. These DlfStream will be inspected to make sure that they contains identical DLF records than the ones specified in the array reference. =back =cut sub assert_dlf_converter_match_results { my ( $self, $expected, $p ) = @_; my $line_count = $p->line_count(), $self->assert_equals( $expected->{'line_count'}, $p->line_count() ); $self->assert_equals( $expected->{'dlf_count'}, $p->dlf_count() ); $self->assert_equals( $expected->{'error_count'}, $p->error_count() ); $self->assert_equals( $expected->{'saved_count'}, $p->saved_count() ) if defined $expected->{'saved_count'}; $self->assert_equals( $expected->{'ignored_count'}, $p->ignored_count() ) if defined $expected->{'ignored_count'}; my $store = $p->dlf_store(); foreach my $schema ( keys %{$expected->{'dlf'}} ) { my $s = $store->open_dlf_stream( $schema, "r" ); my @dlf = (); while ( defined ($_ = $s->read_dlf() ) ) { push @dlf, $_; } $s->close(); $self->assert_deep_equals( $expected->{'dlf'}{$schema}, \@dlf ); } return; } # keep perl happy 1; __END__ =pod =head1 SEE ALSO Test::Unit::TestCase(3pm), Lire::DlfConverter(3pm), Lire::DlfConverterProcess(3pm), Lire::DlfStore(3pm), Lire::ImportJob(3pm), Lire::PluginManager(3pm) =head1 VERSION $Id: DlfConverterProcessFixture.pm,v 1.6 2006/07/23 13:16:32 vanbaal Exp $ =head1 AUTHOR Francis J. Lacoste =head1 COPYRIGHT Copyright (C) 2002-2004 Stichting LogReport Foundation LogReport@LogReport.org This file is part of Lire. Lire is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program (see COPYING); if not, check with http://www.gnu.org/copyleft/gpl.html. =cut