• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / z3c.form / 16248976312

02 Jul 2025 05:53AM UTC coverage: 95.275%. Remained the same
16248976312

push

github

icemac
Back to development: 6.1

717 of 800 branches covered (89.63%)

Branch coverage included in aggregate %.

3699 of 3835 relevant lines covered (96.45%)

0.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.28
/src/z3c/form/outputchecker.py
1
##############################################################################
2
#
3
# Copyright (c) 2007 Zope Foundation and Contributors.
4
# All Rights Reserved.
5
#
6
# This software is subject to the provisions of the Zope Public License,
7
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11
# FOR A PARTICULAR PURPOSE.
12
#
13
##############################################################################
14
"""Custom Output Checker
15
"""
16
import doctest as pythondoctest
1✔
17
import re
1✔
18

19
import lxml.doctestcompare
1✔
20
import lxml.etree
1✔
21
from lxml.doctestcompare import LHTMLOutputChecker
1✔
22
from zope.testing.renormalizing import RENormalizing
1✔
23

24

25
class OutputChecker(LHTMLOutputChecker, RENormalizing):
1✔
26
    """Doctest output checker which is better equippied to identify
27
    HTML markup than the checker from the ``lxml.doctestcompare``
28
    module. It also uses the text comparison function from the
29
    built-in ``doctest`` module to allow the use of ellipsis.
30

31
    Also, we need to support RENormalizing.
32
    """
33

34
    _repr_re = re.compile(
1✔
35
        r'^<([A-Z]|[^>]+ (at|object) |[a-z]+ \'[A-Za-z0-9_.]+\'>)')
36

37
    def __init__(self, doctest=pythondoctest, patterns=()):
1✔
38
        RENormalizing.__init__(self, patterns)
1✔
39
        self.doctest = doctest
1✔
40

41
        # make sure these optionflags are registered
42
        doctest.register_optionflag('PARSE_HTML')
1✔
43
        doctest.register_optionflag('PARSE_XML')
1✔
44
        doctest.register_optionflag('NOPARSE_MARKUP')
1✔
45

46
    def _looks_like_markup(self, s):
1✔
47
        s = s.replace('<BLANKLINE>', '\n').strip()
1✔
48
        return (s.startswith('<')
1✔
49
                and not self._repr_re.search(s))
50

51
    def text_compare(self, want, got, strip):
1✔
52
        if want is None:
1✔
53
            want = ""
1✔
54
        if got is None:
1✔
55
            got = ""
1✔
56
        checker = self.doctest.OutputChecker()
1✔
57
        return checker.check_output(
1✔
58
            want, got,
59
            self.doctest.ELLIPSIS | self.doctest.NORMALIZE_WHITESPACE)
60

61
    def check_output(self, want, got, optionflags):
1✔
62
        if got == want:
1✔
63
            return True
1✔
64

65
        for transformer in self.transformers:
1!
66
            want = transformer(want)
×
67
            got = transformer(got)
×
68

69
        return LHTMLOutputChecker.check_output(self, want, got, optionflags)
1✔
70

71
    def output_difference(self, example, got, optionflags):
1✔
72
        want = example.want
×
73
        if not want.strip():
×
74
            return LHTMLOutputChecker.output_difference(
×
75
                self, example, got, optionflags)
76

77
        # Dang, this isn't as easy to override as we might wish
78
        original = want
×
79

80
        for transformer in self.transformers:
×
81
            want = transformer(want)
×
82
            got = transformer(got)
×
83

84
        # temporarily hack example with normalized want:
85
        example.want = want
×
86
        result = LHTMLOutputChecker.output_difference(
×
87
            self, example, got, optionflags)
88
        example.want = original
×
89

90
        # repeat lines with a diff, otherwise it's wading through mud
91
        difflines = [line for line in result.splitlines()
×
92
                     if '(got:' in line]
93

94
        if difflines:
×
95
            result += '\nLines with differences:\n' + '\n'.join(difflines)
×
96

97
        return result
×
98

99
    def get_parser(self, want, got, optionflags):
1✔
100
        NOPARSE_MARKUP = self.doctest.OPTIONFLAGS_BY_NAME.get(
1✔
101
            "NOPARSE_MARKUP", 0)
102
        PARSE_HTML = self.doctest.OPTIONFLAGS_BY_NAME.get(
1✔
103
            "PARSE_HTML", 0)
104
        PARSE_XML = self.doctest.OPTIONFLAGS_BY_NAME.get(
1✔
105
            "PARSE_XML", 0)
106

107
        parser = None
1✔
108
        if NOPARSE_MARKUP & optionflags:
1✔
109
            return None
1✔
110
        if PARSE_HTML & optionflags:
1!
111
            parser = lxml.doctestcompare.html_fromstring
×
112
        elif PARSE_XML & optionflags:
1!
113
            parser = lxml.etree.XML
×
114
        elif (want.strip().lower().startswith('<html')
1!
115
              and got.strip().startswith('<html')):
116
            parser = lxml.doctestcompare.html_fromstring
×
117
        elif (self._looks_like_markup(want)
1✔
118
              and self._looks_like_markup(got)):
119
            parser = self.get_default_parser()
1✔
120
        return parser
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc