# -*- coding: utf-8 -*-
##
## This file is part of Harvesting Kit.
## Copyright (C) 2014 CERN.
##
## Harvesting Kit 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.
##
## Harvesting Kit 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 Harvesting Kit; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

"""
The BibRecord test suite.
"""

import unittest
import os
import pkg_resources

from harvestingkit import bibrecord


class BibRecordSuccessTest(unittest.TestCase):
    """ bibrecord - demo file parsing test """

    def setUp(self):
        """Initialize stuff"""
        xmltext = pkg_resources.resource_string('harvestingkit.tests',
                os.path.join('data', 'sample_bibrecord.xml'))
        self.recs = [rec[0] for rec in bibrecord.create_records(xmltext)]

    def test_records_created(self):
        """ bibrecord - demo file how many records are created """
        self.assertEqual(142, len(self.recs))

    def test_tags_created(self):
        """ bibrecord - demo file which tags are created """
        ## check if the tags are correct

        tags = ['003', '005', '020', '024', '035', '037', '041', '080', '084', '088',
                '100', '110', '148', '150', '242', '245', '246', '250', '260', '269',
                '270', '300', '340', '371', '372', '400', '410', '430', '440', '450',
                '490', '500', '502', '506', '510', '520', '542', '550', '588', '590',
                '595', '643', '650', '653', '670', '678', '680', '690', '691', '693',
                '694', '695', '697', '700', '710', '711', '720', '773', '852', '856',
                '859', '901', '909', '913', '914', '916', '920', '960', '961', '962',
                '963', '964', '970', '980', '999', 'FFT']

        t = []
        for rec in self.recs:
            t.extend(rec.keys())
        t.sort()
        #eliminate the elements repeated
        tt = []
        for x in t:
            if not x in tt:
                tt.append(x)
        self.assertEqual(tags, tt)

    def test_fields_created(self):
        """bibrecord - demo file how many fields are created"""
        ## check if the number of fields for each record is correct

        fields = [14, 14, 8, 11, 11, 13, 11, 15, 10, 18, 15, 16,
                  10, 9, 15, 10, 11, 11, 11, 9, 11, 11, 10, 9, 9, 9,
                  10, 9, 10, 10, 8, 9, 8, 9, 14, 13, 14, 14, 15, 12,
                  13, 12, 15, 15, 13, 16, 16, 15, 15, 14, 16, 15, 15,
                  15, 16, 15, 16, 15, 15, 16, 15, 15, 14, 15, 12, 13,
                  11, 15, 8, 11, 14, 13, 12, 13, 6, 6, 25, 24, 27, 26,
                  26, 24, 26, 26, 25, 28, 24, 23, 27, 25, 25, 26, 26,
                  25, 20, 26, 25, 22, 9, 8, 9, 9, 8, 7, 19, 21, 27, 23,
                  23, 22, 9, 8, 16, 7, 7, 9, 5, 5, 3, 9, 12, 6,
                  8, 8, 8, 13, 20, 20, 5, 8, 7, 7, 7, 7, 7, 8, 7, 8, 7, 7, 8, 6]
        cr = []
        ret = []
        for rec in self.recs:
            cr.append(len(rec.values()))
            ret.append(rec)
        self.assertEqual(fields, cr, "\n%s\n!=\n%s" % (fields, cr))

    def test_create_record_with_collection_tag(self):
        """ bibrecord - create_record() for single record in collection"""
        xmltext = """
        <collection>
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        </record>
        </collection>
        """
        record = bibrecord.create_record(xmltext)
        record1 = bibrecord.create_records(xmltext)[0]
        self.assertEqual(record1, record)

class BibRecordParsersTest(unittest.TestCase):
    """ bibrecord - testing the creation of records with different parsers"""

    def setUp(self):
        """Initialize stuff"""
        self.xmltext = """
        <!-- A first comment -->
        <collection>
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <!-- A second comment -->
        <subfield code="a">eng</subfield>
        </datafield>
        </record>
        </collection>
        """
        self.expected_record = {
            '001': [([], ' ', ' ', '33', 1)],
            '041': [([('a', 'eng')], ' ', ' ', '', 2)]
            }

    def test_lxml(self):
        """ bibrecord - create_record() with lxml"""
        record = bibrecord._create_record_lxml(self.xmltext)
        self.assertEqual(record, self.expected_record)


class BibRecordDropDuplicateFieldsTest(unittest.TestCase):
    def test_drop_duplicate_fields(self):
        """bibrecord - testing record_drop_duplicate_fields()"""
        record = """
        <record>
        <controlfield tag="001">123</controlfield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe, John</subfield>
        <subfield code="u">Foo University</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe, John</subfield>
        <subfield code="u">Foo University</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="u">Foo University</subfield>
        <subfield code="a">Doe, John</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe, John</subfield>
        <subfield code="u">Foo University</subfield>
        <subfield code="a">Doe, John</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2=" ">
        <subfield cde="a">On the foo and bar</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe, John</subfield>
        <subfield code="u">Foo University</subfield>
        </datafield>
        </record>
        """
        record_result = """
        <record>
        <controlfield tag="001">123</controlfield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe, John</subfield>
        <subfield code="u">Foo University</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="u">Foo University</subfield>
        <subfield code="a">Doe, John</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe, John</subfield>
        <subfield code="u">Foo University</subfield>
        <subfield code="a">Doe, John</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2=" ">
        <subfield cde="a">On the foo and bar</subfield>
        </datafield>
        </record>
        """
        rec = bibrecord.create_record(record)[0]
        rec = bibrecord.record_drop_duplicate_fields(rec)
        rec2 = bibrecord.create_record(record_result)[0]
        self.maxDiff = None
        self.assertEqual(rec, rec2)


class BibRecordBadInputTreatmentTest(unittest.TestCase):
    """ bibrecord - testing for bad input treatment """
    def test_empty_collection(self):
        """bibrecord - empty collection"""
        xml_error0 = """<collection></collection>"""
        rec = bibrecord.create_record(xml_error0)[0]
        self.assertEqual(rec, {})
        records = bibrecord.create_records(xml_error0)
        self.assertEqual(len(records), 0)

    def test_wrong_attribute(self):
        """bibrecord - bad input subfield \'cde\' instead of \'code\'"""
        ws = bibrecord.CFG_BIBRECORD_WARNING_MSGS
        xml_error1 = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe, John</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2=" ">
        <subfield cde="a">On the foo and bar</subfield>
        </datafield>
        </record>
        """
        e = bibrecord.create_record(xml_error1, 1, 1)[2]
        ee =''
        for i in e:
            if type(i).__name__ == 'str':
                if i.count(ws[3])>0:
                    ee = i
        self.assertEqual(bibrecord._warning((3, '(field number: 4)')), ee)

    def test_missing_attribute(self):
        """ bibrecord - bad input missing \"tag\" """
        ws = bibrecord.CFG_BIBRECORD_WARNING_MSGS
        xml_error2 = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe, John</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2=" ">
        <subfield code="a">On the foo and bar</subfield>
        </datafield>
        </record>
        """
        e = bibrecord.create_record(xml_error2, 1, 1)[2]
        ee = ''
        for i in e:
            if type(i).__name__ == 'str':
                if i.count(ws[1])>0:
                    ee = i
        self.assertEqual(bibrecord._warning((1, '(field number(s): [2])')), ee)

    def test_empty_datafield(self):
        """ bibrecord - bad input no subfield """
        ws = bibrecord.CFG_BIBRECORD_WARNING_MSGS
        xml_error3 = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe, John</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2=" ">
        <subfield code="a">On the foo and bar</subfield>
        </datafield>
        </record>
        """
        e = bibrecord.create_record(xml_error3, 1, 1)[2]
        ee = ''
        for i in e:
            if type(i).__name__ == 'str':
                if i.count(ws[8])>0:
                    ee = i
        self.assertEqual(bibrecord._warning((8, '(field number: 2)')), ee)

    def test_missing_tag(self):
        """bibrecord - bad input missing end \"tag\" """
        ws = bibrecord.CFG_BIBRECORD_WARNING_MSGS
        xml_error4 = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe, John</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2=" ">
        <subfield code="a">On the foo and bar</subfield>
        </record>
        """
        e = bibrecord.create_record(xml_error4, 1, 1)[2]
        ee = ''
        for i in e:
            if type(i).__name__ == 'str':
                if i.count(ws[99])>0:
                    ee = i
        self.assertEqual(bibrecord._warning((99, '(Tagname : datafield)')), ee)

class BibRecordAccentedUnicodeLettersTest(unittest.TestCase):
    """ bibrecord - testing accented UTF-8 letters """

    def setUp(self):
        """Initialize stuff"""
        self.xml_example_record = """<record>
  <controlfield tag="001">33</controlfield>
  <datafield tag="041" ind1=" " ind2=" ">
    <subfield code="a">eng</subfield>
  </datafield>
  <datafield tag="100" ind1=" " ind2=" ">
    <subfield code="a">Döè1, John</subfield>
  </datafield>
  <datafield tag="100" ind1=" " ind2=" ">
    <subfield code="a">Doe2, J>ohn</subfield>
    <subfield code="b">editor</subfield>
  </datafield>
  <datafield tag="245" ind1=" " ind2="1">
    <subfield code="a">Пушкин</subfield>
  </datafield>
  <datafield tag="245" ind1=" " ind2="2">
    <subfield code="a">On the foo and bar2</subfield>
  </datafield>
