def test_has_parent_definitions_indicator_p_marker(self):
     t = Terms(None)
     stack = ParentStack()
     stack.add(
         0,
         Node("(a) Definitions. For purposes of this " +
              "section except blah"))
     self.assertTrue(t.has_parent_definitions_indicator(stack))
    def test_node_defintions_act(self):
        t = Terms(None)
        stack = ParentStack()
        stack.add(0, Node('Definitions', label=['9999']))

        node = Node(u'“Act” means something else entirely')
        included, excluded = t.node_definitions(node, stack)
        self.assertEqual(1, len(included))
        self.assertEqual([], excluded)
Exemplo n.º 3
0
    def test_node_defintions_act(self):
        t = Terms(None)
        stack = ParentStack()
        stack.add(0, Node('Definitions', label=['9999']))

        node = Node(u'“Act” means something else entirely')
        included, excluded = t.node_definitions(node, stack)
        self.assertEqual(1, len(included))
        self.assertEqual([], excluded)
Exemplo n.º 4
0
 def test_node_definitions_needs_term(self):
     t = Terms(None)
     stack = ParentStack()
     stack.add(0, Node('Definitions', label=['9999']))
     node = Node(u"However, for purposes of rescission under §§ 1111.15 " +
                 u"and 1111.13, and for purposes of §§ 1111.12(a)(1), " +
                 u"and 1111.46(d)(4), the term means all calendar " +
                 u"days...")
     self.assertEqual(([], []), t.node_definitions(node, stack))
 def test_node_definitions_needs_term(self):
     t = Terms(None)
     stack = ParentStack()
     stack.add(0, Node('Definitions', label=['9999']))
     node = Node(u"However, for purposes of rescission under §§ 1111.15 "
                 + u"and 1111.13, and for purposes of §§ 1111.12(a)(1), "
                 + u"and 1111.46(d)(4), the term means all calendar "
                 + u"days...")
     self.assertEqual(([], []), t.node_definitions(node, stack))
    def test_node_definitions_no_def(self):
        """Verify that none of the matchers match certain strings"""
        t = Terms(None)
        stack = ParentStack()
        stack.add(0, Node(label=['999']))
        stack.add(1, Node('Definitions', label=['999', '1']))

        no_defs = ['This has no defs',
                   'Also has no terms',
                   'Still no terms, but',
                   'the next one does']

        for txt in no_defs:
            defs, exc = t.node_definitions(Node(txt), stack)
            self.assertEqual([], defs)
            self.assertEqual([], exc)
