summaryrefslogtreecommitdiff
path: root/src/lxml/tests/test_doctestcompare.py
blob: 3663281247ef00bde0f75f602b295d6047b854b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

from __future__ import absolute_import

import unittest

from lxml import etree
from .common_imports import HelperTestCase
from lxml.doctestcompare import LXMLOutputChecker, PARSE_HTML, PARSE_XML


class DummyInput:
    def __init__(self, **kw):
        for name, value in kw.items():
            setattr(self, name, value)


def indent(elem, level=0):
    i = "\n" + level*"  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i


class DoctestCompareTest(HelperTestCase):
    _checker = LXMLOutputChecker()

    def compare(self, want, got, html=False):
        if html:
            options = PARSE_HTML
        else:
            options = PARSE_XML

        parse = self._checker.get_parser(want, got, options)
        want_doc = parse(want)
        got_doc = parse(got)
        return self._checker.collect_diff(
            want_doc, got_doc, html, indent=0).lstrip()

    def assert_diff(self, want, got, diff, html=False):
        self.assertEqual(self.compare(want, got, html), diff)

    def assert_nodiff(self, want, got, html=False):
        root = etree.fromstring(want)
        root.tail = '\n'
        indent(root)
        diff = etree.tostring(
            root, encoding='unicode', method=html and 'html' or 'xml')
        self.assert_diff(want, got, diff, html=html)

    def test_equal_input(self):
        self.assert_nodiff(
            '<p title="expected">Expected</p>',
            '<p title="expected">Expected</p>')

    def test_differing_tags(self):
        self.assert_diff(
            '<p title="expected">Expected</p>',
            '<b title="expected">Expected</b>',
            '<p (got: b) title="expected">Expected</p (got: b)>\n')

    def test_tags_upper_lower_case(self):
        self.assert_diff(
            '<p title="expected">Expected</p>',
            '<P title="expected">Expected</P>',
            '<p (got: P) title="expected">Expected</p (got: P)>\n')

    def test_tags_upper_lower_case_html(self):
        self.assert_nodiff(
            '<html><body><p title="expected">Expected</p></body></html>',
            '<HTML><BODY><P title="expected">Expected</P></BODY></HTML>',
            html=True)

    def test_differing_attributes(self):
        self.assert_diff(
            '<p title="expected">Expected</p>',
            '<p title="actual">Actual</p>',
            '<p title="expected (got: actual)">Expected (got: Actual)</p>\n')

    def test_extra_children(self):
        # https://bugs.launchpad.net/lxml/+bug/1238503
        self.assert_diff(
            '<p><span>One</span></p>',
            '<p><span>One</span><b>Two</b><em>Three</em></p>',
            '<p>\n'
            '  <span>One</span>\n'
            '  +<b>Two</b>\n'
            '  +<em>Three</em>\n'
            '</p>\n')

    def test_missing_children(self):
        self.assert_diff(
            '<p><span>One</span><b>Two</b><em>Three</em></p>',
            '<p><span>One</span></p>',
            '<p>\n'
            '  <span>One</span>\n'
            '  -<b>Two</b>\n'
            '  -<em>Three</em>\n'
            '</p>\n')

    def test_extra_attributes(self):
        self.assert_diff(
            '<p><span class="foo">Text</span></p>',
            '<p><span class="foo" id="bar">Text</span></p>',
            '<p>\n'
            '  <span class="foo" +id="bar">Text</span>\n'
            '</p>\n')

    def test_missing_attributes(self):
        self.assert_diff(
            '<p><span class="foo" id="bar">Text</span></p>',
            '<p><span class="foo">Text</span></p>',
            '<p>\n'
            '  <span class="foo" -id="bar">Text</span>\n'
            '</p>\n')


def test_suite():
    suite = unittest.TestSuite()
    suite.addTests([unittest.makeSuite(DoctestCompareTest)])
    return suite


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