Пример #1
0
 def test_remove(self):
     igt = Igt(tiers=[Tier(id='a'), Tier(id='b')])
     assert len(igt) == 2
     igt.remove(igt[0])
     assert len(igt) == 1
     assert igt[0].id == 'b'
     with pytest.raises(KeyError): igt['a']
Пример #2
0
def separate_tiers(args):
    tiers = set(args.tiers)
    # assuming XML for now
    with open(args.infile, 'r') as instream:
        src_xc = xigtxml.load(instream)
        sep_xc = XigtCorpus(attributes=src_xc.attributes,
                            metadata=src_xc.metadata)
        for igt in src_xc.igts:
            sep_xc.add(
                Igt(id=igt.id,
                    type=igt.type,
                    attributes=igt.attributes,
                    metadata=igt.metadata,
                    tiers=[t for t in igt.tiers if t.type in tiers]))
        xigtxml.dump(open(args.outfile, 'w'), sep_xc)

    if not args.remainder: return
    with open(args.infile, 'r') as instream:
        src_xc = xigtxml.load(instream)
        rem_xc = XigtCorpus(attributes=src_xc.attributes,
                            metadata=src_xc.metadata)
        for igt in src_xc.igts:
            rem_xc.add(
                Igt(id=igt.id,
                    type=igt.type,
                    attributes=igt.attributes,
                    metadata=igt.metadata,
                    tiers=[t for t in igt.tiers if t.type not in tiers]))
        xigtxml.dump(open(args.remainder, 'w'), rem_xc)
Пример #3
0
 def test_get_attribute(self):
     igt = Igt(id='i1', attributes={'one': 1, 'two': 2})
     xc = XigtCorpus(igts=[igt], attributes={'three': 3})
     self.assertEqual(igt.get_attribute('one'), 1)
     self.assertEqual(igt.get_attribute('two'), 2)
     self.assertIs(igt.get_attribute('three'), None)
     self.assertEqual(igt.get_attribute('three', inherit=True), 3)
     self.assertEqual(igt.get_attribute('three', default=4), 4)
Пример #4
0
 def test_get_attribute(self):
     igt = Igt(id='i1', attributes={'one': 1, 'two': 2})
     xc = XigtCorpus(igts=[igt], attributes={'three': 3})
     assert igt.get_attribute('one') == 1
     assert igt.get_attribute('two') == 2
     assert igt.get_attribute('three') is None
     assert igt.get_attribute('three', inherit=True) == 3
     assert igt.get_attribute('three', default=4) == 4
Пример #5
0
    def setUp(self):
        self.i1 = Igt()

        self.i2 = Igt(
            id='i1',
            type='basic',
            attributes={'attr':'val'},
            metadata=[Metadata(type='meta',
                               metas=[Meta(text='meta')])],
            tiers=[Tier(id='a', items=[Item(id='a1'), Item(id='a2')]),
                   Tier(id='b', items=[Item(id='b1'), Item(id='b2')])]
        )
Пример #6
0
 def test_append(self):
     igt = Igt()
     self.assertRaises(XigtStructureError, igt.append, Item())
     self.assertRaises(XigtStructureError, igt.append, Igt())
     self.assertRaises(XigtStructureError, igt.append, XigtCorpus())
     self.assertRaises(XigtStructureError, igt.append, Metadata())
     self.assertRaises(XigtStructureError, igt.append, Meta())
     self.assertEqual(len(igt), 0)
     igt.append(Tier(id='t'))
     self.assertEqual(len(igt), 1)
     self.assertRaises(XigtError, igt.append, Tier(id='t'))
     igt.append(Tier(id='x'))
     self.assertEqual(len(igt), 2)
     self.assertEqual(igt[0].id, 't')
     self.assertEqual(igt[1].id, 'x')
Пример #7
0
 def test_insert(self):
     igt = Igt()
     assert len(igt) == 0
     igt.insert(0, Tier(id='t'))
     assert len(igt) == 1
     with pytest.raises(XigtError): igt.insert(0, Tier(id='t'))
     igt.insert(0, Tier(id='x'))
     igt.insert(100, Tier(id='y'))
     assert len(igt) == 3
     assert igt[0].id == 'x'
     assert igt[1].id == 't'
     assert igt[2].id == 'y'