Exemplo n.º 7
0
    def test_node_definitions_no_def(self):
        """Verify that none of the matchers match certain strings"""
        t = Terms(None)
        stack = ParentStack()
        stack.add(0, Node(label=['999']))
        stack.add(1, Node('Definitions', label=['999', '1']))

        no_defs = [
            'This has no defs', 'Also has no terms', 'Still no terms, but',
            'the next one does'
        ]

        for txt in no_defs:
            defs, exc = t.node_definitions(Node(txt), stack)
            self.assertEqual([], defs)
            self.assertEqual([], exc)
    def test_has_parent_definitions_indicator_the_term_means(self):
        t = Terms(None)
        stack = ParentStack()
        stack.add(0, Node('Contains no terms or definitions'))
        self.assertFalse(t.has_parent_definitions_indicator(stack))
        stack.add(1, Node("(a) The term Bob means awesome"))
        self.assertTrue(t.has_parent_definitions_indicator(stack))
        stack.add(2, Node("No defs either"))
        self.assertTrue(t.has_parent_definitions_indicator(stack))

        stack.pop()
        stack.pop()
        stack.add(1, Node(u"(a) “Term” means some stuff"))
        self.assertTrue(t.has_parent_definitions_indicator(stack))

        stack.pop()
        stack.add(1, Node("(a) The term Bob refers to"))
        self.assertTrue(t.has_parent_definitions_indicator(stack))
    def test_node_definitions_exclusion(self):
        n1 = Node(u'“Bologna” is a type of deli meat', label=['111', '1'])
        n2 = Node(u'Let us not forget that the term “bologna” does not ' +
                  'include turtle meat', label=['111', '1', 'a'])
        t = Terms(Node(label=['111'], children=[n1, n2]))
        t.pre_process()

        stack = ParentStack()
        stack.add(1, Node('Definitions'))

        included, excluded = t.node_definitions(n1, stack)
        self.assertEqual([Ref('bologna', '111-1', (1, 8))], included)
        self.assertEqual([], excluded)
        t.scoped_terms[('111', '1')] = included

        included, excluded = t.node_definitions(n2, stack)
        self.assertEqual([], included)
        self.assertEqual([Ref('bologna', '111-1-a', (33, 40))], excluded)
    def test_node_definitions_exclusion(self):
        n1 = Node(u'“Bologna” is a type of deli meat', label=['111', '1'])
        n2 = Node(u'Let us not forget that the term “bologna” does not ' +
                  'include turtle meat', label=['111', '1', 'a'])
        t = Terms(Node(label=['111'], children=[n1, n2]))
        t.pre_process()

        stack = ParentStack()
        stack.add(1, Node('Definitions'))

        included, excluded = t.node_definitions(n1, stack)
        self.assertEqual([Ref('bologna', '111-1', (1, 8))], included)
        self.assertEqual([], excluded)
        t.scoped_terms[('111', '1')] = included

        included, excluded = t.node_definitions(n2, stack)
        self.assertEqual([], included)
        self.assertEqual([Ref('bologna', '111-1-a', (33, 40))], excluded)
    def test_has_parent_definitions_indicator_the_term_means(self):
        t = Terms(None)
        stack = ParentStack()
        stack.add(0, Node('Contains no terms or definitions'))
        self.assertFalse(t.has_parent_definitions_indicator(stack))
        stack.add(1, Node("(a) The term Bob means awesome"))
        self.assertTrue(t.has_parent_definitions_indicator(stack))
        stack.add(2, Node("No defs either"))
        self.assertTrue(t.has_parent_definitions_indicator(stack))

        stack.pop()
        stack.pop()
        stack.add(1, Node(u"(a) “Term” means some stuff"))
        self.assertTrue(t.has_parent_definitions_indicator(stack))

        stack.pop()
        stack.add(1, Node("(a) The term Bob refers to"))
        self.assertTrue(t.has_parent_definitions_indicator(stack))
    def test_node_definitions_multiple_xml(self):
        t = Terms(None)
        stack = ParentStack()
        stack.add(0, Node(label=['9999']))

        winter = Node("(4) Cold and dreary mean winter.", label=['9999', '4'])
        tagged = '(4) <E T="03">Cold</E> and <E T="03">dreary</E> mean '
        tagged += 'winter.'
        winter.tagged_text = tagged
        inc, _ = t.node_definitions(winter, stack)
        self.assertEqual(len(inc), 2)
        cold, dreary = inc
        self.assertEqual(cold, Ref('cold', '9999-4', (4, 8)))
        self.assertEqual(dreary, Ref('dreary', '9999-4', (13, 19)))

        summer = Node("(i) Hot, humid, or dry means summer.",
                      label=['9999', '4'])
        tagged = '(i) <E T="03">Hot</E>, <E T="03">humid</E>, or '
        tagged += '<E T="03">dry</E> means summer.'
        summer.tagged_text = tagged
        inc, _ = t.node_definitions(summer, stack)
        self.assertEqual(len(inc), 3)
        hot, humid, dry = inc
        self.assertEqual(hot, Ref('hot', '9999-4', (4, 7)))
        self.assertEqual(humid, Ref('humid', '9999-4', (9, 14)))
        self.assertEqual(dry, Ref('dry', '9999-4', (19, 22)))

        tamale = Node("(i) Hot tamale or tamale means nom nom",
                      label=['9999', '4'])
        tagged = '(i) <E T="03">Hot tamale</E> or <E T="03"> tamale</E> '
        tagged += 'means nom nom '
        tamale.tagged_text = tagged
        inc, _ = t.node_definitions(tamale, stack)
        self.assertEqual(len(inc), 2)
        hot, tamale = inc
        self.assertEqual(hot, Ref('hot tamale', '9999-4', (4, 14)))
        self.assertEqual(tamale, Ref('tamale', '9999-4', (18, 24)))
    def test_node_definitions_multiple_xml(self):
        t = Terms(None)
        stack = ParentStack()
        stack.add(0, Node(label=['9999']))

        winter = Node("(4) Cold and dreary mean winter.", label=['9999', '4'])
        tagged = '(4) <E T="03">Cold</E> and <E T="03">dreary</E> mean '
        tagged += 'winter.'
        winter.tagged_text = tagged
        inc, _ = t.node_definitions(winter, stack)
        self.assertEqual(len(inc), 2)
        cold, dreary = inc
        self.assertEqual(cold, Ref('cold', '9999-4', (4, 8)))
        self.assertEqual(dreary, Ref('dreary', '9999-4', (13, 19)))

        summer = Node("(i) Hot, humid, or dry means summer.",
                      label=['9999', '4'])
        tagged = '(i) <E T="03">Hot</E>, <E T="03">humid</E>, or '
        tagged += '<E T="03">dry</E> means summer.'
        summer.tagged_text = tagged
        inc, _ = t.node_definitions(summer, stack)
        self.assertEqual(len(inc), 3)
        hot, humid, dry = inc
        self.assertEqual(hot, Ref('hot', '9999-4', (4, 7)))
        self.assertEqual(humid, Ref('humid', '9999-4', (9, 14)))
        self.assertEqual(dry, Ref('dry', '9999-4', (19, 22)))

        tamale = Node("(i) Hot tamale or tamale means nom nom",
                      label=['9999', '4'])
        tagged = '(i) <E T="03">Hot tamale</E> or <E T="03"> tamale</E> '
        tagged += 'means nom nom '
        tamale.tagged_text = tagged
        inc, _ = t.node_definitions(tamale, stack)
        self.assertEqual(len(inc), 2)
        hot, tamale = inc
        self.assertEqual(hot, Ref('hot tamale', '9999-4', (4, 14)))
        self.assertEqual(tamale, Ref('tamale', '9999-4', (18, 24)))
