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_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_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))
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))