Пример #8
0
 def test_clear(self):
     igt = Igt()
     igt.extend([Tier(id='t'), Tier(id='x'), Tier(id='y')])
     assert len(igt) == 3
     igt.clear()
     assert len(igt) == 0
     assert igt.get(0) is None
     assert igt.get('t') is None
Пример #9
0
 def test_clear(self):
     igt = Igt()
     igt.extend([Tier(id='t'), Tier(id='x'), Tier(id='y')])
     self.assertEqual(len(igt), 3)
     igt.clear()
     self.assertEqual(len(igt), 0)
     self.assertIs(igt.get(0), None)
     self.assertIs(igt.get('t'), None)
Пример #10
0
def make_igt(block, options):
    igt_id = block.get('igt_id', None)

    attributes = make_igt_attributes(block, options)
    metadata = make_igt_metadata(block, options)
    raw_tier = make_igt_raw_tier(block, options)

    return Igt(id=igt_id,
               attributes=attributes,
               metadata=[metadata],
               tiers=[raw_tier])
Пример #11
0
class WordTypeTest(TestCase):
    def setUp(self):
        self.i = Igt(id='i1')
        self.w = Tier(id='w', type=WORDS_TYPE)
        self.gw =Tier(id='gw', type=GLOSS_WORD_TYPE, alignment=self.w.id)

        self.i.extend([self.w, self.gw])

    def test_wo_metadata(self):
        self.assertTrue(is_word_level_gloss(self.gw))

    def test_w_metadata(self):
        self.gw.alignment = None
        self.assertFalse(is_word_level_gloss(self.gw))

        add_word_level_info(self.gw, INTENT_GLOSS_WORD)
        self.assertTrue(is_word_level_gloss(self.gw))

        add_word_level_info(self.gw, INTENT_GLOSS_MORPH)
        self.assertFalse(is_word_level_gloss(self.gw))
Пример #12
0
    def test_resolve_ref(self):
        # item has no reference attribute
        b1 = Item(id='b1')
        self.assertRaises(KeyError, b1.resolve_ref, 'alignment')
        # has a reference attribute, but is not contained by a tier
        b1.alignment = 'a1'
        self.assertRaises(XigtStructureError, b1.resolve_ref, 'alignment')
        # item in tier, but tier has no reference attribute
        t_b = Tier(id='b', items=[b1])
        self.assertRaises(KeyError, b1.resolve_ref, 'alignment')
        # tier has reference attribute, but is not contained by an Igt
        t_b.alignment = 'a'
        self.assertRaises(XigtStructureError, b1.resolve_ref, 'alignment')
        # item in IGT, but referred tier doesn't exist
        igt = Igt(tiers=[t_b])
        self.assertRaises(XigtStructureError, b1.resolve_ref, 'alignment')
        # referred tier exists, but has no item referred by item's alignment
        t_a = Tier(id='a')
        igt.append(t_a)
        self.assertRaises(XigtStructureError, b1.resolve_ref, 'alignment')
        # referred item exists, but has no value (which resolves to '')
        a1 = Item(id='a1')
        t_a.append(a1)
        self.assertEqual(b1.resolve_ref('alignment'), '')
        # referred item has a value
        a1.text = 'text'
        self.assertEqual(b1.resolve_ref('alignment'), 'text')

        # stored item tests
        self.assertRaises(KeyError, self.i1.resolve_ref, 'alignment')

        self.assertRaises(KeyError, self.i2.resolve_ref, 'alignment')

        self.assertEqual(self.i_ac.resolve_ref('alignment'), 'text')
        self.assertEqual(self.i_ac.resolve_ref('content'), 'te')

        self.assertEqual(self.i_s.resolve_ref('segmentation'), 'xt')

        self.assertEqual(self.i_t.resolve_ref('content'), 'text')
Пример #13
0
def default_decode_igt(elem):
    ns, tag = _qname_split(elem.tag)
    assert tag == 'igt'
    igt = Igt(
        id=elem.get('id'),
        type=elem.get('type'),
        attributes=get_attributes(elem, ignore=('id', 'type')),
        metadata=[decode_metadata(md) for md in elem.findall('metadata')],
        tiers=[decode_tier(tier) for tier in elem.findall('tier')],
        namespace=ns,
        nsmap=elem.attrib.nsmap)
    elem.clear()
    return igt