</record>"""
        self.rec = bibrecord.create_record(self.xml_example_record, 1, 1)[0]

    def test_accented_unicode_characters(self):
        """bibrecord - accented Unicode letters"""
        self.assertEqual(self.xml_example_record,
                         bibrecord.record_xml_output(self.rec))
        self.assertEqual(bibrecord.record_get_field_instances(self.rec, "100", " ", " "),
                         [([('a', 'Döè1, John')], " ", " ", "", 3), ([('a', 'Doe2, J>ohn'), ('b', 'editor')], " ", " ", "", 4)])
        self.assertEqual(bibrecord.record_get_field_instances(self.rec, "245", " ", "1"),
                         [([('a', 'Пушкин')], " ", '1', "", 5)])

class BibRecordGettingFieldValuesTest(unittest.TestCase):
    """ bibrecord - testing for getting field/subfield values """

    def setUp(self):
        """Initialize stuff"""
        xml_example_record = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe1, John</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe2, John</subfield>
        <subfield code="b">editor</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="1">
        <subfield code="a">On the foo and bar1</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="2">
        <subfield code="a">On the foo and bar2</subfield>
        </datafield>
        <datafield tag="700" ind1=" " ind2="2">
        <subfield code="a">Penrose, Roger</subfield>
        <subfield code="u">University College London</subfield>
        </datafield>
        <datafield tag="700" ind1=" " ind2="2">
        <subfield code="a">Messi, Lionel</subfield>
        <subfield code="u">FC Barcelona</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]

    def test_get_field_instances(self):
        """bibrecord - getting field instances"""
        self.assertEqual(bibrecord.record_get_field_instances(self.rec, "100", " ", " "),
                         [([('a', 'Doe1, John')], " ", " ", "", 3), ([('a', 'Doe2, John'), ('b', 'editor')], " ", " ", "", 4)])
        self.assertEqual(bibrecord.record_get_field_instances(self.rec, "", " ", " "),
                        [('245', [([('a', 'On the foo and bar1')], " ", '1', "", 5), ([('a', 'On the foo and bar2')], " ", '2', "", 6)]), ('001', [([], " ", " ", '33', 1)]), ('700', [([('a', 'Penrose, Roger'), ('u', "University College London")], ' ', '2', '', 7), ([('a', 'Messi, Lionel'), ('u', 'FC Barcelona')], ' ', '2', '', 8)]), ('100', [([('a', 'Doe1, John')], " ", " ", "", 3), ([('a', 'Doe2, John'), ('b', 'editor')], " ", " ", "", 4)]), ('041', [([('a', 'eng')], " ", " ", "", 2)]),])

    def test_get_field_values(self):
        """bibrecord - getting field values"""
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "a"),
                         ['Doe1, John', 'Doe2, John'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "b"),
                         ['editor'])

    def test_get_field_value(self):
        """bibrecord - getting first field value"""
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "100", " ", " ", "a"),
                         'Doe1, John')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "100", " ", " ", "b"),
                         'editor')

    def test_get_subfield_values(self):
        """bibrecord - getting subfield values"""
        fi1, fi2 = bibrecord.record_get_field_instances(self.rec, "100", " ", " ")
        self.assertEqual(bibrecord.field_get_subfield_values(fi1, "b"), [])
        self.assertEqual(bibrecord.field_get_subfield_values(fi2, "b"), ["editor"])

    def test_filter_field(self):
        """bibrecord - filter field instances"""
        field_instances = bibrecord.record_get_field_instances(self.rec, "700", "%", "%")
        out = bibrecord.filter_field_instances(field_instances, "u", "University College London", 'e')
        self.assertEqual(out, [([('a', 'Penrose, Roger'), ('u', "University College London")], ' ', '2', '', 7)])
        out = bibrecord.filter_field_instances(field_instances, "u", "Bar", "s")
        self.assertEqual(out, [([('a', 'Messi, Lionel'), ('u', 'FC Barcelona')], ' ', '2', '', 8)])
        out = bibrecord.filter_field_instances(field_instances, "u", "on", "s")
        self.assertEqual(out, [([('a', 'Penrose, Roger'), ('u', "University College London")], ' ', '2', '', 7),
                               ([('a', 'Messi, Lionel'), ('u', 'FC Barcelona')], ' ', '2', '', 8)])
        out = bibrecord.filter_field_instances(field_instances, "u", r".*\scoll", "r")
        self.assertEqual(out,[])
        out = bibrecord.filter_field_instances(field_instances, "u", r"[FC]{2}\s.*", "r")
        self.assertEqual(out, [([('a', 'Messi, Lionel'), ('u', 'FC Barcelona')], ' ', '2', '', 8)])


class BibRecordGettingFieldValuesViaWildcardsTest(unittest.TestCase):
    """ bibrecord - testing for getting field/subfield values via wildcards """

    def setUp(self):
        """Initialize stuff"""
        xml_example_record = """
        <record>
        <controlfield tag="001">1</controlfield>
        <datafield tag="100" ind1="C" ind2="5">
        <subfield code="a">val1</subfield>
        </datafield>
        <datafield tag="555" ind1="A" ind2="B">
        <subfield code="a">val2</subfield>
        </datafield>
        <datafield tag="555" ind1="A" ind2=" ">
        <subfield code="a">val3</subfield>
        </datafield>
        <datafield tag="555" ind1=" " ind2=" ">
        <subfield code="a">val4a</subfield>
        <subfield code="b">val4b</subfield>
        </datafield>
        <datafield tag="555" ind1=" " ind2="B">
        <subfield code="a">val5</subfield>
        </datafield>
        <datafield tag="556" ind1="A" ind2="C">
        <subfield code="a">val6</subfield>
        </datafield>
        <datafield tag="556" ind1="A" ind2=" ">
        <subfield code="a">val7a</subfield>
        <subfield code="b">val7b</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]

    def test_get_field_instances_via_wildcard(self):
        """bibrecord - getting field instances via wildcards"""
        self.assertEqual(bibrecord.record_get_field_instances(self.rec, "100", " ", " "),
                         [])
        self.assertEqual(bibrecord.record_get_field_instances(self.rec, "100", "%", " "),
                         [])
        self.assertEqual(bibrecord.record_get_field_instances(self.rec, "100", "%", "%"),
                         [([('a', 'val1')], 'C', '5', "", 2)])
        self.assertEqual(bibrecord.record_get_field_instances(self.rec, "55%", "A", "%"),
                         [([('a', 'val2')], 'A', 'B', "", 3),
                          ([('a', 'val3')], 'A', " ", "", 4),
                          ([('a', 'val6')], 'A', 'C', "", 7),
                          ([('a', 'val7a'), ('b', 'val7b')], 'A', " ", "", 8)])
        self.assertEqual(bibrecord.record_get_field_instances(self.rec, "55%", "A", " "),
                         [([('a', 'val3')], 'A', " ", "", 4),
                          ([('a', 'val7a'), ('b', 'val7b')], 'A', " ", "", 8)])
        self.assertEqual(bibrecord.record_get_field_instances(self.rec, "556", "A", " "),
                         [([('a', 'val7a'), ('b', 'val7b')], 'A', " ", "", 8)])

    def test_get_field_values_via_wildcard(self):
        """bibrecord - getting field values via wildcards"""
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", " "),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", "%", " ", " "),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", "%", " "),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", "%", "%", " "),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", "%", "%", "z"),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "%"),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "a"),
                        [])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", "%", " ", "a"),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", "%", "%", "a"),
                         ['val1'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", "%", "%", "%"),
                         ['val1'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "A", "%", "a"),
                         ['val2', 'val3', 'val6', 'val7a'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "A", " ", "a"),
                         ['val3', 'val7a'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "556", "A", " ", "a"),
                         ['val7a'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "555", " ", " ", " "),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "555", " ", " ", "z"),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "555", " ", " ", "%"),
                         ['val4a', 'val4b'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", " ", " ", "b"),
                         ['val4b'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "%", "%", "b"),
                         ['val4b', 'val7b'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "A", " ", "b"),
                         ['val7b'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "A", "%", "b"),
                         ['val7b'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "A", " ", "a"),
                         ['val3', 'val7a'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "A", "%", "a"),
                         ['val2', 'val3', 'val6', 'val7a'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "%", "%", "a"),
                         ['val2', 'val3', 'val4a', 'val5', 'val6', 'val7a'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", " ", " ", "a"),
                         ['val4a'])

    def test_get_field_values_filtering_exact(self):
        """bibrecord - getting field values and exact filtering"""
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "556", "%", "%", "%", 'a', 'val7a'),
                         ['val7a', 'val7b'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "556", "%", "%", "a", 'a', 'val7a'),
                         ['val7a'])

    def test_get_field_values_filtering_substring(self):
        """bibrecord - getting field values and substring filtering"""
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "556", "%", "%", "%", 'a', '7a', 's'),
                         ['val7a', 'val7b'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "556", "%", "%", "b", 'a', '7a', 's'),
                         ['val7b'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "%", "%", "%", 'b', 'val', 's'),
                         ['val4a', 'val4b', 'val7a', 'val7b'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "%", "%", " ", 'b', 'val', 's'),
                         [])

    def test_get_field_values_filtering_regexp(self):
        """bibrecord - getting field values and regexp filtering"""
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "%", "%", "%", 'b', r'al', 'r'),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "%", "%", "%", 'a', r'.*al[6,7]', 'r'),
                         ['val6', 'val7a', 'val7b'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "55%", "%", "%", "a", 'a', r'.*al[6,7]', 'r'),
                         ['val6', 'val7a'])

    def test_get_field_value_via_wildcard(self):
        """bibrecord - getting first field value via wildcards"""
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "100", " ", " ", " "),
                         '')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "100", "%", " ", " "),
                         '')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "100", " ", "%", " "),
                         '')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "100", "%", "%", " "),
                         '')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "100", " ", " ", "%"),
                         '')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "100", " ", " ", "a"),
                         '')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "100", "%", " ", "a"),
                         '')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "100", "%", "%", "a"),
                         'val1')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "100", "%", "%", "%"),
                         'val1')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "55%", "A", "%", "a"),
                         'val2')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "55%", "A", " ", "a"),
                         'val3')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "556", "A", " ", "a"),
                         'val7a')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "555", " ", " ", " "),
                         '')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "555", " ", " ", "%"),
                         'val4a')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "55%", " ", " ", "b"),
                         'val4b')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "55%", "%", "%", "b"),
                         'val4b')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "55%", "A", " ", "b"),
                         'val7b')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "55%", "A", "%", "b"),
                         'val7b')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "55%", "A", " ", "a"),
                         'val3')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "55%", "A", "%", "a"),
                         'val2')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "55%", "%", "%", "a"),
                         'val2')
        self.assertEqual(bibrecord.record_get_field_value(self.rec, "55%", " ", " ", "a"),
                         'val4a')

