X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=t%2FMatcher.t;h=3345e142510a5b9a018b7ed49bbb10a7e5c0a345;hb=9d6d641d1f8b77271800f43bc027b651f9aea52b;hp=484afe0473b76d7608804d201c93e3728edcdf51;hpb=6eeb5180422d9439afb9e783aae70f7c1beb27e7;p=srvgit diff --git a/t/Matcher.t b/t/Matcher.t index 484afe0473..3345e14251 100755 --- a/t/Matcher.t +++ b/t/Matcher.t @@ -1,33 +1,52 @@ #!/usr/bin/perl + +# This file is part of Koha. +# +# Koha 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 3 of the License, or +# (at your option) any later version. # -#testing C4 matcher +# Koha 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 Koha; if not, see . + +use Modern::Perl; -use strict; -use warnings; -use Test::More tests => 10; +use Test::More; use Test::MockModule; +use Test::Warn; + +use MARC::Record; + +use Module::Load::Conditional qw/check_install/; BEGIN { - use_ok('C4::Matcher'); + if ( check_install( module => 'Test::DBIx::Class' ) ) { + plan tests => 13; + } else { + plan skip_all => "Need Test::DBIx::Class" + } } -my $module = new Test::MockModule('C4::Context'); -$module->mock( - '_new_dbh', - sub { - my $dbh = DBI->connect( 'DBI:Mock:', '', '' ) - || die "Cannot create handle: $DBI::errstr\n"; - return $dbh; - } -); -my $matcher = [ - [ 'matcher_id', 'code', 'description', 'record_type', 'threshold' ], - [ 1, 'ISBN', 'ISBN', 'red', 1 ], - [ 2, 'ISSN', 'ISSN', 'blue', 0 ] -]; -my $dbh = C4::Context->dbh(); +use Test::DBIx::Class; -$dbh->{mock_add_resultset} = $matcher; +my $db = Test::MockModule->new('Koha::Database'); +$db->mock( _new_schema => sub { return Schema(); } ); + +use_ok('C4::Matcher', qw( GetMatcherList GetMatcherId )); + +fixtures_ok [ + MarcMatcher => [ + [ 'matcher_id', 'code', 'description', 'record_type', 'threshold' ], + [ 1, 'ISBN', 'ISBN', 'red', 1 ], + [ 2, 'ISSN', 'ISSN', 'blue', 0 ] + ], +], 'add fixtures'; my @matchers = C4::Matcher::GetMatcherList(); @@ -35,8 +54,6 @@ is( $matchers[0]->{'matcher_id'}, 1, 'First matcher_id value is 1' ); is( $matchers[1]->{'matcher_id'}, 2, 'Second matcher_id value is 2' ); -$dbh->{mock_add_resultset} = $matcher; - my $matcher_id = C4::Matcher::GetMatcherId('ISBN'); is( $matcher_id, 1, 'testing getmatcherid' ); @@ -62,3 +79,319 @@ is( $testmatcher->code(), 'match on ISBN', 'testing code accessor' ); $testmatcher->description('match on ISSN'); is( $testmatcher->description(), 'match on ISSN', 'testing code accessor' ); + +subtest '_get_match_keys() tests' => sub { + + plan tests => 20; + + my $matchpoint = get_title_matchpoint({ + length => 0, + norms => [ 'legacy_default' ], + offset => 0 + }); + + my $record = MARC::Record->new(); + $record->append_fields( + MARC::Field->new('020', '1', ' ', + a => '978-1451697216 (alk. paper)'), + MARC::Field->new('020', '1', ' ', + a => '145169721X (alk. paper)'), + MARC::Field->new('020', '1', ' ', + a => '1NOTISBN3'), + MARC::Field->new('100', '1', ' ', + a => 'King, Stephen', + d => 'd1947-'), + MARC::Field->new('245', ' ', ' ', + a => ' .; thE t[]:,aliS(m)/An\'"', + c => 'Stephen King, Peter Straub.' ), + MARC::Field->new('700', ' ', ' ', + a => 'Straub, Peter', + d => '1943-') + ); + + my @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + + is( $keys[0], 'THE TALISMAN STEPHEN KING PETER STRAUB', + 'Match key correctly calculated with no $norms'); + + $matchpoint = get_title_matchpoint({ + length => 9, + norms => [ 'legacy_default' ], + offset => 0 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], 'THE', + 'Match key correctly calculated with length 9'); + + $matchpoint = get_title_matchpoint({ + length => 9, + norms => [ 'legacy_default' ], + offset => 1 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], 'THE T', + 'Match key correctly calculated with length 9 and offset 1'); + + $matchpoint = get_title_matchpoint({ + length => 9, + norms => [ 'legacy_default' ], + offset => 2 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], 'THE T', + 'Match key correctly calculated with length 9 and offset 2, should not remove space'); + + $matchpoint = get_authors_matchpoint({ + length => 0, + norms => [ 'legacy_default' ], + offset => 0 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], 'STRAUB PETER KING STEPHEN', + 'Match key correctly calculated with multiple components'); + + $matchpoint = get_authors_matchpoint({ + length => 9, + norms => [ 'legacy_default' ], + offset => 0 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], 'STRAUB P KING STE', + 'Match key correctly calculated with multiple components, length 9'); + + $matchpoint = get_authors_matchpoint({ + length => 10, + norms => [ 'legacy_default' ], + offset => 0 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], 'STRAUB PE KING STEP', + 'Match key correctly calculated with multiple components, length 10'); + + $matchpoint = get_authors_matchpoint({ + length => 10, + norms => [ 'legacy_default' ], + offset => 2 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], 'RAUB PETE NG STEPHE', + 'Match key correctly calculated with multiple components, length 10, offset 1'); + + $matchpoint = get_title_matchpoint({ + length => 0, + norms => [ 'none', 'none' ], + offset => 0 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], ' .; thE t[]:,aliS(m)/An\'" Stephen King, Peter Straub.', + 'Match key intact if \'none\' specified, length 0 and offset 0' ); + + $matchpoint = get_authors_matchpoint({ + length => 0, + norms => [ 'upper_case' ], + offset => 0 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], 'STRAUB, PETER KING, STEPHEN', + 'Match key correctly calculated with multiple components, \'upper_case\' norm'); + + $matchpoint = get_authors_matchpoint({ + length => 0, + norms => [ 'lower_case' ], + offset => 0 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], 'straub, peter king, stephen', + 'Match key correctly calculated with multiple components, \'lower_case\' norm'); + + $matchpoint = get_authors_matchpoint({ + length => 0, + norms => [ 'remove_spaces' ], + offset => 0 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], 'Straub,Peter King,Stephen', + 'Match key correctly calculated with multiple components, \'remove_spaces\' norm'); + + $matchpoint = get_authors_matchpoint({ + length => 0, + norms => [ 'remove_spaces', 'lower_case' ], + offset => 0 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], 'straub,peter king,stephen', + 'Match key correctly calculated with multiple components, \'remove_spaces\' and \'lower_case\' norm'); + + my $norm = 'unknown_norm'; + $matchpoint = get_title_matchpoint({ + length => 0, + norms => [ $norm ], + offset => 0 + }); + warning_is + { @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ) } + qq{Invalid normalization routine required ($norm)}, + 'Passing an invalid normalization routine name raises a warning'; + + is( $keys[0], ' .; thE t[]:,aliS(m)/An\'" Stephen King, Peter Straub.', + 'Match key intact if invalid normalization routine specified' ); + + $matchpoint = get_title_matchpoint({ + length => 0, + norms => [ $norm, 'upper_case' ], + offset => 0 + }); + warning_is + { @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ) } + qq{Invalid normalization routine required ($norm)}, + 'Passing an invalid normalization routine name raises a warning'; + + is( $keys[0], ' .; THE T[]:,ALIS(M)/AN\'" STEPHEN KING, PETER STRAUB.', + 'Match key correctly normalized if invalid normalization routine specified' ); + + $matchpoint = get_isbn_matchpoint({ + length => 0, + norms => [ 'ISBN' ], + offset => 0 + }); + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], '9781451697216', + 'Match key correctly calculated as ISBN13 when ISBN normalizer used'); + is( $keys[1], '9781451697216', + 'Match key correctly calculated as ISBN13 when ISBN normalizer used'); + is( $keys[2], '1NOTISBN3', + 'Match key passed through if not an isbn when ISBN normalizer used'); + +}; + +subtest '_get_match_keys() leader tests' => sub { + plan tests => 2; + my $record = MARC::Record->new(); + my $matchpoint = get_leader_matchpoint({ + length => 1, + offset => 6, + }); + + my @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], ' ', 'Match key correctly calculated as " " from LDR6 when no leader available'); + + $record->leader('01344cam a22003014a 4500'); + + @keys = C4::Matcher::_get_match_keys( $record, $matchpoint ); + is( $keys[0], 'a', 'Match key correctly calculated as "a" from LDR6'); +}; + +sub get_title_matchpoint { + + my $params = shift; + + my $length = $params->{length} // 0; + my $norms = $params->{norms} // []; + my $offset = $params->{offset} // 0; + + my $matchpoint = { + components => [ + { + length => $length, + norms => $norms, + offset => $offset, + subfields => + { + a => 1, + c => 1 + }, + tag => '245' + } + ], + index => "title", + score => 1000 + }; + + return $matchpoint; +} + +sub get_authors_matchpoint { + + my $params = shift; + + my $length = $params->{length} // 0; + my $norms = $params->{norms} // []; + my $offset = $params->{offset} // 0; + + my $matchpoint = { + components => [ + { + length => $length, + norms => $norms, + offset => $offset, + subfields => + { + a => 1 + }, + tag => '700' + }, + { + length => $length, + norms => $norms, + offset => $offset, + subfields => + { + a => 1 + }, + tag => '100' + } + ], + index => "author", + score => 1000 + }; + + return $matchpoint; +} + +sub get_isbn_matchpoint { + + my $params = shift; + + my $length = $params->{length} // 0; + my $norms = $params->{norms} // []; + my $offset = $params->{offset} // 0; + + my $matchpoint = { + components => [ + { + length => $length, + norms => $norms, + offset => $offset, + subfields => + { + a => 1 + }, + tag => '020' + }, + ], + index => "isbn", + score => 1000 + }; + + return $matchpoint; +} + +sub get_leader_matchpoint { + my $params = shift; + my $length = $params->{length} // 0; + my $norms = $params->{norms} // []; + my $offset = $params->{offset} // 0; + + my $matchpoint = { + components => [ + { + length => $length, + norms => $norms, + offset => $offset, + tag => 'LDR' + }, + ], + }; + + return $matchpoint; +}