Пример #14
0
 def test_extend(self):
     igt = Igt()
     self.assertEqual(len(igt), 0)
     igt.extend([Tier(id='t')])
     self.assertEqual(len(igt), 1)
     igt.extend([])
     self.assertEqual(len(igt), 1)
     igt.extend([Tier(id='x'), Tier(id='y')])
     self.assertEqual(len(igt), 3)
     self.assertEqual(igt[0].id, 't')
     self.assertEqual(igt[1].id, 'x')
     self.assertEqual(igt[2].id, 'y')
Пример #15
0
 def test_insert(self):
     igt = Igt()
     self.assertEqual(len(igt), 0)
     igt.insert(0, Tier(id='t'))
     self.assertEqual(len(igt), 1)
     self.assertRaises(XigtError, igt.insert, 0, Tier(id='t'))
     igt.insert(0, Tier(id='x'))
     igt.insert(100, Tier(id='y'))
     self.assertEqual(len(igt), 3)
     self.assertEqual(igt[0].id, 'x')
     self.assertEqual(igt[1].id, 't')
     self.assertEqual(igt[2].id, 'y')
Пример #16
0
 def test_extend(self):
     igt = Igt()
     assert len(igt) == 0
     igt.extend([Tier(id='t')])
     assert len(igt) == 1
     igt.extend([])
     assert len(igt) == 1
     igt.extend([Tier(id='x'), Tier(id='y')])
     assert len(igt) == 3
     assert igt[0].id == 't'
     assert igt[1].id == 'x'
     assert igt[2].id == 'y'
Пример #17
0
def make_igt(block, options):

    igt_id = make_igt_id(block['i'], options['used_igt_ids'])
    options['used_igt_ids'].add(igt_id)

    attributes = make_igt_attributes(block, options)
    metadata = make_igt_metadata(block, options)
    raw_tier = make_igt_raw_tier(block, options)

    return Igt(
        id=igt_id,
        attributes=attributes,
        metadata=[metadata],
        tiers=[raw_tier]
    )
Пример #18
0
def make_igt(key, data, context, options):
    # IDs must start with a letter
    assert key
    if not key[0].isalpha():
        key = 'igt{}'.format(key)
    if context is None:
        context = {}
    attrs = {}
    attmap = options['igt_attribute_map']
    for (mkr, val) in chain(data, context.items()):
        if val is None:  # will be None if mkr not encountered
            continue
        if mkr in attmap:
            attrs[attmap[mkr]] = val
    metadata = None

    w = None
    with warnings.catch_warnings(record=True) as ws:
        warnings.simplefilter('always')

        try:
            tiers = make_all_tiers(data, options)
            igt = Igt(
                id=key,
                attributes=attrs,
                metadata=metadata,
                tiers=tiers
            )
        except (toolbox.ToolboxError, XigtImportError) as ex:
            logging.error('Error during import of item {}:\n  {}'
                          .format(key, str(ex)))
            igt = None
        if len(ws) > 0:
            w = ws[0]

    if w is not None:
        if issubclass(w.category, toolbox.ToolboxWarning):
            warnings.warn('{}: {}'.format(key, w.message), w.category)
        else:
            warnings.warn_explicit(w.message, w.category, w.filename, w.lineno)

    return igt
Пример #19
0
class TierIdTests(TestCase):
    def setUp(self):
        self.i = Igt(id='i1')
        self.i.append(Tier(id='tw'))
        self.i.append(Tier(id='w'))

    def same_type_different_tiers_test(self):
        pos1_id = gen_tier_id(self.i, 'pos', tier_type='pos', alignment='tw')
        self.assertEqual(pos1_id, 'tw-pos')

        self.i.append(Tier(id=pos1_id, type='pos', alignment='tw'))
        pos2_id = gen_tier_id(self.i, 'pos', tier_type='pos', alignment='tw')
        self.assertEqual(pos2_id, 'tw-pos_b')

    def unique_tier_test(self):
        tw_id = gen_tier_id(self.i, 'w', tier_type='words', alignment='t', no_hyphenate=True)
        print(tw_id)