class BibRecordAddFieldTest(unittest.TestCase):
    """ bibrecord - testing adding field """

    def setUp(self):
        """Initialize stuff"""
        xml_example_record = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe1, John</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe2, John</subfield>
        <subfield code="b">editor</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="1">
        <subfield code="a">On the foo and bar1</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="2">
        <subfield code="a">On the foo and bar2</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]

    def test_add_controlfield(self):
        """bibrecord - adding controlfield"""
        field_position_global_1 = bibrecord.record_add_field(self.rec, "003",
                                                    controlfield_value="SzGeCERN")
        field_position_global_2 = bibrecord.record_add_field(self.rec, "004",
                                                    controlfield_value="Test")
        self.assertEqual(field_position_global_1, 2)
        self.assertEqual(field_position_global_2, 3)
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "003", " ", " ", ""),
                         ['SzGeCERN'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "004", " ", " ", ""),
                         ['Test'])

    def test_add_datafield(self):
        """bibrecord - adding datafield"""
        field_position_global_1 = bibrecord.record_add_field(self.rec, "100",
                                                    subfields=[('a', 'Doe3, John')])
        field_position_global_2 = bibrecord.record_add_field(self.rec, "100",
                                                    subfields= [('a', 'Doe4, John'), ('b', 'editor')])
        self.assertEqual(field_position_global_1, 5)
        self.assertEqual(field_position_global_2, 6)
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "a"),
                         ['Doe1, John', 'Doe2, John', 'Doe3, John', 'Doe4, John'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "b"),
                         ['editor', 'editor'])

    def test_add_controlfield_on_desired_position(self):
        """bibrecord - adding controlfield on desired position"""
        field_position_global_1 = bibrecord.record_add_field(self.rec, "005",
                                                    controlfield_value="Foo",
                                                    field_position_global=0)
        field_position_global_2 = bibrecord.record_add_field(self.rec, "006",
                                                    controlfield_value="Bar",
                                                    field_position_global=0)
        self.assertEqual(field_position_global_1, 7)
        self.assertEqual(field_position_global_2, 8)

    def test_add_datafield_on_desired_position_field_position_global(self):
        """bibrecord - adding datafield on desired global field position"""
        field_position_global_1 = bibrecord.record_add_field(self.rec, "100",
            subfields=[('a', 'Doe3, John')], field_position_global=0)
        field_position_global_2 = bibrecord.record_add_field(self.rec, "100",
            subfields=[('a', 'Doe4, John'), ('b', 'editor')], field_position_global=0)
        self.assertEqual(field_position_global_1, 3)
        self.assertEqual(field_position_global_2, 3)

    def test_add_datafield_on_desired_position_field_position_local(self):
        """bibrecord - adding datafield on desired local field position"""
        field_position_global_1 = bibrecord.record_add_field(self.rec, "100",
             subfields=[('a', 'Doe3, John')], field_position_local=0)
        field_position_global_2 = bibrecord.record_add_field(self.rec, "100",
             subfields=[('a', 'Doe4, John'), ('b', 'editor')],
             field_position_local=2)
        self.assertEqual(field_position_global_1, 3)
        self.assertEqual(field_position_global_2, 5)