Exemplo n.º 14
0
class ScopeFinderTest(TestCase):
    def setUp(self):
        self.finder = ScopeFinder()
        self.stack = ParentStack()

    def add_nodes(self, length):
        """There's a common prefix of nodes we'll add"""
        label = ['1000', '3', 'd', '6', 'iii']
        for i in range(length):
            self.stack.add(i, Node(label=label[:i+1]))

    def assert_scope(self, *scopes):
        self.assertEqual(list(scopes), self.finder.determine_scope(self.stack))

    def test_determine_scope_default(self):
        """Defaults to the entire reg"""
        self.add_nodes(2)
        self.assert_scope(('1000',))

    def test_determine_scope_this_part(self):
        """Definitions scoped to a part also cover the interpretations for
        that part"""
        self.add_nodes(1)
        self.stack.add(1, Node('For the purposes of this part, blah blah',
                               label=['1001', '3']))
        self.assert_scope(('1001',), ('1001', Node.INTERP_MARK))

    def test_determine_scope_this_subpart(self):
        """Subpart scope gets expanded to include other sections in the same
        subpart"""
        self.finder.subpart_map = {
            'SubPart 1': ['A', '3'],
            'Other': []
        }
        self.add_nodes(2)
        self.stack.add(2, Node('For the purposes of this subpart, yada yada',
                               label=['1000', '3', 'c']))
        self.assert_scope(('1000', 'A'), ('1000', '3'),
                          ('1000', 'A', Node.INTERP_MARK),
                          ('1000', '3', Node.INTERP_MARK))

    def test_determine_scope_this_section(self):
        """Section scope can be triggered in a child paragraph"""
        self.add_nodes(2)
        self.stack.add(2, Node('For the purposes of this section, blah blah',
                               label=['1000', '3', 'd']))
        self.assert_scope(('1000', '3'), ('1000', '3', Node.INTERP_MARK))

    def test_determine_scope_this_paragraph(self):
        """Paragraph scope is tied to the paragraph that determined it.
        Previous paragraph scopes won't apply to adjacent children"""
        self.add_nodes(2)
        self.stack.add(2, Node('For the purposes of this section, blah blah',
                               label=['1000', '3', 'd']))
        self.stack.add(3, Node('For the purposes of this paragraph, blah blah',
                               label=['1000', '3', 'd', '5']))
        self.assert_scope(('1000', '3', 'd', '5'),
                          ('1000', '3', 'd', '5', Node.INTERP_MARK))

        self.stack.add(3, Node(label=['1002', '3', 'd', '6']))
        self.assert_scope(('1000', '3'), ('1000', '3', Node.INTERP_MARK))

        self.stack.add(3, Node('Blah as used in this paragraph, blah blah',
                               label=['1000', '3', 'd', '7']))
        self.assert_scope(('1000', '3', 'd', '7'),
                          ('1000', '3', 'd', '7', Node.INTERP_MARK))

    def test_determine_scope_purposes_of_specific_paragraph(self):
        self.add_nodes(4)
        self.stack.add(
            4, Node(u'For the purposes of this § 1000.3(d)(6)(i), blah',
                    label=['1000', '3', 'd', '6', 'i']))
        self.assert_scope(('1000', '3', 'd', '6', 'i'),
                          ('1000', '3', 'd', '6', 'i', Node.INTERP_MARK))

    def test_determine_scope_purposes_of_specific_section(self):
        self.add_nodes(4)
        self.stack.add(4, Node(u'For the purposes of § 1000.3, blah',
                               label=['1000', '3', 'd', '6', 'ii']))
        self.assert_scope(('1000', '3'), ('1000', '3', Node.INTERP_MARK))

    def test_determine_scope_as_used_in_thi_section(self):
        self.add_nodes(4)
        self.stack.add(4, Node('As used in this section, blah blah',
                               label=['1000', '3', 'd', '6', 'iii']))
        self.assert_scope(('1000', '3'), ('1000', '3', Node.INTERP_MARK))

    def test_subpart_scope(self):
        self.finder.subpart_map = {
            None: ['1', '2', '3'],
            'A': ['7', '5', '0'],
            'Q': ['99', 'abc', 'q']
        }
        self.assertEqual([['111', '1'], ['111', '2'], ['111', '3']],
                         self.finder.subpart_scope(['111', '3']))
        self.assertEqual([['115', '7'], ['115', '5'], ['115', '0']],
                         self.finder.subpart_scope(['115', '5']))
        self.assertEqual([['62', '99'], ['62', 'abc'], ['62', 'q']],
                         self.finder.subpart_scope(['62', 'abc']))
        self.assertEqual([], self.finder.subpart_scope(['71', 'Z']))
class SmartQuotesTest(TestCase):
    def setUp(self):
        self.stack = ParentStack()
        self.finder = def_finders.SmartQuotes(self.stack)
        self.depth = 0

    def check_indicator(self, expected, text, title=None):
        """Common pattern for adding a node to the stack and then verifying
        the `has_def_indicator` method"""
        self.stack.add(self.depth, Node(text, title=title))
        self.assertEqual(self.finder.has_def_indicator(), expected)
        self.depth += 1

    def pop_and_check(self, expected=False):
        """Common pattern for popping the stack and then verifying the
        `has_def_indicator` method"""
        self.stack.pop()
        self.assertEqual(self.finder.has_def_indicator(), expected)
        self.depth -= 1

    def test_has_def_indicator(self):
        self.check_indicator(False, "This has no defs")
        self.check_indicator(False, "No Def", title="No def")
        self.check_indicator(
            False, "Tomatoes do not meet the definition 'vegetable'")
        self.check_indicator(True, "Definition. This has a definition.")
        self.pop_and_check()
        self.check_indicator(True, "Definitions. This has multiple!")
        self.pop_and_check()
        self.check_indicator(True, "No body",
                             title="But Definition is in the title")

    def test_has_def_indicator_p_marker(self):
        self.check_indicator(
            True,
            "(a) Definitions. For purposes of this section except blah")

    def test_has_def_indicator_the_term_means(self):
        self.check_indicator(False, 'Contains no terms or definitions')
        self.check_indicator(True, "(a) The term Bob means awesome")
        self.check_indicator(True, "No defs either")

        self.pop_and_check(expected=True)
        self.pop_and_check()
        self.check_indicator(True, u"(a) “Term” means some stuff")

        self.pop_and_check()
        self.check_indicator(True, "(a) The term Bob refers to")

    def assert_finds_definition(self, text, *expected):
        """Check that the definition is _not_ found when it has no
        "Definition" parent and _is_ found when such a parent exists"""
        self.stack.add(0, Node(label=['999']))
        node = Node(text)
        self.assertEqual([], self.finder.find(node))

        self.stack.add(1, Node("Definitions", label=['999', '1']))
        actual = self.finder.find(node)
        self.assertEqual(len(expected), len(actual))
        for expected_ref, actual_ref in zip(expected, actual):
            self.assertEqual(expected_ref.term, actual_ref.term)
            self.assertEqual(expected_ref.start, actual_ref.start)

        self.stack.pop()

    def test_find(self):
        """Tests several examples involving smart quotes"""
        self.assert_finds_definition(
            u'This has a “worD” and then more',
            def_finders.Ref('word', None, 12))
        self.assert_finds_definition(
            u'I have “anotheR word” term and “moree”',
            def_finders.Ref('another word', None, 8),
            def_finders.Ref('moree', None, 32))
        self.assert_finds_definition(
            u'But the child “DoeS sEe”?',
            def_finders.Ref('does see', None, 15))
        self.assert_finds_definition(
            u'Start with “this,”', def_finders.Ref('this', None, 12))
        self.assert_finds_definition(
            u'Start with “this;”', def_finders.Ref('this', None, 12))
        self.assert_finds_definition(
            u'Start with “this.”', def_finders.Ref('this', None, 12))
        self.assert_finds_definition(
            u'As do “subchildren”', def_finders.Ref('subchildren', None, 7))
    def test_determine_scope(self):
        stack = ParentStack()
        t = Terms(None)

        stack.add(0, Node(label=['1000']))
        stack.add(1, Node(label=['1000', '1']))

        # Defaults to the entire reg
        self.assertEqual([('1000',)], t.determine_scope(stack))

        stack.add(1, Node('For the purposes of this part, blah blah',
                          label=['1001', '2']))
        self.assertEqual([('1001',), ('1001', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        t.subpart_map = {
            'SubPart 1': ['A', '3'],
            'Other': []
        }
        stack.add(1, Node(label=['1000', '3']))
        stack.add(2, Node('For the purposes of this subpart, yada yada',
                          label=['1000', '3', 'c']))
        self.assertEqual([('1000', 'A'), ('1000', '3'),
                          ('1000', 'A', Node.INTERP_MARK),
                          ('1000', '3', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        stack.add(2, Node('For the purposes of this section, blah blah',
                          label=['1000', '3', 'd']))
        self.assertEqual([('1000', '3'), ('1000', '3', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        stack.add(3, Node('For the purposes of this paragraph, blah blah',
                          label=['1000', '3', 'd', '5']))
        self.assertEqual([('1000', '3', 'd', '5'),
                          ('1000', '3', 'd', '5', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        stack.add(3, Node(label=['1002', '3', 'd', '6']))
        self.assertEqual([('1000', '3'), ('1000', '3', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        stack.add(3, Node('Blah as used in this paragraph, blah blah',
                          label=['1000', '3', 'd', '7']))
        self.assertEqual([('1000', '3', 'd', '7'),
                          ('1000', '3', 'd', '7', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        stack.add(4, Node(u'For the purposes of this § 1000.3(d)(6)(i), blah',
                          label=['1000', '3', 'd', '6', 'i']))
        self.assertEqual([('1000', '3', 'd', '6', 'i'),
                          ('1000', '3', 'd', '6', 'i', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        stack.add(4, Node(u'For the purposes of § 1000.3, blah',
                          label=['1000', '3', 'd', '6', 'ii']))
        self.assertEqual([('1000', '3'),
                          ('1000', '3', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        stack.add(4, Node('As used in this section, blah blah',
                          label=['1000', '3', 'd', '6', 'iii']))
        self.assertEqual(
            [('1000', '3'), ('1000', '3', Node.INTERP_MARK)],
            t.determine_scope(stack))
    def test_node_definitions(self):
        t = Terms(None)
        smart_quotes = [
            (u'This has a “worD” and then more',
             [Ref('word', 'aaa', (12, 16))]),
            (u'I have “anotheR word” term and “moree”',
             [Ref('another word', 'bbb', (8, 20)),
              Ref('moree', 'bbb', (32, 37))]),
            (u'But the child “DoeS sEe”?',
             [Ref('does see', 'ccc', (15, 23))]),
            (u'Start with “this,”', [Ref('this', 'hhh', (12, 16))]),
            (u'Start with “this;”', [Ref('this', 'iii', (12, 16))]),
            (u'Start with “this.”', [Ref('this', 'jjj', (12, 16))]),
            (u'As do “subchildren”',
             [Ref('subchildren', 'ddd', (7, 18))])]

        no_defs = [
            u'This has no defs',
            u'Also has no terms',
            u'Still no terms, but',
            u'the next one does']

        xml_defs = [
            (u'(4) Thing means a thing that is defined',
             u'(4) <E T="03">Thing</E> means a thing that is defined',
             Ref('thing', 'eee', (4, 9))),
            (u'(e) Well-meaning lawyers means people who do weird things',
             u'(e) <E T="03">Well-meaning lawyers</E> means people who do '
             + 'weird things',
             Ref('well-meaning lawyers', 'fff', (4, 24))),
            (u'(e) Words have the same meaning as in a dictionary',
             u'(e) <E T="03">Words</E> have the same meaning as in a '
             + 'dictionary',
             Ref('words', 'ffg', (4, 9))),
            (u'(e) Banana has the same meaning as bonono',
             u'(e) <E T="03">Banana</E> has the same meaning as bonono',
             Ref('banana', 'fgf', (4, 10))),
            (u'(f) Huge billowy clouds means I want to take a nap',
             u'(f) <E T="03">Huge billowy clouds</E> means I want to take a '
             + 'nap',
             Ref('huge billowy clouds', 'ggg', (4, 23)))]

        xml_no_defs = [
            (u'(d) Term1 or term2 means stuff',
             u'(d) <E T="03">Term1</E> or <E T="03">term2></E> means stuff'),
            (u'This term means should not match',
             u'<E T="03">This term</E> means should not match')]

        scope_term_defs = [
            ('For purposes of this section, the term blue means the color',
             Ref('blue', '11-11', (39, 43))),
            ('For purposes of paragraph (a)(1) of this section, the term '
             + 'cool bro means hip cat', Ref('cool bro', '11-22', (59, 67))),
            ('For purposes of this paragraph, po jo means "poor Joe"',
             Ref('po jo', '11-33', (32, 37)))]

        stack = ParentStack()
        stack.add(0, Node(label=['999']))
        for txt in no_defs:
            defs, exc = t.node_definitions(Node(txt), stack)
            self.assertEqual([], defs)
            self.assertEqual([], exc)
        for txt, refs in smart_quotes:
            defs, exc = t.node_definitions(Node(txt), stack)
            self.assertEqual([], defs)
            self.assertEqual([], exc)
        for txt, xml in xml_no_defs:
            node = Node(txt)
            node.tagged_text = xml
            defs, exc = t.node_definitions(node, stack)
            self.assertEqual([], defs)
            self.assertEqual([], exc)
        for txt, xml, ref in xml_defs:
            node = Node(txt, label=[ref.label])
            node.tagged_text = xml
            defs, exc = t.node_definitions(node, stack)
            self.assertEqual([ref], defs)
            self.assertEqual([], exc)
        for txt, ref in scope_term_defs:
            defs, exc = t.node_definitions(
                Node(txt, label=ref.label.split('-')), stack)
            self.assertEqual([ref], defs)
            self.assertEqual([], exc)

        #   smart quotes are affected by the parent
        stack.add(1, Node('Definitions', label=['999', '1']))
        for txt in no_defs:
            defs, exc = t.node_definitions(Node(txt), stack)
            self.assertEqual([], defs)
            self.assertEqual([], exc)
        for txt, refs in smart_quotes:
            defs, exc = t.node_definitions(Node(txt, label=[refs[0].label]),
                                           stack)
            self.assertEqual(refs, defs)
            self.assertEqual([], exc)
        for txt, xml in xml_no_defs:
            node = Node(txt)
            node.tagged_text = xml
            defs, exc = t.node_definitions(node, stack)
            self.assertEqual([], defs)
            self.assertEqual([], exc)
        for txt, xml, ref in xml_defs:
            node = Node(txt, label=[ref.label])
            node.tagged_text = xml
            defs, exc = t.node_definitions(node, stack)
            self.assertEqual([ref], defs)
            self.assertEqual([], exc)
    def test_node_definitions(self):
        t = Terms(None)
        smart_quotes = [
            (u'This has a “worD” and then more',
             [Ref('word', 'aaa', (12, 16))]),
            (u'I have “anotheR word” term and “moree”',
             [Ref('another word', 'bbb', (8, 20)),
              Ref('moree', 'bbb', (32, 37))]),
            (u'But the child “DoeS sEe”?',
             [Ref('does see', 'ccc', (15, 23))]),
            (u'Start with “this,”', [Ref('this', 'hhh', (12, 16))]),
            (u'Start with “this;”', [Ref('this', 'iii', (12, 16))]),
            (u'Start with “this.”', [Ref('this', 'jjj', (12, 16))]),
            (u'As do “subchildren”',
             [Ref('subchildren', 'ddd', (7, 18))])]

        no_defs = [
            u'This has no defs',
            u'Also has no terms',
            u'Still no terms, but',
            u'the next one does']

        xml_defs = [
            (u'(4) Thing means a thing that is defined',
             u'(4) <E T="03">Thing</E> means a thing that is defined',
             Ref('thing', 'eee', (4, 9))),
            (u'(e) Well-meaning lawyers means people who do weird things',
             u'(e) <E T="03">Well-meaning lawyers</E> means people who do '
             + 'weird things',
             Ref('well-meaning lawyers', 'fff', (4, 24))),
            (u'(f) Huge billowy clouds means I want to take a nap',
             u'(f) <E T="03">Huge billowy clouds</E> means I want to take a '
             + 'nap',
             Ref('huge billowy clouds', 'ggg', (4, 23)))]

        xml_no_defs = [
            (u'(d) Term1 or term2 means stuff',
             u'(d) <E T="03">Term1</E> or <E T="03">term2></E> means stuff'),
            (u'This term means should not match',
             u'<E T="03">This term</E> means should not match')]

        scope_term_defs = [
            ('For purposes of this section, the term blue means the color',
             Ref('blue', '11-11', (39, 43))),
            ('For purposes of paragraph (a)(1) of this section, the term '
             + 'cool bro means hip cat', Ref('cool bro', '11-22', (59, 67))),
            ('For purposes of this paragraph, po jo means "poor Joe"',
             Ref('po jo', '11-33', (32, 37)))]

        stack = ParentStack()
        stack.add(0, Node(label=['999']))
        for txt in no_defs:
            defs, exc = t.node_definitions(Node(txt), stack)
            self.assertEqual([], defs)
            self.assertEqual([], exc)
        for txt, refs in smart_quotes:
            defs, exc = t.node_definitions(Node(txt), stack)
            self.assertEqual([], defs)
            self.assertEqual([], exc)
        for txt, xml in xml_no_defs:
            node = Node(txt)
            node.tagged_text = xml
            defs, exc = t.node_definitions(node, stack)
            self.assertEqual([], defs)
            self.assertEqual([], exc)
        for txt, xml, ref in xml_defs:
            node = Node(txt, label=[ref.label])
            node.tagged_text = xml
            defs, exc = t.node_definitions(node, stack)
            self.assertEqual([ref], defs)
            self.assertEqual([], exc)
        for txt, ref in scope_term_defs:
            defs, exc = t.node_definitions(
                Node(txt, label=ref.label.split('-')), stack)
            self.assertEqual([ref], defs)
            self.assertEqual([], exc)

        #   smart quotes are affected by the parent
        stack.add(1, Node('Definitions', label=['999', '1']))
        for txt in no_defs:
            defs, exc = t.node_definitions(Node(txt), stack)
            self.assertEqual([], defs)
            self.assertEqual([], exc)
        for txt, refs in smart_quotes:
            defs, exc = t.node_definitions(Node(txt, label=[refs[0].label]),
                                           stack)
            self.assertEqual(refs, defs)
            self.assertEqual([], exc)
        for txt, xml in xml_no_defs:
            node = Node(txt)
            node.tagged_text = xml
            defs, exc = t.node_definitions(node, stack)
            self.assertEqual([], defs)
            self.assertEqual([], exc)
        for txt, xml, ref in xml_defs:
            node = Node(txt, label=[ref.label])
            node.tagged_text = xml
            defs, exc = t.node_definitions(node, stack)
            self.assertEqual([ref], defs)
            self.assertEqual([], exc)
 def test_has_parent_definitions_indicator_p_marker(self):
     t = Terms(None)
     stack = ParentStack()
     stack.add(0, Node("(a) Definitions. For purposes of this " +
                       "section except blah"))
     self.assertTrue(t.has_parent_definitions_indicator(stack))
    def test_determine_scope(self):
        stack = ParentStack()
        t = Terms(None)

        stack.add(0, Node(label=['1000']))
        stack.add(1, Node(label=['1000', '1']))

        # Defaults to the entire reg
        self.assertEqual([('1000',)], t.determine_scope(stack))

        stack.add(1, Node('For the purposes of this part, blah blah',
                          label=['1001', '2']))
        self.assertEqual([('1001',), ('1001', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        t.subpart_map = {
            'SubPart 1': ['A', '3'],
            'Other': []
        }
        stack.add(1, Node(label=['1000', '3']))
        stack.add(2, Node('For the purposes of this subpart, yada yada',
                          label=['1000', '3', 'c']))
        self.assertEqual([('1000', 'A'), ('1000', '3'),
                          ('1000', 'A', Node.INTERP_MARK),
                          ('1000', '3', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        stack.add(2, Node('For the purposes of this section, blah blah',
                          label=['1000', '3', 'd']))
        self.assertEqual([('1000', '3'), ('1000', '3', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        stack.add(3, Node('For the purposes of this paragraph, blah blah',
                          label=['1000', '3', 'd', '5']))
        self.assertEqual([('1000', '3', 'd', '5'),
                          ('1000', '3', 'd', '5', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        stack.add(3, Node(label=['1002', '3', 'd', '6']))
        self.assertEqual([('1000', '3'), ('1000', '3', Node.INTERP_MARK)],
                         t.determine_scope(stack))
        stack.add(4, Node(u'For the purposes of this § 1000.3(d)(6)(i), blah',
                          label=['1000', '3', 'd', '6', 'i']))
        self.assertEqual([('1000', '3', 'd', '6', 'i'),
                          ('1000', '3', 'd', '6', 'i', Node.INTERP_MARK)],
                         t.determine_scope(stack))

        stack.add(4, Node(u'For the purposes of § 1000.3, blah',
                          label=['1000', '3', 'd', '6', 'ii']))
        self.assertEqual([('1000', '3'),
                          ('1000', '3', Node.INTERP_MARK)],
                         t.determine_scope(stack))
    def test_has_parent_definitions_indicator(self):
        t = Terms(None)
        stack = ParentStack()
        stack.add(0, Node("This has no defs"))
        self.assertFalse(t.has_parent_definitions_indicator(stack))
        stack.add(1, Node("No Def", title="No def"))
        self.assertFalse(t.has_parent_definitions_indicator(stack))
        stack.add(2, Node("Tomatoes do not meet the definition 'vegetable'"))
        self.assertFalse(t.has_parent_definitions_indicator(stack))

        stack.add(3, Node("Definition. This has a definition."))
        self.assertTrue(t.has_parent_definitions_indicator(stack))
        stack.pop()
        self.assertFalse(t.has_parent_definitions_indicator(stack))

        stack.add(3, Node("Definitions. This has multiple!"))
        self.assertTrue(t.has_parent_definitions_indicator(stack))
        stack.pop()
        self.assertFalse(t.has_parent_definitions_indicator(stack))

        stack.add(3, Node("No body", title="But Definition is in the title"))
        self.assertTrue(t.has_parent_definitions_indicator(stack))
    def test_has_parent_definitions_indicator(self):
        t = Terms(None)
        stack = ParentStack()
        stack.add(0, Node("This has no defs"))
        self.assertFalse(t.has_parent_definitions_indicator(stack))
        stack.add(1, Node("No Def", title="No def"))
        self.assertFalse(t.has_parent_definitions_indicator(stack))
        stack.add(2, Node("Tomatoes do not meet the definition 'vegetable'"))
        self.assertFalse(t.has_parent_definitions_indicator(stack))

        stack.add(3, Node("Definition. This has a definition."))
        self.assertTrue(t.has_parent_definitions_indicator(stack))
        stack.pop()
        self.assertFalse(t.has_parent_definitions_indicator(stack))

        stack.add(3, Node("Definitions. This has multiple!"))
        self.assertTrue(t.has_parent_definitions_indicator(stack))
        stack.pop()
        self.assertFalse(t.has_parent_definitions_indicator(stack))

        stack.add(3, Node("No body", title="But Definition is in the title"))
        self.assertTrue(t.has_parent_definitions_indicator(stack))