Пример #20
0
def naacl_to_xigt(naacl_path):
    """
    Convert the NAACL format to XIGT.

    :param naacl_path:
    """
    content = open(naacl_path, 'r').read()

    # First, collect all the instances.
    instances = re.findall('Igt_id[\s\S]+?Q6.*Answer', content)

    xc = XigtCorpus()

    for instance_txt in instances:
        # id = re.search('Igt_id=([\S]+)', instance_txt).group(1)
        inst = Igt(id='i{}'.format(len(xc)))

        lang_raw, gloss_raw, trans_raw = instance_txt.split('\n')[1:4]

        # Now, create the raw tier...
        raw_tier = Tier(id=gen_tier_id(inst, 'r'), type='odin', attributes={STATE_ATTRIBUTE:RAW_STATE})
        raw_tier.append(Item(id=ask_item_id(raw_tier), text=lang_raw, attributes={ODIN_TAG_ATTRIBUTE:ODIN_LANG_TAG}))
        raw_tier.append(Item(id=ask_item_id(raw_tier), text=gloss_raw, attributes={ODIN_TAG_ATTRIBUTE:ODIN_GLOSS_TAG}))
        raw_tier.append(Item(id=ask_item_id(raw_tier), text=trans_raw, attributes={ODIN_TAG_ATTRIBUTE:ODIN_TRANS_TAG}))

        inst.append(raw_tier)
        xc.append(inst)

        # Generate the clean/normal tiers, but without any cleaning.
        generate_normal_tier(inst, clean=False)

        # Lang Dependency representation handling...
        lang_ds_str = re.search('Q6:([\s\S]+?)Q6:', instance_txt).group(1)
        lang_ds_lines = lang_ds_str.split('\n')[5:-3]

        try:
            lang_dt = parse_naacl_dep(lang(inst), lang_ds_lines)
            create_dt_tier(inst, lang_dt, lang(inst), parse_method=INTENT_POS_MANUAL)
        except TreeError as te:
            pass
        except IndexError as ie:
            pass

        # Eng DS handling...
        eng_ds_str = re.search('Q3:([\s\S]+?)Q3:', instance_txt).group(1)
        eng_ds_lines = eng_ds_str.split('\n')[2:-3]

        try:
            eng_dt = parse_naacl_dep(trans(inst), eng_ds_lines)
            create_dt_tier(inst, eng_dt, trans(inst), parse_method=INTENT_POS_MANUAL)
        except TreeError as te:
            pass
        except IndexError as ie:
            pass
        except ValueError as ve:
            pass

        # Add Alignment...
        biling_aln_str = re.search('Q5:([\s\S]+?)Q5:', instance_txt).group(1)
        biling_aln_lines = biling_aln_str.split('\n')[4:-3]

        trans_offset = trans_raw.startswith(' ')
        gloss_offset = gloss_raw.startswith(' ')

        try:
            a = Alignment()
            for line in biling_aln_lines:
                gloss_s, trans_s = line.split()[0:2]

                if '.' in gloss_s:
                    continue

                gloss_i = int(gloss_s)

                for trans_token in trans_s.split(','):
                    trans_i = int(trans_token)
                    if trans_i == 0:
                        continue
                    else:
                        if trans_offset:
                            trans_i -= 1
                        if gloss_offset:
                            gloss_i -= 1
                        a.add((trans_i, gloss_i))
        except:
            pass

        set_bilingual_alignment(inst, trans(inst), gloss(inst), a, aln_method=INTENT_ALN_MANUAL)

    return xc
Пример #21
0
 def setUp(self):
     self.i = Igt(id='i1')
     self.i.append(Tier(id='tw'))
     self.i.append(Tier(id='w'))