class BibRecordManageMultipleFieldsTest(unittest.TestCase):
    """ bibrecord - testing the management of multiple fields """

    def setUp(self):
        """Initialize stuff"""
        xml_example_record = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="245" ind1=" " ind2=" ">
        <subfield code="a">subfield1</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2=" ">
        <subfield code="a">subfield2</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2=" ">
        <subfield code="a">subfield3</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2=" ">
        <subfield code="a">subfield4</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]

    def test_delete_multiple_datafields(self):
        """bibrecord - deleting multiple datafields"""
        self.fields = bibrecord.record_delete_fields(self.rec, '245', [1, 2])
        self.assertEqual(self.fields[0],
            ([('a', 'subfield2')], ' ', ' ', '', 3))
        self.assertEqual(self.fields[1],
            ([('a', 'subfield3')], ' ', ' ', '', 4))

    def test_add_multiple_datafields_default_index(self):
        """bibrecord - adding multiple fields with the default index"""
        fields = [([('a', 'subfield5')], ' ', ' ', '', 4),
            ([('a', 'subfield6')], ' ', ' ', '', 19)]
        index = bibrecord.record_add_fields(self.rec, '245', fields)
        self.assertEqual(index, None)
        self.assertEqual(self.rec['245'][-2],
            ([('a', 'subfield5')], ' ', ' ', '', 6))
        self.assertEqual(self.rec['245'][-1],
            ([('a', 'subfield6')], ' ', ' ', '', 7))

    def test_add_multiple_datafields_with_index(self):
        """bibrecord - adding multiple fields with an index"""
        fields = [([('a', 'subfield5')], ' ', ' ', '', 4),
            ([('a', 'subfield6')], ' ', ' ', '', 19)]
        index = bibrecord.record_add_fields(self.rec, '245', fields,
            field_position_local=0)
        self.assertEqual(index, 0)
        self.assertEqual(self.rec['245'][0],
            ([('a', 'subfield5')], ' ', ' ', '', 2))
        self.assertEqual(self.rec['245'][1],
            ([('a', 'subfield6')], ' ', ' ', '', 3))
        self.assertEqual(self.rec['245'][2],
            ([('a', 'subfield1')], ' ', ' ', '', 4))

    def test_move_multiple_fields(self):
        """bibrecord - move multiple fields"""
        bibrecord.record_move_fields(self.rec, '245', [1, 3])
        self.assertEqual(self.rec['245'][0],
            ([('a', 'subfield1')], ' ', ' ', '', 2))
        self.assertEqual(self.rec['245'][1],
            ([('a', 'subfield3')], ' ', ' ', '', 4))
        self.assertEqual(self.rec['245'][2],
            ([('a', 'subfield2')], ' ', ' ', '', 5))
        self.assertEqual(self.rec['245'][3],
            ([('a', 'subfield4')], ' ', ' ', '', 6))

class BibRecordDeleteFieldTest(unittest.TestCase):
    """ bibrecord - testing field deletion """

    def setUp(self):
        """Initialize stuff"""
        xml_example_record = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe1, John</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe2, John</subfield>
        <subfield code="b">editor</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="1">
        <subfield code="a">On the foo and bar1</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="2">
        <subfield code="a">On the foo and bar2</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]

        xml_example_record_empty = """
        <record>
        </record>
        """
        self.rec_empty = bibrecord.create_record(xml_example_record_empty, 1, 1)[0]

    def test_delete_controlfield(self):
        """bibrecord - deleting controlfield"""
        bibrecord.record_delete_field(self.rec, "001", " ", " ")
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "001", " ", " ", " "),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "b"),
                         ['editor'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "245", " ", "2", "a"),
                         ['On the foo and bar2'])

    def test_delete_datafield(self):
        """bibrecord - deleting datafield"""
        bibrecord.record_delete_field(self.rec, "100", " ", " ")
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "001", " ", " ", ""),
                         ['33'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "b"),
                         [])
        bibrecord.record_delete_field(self.rec, "245", " ", " ")
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "245", " ", "1", "a"),
                         ['On the foo and bar1'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "245", " ", "2", "a"),
                         ['On the foo and bar2'])
        bibrecord.record_delete_field(self.rec, "245", " ", "2")
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "245", " ", "1", "a"),
                         ['On the foo and bar1'])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "245", " ", "2", "a"),
                         [])

    def test_add_delete_add_field_to_empty_record(self):
        """bibrecord - adding, deleting, and adding back a field to an empty record"""
        field_position_global_1 = bibrecord.record_add_field(self.rec_empty, "003",
                                                    controlfield_value="SzGeCERN")
        self.assertEqual(field_position_global_1, 1)
        self.assertEqual(bibrecord.record_get_field_values(self.rec_empty, "003", " ", " ", ""),
                         ['SzGeCERN'])
        bibrecord.record_delete_field(self.rec_empty, "003", " ", " ")
        self.assertEqual(bibrecord.record_get_field_values(self.rec_empty, "003", " ", " ", ""),
                         [])
        field_position_global_1 = bibrecord.record_add_field(self.rec_empty, "003",
                                                    controlfield_value="SzGeCERN2")
        self.assertEqual(field_position_global_1, 1)
        self.assertEqual(bibrecord.record_get_field_values(self.rec_empty, "003", " ", " ", ""),
                         ['SzGeCERN2'])


class BibRecordDeleteFieldFromTest(unittest.TestCase):
    """ bibrecord - testing field deletion from position"""

    def setUp(self):
        """Initialize stuff"""
        xml_example_record = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe1, John</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe2, John</subfield>
        <subfield code="b">editor</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="1">
        <subfield code="a">On the foo and bar1</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="2">
        <subfield code="a">On the foo and bar2</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]

    def test_delete_field_from(self):
        """bibrecord - deleting field from position"""
        bibrecord.record_delete_field(self.rec, "100", field_position_global=4)
        self.assertEqual(self.rec['100'], [([('a', 'Doe1, John')], ' ', ' ', '', 3)])
        bibrecord.record_delete_field(self.rec, "100", field_position_global=3)
        self.failIf('100' in self.rec)
        bibrecord.record_delete_field(self.rec, "001", field_position_global=1)
        bibrecord.record_delete_field(self.rec, "245", field_position_global=6)
        self.failIf('001' in self.rec)
        self.assertEqual(self.rec['245'], [([('a', 'On the foo and bar1')], ' ', '1', '', 5)])

        # Some crash tests
        bibrecord.record_delete_field(self.rec, '999', field_position_global=1)
        bibrecord.record_delete_field(self.rec, '245', field_position_global=999)


