| 34 | | if not ok: |
|---|
| 35 | | return normalize_long_ints(want) == normalize_long_ints(got) |
|---|
| 36 | | return ok |
|---|
| | 47 | return normalize_long_ints(want) == normalize_long_ints(got) |
|---|
| | 48 | |
|---|
| | 49 | def check_output_xml(self, want, got, optionsflags): |
|---|
| | 50 | # Tries to do a 'xml-comparision' of want and got. Plan string |
|---|
| | 51 | # comparision doesn't always work, because, for example, attribute |
|---|
| | 52 | # ordering should not be important. |
|---|
| | 53 | # |
|---|
| | 54 | # Based on http://codespeak.net/svn/lxml/trunk/src/lxml/doctestcompare.py |
|---|
| | 55 | |
|---|
| | 56 | # We use this to distinguish repr()s from elements: |
|---|
| | 57 | _repr_re = re.compile(r'^<[^>]+ (at|object) ') |
|---|
| | 58 | |
|---|
| | 59 | _norm_whitespace_re = re.compile(r'[ \t\n][ \t\n]+') |
|---|
| | 60 | def norm_whitespace(v): |
|---|
| | 61 | return _norm_whitespace_re.sub(' ', v) |
|---|
| | 62 | |
|---|
| | 63 | def looks_like_markup(s): |
|---|
| | 64 | s = s.strip() |
|---|
| | 65 | return (s.startswith('<') |
|---|
| | 66 | and not _repr_re.search(s)) |
|---|
| | 67 | |
|---|
| | 68 | def child_text(element): |
|---|
| | 69 | return ''.join([c.data for c in element.childNodes |
|---|
| | 70 | if c.nodeType == Node.TEXT_NODE]) |
|---|
| | 71 | |
|---|
| | 72 | def children(element): |
|---|
| | 73 | return [c for c in element.childNodes |
|---|
| | 74 | if c.nodeType == Node.ELEMENT_NODE] |
|---|
| | 75 | |
|---|
| | 76 | def norm_child_text(element): |
|---|
| | 77 | return norm_whitespace(child_text(element)) |
|---|
| | 78 | |
|---|
| | 79 | def attrs_dict(element): |
|---|
| | 80 | return dict(element.attributes.items()) |
|---|
| | 81 | |
|---|
| | 82 | def check_element(want_element, got_element): |
|---|
| | 83 | if want_element.tagName != got_element.tagName: |
|---|
| | 84 | return False |
|---|
| | 85 | if norm_child_text(want_element) != norm_child_text(got_element): |
|---|
| | 86 | return False |
|---|
| | 87 | if attrs_dict(want_element) != attrs_dict(got_element): |
|---|
| | 88 | return False |
|---|
| | 89 | want_children = children(want_element) |
|---|
| | 90 | got_children = children(got_element) |
|---|
| | 91 | if len(want_children) != len(got_children): |
|---|
| | 92 | return False |
|---|
| | 93 | for want, got in zip(want_children, got_children): |
|---|
| | 94 | if not check_element(want, got): |
|---|
| | 95 | return False |
|---|
| | 96 | return True |
|---|
| | 97 | |
|---|
| | 98 | want, got = self._strip_quotes(want, got) |
|---|
| | 99 | if not looks_like_markup(want): |
|---|
| | 100 | return False |
|---|
| | 101 | |
|---|
| | 102 | # Wrapper to support XML fragments |
|---|
| | 103 | wrapper = u"<root>%s</root>" |
|---|
| | 104 | try: |
|---|
| | 105 | want_root = parseString(wrapper % want).firstChild |
|---|
| | 106 | got_root = parseString(wrapper % got).firstChild |
|---|
| | 107 | except: |
|---|
| | 108 | return False |
|---|
| | 109 | return check_element(want_root, got_root) |
|---|
| | 110 | |
|---|
| | 111 | def check_output_json(self, want, got, optionsflags): |
|---|
| | 112 | # Tries do compare want and got as if they were JSON-encoded data |
|---|
| | 113 | want, got = self._strip_quotes(want, got) |
|---|
| | 114 | try: |
|---|
| | 115 | want_json = simplejson.loads(want) |
|---|
| | 116 | got_json = simplejson.loads(got) |
|---|
| | 117 | except: |
|---|
| | 118 | return False |
|---|
| | 119 | return want_json == got_json |
|---|
| | 120 | |
|---|
| | 121 | def _strip_quotes(self, want, got): |
|---|
| | 122 | """ |
|---|
| | 123 | Strip quotes of doctests output values: |
|---|
| | 124 | |
|---|
| | 125 | >>> o = OutputChecker() |
|---|
| | 126 | >>> o._strip_quotes("'foo'") |
|---|
| | 127 | "foo" |
|---|
| | 128 | >>> o._strip_quotes('"foo"') |
|---|
| | 129 | "foo" |
|---|
| | 130 | >>> o._strip_quotes("u'foo'") |
|---|
| | 131 | "foo" |
|---|
| | 132 | >>> o._strip_quotes('u"foo"') |
|---|
| | 133 | "foo" |
|---|
| | 134 | """ |
|---|
| | 135 | def is_quoted_string(s): |
|---|
| | 136 | s = s.strip() |
|---|
| | 137 | return (len(s) >= 2 |
|---|
| | 138 | and s[0] == s[-1] |
|---|
| | 139 | and s[0] in ('"', "'")) |
|---|
| | 140 | |
|---|
| | 141 | def is_quoted_unicode(s): |
|---|
| | 142 | s = s.strip() |
|---|
| | 143 | return (len(s) >= 3 |
|---|
| | 144 | and s[0] == 'u' |
|---|
| | 145 | and s[1] == s[-1] |
|---|
| | 146 | and s[1] in ('"', "'")) |
|---|
| | 147 | |
|---|
| | 148 | if is_quoted_string(want) and is_quoted_string(got): |
|---|
| | 149 | want = want.strip()[1:-1] |
|---|
| | 150 | got = got.strip()[1:-1] |
|---|
| | 151 | elif is_quoted_unicode(want) and is_quoted_unicode(got): |
|---|
| | 152 | want = want.strip()[2:-1] |
|---|
| | 153 | got = got.strip()[2:-1] |
|---|
| | 154 | return want, got |
|---|
| | 155 | |
|---|