Пример #22
0
def convert_pml(aln_path, out_path, hindi=True):

    if hindi:
        igt_data = retrieve_hindi()
    else:
        igt_data = retrieve_naacl()

    a_root = load_xml(aln_path)
    doc_a  = a_root.find(".//reffile[@name='document_a']").get('href')
    doc_b  = a_root.find(".//reffile[@name='document_b']").get('href')



    doc_a = os.path.join(os.path.join(os.path.dirname(aln_path), doc_a))
    doc_b  = os.path.join(os.path.join(os.path.dirname(aln_path), doc_b))

    # Load the sentences for each document.
    a_sents, a_glossed = load_sents(doc_a)
    b_sents, b_glossed = load_sents(doc_b)



    sent_alignments = a_root.findall(".//body/LM")

    assert (a_glossed and not b_glossed) or (b_glossed and not a_glossed), "Only one file should have glosses"

    xc = XigtCorpus()

    for sent_alignment in sent_alignments:

        # Get the sentence id...
        aln_id = sent_alignment.attrib.get('id')
        a_snt_id = re.search('^.+?-(.*)$', aln_id).group(1)
        if a_snt_id not in igt_data:
            continue

        # Get the text and tokens from the naacl data.
        pre_txt, lang_txt, gloss_txt, trans_txt = igt_data[a_snt_id]
        lang_tokens = lang_txt.split()
        gloss_tokens = gloss_txt.split()
        trans_tokens = trans_txt.split()

        a_snt_ref = sent_alignment.find('./tree_a.rf').text.split('#')[1]
        b_snt_ref = sent_alignment.find('./tree_b.rf').text.split('#')[1]

        word_alignments = sent_alignment.findall('./node_alignments/LM')

        a_snt, a_edges = a_sents[a_snt_ref]
        b_snt, b_edges = b_sents[b_snt_ref]

        assert isinstance(a_snt, Sentence)
        assert isinstance(b_snt, Sentence)
        # -------------------------------------------
        # Skip sentences if they are not found for whatever reason
        # -------------------------------------------
        if not a_snt or not b_snt:
            continue

        # -------------------------------------------
        # Start constructing the IGT Instance.
        # -------------------------------------------

        trans_snt, trans_indices = a_snt, a_edges
        gloss_snt, gloss_indices = b_snt, b_edges
        if a_glossed:
            trans_snt, trans_indices = b_snt, b_edges
            gloss_snt, gloss_indices = a_snt, a_edges

        # Hindi stuff...
        if hindi:
            lang_tokens = [w.text for w in gloss_snt]
            lang_postags   = [w.pos  for w in gloss_snt]
            lang_txt    = ' '.join(lang_tokens)

            trans_tokens = [w.text for w in trans_snt]
            trans_postags   = [w.pos  for w in trans_snt]
            trans_txt    = ' '.join(trans_tokens)

            gloss_tokens  = [w.gloss if w.gloss else 'NULL' for w in gloss_snt]
            gloss_postags = lang_postags
            gloss_txt     = ' '.join(gloss_tokens)



        inst = Igt(id=re.sub('s-', 'igt', a_snt_ref))
        nt   = Tier(type=ODIN_TIER_TYPE, id=NORM_ID, attributes={STATE_ATTRIBUTE:NORM_STATE})
        ll   = Item(id='n1', attributes={ODIN_TAG_ATTRIBUTE:ODIN_LANG_TAG}, text=lang_txt)
        gl   = Item(id='n2', attributes={ODIN_TAG_ATTRIBUTE:ODIN_GLOSS_TAG}, text=gloss_txt)
        tl   = Item(id='n3', attributes={ODIN_TAG_ATTRIBUTE:ODIN_TRANS_TAG}, text=trans_txt)
        nt.extend([ll,gl,tl])
        inst.append(nt)


        # -------------------------------------------
        # Handle the phrase tiers
        # -------------------------------------------
        generate_lang_phrase_tier(inst)
        generate_trans_phrase_tier(inst)

        def process_postags(sent, tokens):
            postags = []
            for i, token in enumerate(tokens):
                word = sent.getorder(i+1)
                if word is None:
                    postags.append(None)
                else:
                    postags.append(word.pos)
            return postags

        # -------------------------------------------
        # Now, handle the translation words.
        # -------------------------------------------
        tt = create_word_tier(ODIN_TRANS_TAG, trans_tokens, trans_phrase(inst)[0])
        inst.append(tt)

        if not hindi:
            trans_postags = process_postags(trans_snt, trans_tokens)

        add_pos_tags(inst, tt.id, trans_postags, tag_method=INTENT_POS_MANUAL)


        # -------------------------------------------
        # Handle the words tiers...
        # -------------------------------------------
        wt = create_word_tier(ODIN_LANG_TAG, lang_tokens, lang_phrase(inst)[0])
        gwt= create_word_tier(ODIN_GLOSS_TAG, gloss_tokens, gl)
        inst.extend([wt, gwt])
        # Quickly set the alignment for the gloss words.
        for w, gw in zip(wt, gwt):
            gw.alignment = w.id


        if not hindi:
            lang_postags = process_postags(gloss_snt, gloss_tokens)
            gloss_postags = lang_postags

        add_pos_tags(inst, wt.id, lang_postags, tag_method=INTENT_POS_MANUAL)
        add_pos_tags(inst, gwt.id, gloss_postags, tag_method=INTENT_POS_MANUAL)

        create_dt_tier(inst, assemble_ds(gloss_snt, gloss_indices), wt, INTENT_DS_MANUAL)
        create_dt_tier(inst, assemble_ds(trans_snt, trans_indices), tt, INTENT_DS_MANUAL)



        # -------------------------------------------
        # Now, the word alignments.
        # -------------------------------------------
        a = Alignment()
        for word_alignment in word_alignments:
            a_ref = word_alignment.find('./a.rf').text.split('#')[1]
            b_ref = word_alignment.find('./b.rf').text.split('#')[1]

            a_word = a_snt.getid(a_ref)
            b_word = b_snt.getid(b_ref)

            if a_word is None or b_word is None:
                continue

            if not hindi:
                a_idx  = a_word.order
                b_idx  = b_word.order
            else:
                a_idx  = a_snt.index(a_word)+1
                b_idx  = b_snt.index(b_word)+1

            # Make sure the gloss is in the
            if a_glossed:
                trans_idx = b_idx
                lang_idx  = a_idx
            else:
                trans_idx = a_idx
                lang_idx  = b_idx

            a.add((trans_idx, lang_idx))


        set_bilingual_alignment(inst, trans(inst), lang(inst), a, INTENT_ALN_MANUAL)
        set_bilingual_alignment(inst, trans(inst), gloss(inst), a, INTENT_ALN_MANUAL)

        xc.append(inst)

    with open(out_path, 'w', encoding='utf-8') as f:
        xigtxml.dump(f, xc)