class BibRecordAddSubfieldIntoTest(unittest.TestCase):
    """ bibrecord - testing subfield addition """

    def setUp(self):
        """Initialize stuff"""
        xml_example_record = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe2, John</subfield>
        <subfield code="b">editor</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="1">
        <subfield code="a">On the foo and bar1</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="2">
        <subfield code="a">On the foo and bar2</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]

    def test_add_subfield_into(self):
        """bibrecord - adding subfield into position"""
        bibrecord.record_add_subfield_into(self.rec, "100", "b", "Samekniv",
            field_position_global=3)
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "b"),
                         ['editor', 'Samekniv'])
        bibrecord.record_add_subfield_into(self.rec, "245", "x", "Elgokse",
            field_position_global=4)
        bibrecord.record_add_subfield_into(self.rec, "245", "x", "Fiskeflue",
            subfield_position=0, field_position_global=4)
        bibrecord.record_add_subfield_into(self.rec, "245", "z", "Ulriken",
            subfield_position=2, field_position_global=4)
        bibrecord.record_add_subfield_into(self.rec, "245", "z",
            "Stortinget", subfield_position=999, field_position_global=4)
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "245", " ", "1", "%"),
                         ['Fiskeflue', 'On the foo and bar1', 'Ulriken', 'Elgokse', 'Stortinget'])
        # Some crash tests
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_add_subfield_into, self.rec, "187", "x", "Crash",
            field_position_global=1)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_add_subfield_into, self.rec, "245", "x", "Crash",
            field_position_global=999)


class BibRecordModifyControlfieldTest(unittest.TestCase):
    """ bibrecord - testing controlfield modification """

    def setUp(self):
        """Initialize stuff"""
        xml_example_record = """
        <record>
        <controlfield tag="001">33</controlfield>
        <controlfield tag="005">A Foo's Tale</controlfield>
        <controlfield tag="008">Skeech Skeech</controlfield>
        <controlfield tag="008">Whoop Whoop</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="2">
        <subfield code="a">On the foo and bar2</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]

    def test_modify_controlfield(self):
        """bibrecord - modify controlfield"""
        bibrecord.record_modify_controlfield(self.rec, "001", "34",
            field_position_global=1)
        bibrecord.record_modify_controlfield(self.rec, "008", "Foo Foo",
            field_position_global=3)
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "001"), ["34"])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "005"), ["A Foo's Tale"])
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "008"), ["Foo Foo", "Whoop Whoop"])
        # Some crash tests
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_modify_controlfield, self.rec, "187", "Crash",
            field_position_global=1)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_modify_controlfield, self.rec, "008", "Test",
            field_position_global=10)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_modify_controlfield, self.rec, "245", "Burn",
            field_position_global=5)
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "245", " ", "2", "%"),
                         ["On the foo and bar2"])


class BibRecordModifySubfieldTest(unittest.TestCase):
    """ bibrecord - testing subfield modification """

    def setUp(self):
        """Initialize stuff"""
        xml_example_record = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe2, John</subfield>
        <subfield code="b">editor</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="1">
        <subfield code="a">On the foo and bar1</subfield>
        <subfield code="b">On writing unit tests</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="2">
        <subfield code="a">On the foo and bar2</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]

    def test_modify_subfield(self):
        """bibrecord - modify subfield"""
        bibrecord.record_modify_subfield(self.rec, "245", "a", "Holmenkollen",
            0, field_position_global=4)
        bibrecord.record_modify_subfield(self.rec, "245", "x", "Brann", 1,
            field_position_global=4)
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "245", " ", "1", "%"),
                         ['Holmenkollen', 'Brann'])
        # Some crash tests
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_modify_subfield, self.rec, "187", "x", "Crash", 0,
            field_position_global=1)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_modify_subfield, self.rec, "245", "x", "Burn", 1,
            field_position_global=999)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_modify_subfield, self.rec, "245", "a", "Burn",
            999, field_position_global=4)

class BibRecordDeleteSubfieldFromTest(unittest.TestCase):
    """ bibrecord - testing subfield deletion """

    def setUp(self):
        """Initialize stuff"""
        xml_example_record = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe2, John</subfield>
        <subfield code="b">editor</subfield>
        <subfield code="z">Skal vi danse?</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="1">
        <subfield code="a">On the foo and bar1</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="2">
        <subfield code="a">On the foo and bar2</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]

    def test_delete_subfield_from(self):
        """bibrecord - delete subfield from position"""
        bibrecord.record_delete_subfield_from(self.rec, "100", 2,
            field_position_global=3)
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "z"),
                         [])
        bibrecord.record_delete_subfield_from(self.rec, "100", 0,
            field_position_global=3)
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "%"),
                         ['editor'])
        bibrecord.record_delete_subfield_from(self.rec, "100", 0,
            field_position_global=3)
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "%"),
                         [])
        # Some crash tests
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_delete_subfield_from, self.rec, "187", 0,
            field_position_global=1)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_delete_subfield_from, self.rec, "245", 0,
            field_position_global=999)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_delete_subfield_from, self.rec, "245", 999,
            field_position_global=4)


class BibRecordDeleteSubfieldTest(unittest.TestCase):
    """ bibrecord - testing subfield deletion """

    def setUp(self):
        """Initialize stuff"""
        self.xml_example_record = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
            <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
            <subfield code="a">Doe2, John</subfield>
            <subfield code="b">editor</subfield>
            <subfield code="z">Skal vi danse?</subfield>
            <subfield code="a">Doe3, Zbigniew</subfield>
            <subfield code="d">Doe4, Joachim</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="1">
            <subfield code="a">On the foo and bar1</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="2">
            <subfield code="a">On the foo and bar2</subfield>
        </datafield>
        <datafield tag="246" ind1="1" ind2="2">
            <subfield code="c">On the foo and bar1</subfield>
        </datafield>
        <datafield tag="246" ind1="1" ind2="2">
            <subfield code="c">On the foo and bar2</subfield>
        </datafield>
        </record>
        """

    def test_simple_removals(self):
        """ bibrecord - delete subfield by its code"""
        # testing a simple removals where all the fields are removed
        rec = bibrecord.create_record(self.xml_example_record, 1, 1)[0]

        bibrecord.record_delete_subfield(rec, "041", "b") # nothing should change
        self.assertEqual(rec["041"][0][0], [("a", "eng")])
        bibrecord.record_delete_subfield(rec, "041", "a")
        self.assertEqual(rec["041"][0][0], [])

    def test_indices_important(self):
        """ bibrecord - delete subfield where indices are important"""
        rec = bibrecord.create_record(self.xml_example_record, 1, 1)[0]
        bibrecord.record_delete_subfield(rec, "245", "a", " ", "1")
        self.assertEqual(rec["245"][0][0], [])
        self.assertEqual(rec["245"][1][0], [("a", "On the foo and bar2")])
        bibrecord.record_delete_subfield(rec, "245", "a", " ", "2")
        self.assertEqual(rec["245"][1][0], [])

    def test_remove_some(self):
        """ bibrecord - delete subfield when some should be preserved and some removed"""
        rec = bibrecord.create_record(self.xml_example_record, 1, 1)[0]
        bibrecord.record_delete_subfield(rec, "100", "a", " ", " ")
        self.assertEqual(rec["100"][0][0], [("b", "editor"), ("z", "Skal vi danse?"), ("d", "Doe4, Joachim")])

    def test_more_fields(self):
        """ bibrecord - delete subfield where more fits criteria"""
        rec = bibrecord.create_record(self.xml_example_record, 1, 1)[0]
        bibrecord.record_delete_subfield(rec, "246", "c", "1", "2")
        self.assertEqual(rec["246"][1][0], [])
        self.assertEqual(rec["246"][0][0], [])

    def test_nonexisting_removals(self):
        """ bibrecord - delete subfield that does not exist """
        rec = bibrecord.create_record(self.xml_example_record, 1, 1)[0]
        # further preparation
        bibrecord.record_delete_subfield(rec, "100", "a", " ", " ")
        self.assertEqual(rec["100"][0][0], [("b", "editor"), ("z", "Skal vi danse?"), ("d", "Doe4, Joachim")])
        #the real tests begin
        #   1) removing the subfield from an empty list of subfields
        bibrecord.record_delete_subfield(rec, "246", "c", "1", "2")
        self.assertEqual(rec["246"][1][0], [])
        self.assertEqual(rec["246"][0][0], [])
        bibrecord.record_delete_subfield(rec, "246", "8", "1", "2")
        self.assertEqual(rec["246"][1][0], [])
        self.assertEqual(rec["246"][0][0], [])
        #   2) removing a subfield from a field that has some subfields but none has an appropriate code
        bibrecord.record_delete_subfield(rec, "100", "a", " ", " ")
        self.assertEqual(rec["100"][0][0], [("b", "editor"), ("z", "Skal vi danse?"), ("d", "Doe4, Joachim")])
        bibrecord.record_delete_subfield(rec, "100", "e", " ", " ")
        self.assertEqual(rec["100"][0][0], [("b", "editor"), ("z", "Skal vi danse?"), ("d", "Doe4, Joachim")])


