| [2] | 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | # |
|---|
| [1077] | 3 | # Copyright (C) 2006-2009 Edgewall Software |
|---|
| [2] | 4 | # All rights reserved. |
|---|
| 5 | # |
|---|
| 6 | # This software is licensed as described in the file COPYING, which |
|---|
| 7 | # you should have received as part of this distribution. The terms |
|---|
| [287] | 8 | # are also available at http://genshi.edgewall.org/wiki/License. |
|---|
| [2] | 9 | # |
|---|
| 10 | # This software consists of voluntary contributions made by many |
|---|
| 11 | # individuals. For the exact contribution history, see the revision |
|---|
| [287] | 12 | # history and logs, available at http://genshi.edgewall.org/log/. |
|---|
| [2] | 13 | |
|---|
| 14 | import doctest |
|---|
| [344] | 15 | import pickle |
|---|
| [2] | 16 | import unittest |
|---|
| 17 | |
|---|
| [344] | 18 | from genshi import core |
|---|
| [831] | 19 | from genshi.core import Markup, Attrs, Namespace, QName, escape, unescape |
|---|
| [287] | 20 | from genshi.input import XML, ParseError |
|---|
| [1157] | 21 | from genshi.compat import StringIO, BytesIO |
|---|
| [2] | 22 | |
|---|
| 23 | |
|---|
| [189] | 24 | class StreamTestCase(unittest.TestCase): |
|---|
| 25 | |
|---|
| 26 | def test_render_utf8(self): |
|---|
| 27 | xml = XML('<li>Über uns</li>') |
|---|
| [1157] | 28 | self.assertEqual(u'<li>Über uns</li>'.encode('utf-8'), xml.render(encoding='utf-8')) |
|---|
| [189] | 29 | |
|---|
| 30 | def test_render_unicode(self): |
|---|
| 31 | xml = XML('<li>Über uns</li>') |
|---|
| [1157] | 32 | self.assertEqual(u'<li>Über uns</li>', xml.render()) |
|---|
| [189] | 33 | self.assertEqual(u'<li>Über uns</li>', xml.render(encoding=None)) |
|---|
| 34 | |
|---|
| 35 | def test_render_ascii(self): |
|---|
| 36 | xml = XML('<li>Über uns</li>') |
|---|
| [1157] | 37 | self.assertEqual(u'<li>Über uns</li>'.encode('ascii'), xml.render(encoding='ascii')) |
|---|
| [189] | 38 | |
|---|
| [804] | 39 | def test_render_output_stream_utf8(self): |
|---|
| 40 | xml = XML('<li>Über uns</li>') |
|---|
| [1157] | 41 | strio = BytesIO() |
|---|
| 42 | self.assertEqual(None, xml.render(encoding='utf-8', out=strio)) |
|---|
| 43 | self.assertEqual(u'<li>Über uns</li>'.encode('utf-8'), strio.getvalue()) |
|---|
| [804] | 44 | |
|---|
| 45 | def test_render_output_stream_unicode(self): |
|---|
| 46 | xml = XML('<li>Über uns</li>') |
|---|
| 47 | strio = StringIO() |
|---|
| 48 | self.assertEqual(None, xml.render(encoding=None, out=strio)) |
|---|
| 49 | self.assertEqual(u'<li>Über uns</li>', strio.getvalue()) |
|---|
| 50 | |
|---|
| [344] | 51 | def test_pickle(self): |
|---|
| 52 | xml = XML('<li>Foo</li>') |
|---|
| [1157] | 53 | buf = BytesIO() |
|---|
| [344] | 54 | pickle.dump(xml, buf, 2) |
|---|
| 55 | buf.seek(0) |
|---|
| 56 | xml = pickle.load(buf) |
|---|
| [1085] | 57 | self.assertEquals('<li>Foo</li>', xml.render(encoding=None)) |
|---|
| [189] | 58 | |
|---|
| [344] | 59 | |
|---|
| [2] | 60 | class MarkupTestCase(unittest.TestCase): |
|---|
| 61 | |
|---|
| [829] | 62 | def test_new_with_encoding(self): |
|---|
| [1157] | 63 | markup = Markup(u'Döner'.encode('utf-8'), encoding='utf-8') |
|---|
| 64 | # mimic Markup.__repr__ when constructing output for Python 2/3 compatibility |
|---|
| 65 | self.assertEquals("<Markup %r>" % u'D\u00f6ner', repr(markup)) |
|---|
| [829] | 66 | |
|---|
| [140] | 67 | def test_repr(self): |
|---|
| 68 | markup = Markup('foo') |
|---|
| [464] | 69 | self.assertEquals("<Markup u'foo'>", repr(markup)) |
|---|
| [140] | 70 | |
|---|
| [2] | 71 | def test_escape(self): |
|---|
| 72 | markup = escape('<b>"&"</b>') |
|---|
| [263] | 73 | assert type(markup) is Markup |
|---|
| [2] | 74 | self.assertEquals('<b>"&"</b>', markup) |
|---|
| 75 | |
|---|
| 76 | def test_escape_noquotes(self): |
|---|
| 77 | markup = escape('<b>"&"</b>', quotes=False) |
|---|
| [263] | 78 | assert type(markup) is Markup |
|---|
| [2] | 79 | self.assertEquals('<b>"&"</b>', markup) |
|---|
| 80 | |
|---|
| 81 | def test_unescape_markup(self): |
|---|
| 82 | string = '<b>"&"</b>' |
|---|
| 83 | markup = Markup.escape(string) |
|---|
| [263] | 84 | assert type(markup) is Markup |
|---|
| [2] | 85 | self.assertEquals(string, unescape(markup)) |
|---|
| 86 | |
|---|
| [1168] | 87 | def test_Markup_escape_None_noquotes(self): |
|---|
| 88 | markup = Markup.escape(None, False) |
|---|
| 89 | assert type(markup) is Markup |
|---|
| 90 | self.assertEquals('', markup) |
|---|
| 91 | |
|---|
| [2] | 92 | def test_add_str(self): |
|---|
| 93 | markup = Markup('<b>foo</b>') + '<br/>' |
|---|
| [263] | 94 | assert type(markup) is Markup |
|---|
| [2] | 95 | self.assertEquals('<b>foo</b><br/>', markup) |
|---|
| 96 | |
|---|
| 97 | def test_add_markup(self): |
|---|
| 98 | markup = Markup('<b>foo</b>') + Markup('<br/>') |
|---|
| [263] | 99 | assert type(markup) is Markup |
|---|
| [2] | 100 | self.assertEquals('<b>foo</b><br/>', markup) |
|---|
| 101 | |
|---|
| 102 | def test_add_reverse(self): |
|---|
| [254] | 103 | markup = '<br/>' + Markup('<b>bar</b>') |
|---|
| [263] | 104 | assert type(markup) is Markup |
|---|
| [254] | 105 | self.assertEquals('<br/><b>bar</b>', markup) |
|---|
| [2] | 106 | |
|---|
| 107 | def test_mod(self): |
|---|
| 108 | markup = Markup('<b>%s</b>') % '&' |
|---|
| [263] | 109 | assert type(markup) is Markup |
|---|
| [2] | 110 | self.assertEquals('<b>&</b>', markup) |
|---|
| 111 | |
|---|
| 112 | def test_mod_multi(self): |
|---|
| 113 | markup = Markup('<b>%s</b> %s') % ('&', 'boo') |
|---|
| [263] | 114 | assert type(markup) is Markup |
|---|
| [2] | 115 | self.assertEquals('<b>&</b> boo', markup) |
|---|
| 116 | |
|---|
| [829] | 117 | def test_mod_mapping(self): |
|---|
| 118 | markup = Markup('<b>%(foo)s</b>') % {'foo': '&'} |
|---|
| 119 | assert type(markup) is Markup |
|---|
| 120 | self.assertEquals('<b>&</b>', markup) |
|---|
| 121 | |
|---|
| 122 | def test_mod_noescape(self): |
|---|
| 123 | markup = Markup('<b>%(amp)s</b>') % {'amp': Markup('&')} |
|---|
| 124 | assert type(markup) is Markup |
|---|
| 125 | self.assertEquals('<b>&</b>', markup) |
|---|
| 126 | |
|---|
| [2] | 127 | def test_mul(self): |
|---|
| 128 | markup = Markup('<b>foo</b>') * 2 |
|---|
| [263] | 129 | assert type(markup) is Markup |
|---|
| [2] | 130 | self.assertEquals('<b>foo</b><b>foo</b>', markup) |
|---|
| 131 | |
|---|
| [254] | 132 | def test_mul_reverse(self): |
|---|
| 133 | markup = 2 * Markup('<b>foo</b>') |
|---|
| [263] | 134 | assert type(markup) is Markup |
|---|
| [254] | 135 | self.assertEquals('<b>foo</b><b>foo</b>', markup) |
|---|
| 136 | |
|---|
| [2] | 137 | def test_join(self): |
|---|
| 138 | markup = Markup('<br />').join(['foo', '<bar />', Markup('<baz />')]) |
|---|
| [263] | 139 | assert type(markup) is Markup |
|---|
| [2] | 140 | self.assertEquals('foo<br /><bar /><br /><baz />', markup) |
|---|
| 141 | |
|---|
| [1266] | 142 | def test_join_over_iter(self): |
|---|
| 143 | items = ['foo', '<bar />', Markup('<baz />')] |
|---|
| 144 | markup = Markup('<br />').join(i for i in items) |
|---|
| 145 | self.assertEquals('foo<br /><bar /><br /><baz />', markup) |
|---|
| 146 | |
|---|
| [2] | 147 | def test_stripentities_all(self): |
|---|
| 148 | markup = Markup('& j').stripentities() |
|---|
| [263] | 149 | assert type(markup) is Markup |
|---|
| [2] | 150 | self.assertEquals('& j', markup) |
|---|
| 151 | |
|---|
| 152 | def test_stripentities_keepxml(self): |
|---|
| [140] | 153 | markup = Markup('& j').stripentities(keepxmlentities=True) |
|---|
| [263] | 154 | assert type(markup) is Markup |
|---|
| [140] | 155 | self.assertEquals('& j', markup) |
|---|
| [2] | 156 | |
|---|
| 157 | def test_striptags_empty(self): |
|---|
| 158 | markup = Markup('<br />').striptags() |
|---|
| [263] | 159 | assert type(markup) is Markup |
|---|
| [2] | 160 | self.assertEquals('', markup) |
|---|
| 161 | |
|---|
| 162 | def test_striptags_mid(self): |
|---|
| 163 | markup = Markup('<a href="#">fo<br />o</a>').striptags() |
|---|
| [263] | 164 | assert type(markup) is Markup |
|---|
| [2] | 165 | self.assertEquals('foo', markup) |
|---|
| 166 | |
|---|
| [344] | 167 | def test_pickle(self): |
|---|
| 168 | markup = Markup('foo') |
|---|
| [1157] | 169 | buf = BytesIO() |
|---|
| [344] | 170 | pickle.dump(markup, buf, 2) |
|---|
| 171 | buf.seek(0) |
|---|
| [464] | 172 | self.assertEquals("<Markup u'foo'>", repr(pickle.load(buf))) |
|---|
| [2] | 173 | |
|---|
| [344] | 174 | |
|---|
| [831] | 175 | class AttrsTestCase(unittest.TestCase): |
|---|
| 176 | |
|---|
| 177 | def test_pickle(self): |
|---|
| 178 | attrs = Attrs([("attr1", "foo"), ("attr2", "bar")]) |
|---|
| [1157] | 179 | buf = BytesIO() |
|---|
| [831] | 180 | pickle.dump(attrs, buf, 2) |
|---|
| 181 | buf.seek(0) |
|---|
| 182 | unpickled = pickle.load(buf) |
|---|
| 183 | self.assertEquals("Attrs([('attr1', 'foo'), ('attr2', 'bar')])", |
|---|
| 184 | repr(unpickled)) |
|---|
| 185 | |
|---|
| [1075] | 186 | def test_non_ascii(self): |
|---|
| 187 | attrs_tuple = Attrs([("attr1", u"föö"), ("attr2", u"bär")]).totuple() |
|---|
| 188 | self.assertEqual(u'fööbär', attrs_tuple[1]) |
|---|
| [831] | 189 | |
|---|
| [1075] | 190 | |
|---|
| [344] | 191 | class NamespaceTestCase(unittest.TestCase): |
|---|
| 192 | |
|---|
| [1080] | 193 | def test_repr(self): |
|---|
| 194 | self.assertEqual("Namespace('http://www.example.org/namespace')", |
|---|
| 195 | repr(Namespace('http://www.example.org/namespace'))) |
|---|
| 196 | |
|---|
| 197 | def test_repr_eval(self): |
|---|
| 198 | ns = Namespace('http://www.example.org/namespace') |
|---|
| 199 | self.assertEqual(eval(repr(ns)), ns) |
|---|
| 200 | |
|---|
| 201 | def test_repr_eval_non_ascii(self): |
|---|
| 202 | ns = Namespace(u'http://www.example.org/nämespäcé') |
|---|
| 203 | self.assertEqual(eval(repr(ns)), ns) |
|---|
| 204 | |
|---|
| [344] | 205 | def test_pickle(self): |
|---|
| 206 | ns = Namespace('http://www.example.org/namespace') |
|---|
| [1157] | 207 | buf = BytesIO() |
|---|
| [344] | 208 | pickle.dump(ns, buf, 2) |
|---|
| 209 | buf.seek(0) |
|---|
| 210 | unpickled = pickle.load(buf) |
|---|
| [1080] | 211 | self.assertEquals("Namespace('http://www.example.org/namespace')", |
|---|
| [344] | 212 | repr(unpickled)) |
|---|
| 213 | self.assertEquals('http://www.example.org/namespace', unpickled.uri) |
|---|
| 214 | |
|---|
| 215 | |
|---|
| 216 | class QNameTestCase(unittest.TestCase): |
|---|
| 217 | |
|---|
| 218 | def test_pickle(self): |
|---|
| 219 | qname = QName('http://www.example.org/namespace}elem') |
|---|
| [1157] | 220 | buf = BytesIO() |
|---|
| [344] | 221 | pickle.dump(qname, buf, 2) |
|---|
| 222 | buf.seek(0) |
|---|
| 223 | unpickled = pickle.load(buf) |
|---|
| 224 | self.assertEquals('{http://www.example.org/namespace}elem', unpickled) |
|---|
| 225 | self.assertEquals('http://www.example.org/namespace', |
|---|
| 226 | unpickled.namespace) |
|---|
| 227 | self.assertEquals('elem', unpickled.localname) |
|---|
| 228 | |
|---|
| [403] | 229 | def test_repr(self): |
|---|
| [1080] | 230 | self.assertEqual("QName('elem')", repr(QName('elem'))) |
|---|
| 231 | self.assertEqual("QName('http://www.example.org/namespace}elem')", |
|---|
| [403] | 232 | repr(QName('http://www.example.org/namespace}elem'))) |
|---|
| [344] | 233 | |
|---|
| [1080] | 234 | def test_repr_eval(self): |
|---|
| 235 | qn = QName('elem') |
|---|
| 236 | self.assertEqual(eval(repr(qn)), qn) |
|---|
| 237 | |
|---|
| 238 | def test_repr_eval_non_ascii(self): |
|---|
| 239 | qn = QName(u'élem') |
|---|
| 240 | self.assertEqual(eval(repr(qn)), qn) |
|---|
| 241 | |
|---|
| [782] | 242 | def test_leading_curly_brace(self): |
|---|
| 243 | qname = QName('{http://www.example.org/namespace}elem') |
|---|
| 244 | self.assertEquals('http://www.example.org/namespace', qname.namespace) |
|---|
| 245 | self.assertEquals('elem', qname.localname) |
|---|
| [403] | 246 | |
|---|
| [1148] | 247 | def test_curly_brace_equality(self): |
|---|
| 248 | qname1 = QName('{http://www.example.org/namespace}elem') |
|---|
| 249 | qname2 = QName('http://www.example.org/namespace}elem') |
|---|
| 250 | self.assertEqual(qname1.namespace, qname2.namespace) |
|---|
| 251 | self.assertEqual(qname1.localname, qname2.localname) |
|---|
| 252 | self.assertEqual(qname1, qname2) |
|---|
| [782] | 253 | |
|---|
| [1148] | 254 | |
|---|
| [2] | 255 | def suite(): |
|---|
| 256 | suite = unittest.TestSuite() |
|---|
| [189] | 257 | suite.addTest(unittest.makeSuite(StreamTestCase, 'test')) |
|---|
| [2] | 258 | suite.addTest(unittest.makeSuite(MarkupTestCase, 'test')) |
|---|
| [344] | 259 | suite.addTest(unittest.makeSuite(NamespaceTestCase, 'test')) |
|---|
| [831] | 260 | suite.addTest(unittest.makeSuite(AttrsTestCase, 'test')) |
|---|
| [344] | 261 | suite.addTest(unittest.makeSuite(QNameTestCase, 'test')) |
|---|
| 262 | suite.addTest(doctest.DocTestSuite(core)) |
|---|
| [2] | 263 | return suite |
|---|
| 264 | |
|---|
| 265 | if __name__ == '__main__': |
|---|
| 266 | unittest.main(defaultTest='suite') |
|---|