Пример #23
0
 def test_append(self):
     igt = Igt()
     with pytest.raises(XigtStructureError): igt.append(Item())
     with pytest.raises(XigtStructureError): igt.append(Igt())
     with pytest.raises(XigtStructureError): igt.append(XigtCorpus())
     with pytest.raises(XigtStructureError): igt.append(Metadata())
     with pytest.raises(XigtStructureError): igt.append(Meta())
     assert len(igt) == 0
     igt.append(Tier(id='t'))
     assert len(igt) == 1
     with pytest.raises(XigtError): igt.append(Tier(id='t'))
     igt.append(Tier(id='x'))
     assert len(igt) == 2
     assert igt[0].id == 't'
     assert igt[1].id == 'x'
Пример #24
0
    def setUp(self):
        self.i = Igt(id='i1')
        self.w = Tier(id='w', type=WORDS_TYPE)
        self.gw =Tier(id='gw', type=GLOSS_WORD_TYPE, alignment=self.w.id)

        self.i.extend([self.w, self.gw])
Пример #25
0
class TestIgt(unittest.TestCase):
    def setUp(self):
        self.i1 = Igt()

        self.i2 = Igt(
            id='i1',
            type='basic',
            attributes={'attr':'val'},
            metadata=[Metadata(type='meta',
                               metas=[Meta(text='meta')])],
            tiers=[Tier(id='a', items=[Item(id='a1'), Item(id='a2')]),
                   Tier(id='b', items=[Item(id='b1'), Item(id='b2')])]
        )

    def test_init(self):
        self.assertRaises(ValueError, Igt, id='1')  # invalid id
        # don't allow multiple tiers with the same ID
        self.assertRaises(XigtError, Igt, tiers=[Tier(id='a'),
                                                 Tier(id='a')])

    def test_id(self):
        self.assertIs(self.i1.id, None)

        self.assertEqual(self.i2.id, 'i1')

    def test_type(self):
        self.assertIs(self.i1.type, None)

        self.assertEqual(self.i2.type, 'basic')

    def test_tiers(self):
        self.assertEqual(len(self.i1.tiers), 0)

        self.assertEqual(len(self.i2.tiers), 2)
        # contained Tiers should now have their igt specified
        for t in self.i2.tiers:
            self.assertIs(t.igt, self.i2)

    def test_parents(self):
        self.assertIs(self.i1.corpus, None)

        self.assertIs(self.i2.corpus, None)

    def test_metadata(self):
        self.assertEqual(len(self.i1.metadata), 0)

        self.assertEqual(self.i2.metadata[0].type, 'meta')
        self.assertEqual(len(self.i2.metadata[0].metas), 1)
        self.assertEqual(self.i2.metadata[0][0].text, 'meta')

    def test_attributes(self):
        self.assertEqual(self.i1.attributes, dict())

        self.assertEqual(self.i2.attributes, {'attr':'val'})

    def test_get(self):
        self.assertIs(self.i1.get(0), None)
        self.assertIs(self.i1.get('t'), None)
        self.assertEqual(self.i1.get('t', default=1), 1)

        self.assertEqual(self.i2.get(0).id, 'a')
        self.assertIs(self.i2.get(3), None)
        self.assertEqual(self.i2.get('a').id, 'a')
        self.assertEqual(
            self.i2.get('a', default=Tier(id='x')).id, 'a'
        )

    def test_get_item(self):
        self.assertIs(self.i1.get_item('a'), None)
        self.assertIs(self.i1.get_item('a1'), None)

        self.assertIs(self.i2.get_item('a'), None)
        self.assertEqual(self.i2.get_item('a1').id, 'a1')
        self.assertEqual(self.i2.get_item('b2').id, 'b2')

    def test_get_any(self):
        self.assertIs(self.i1.get_any('a'), None)
        self.assertIs(self.i1.get_any('a1'), None)

        self.assertIs(self.i2.get_any('a').id, 'a')
        self.assertEqual(self.i2.get_any('a1').id, 'a1')
        self.assertEqual(self.i2.get_any('b2').id, 'b2')

    def test_append(self):
        igt = Igt()
        self.assertRaises(XigtStructureError, igt.append, Item())
        self.assertRaises(XigtStructureError, igt.append, Igt())
        self.assertRaises(XigtStructureError, igt.append, XigtCorpus())
        self.assertRaises(XigtStructureError, igt.append, Metadata())
        self.assertRaises(XigtStructureError, igt.append, Meta())
        self.assertEqual(len(igt), 0)
        igt.append(Tier(id='t'))
        self.assertEqual(len(igt), 1)
        self.assertRaises(XigtError, igt.append, Tier(id='t'))
        igt.append(Tier(id='x'))
        self.assertEqual(len(igt), 2)
        self.assertEqual(igt[0].id, 't')
        self.assertEqual(igt[1].id, 'x')

    def test_insert(self):
        igt = Igt()
        self.assertEqual(len(igt), 0)
        igt.insert(0, Tier(id='t'))
        self.assertEqual(len(igt), 1)
        self.assertRaises(XigtError, igt.insert, 0, Tier(id='t'))
        igt.insert(0, Tier(id='x'))
        igt.insert(100, Tier(id='y'))
        self.assertEqual(len(igt), 3)
        self.assertEqual(igt[0].id, 'x')
        self.assertEqual(igt[1].id, 't')
        self.assertEqual(igt[2].id, 'y')

    def test_extend(self):
        igt = Igt()
        self.assertEqual(len(igt), 0)
        igt.extend([Tier(id='t')])
        self.assertEqual(len(igt), 1)
        igt.extend([])
        self.assertEqual(len(igt), 1)
        igt.extend([Tier(id='x'), Tier(id='y')])
        self.assertEqual(len(igt), 3)
        self.assertEqual(igt[0].id, 't')
        self.assertEqual(igt[1].id, 'x')
        self.assertEqual(igt[2].id, 'y')

    def test_clear(self):
        igt = Igt()
        igt.extend([Tier(id='t'), Tier(id='x'), Tier(id='y')])
        self.assertEqual(len(igt), 3)
        igt.clear()
        self.assertEqual(len(igt), 0)
        self.assertIs(igt.get(0), None)
        self.assertIs(igt.get('t'), None)

    def test_get_attribute(self):
        igt = Igt(id='i1', attributes={'one': 1, 'two': 2})
        xc = XigtCorpus(igts=[igt], attributes={'three': 3})
        self.assertEqual(igt.get_attribute('one'), 1)
        self.assertEqual(igt.get_attribute('two'), 2)
        self.assertIs(igt.get_attribute('three'), None)
        self.assertEqual(igt.get_attribute('three', inherit=True), 3)
        self.assertEqual(igt.get_attribute('three', default=4), 4)