class BibRecordMoveSubfieldTest(unittest.TestCase):
    """ bibrecord - testing subfield moving """

    def setUp(self):
        """Initialize stuff"""
        xml_example_record = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe2, John</subfield>
        <subfield code="b">editor</subfield>
        <subfield code="c">fisk</subfield>
        <subfield code="d">eple</subfield>
        <subfield code="e">hammer</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="1">
        <subfield code="a">On the foo and bar1</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]

    def test_move_subfield(self):
        """bibrecord - move subfields"""
        bibrecord.record_move_subfield(self.rec, "100", 2, 4,
            field_position_global=3)
        bibrecord.record_move_subfield(self.rec, "100", 1, 0,
            field_position_global=3)
        bibrecord.record_move_subfield(self.rec, "100", 2, 999,
            field_position_global=3)
        self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", " ", " ", "%"),
                         ['editor', 'Doe2, John', 'hammer', 'fisk', 'eple'])
        # Some crash tests
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_move_subfield, self.rec, "187", 0, 1,
            field_position_global=3)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_move_subfield, self.rec, "100", 1, 0,
            field_position_global=999)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.record_move_subfield, self.rec, "100", 999, 0,
            field_position_global=3)


class BibRecordCompareSubfieldTest(unittest.TestCase):
    """ bibrecord -  """

    def setUp(self):
        """Initialize stuff"""
        xml_example_record = """
        <record>
        <controlfield tag="001">33</controlfield>
        <datafield tag="041" ind1=" " ind2=" ">
        <subfield code="a">eng</subfield>
        </datafield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Doe2, John</subfield>
        <subfield code="b">editor</subfield>
        <subfield code="c">fisk</subfield>
        <subfield code="d">eple</subfield>
        <subfield code="e">hammer</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2="1">
        <subfield code="a">On the foo and bar1</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]
        # For simplicity, create an alias of the function
        self._func = bibrecord.record_match_subfields

    def test_check_subfield_exists(self):
        self.assertEqual(self._func(self.rec, '100', sub_key='a'), 3)
        self.assertEqual(self._func(self.rec, '100', sub_key='e'), 3)
        self.assertFalse(self._func(self.rec, '245', sub_key='a'))
        self.assertEqual(self._func(self.rec, '245', ind2='1', sub_key='a'), 4)
        self.assertFalse(self._func(self.rec, '999', sub_key='x'))
        self.assertFalse(self._func(self.rec, '100', sub_key='x'))

    def test_check_subfield_values(self):
        self.assertEqual(self._func(self.rec, '100', sub_key='b',
            sub_value='editor'), 3)
        self.assertEqual(self._func(self.rec, '245', ind2='1', sub_key='a',
            sub_value='On the foo and bar1'), 4)
        self.assertEqual(self._func(self.rec, '100', sub_key='e',
            sub_value='ponies suck'), False)
        self.assertEqual(self._func(self.rec, '100', sub_key='c',
            sub_value='FISK'), False)
        self.assertEqual(self._func(self.rec, '100', sub_key='c',
            sub_value='FISK', case_sensitive=False), 3)

    def test_compare_subfields(self):
        self.assertEqual(self._func(self.rec, '100', sub_key='c',
            sub_value='fisk', sub_key2='d', sub_value2='eple'), 3)
        self.assertFalse(self._func(self.rec, '100', sub_key='c',
            sub_value='fisk', sub_key2='d', sub_value2='tom'))
        self.assertEqual(self._func(self.rec, '100', sub_key='c',
            sub_value='fiSk', sub_key2='d', sub_value2='Eple',
            case_sensitive=False), 3)

    def test_error_conditions(self):
        self.assertRaises(TypeError,
            self._func, self.rec, '100')
        self.assertRaises(TypeError,
            self._func, self.rec, '100', sub_key='a',
                sub_value='fiSk', sub_key2='d')


class BibRecordSpecialTagParsingTest(unittest.TestCase):
    """ bibrecord - parsing special tags (FMT, FFT)"""

    def setUp(self):
        """setting up example records"""
        self.xml_example_record_with_fmt = """
        <record>
         <controlfield tag="001">33</controlfield>
         <datafield tag="041" ind1=" " ind2=" ">
          <subfield code="a">eng</subfield>
         </datafield>
         <datafield tag="FMT" ind1=" " ind2=" ">
          <subfield code="f">HB</subfield>
          <subfield code="g">Let us see if this gets inserted well.</subfield>
         </datafield>
        </record>
        """
        self.xml_example_record_with_fft = """
        <record>
         <controlfield tag="001">33</controlfield>
         <datafield tag="041" ind1=" " ind2=" ">
          <subfield code="a">eng</subfield>
         </datafield>
         <datafield tag="FFT" ind1=" " ind2=" ">
          <subfield code="a">file:///foo.pdf</subfield>
          <subfield code="a">http://bar.com/baz.ps.gz</subfield>
         </datafield>
        </record>
        """
        self.xml_example_record_with_xyz = """
        <record>
         <controlfield tag="001">33</controlfield>
         <datafield tag="041" ind1=" " ind2=" ">
          <subfield code="a">eng</subfield>
         </datafield>
         <datafield tag="XYZ" ind1=" " ind2=" ">
          <subfield code="f">HB</subfield>
          <subfield code="g">Let us see if this gets inserted well.</subfield>
         </datafield>
        </record>
        """

    def test_parsing_file_containing_fmt_special_tag_with_correcting(self):
        """bibrecord - parsing special FMT tag, correcting on"""
        rec = bibrecord.create_record(self.xml_example_record_with_fmt, 1, 1)[0]
        self.assertEqual(rec,
                         {u'001': [([], " ", " ", '33', 1)],
                          'FMT': [([('f', 'HB'), ('g', 'Let us see if this gets inserted well.')], " ", " ", "", 3)],
                          '041': [([('a', 'eng')], " ", " ", "", 2)]})
        self.assertEqual(bibrecord.record_get_field_values(rec, "041", " ", " ", "a"),
                         ['eng'])
        self.assertEqual(bibrecord.record_get_field_values(rec, "FMT", " ", " ", "f"),
                         ['HB'])
        self.assertEqual(bibrecord.record_get_field_values(rec, "FMT", " ", " ", "g"),
                         ['Let us see if this gets inserted well.'])

    def test_parsing_file_containing_fmt_special_tag_without_correcting(self):
        """bibrecord - parsing special FMT tag, correcting off"""
        rec = bibrecord.create_record(self.xml_example_record_with_fmt, 1, 0)[0]
        self.assertEqual(rec,
                         {u'001': [([], " ", " ", '33', 1)],
                          'FMT': [([('f', 'HB'), ('g', 'Let us see if this gets inserted well.')], " ", " ", "", 3)],
                          '041': [([('a', 'eng')], " ", " ", "", 2)]})
        self.assertEqual(bibrecord.record_get_field_values(rec, "041", " ", " ", "a"),
                         ['eng'])
        self.assertEqual(bibrecord.record_get_field_values(rec, "FMT", " ", " ", "f"),
                         ['HB'])
        self.assertEqual(bibrecord.record_get_field_values(rec, "FMT", " ", " ", "g"),
                         ['Let us see if this gets inserted well.'])

    def test_parsing_file_containing_fft_special_tag_with_correcting(self):
        """bibrecord - parsing special FFT tag, correcting on"""
        rec = bibrecord.create_record(self.xml_example_record_with_fft, 1, 1)[0]
        self.assertEqual(rec,
                         {u'001': [([], " ", " ", '33', 1)],
                          'FFT': [([('a', 'file:///foo.pdf'), ('a', 'http://bar.com/baz.ps.gz')], " ", " ", "", 3)],
                          '041': [([('a', 'eng')], " ", " ", "", 2)]})
        self.assertEqual(bibrecord.record_get_field_values(rec, "041", " ", " ", "a"),
                         ['eng'])
        self.assertEqual(bibrecord.record_get_field_values(rec, "FFT", " ", " ", "a"),
                         ['file:///foo.pdf', 'http://bar.com/baz.ps.gz'])

    def test_parsing_file_containing_fft_special_tag_without_correcting(self):
        """bibrecord - parsing special FFT tag, correcting off"""
        rec = bibrecord.create_record(self.xml_example_record_with_fft, 1, 0)[0]
        self.assertEqual(rec,
                         {u'001': [([], " ", " ", '33', 1)],
                          'FFT': [([('a', 'file:///foo.pdf'), ('a', 'http://bar.com/baz.ps.gz')], " ", " ", "", 3)],
                          '041': [([('a', 'eng')], " ", " ", "", 2)]})
        self.assertEqual(bibrecord.record_get_field_values(rec, "041", " ", " ", "a"),
                         ['eng'])
        self.assertEqual(bibrecord.record_get_field_values(rec, "FFT", " ", " ", "a"),
                         ['file:///foo.pdf', 'http://bar.com/baz.ps.gz'])

    def test_parsing_file_containing_xyz_special_tag_with_correcting(self):
        """bibrecord - parsing unrecognized special XYZ tag, correcting on"""
        # XYZ should not get accepted when correcting is on; should get changed to 000
        rec = bibrecord.create_record(self.xml_example_record_with_xyz, 1, 1)[0]
        self.assertEqual(rec,
                         {u'001': [([], " ", " ", '33', 1)],
                          '000': [([('f', 'HB'), ('g', 'Let us see if this gets inserted well.')], " ", " ", "", 3)],
                          '041': [([('a', 'eng')], " ", " ", "", 2)]})
        self.assertEqual(bibrecord.record_get_field_values(rec, "041", " ", " ", "a"),
                         ['eng'])
        self.assertEqual(bibrecord.record_get_field_values(rec, "XYZ", " ", " ", "f"),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(rec, "XYZ", " ", " ", "g"),
                         [])
        self.assertEqual(bibrecord.record_get_field_values(rec, "000", " ", " ", "f"),
                         ['HB'])
        self.assertEqual(bibrecord.record_get_field_values(rec, "000", " ", " ", "g"),
                         ['Let us see if this gets inserted well.'])

    def test_parsing_file_containing_xyz_special_tag_without_correcting(self):
        """bibrecord - parsing unrecognized special XYZ tag, correcting off"""
        # XYZ should get accepted without correcting
        rec = bibrecord.create_record(self.xml_example_record_with_xyz, 1, 0)[0]
        self.assertEqual(rec,
                         {u'001': [([], " ", " ", '33', 1)],
                          'XYZ': [([('f', 'HB'), ('g', 'Let us see if this gets inserted well.')], " ", " ", "", 3)],
                          '041': [([('a', 'eng')], " ", " ", "", 2)]})
        self.assertEqual(bibrecord.record_get_field_values(rec, "041", " ", " ", "a"),
                         ['eng'])
        self.assertEqual(bibrecord.record_get_field_values(rec, "XYZ", " ", " ", "f"),
                         ['HB'])
        self.assertEqual(bibrecord.record_get_field_values(rec, "XYZ", " ", " ", "g"),
                         ['Let us see if this gets inserted well.'])


class BibRecordPrintingTest(unittest.TestCase):
    """ bibrecord - testing for printing record """

    def setUp(self):
        """Initialize stuff"""
        self.xml_example_record = """
        <record>
        <controlfield tag="001">81</controlfield>
        <datafield tag="037" ind1=" " ind2=" ">
        <subfield code="a">TEST-ARTICLE-2006-001</subfield>
        </datafield>
        <datafield tag="037" ind1=" " ind2=" ">
        <subfield code="a">ARTICLE-2006-001</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2=" ">
        <subfield code="a">Test ti</subfield>
        </datafield>
        </record>"""

        self.xml_example_record_short = """
        <record>
        <controlfield tag="001">81</controlfield>
        <datafield tag="037" ind1=" " ind2=" ">
        <subfield code="a">TEST-ARTICLE-2006-001</subfield>
        </datafield>
        <datafield tag="037" ind1=" " ind2=" ">
        <subfield code="a">ARTICLE-2006-001</subfield>
        </datafield>
        </record>"""

        self.xml_example_multi_records = """
        <record>
        <controlfield tag="001">81</controlfield>
        <datafield tag="037" ind1=" " ind2=" ">
        <subfield code="a">TEST-ARTICLE-2006-001</subfield>
        </datafield>
        <datafield tag="037" ind1=" " ind2=" ">
        <subfield code="a">ARTICLE-2006-001</subfield>
        </datafield>
        <datafield tag="245" ind1=" " ind2=" ">
        <subfield code="a">Test ti</subfield>
        </datafield>
        </record>
        <record>
        <controlfield tag="001">82</controlfield>
        <datafield tag="100" ind1=" " ind2=" ">
        <subfield code="a">Author, t</subfield>
        </datafield>
        </record>"""

        self.xml_example_multi_records_short = """
        <record>
        <controlfield tag="001">81</controlfield>
        <datafield tag="037" ind1=" " ind2=" ">
        <subfield code="a">TEST-ARTICLE-2006-001</subfield>
        </datafield>
        <datafield tag="037" ind1=" " ind2=" ">
        <subfield code="a">ARTICLE-2006-001</subfield>
        </datafield>
        </record>
        <record>
        <controlfield tag="001">82</controlfield>
        </record>"""

    def test_record_xml_output(self):
        """bibrecord - xml output"""
        rec = bibrecord.create_record(self.xml_example_record, 1, 1)[0]
        rec_short = bibrecord.create_record(self.xml_example_record_short, 1, 1)[0]
        self.assertEqual(bibrecord.create_record(bibrecord.record_xml_output(rec, tags=[]), 1, 1)[0], rec)
        self.assertEqual(bibrecord.create_record(bibrecord.record_xml_output(rec, tags=["001", "037"]), 1, 1)[0], rec_short)
        self.assertEqual(bibrecord.create_record(bibrecord.record_xml_output(rec, tags=["037"]), 1, 1)[0], rec_short)

class BibRecordCreateFieldTest(unittest.TestCase):
    """ bibrecord - testing for creating field """

    def test_create_valid_field(self):
        """bibrecord - create and check a valid field"""
        bibrecord.create_field()
        bibrecord.create_field([('a', 'testa'), ('b', 'testb')], '2', 'n',
            'controlfield', 15)

    def test_invalid_field_raises_exception(self):
        """bibrecord - exception raised when creating an invalid field"""
        # Invalid subfields.
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.create_field, 'subfields', '1', '2', 'controlfield', 10)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.create_field, ('1', 'value'), '1', '2', 'controlfield', 10)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.create_field, [('value')], '1', '2', 'controlfield', 10)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.create_field, [('1', 'value', '2')], '1', '2', 'controlfield', 10)
        # Invalid indicators.
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.create_field, [], 1, '2', 'controlfield', 10)
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.create_field, [], '1', 2, 'controlfield', 10)
        # Invalid controlfield value
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.create_field, [], '1', '2', 13, 10)
        # Invalid global position
        self.assertRaises(bibrecord.InvenioBibRecordFieldError,
            bibrecord.create_field, [], '1', '2', 'controlfield', 'position')

    def test_compare_fields(self):
        """bibrecord - compare fields"""
        # Identical
        field0 = ([('a', 'test')], '1', '2', '', 0)
        field1 = ([('a', 'test')], '1', '2', '', 3)
        self.assertEqual(True,
            bibrecord._compare_fields(field0, field1, strict=True))
        self.assertEqual(True,
            bibrecord._compare_fields(field0, field1, strict=False))

        # Order of the subfields changed.
        field0 = ([('a', 'testa'), ('b', 'testb')], '1', '2', '', 0)
        field1 = ([('b', 'testb'), ('a', 'testa')], '1', '2', '', 3)
        self.assertEqual(False,
            bibrecord._compare_fields(field0, field1, strict=True))
        self.assertEqual(True,
            bibrecord._compare_fields(field0, field1, strict=False))

        # Different
        field0 = ([], '3', '2', '', 0)
        field1 = ([], '1', '2', '', 3)
        self.assertEqual(False,
            bibrecord._compare_fields(field0, field1, strict=True))
        self.assertEqual(False,
            bibrecord._compare_fields(field0, field1, strict=False))

class BibRecordFindFieldTest(unittest.TestCase):
    """ bibrecord - testing for finding field """

    def setUp(self):
        """Initialize stuff"""
        xml = """
        <record>
        <controlfield tag="001">81</controlfield>
        <datafield tag="037" ind1=" " ind2=" ">
        <subfield code="a">TEST-ARTICLE-2006-001</subfield>
        <subfield code="b">ARTICLE-2007-001</subfield>
        </datafield>
        </record>
        """
        self.rec = bibrecord.create_record(xml)[0]
        self.field0 = self.rec['001'][0]
        self.field1 = self.rec['037'][0]
        self.field2 = (
            [self.field1[0][1], self.field1[0][0]],
            self.field1[1],
            self.field1[2],
            self.field1[3],
            self.field1[4],
            )

    def test_finding_field_strict(self):
        """bibrecord - test finding field strict"""
        self.assertEqual((1, 0),
            bibrecord.record_find_field(self.rec, '001', self.field0,
            strict=True))
        self.assertEqual((2, 0),
            bibrecord.record_find_field(self.rec, '037', self.field1,
            strict=True))
        self.assertEqual((None, None),
            bibrecord.record_find_field(self.rec, '037', self.field2,
            strict=True))

    def test_finding_field_loose(self):
        """bibrecord - test finding field loose"""
        self.assertEqual((1, 0),
            bibrecord.record_find_field(self.rec, '001', self.field0,
            strict=False))
        self.assertEqual((2, 0),
            bibrecord.record_find_field(self.rec, '037', self.field1,
            strict=False))
        self.assertEqual((2, 0),
            bibrecord.record_find_field(self.rec, '037', self.field2,
            strict=False))

class BibRecordSingletonTest(unittest.TestCase):
    """ bibrecord - testing singleton removal """

    def setUp(self):
        """Initialize stuff"""
        self.xml = """<collection>
                       <record>
                         <controlfield tag="001">33</controlfield>
                         <controlfield tag="002" />
                         <datafield tag="99" ind1=" " ind2=" "/>
                         <datafield tag="100" ind1=" " ind2=" ">
                           <subfield code="a" />
                         </datafield>
                         <datafield tag="100" ind1=" " ind2=" ">
                           <subfield code="a">Some value</subfield>
                         </datafield>
                         <tagname />
                       </record>
                       <record />
                      <collection>"""
        self.rec_expected = {
            '001': [([], ' ', ' ', '33', 1)],
            '100': [([('a', 'Some value')], ' ', ' ', '', 2)],
            }


    def test_singleton_removal_lxml(self):
        """bibrecord - enforcing singleton removal with lxml"""
        rec = bibrecord.create_records(self.xml, verbose=1,
                                       correct=1, parser='lxml',
                                       keep_singletons=False)[0][0]
        self.assertEqual(rec, self.rec_expected)

class BibRecordNumCharRefTest(unittest.TestCase):
    """ bibrecord - testing numerical character reference expansion"""

    def setUp(self):
        """Initialize stuff"""
        self.xml = """<?xml version="1.0" encoding="UTF-8"?>
                      <record>
                        <controlfield tag="001">33</controlfield>
                        <datafield tag="123" ind1=" " ind2=" ">
                          <subfield code="a">Σ &amp; &#931;</subfield>
                          <subfield code="a">use &amp;amp; in XML</subfield>
                        </datafield>
                      </record>"""
        self.rec_expected = {
            '001': [([], ' ', ' ', '33', 1)],
            '123': [([('a', '\xce\xa3 & \xce\xa3'), ('a', 'use &amp; in XML'),], ' ', ' ', '', 2)],
            }

    def test_numcharref_expansion_lxml(self):
        """bibrecord - numcharref expansion with lxml"""
        rec = bibrecord.create_records(self.xml, verbose=1,
                                       correct=1, parser='lxml')[0][0]
        self.assertEqual(rec, self.rec_expected)


class BibRecordExtractIdentifiersTest(unittest.TestCase):
    """ bibrecord - testing for getting identifiers from record """

    def setUp(self):
        """Initialize stuff"""
        from harvestingkit.bibrecord import CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG
        xml_example_record = """
        <record>
        <controlfield tag="001">1</controlfield>
        <datafield tag="100" ind1="C" ind2="5">
        <subfield code="a">val1</subfield>
        </datafield>
        <datafield tag="024" ind1="7" ind2=" ">
        <subfield code="2">doi</subfield>
        <subfield code="a">5555/TEST1</subfield>
        </datafield>
        <datafield tag="024" ind1="7" ind2=" ">
        <subfield code="2">DOI</subfield>
        <subfield code="a">5555/TEST2</subfield>
        </datafield>
        <datafield tag="024" ind1="7" ind2=" ">
        <subfield code="2">nondoi</subfield>
        <subfield code="a">5555/TEST3</subfield>
        </datafield>
        <datafield tag="024" ind1="8" ind2=" ">
        <subfield code="2">doi</subfield>
        <subfield code="a">5555/TEST4</subfield>
        </datafield>
        <datafield tag="%(oai_tag)s" ind1="%(oai_ind1)s" ind2="%(oai_ind2)s">
        <subfield code="%(oai_subcode)s">oai:atlantis:1</subfield>
        </datafield>
        </record>
        """ % {'oai_tag': CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG[0:3],
               'oai_ind1': CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG[3],
               'oai_ind2': CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG[4],
               'oai_subcode': CFG_BIBUPLOAD_EXTERNAL_OAIID_TAG[5],
               }
        self.rec = bibrecord.create_record(xml_example_record, 1, 1)[0]

    def test_extract_doi(self):
        """bibrecord - getting DOI identifier(s) from record"""
        self.assertEqual(bibrecord.record_extract_dois(self.rec),
                         ['5555/TEST1', '5555/TEST2'])


if __name__ == '__main__':
    unittest.main()
