+
+ #
+ # test magic re-ordering of input data
+ #
+
+ sub test_rec_rules {
+ my ($msg, $rec, $rules, $struct) = @_;
+
+ _clean_ds();
+ _set_ds($rec);
+
+ foreach my $r (split(/;\s*$/, $rules)) {
+ $r =~ s/[\s\n\r]+/ /gs;
+ $r =~ s/^\s+//gs;
+ $r =~ s/\s+$//gs;
+ diag "rule: $r" if $debug;
+ test_s($r) if ($r);
+ }
+
+ ok(my $marc = WebPAC::Normalize::MARC::_get_marc_fields(), "_get_marc_fields");
+ diag dump( $marc ) if $debug;
+ diag "expects:\n", dump($struct) if ($debug > 1);
+ is_deeply( $marc, $struct, $msg );
+ }
+
+ test_rec_rules(
+ 'correct marc with repetable subfield',
+ {
+ '200' => [{
+ 'a' => '200a-1',
+ 'b' => '200b-1',
+ 'c' => '200c-1',
+ }, {
+ 'a' => '200a-2',
+ 'b' => '200b-2',
+ }, {
+ 'a' => '200a-3',
+ }],
+ },
+ qq{
+ marc_indicators('900',1 ,0);
+ marc('900','a', rec('200','a') );
+ marc('900','b', rec('200','b') );
+ marc('900','c', rec('200','c') );
+ },
+ [
+ [ '900', 1, 0, 'a', '200a-1', 'b', '200b-1', 'c', '200c-1' ],
+ [ '900', 1, 0, 'a', '200a-2', 'b', '200b-2' ],
+ [ '900', 1, 0, 'a', '200a-3' ],
+ ],
+ );
+
+
+ test_rec_rules(
+ 'marc_repeatable_subfield',
+ {
+ '200' => [{
+ 'a' => '200a-1',
+ 'b' => '200b-1',
+ 'c' => '200c-1',
+ }, {
+ 'a' => '200a-2',
+ 'b' => '200b-2',
+ 'c' => '200c-2',
+ }, {
+ 'a' => '200a-3',
+ 'c' => '200c-3',
+ }],
+ },
+ qq{
+ marc_indicators('900',1 ,0);
+ marc_repeatable_subfield('900','a', rec('200','a') );
+ marc('900','b', rec('200','b') );
+ marc('900','c', rec('200','c') );
+ },
+ [
+ [ '900', 1, 0, 'a', '200a-1', 'a', '200a-2', 'a', '200a-3', 'b', '200b-1', 'c', '200c-1' ],
+ [ '900', 1, 0, 'b', '200b-2', 'c', '200c-2' ],
+ [ '900', 1, 0, 'c', '200c-3' ],
+ ],
+ );
+
+ test_rec_rules(
+ 'marc_compose',
+ { '200' => [{ a => 'foo ; bar', b => 42, c => 'baz' }] },
+ qq{
+ marc_compose('900',
+ 'c', rec(200,'b'),
+ 'b', rec(200,'a'),
+ 'a', rec(200,'c'),
+ );
+ },
+ [
+ [ '900', ' ', ' ', 'c', 42, 'b', 'foo ; bar', 'a', 'baz' ]
+ ],
+ );
+
+ test_rec_rules(
+ 'marc_compose with + subfields',
+ { '200' => [{ a => 'foo ; bar', b => 42, c => 'baz' }] },
+ qq{
+ marc_compose('900',
+ 'a', rec(200,'a'),
+ '+', prefix(" * ", rec(200,'c')),
+ 'b', rec(200,'b'),
+ '+', prefix(" : ", rec(200,'c')),
+ );
+ },
+ [
+ [ '900', ' ', ' ', 'a', 'foo ; bar * baz', 'b', '42 : baz' ]
+ ],
+ );
+
+ #
+ # test rules
+ #
+ sub test_rule {
+ my ($msg, $rec, $rule, $struct) = @_;
+ _clean_ds();
+ _set_ds( $rec );
+ $rule =~ s/\\/\\/gs;
+ my $r = test_s( $rule );
+ diag "for ", dump($rec), " got:\n", dump($r), "\nexpect:\n" if ($debug > 1);
+ diag dump($struct) if ($debug);
+ is_deeply( $r, $struct, $msg );
+ }
+
+ # test split_rec_on
+ test_rule(
+ 'split_rec_on',
+ { '200' => [{ a => 'foo ; bar', b => 42, c => 'baz' }] },
+ qq{ split_rec_on('200','a', qr/\\s*;\\s*/, 1) },
+ [ 'foo' ],
+ );
+ test_rule(
+ 'split_rec_on',
+ { '200' => [{ a => 'foo ; bar', b => 42, c => 'baz' }] },
+ qq{ split_rec_on('200','a', qr/\\s*;\\s*/, 2) },
+ [ 'bar' ],
+ );
+ test_rule(
+ 'split_rec_on no part',
+ { '200' => [{ a => 'foo ; bar', b => 42, c => 'baz' }] },
+ qq{ split_rec_on('200','a', qr/\\s*;\\s*/) },
+ [ 'foo', 'bar' ],
+ );
+ test_rule(
+ 'split_rec_on no record',
+ {},
+ qq{ split_rec_on('200','a', qr/\\s*;\\s*/) },
+ [ '' ],
+ );
+
+ test_rec_rules(
+ 'marc_compose+split_rec_on',
+ { '200' => [{ a => 'foo ! bar', b => 42, c => 'baz' }] },
+ qq{
+ marc_compose('900',
+ 'a', split_rec_on(200,'a', qr/\\s*!\\s*/, 1),
+ 'c', rec(200,'c'),
+ 'a', split_rec_on(200,'a', qr/\\s*!\\s*/, 2),
+ 'b', rec(200,'b'),
+ );
+ },
+ [
+ [ '900', ' ', ' ',
+ 'a', 'foo',
+ 'c', 'baz',
+ 'a', 'bar',
+ 'b', 42,
+ ]
+ ],
+ );
+
+ cmp_ok(marc_leader('06',42), '==', 42, 'marc_leader');
+ cmp_ok(marc_leader('11',5), '==', 5, 'marc_leader');
+ ok(marc_leader(), 'marc_leader get');
+ diag "leader: ", dump(marc_leader()) if ($debug);
+ is_deeply(marc_leader(), { '06' => 42, 11 => 5 }, "marc_leader full");
+
+ test_rule(
+ 'rec1(000)',
+ { '000' => [ 42 ]},
+ qq{ rec('000') },
+ [ 42 ],
+ );
+
+ test_rec_rules(
+ 'marc(001,rec(000))',
+ { '000' => [ 42 ]},
+ qq{
+ marc('001', rec('000') );
+ },
+ [
+ [ '001', 42, ]
+ ],
+ );
+
+ test_rec_rules(
+ 'marc_remove subfield',
+ { '200' => [{ a => 42, b => 'bar', c => 'baz' }] },
+ qq{
+ marc('900', 'a', rec('200','a') );
+ marc('900', 'b', rec('200','b') );
+ marc_remove('900','b');
+ marc('900', 'b', rec('200','c') );
+ marc_remove('900','a');
+ },
+ [
+ [ '900', ' ', ' ', 'b', 'baz' ],
+ ],
+ );
+
+ test_rec_rules(
+ 'marc_remove field',
+ { '200' => [{ a => 42, b => 'bar', c => 'baz' }] },
+ qq{
+ marc('900', 'a', rec('200','a') );
+ marc('900', 'b', rec('200','b') );
+ marc('901', 'b', rec('200','b') );
+ marc('901', 'c', rec('200','c') );
+ marc_remove('900');
+ },
+ [
+ [ '901', ' ', ' ', 'b', 'bar', 'c', 'baz' ],
+ ],
+ );
+
+ test_s(qq{ marc_remove('*'); });
+ ok(! WebPAC::Normalize::MARC::_get_marc_fields(), 'marc_remove(*)');
+
+ test_rec_rules(
+ 'marc_duplicate',
+ { '200' => [{ a => 42, b => 'bar', c => 'baz', d => 'bing', e => 'bong' }] },
+ qq{
+ marc_leader('06',42);
+ marc_leader('11',0);
+ marc('900', 'a', rec('200','a') );
+ marc('900', 'b', rec('200','b') );
+ marc_duplicate;
+ marc_leader('11',1);
+ marc_remove('900','b');
+ marc('900', 'b', rec('200','c') );
+ marc_duplicate;
+ marc_leader('11',2);
+ marc_remove('900','b');
+ marc('900', 'b', rec('200','d') );
+ marc_duplicate;
+ marc_leader('11',3);
+ marc_remove('900','b');
+ marc('900', 'b', rec('200','e') );
+ },
+ [
+ # this will return FIRST record
+ [ '900', ' ', ' ', 'a', 42, 'b', 'bar' ],
+ ],
+ );
+
+ cmp_ok( marc_count(), '==', 3, 'marc_count' );
+
+ my $i = 0;
+ foreach my $v ( qw/bar baz bing bong/ ) {
+
+ ok($marc = WebPAC::Normalize::MARC::_get_marc_fields( offset => $i ),
+ "_get_marc_fields( offset => $i )"
+ );
+ diag "marc $i = ", dump( $marc ) if ($debug);
+ is_deeply( $marc,
+ [ [ '900', ' ', ' ', 'a', 42, 'b', $v ] ],
+ "MARC copy $i has $v",
+ );
+ is_deeply(WebPAC::Normalize::MARC::_get_marc_leader(), { '06' => 42, 11 => $i }, "_get_marc_leader copy $i");
+ $i++;
+ }
+
+ test_rec_rules(
+ 'marc_original_order',
+ {
+ '200' => [ {
+ a => [ 'a1', 'a2' ], b => [ 'b1', 'b2' ], c => [ 'c1', 'c2' ],
+ subfields => [ qw/a 0 b 0 a 1 b 1 c 0 c 1/ ],
+ }, {
+ a => [ 'a3', 'a4', 'a5' ], b => 'b3', c => 'c3',
+ subfields => [ qw/a 0 a 1 b 0 c 0 a 2/ ],
+ } ],
+ },
+ qq{
+ marc_original_order(900,200);
+ },
+ [
+ [ '900', ' ', ' ', 'a', 'a1', 'b', 'b1', 'a', 'a2', 'b', 'b2', 'c', 'c1', 'c', 'c2', ],
+ [ '900', ' ', ' ', 'a', 'a3', 'a', 'a4', 'b', 'b3', 'c', 'c3', 'a', 'a5', ],
+ ],
+ );
+
+ test_rule(
+ 'rec1 skips subfields',
+ {
+ '200' => [ {
+ a => [ 'a1', 'a2' ], b => [ 'b1', 'b2' ], c => [ 'c1', 'c2' ],
+ subfields => [ qw/a 0 b 0 a 1 b 1 c 0 c 1/ ],
+ }, {
+ a => [ 'a3', 'a4', 'a5' ], b => 'b3', c => 'c3',
+ subfields => [ qw/a 0 a 1 b 0 c 0 a 2/ ],
+ } ],
+ },
+ qq{
+ rec1(200);
+ },
+ ['a1', 'b1', 'a2', 'b2', 'c1', 'c2', 'a3', 'a4', 'b3', 'c3', 'a5' ],
+ );
+
+ is_deeply(
+ [ _pack_subfields_hash({
+ a => [ 'a1', 'a2' ], b => [ 'b1', 'b2' ], c => [ 'c1', 'c2' ],
+ subfields => [ qw/a 0 b 0 a 1 b 1 c 0 c 1/ ],
+ }) ],
+ ['a1', 'b1', 'a2', 'b2', 'c1', 'c2'],
+ '_pack_subfields_hash( $h )'
+ );
+
+ cmp_ok(
+ _pack_subfields_hash({
+ a => [ 'a1', 'a2' ], b => [ 'b1', 'b2' ], c => [ 'c1', 'c2' ],
+ subfields => [ qw/a 0 b 0 a 1 b 1 c 0 c 1/ ],
+ }, 1),
+ 'eq',
+ '^aa1^bb1^aa2^bb2^cc1^cc2',
+ '_pack_subfields_hash( $h, 1 )'
+ );
+
+ _clean_ds();
+ test_s(qq{
+ marc_fixed('008', 0, 'abcdef');
+ marc_fixed('000', 5, '5');
+ marc_fixed('000', 10, 'A');
+ marc_fixed('000', 0, '0');
+ });
+ ok( my $m = WebPAC::Normalize::MARC::_get_marc_fields(), '_get_marc_fields');
+ diag dump( $m );
+ is_deeply( WebPAC::Normalize::MARC::_get_marc_fields(),
+ [
+ ["008", "abcdef"],
+ # 0....5....10
+ ["000", "0 5 A"]
+ ]
+ );
+
+ test_s(qq{ isbn_13( '1558607013', '978-1558607019' ) });
+ test_s(qq{ isbn_10( '1558607013', '978-1558607019' ) });
+
+ is_deeply(
+ [ isbn_13( '1558607013', '978-1558607019' ) ],
+ [ '978-1-55860-701-9', '978-1-55860-701-9', ],
+ 'isbn_13' );
+
+ is_deeply(
+ [ isbn_10( '1558607013', '978-1558607019' ) ],
+ [ '1-55860-701-3', '1-55860-701-3' ],
+ 'isbn_10' );
+
+ # frec
+
+ $rec = {
+ '200' => [ {
+ a => [ 'a1', 'a2' ], b => [ 'b1', 'b2' ], c => [ 'c1', 'c2' ],
+ subfields => [ qw/a 0 b 0 a 1 b 1 c 0 c 1/ ],
+ i1 => '0', i2 => '1',
+ }, {
+ a => [ 'a3', 'a4', 'a5' ], b => 'b3', c => 'c3',
+ subfields => [ qw/a 0 a 1 b 0 c 0 a 2/ ],
+ } ],
+ };
+
+ test_rule( 'frec', $rec, qq{ frec(200) }, [ 'a1' ] );
+ test_rule( 'frec', $rec, qq{ frec(200,'a') }, [ 'a1' ] );
+ test_rule( 'frec', $rec, qq{ frec(200,'b') }, [ 'b1' ] );
+ test_rule( 'frec', $rec, qq{ frec(200,'c') }, [ 'c1' ] );
+
+ $rec->{'900'} = $rec->{'200'};
+ foreach my $sf ( qw/a b c/ ) {
+ ok( frec_eq( '200' => $sf, '900' => $sf ), "frec_eq 200 == 900 $sf");
+ ok( ! frec_ne( '200' => $sf, '900' => $sf ), "! frec_ne 200 == 900 $sf");
+ }
+
+ foreach my $sf ( qw/a b/ ) {
+ ok( ! frec_eq( '200' => $sf, '200' => 'c' ), "! frec_eq 200 $sf == 200 c");
+ ok( frec_ne( '200' => $sf, '200' => 'c' ), "frec_ne 200 $sf == 200 c");
+ }
+
+ test_rule( 'rec(200,i1)', $rec, qq{ rec(200,'i1') }, [ '0' ] );
+ test_rule( 'rec(200,i2)', $rec, qq{ rec(200,'i2') }, [ '1' ] );
+
+ my $hash = { a => '[a]', 'b' => '[b]', subfields => [ 'a', 0, 'b', 0 ] };
+ is_deeply([ _pack_subfields_hash( $hash ) ], [ '[a]', '[b]' ], '_pack_subfields_hash' );
+ ok( $hash->{subfields}, 'subfields exist' );
+ cmp_ok( _pack_subfields_hash( $hash, 1 ), 'eq', '^a[a]^b[b]', '_pack_subfields_hash' );
+ ok( $hash->{subfields}, 'subfields exist' );
+
+ $rec = { 'arr' => [ 1, 2, 3 ] };
+ test_rule( 'rec_array', $rec, qq{ rec_array('arr') }, $rec->{arr} );
+
+ _clean_ds();
+ _set_ds( $rec );
+ test_s(q{
+ row( 'table', e => $_ ) foreach ( rec_array('arr') );
+ });
+ ok( my $rows = _get_ds->{_rows}->{table}, 'ds have _rows' );
+
+ foreach my $i ( 1 .. 3 ) {
+ cmp_ok( $rows->[ $i - 1 ]->{e}, '==', $i, "e $i" );
+ }
+
+ test_rule( 'utf-8'
+ , { '900' => [{ a => 'Čev', b => 'ić' }] }
+ , qq{ join_with('', rec(900,'a'), 'apč', rec(900,'b') ) }
+ , [ "\x{10C}evap\x{10D}i\x{107}" ]
+ );
+