annotate genshi/tests/core.py @ 932:e53161c2773c

Merge r1140 from py3k: add support for python 3 to core genshi components (genshi.core, genshi.input and genshi.output): * default input and output encodings changed from UTF-8 to None (i.e. unicode strings) * Namespace and QName objects do not call stringrepr in __repr__ in Python 3 since repr() returns a unicode string there. * track changes to expat parser in Python 3 (mostly it accepts bytes instead of strings)
author hodgestar
date Fri, 18 Mar 2011 09:08:12 +0000
parents 8cef75b02ac1
children
rev   line source
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
2 #
854
0d9e87c6cf6e More work on reducing the size of the diff produced by 2to3.
cmlenz
parents: 852
diff changeset
3 # Copyright (C) 2006-2009 Edgewall Software
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
4 # All rights reserved.
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
5 #
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
230
24757b771651 Renamed Markup to Genshi in repository.
cmlenz
parents: 212
diff changeset
8 # are also available at http://genshi.edgewall.org/wiki/License.
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
9 #
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
230
24757b771651 Renamed Markup to Genshi in repository.
cmlenz
parents: 212
diff changeset
12 # history and logs, available at http://genshi.edgewall.org/log/.
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
13
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
14 import doctest
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
15 import pickle
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
16 import unittest
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
17
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
18 from genshi import core
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
19 from genshi.core import Markup, Attrs, Namespace, QName, escape, unescape
230
24757b771651 Renamed Markup to Genshi in repository.
cmlenz
parents: 212
diff changeset
20 from genshi.input import XML, ParseError
932
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
21 from genshi.compat import StringIO, BytesIO
147
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
22
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
23
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
24 class StreamTestCase(unittest.TestCase):
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
25
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
26 def test_render_utf8(self):
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
27 xml = XML('<li>Über uns</li>')
932
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
28 self.assertEqual(u'<li>Über uns</li>'.encode('utf-8'), xml.render(encoding='utf-8'))
147
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
29
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
30 def test_render_unicode(self):
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
31 xml = XML('<li>Über uns</li>')
932
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
32 self.assertEqual(u'<li>Über uns</li>', xml.render())
147
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
33 self.assertEqual(u'<li>Über uns</li>', xml.render(encoding=None))
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
34
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
35 def test_render_ascii(self):
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
36 xml = XML('<li>Über uns</li>')
932
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
37 self.assertEqual(u'<li>&#220;ber uns</li>'.encode('ascii'), xml.render(encoding='ascii'))
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
38
688
88814cc26d2b The `Stream.render` now accepts an optional `out` parameter that can be used to pass in a writable file-like object to use for assembling the output, instead of building a big string and returning it.
cmlenz
parents: 666
diff changeset
39 def test_render_output_stream_utf8(self):
88814cc26d2b The `Stream.render` now accepts an optional `out` parameter that can be used to pass in a writable file-like object to use for assembling the output, instead of building a big string and returning it.
cmlenz
parents: 666
diff changeset
40 xml = XML('<li>Über uns</li>')
932
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
41 strio = BytesIO()
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
42 self.assertEqual(None, xml.render(encoding='utf-8', out=strio))
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
43 self.assertEqual(u'<li>Über uns</li>'.encode('utf-8'), strio.getvalue())
688
88814cc26d2b The `Stream.render` now accepts an optional `out` parameter that can be used to pass in a writable file-like object to use for assembling the output, instead of building a big string and returning it.
cmlenz
parents: 666
diff changeset
44
88814cc26d2b The `Stream.render` now accepts an optional `out` parameter that can be used to pass in a writable file-like object to use for assembling the output, instead of building a big string and returning it.
cmlenz
parents: 666
diff changeset
45 def test_render_output_stream_unicode(self):
88814cc26d2b The `Stream.render` now accepts an optional `out` parameter that can be used to pass in a writable file-like object to use for assembling the output, instead of building a big string and returning it.
cmlenz
parents: 666
diff changeset
46 xml = XML('<li>Über uns</li>')
88814cc26d2b The `Stream.render` now accepts an optional `out` parameter that can be used to pass in a writable file-like object to use for assembling the output, instead of building a big string and returning it.
cmlenz
parents: 666
diff changeset
47 strio = StringIO()
88814cc26d2b The `Stream.render` now accepts an optional `out` parameter that can be used to pass in a writable file-like object to use for assembling the output, instead of building a big string and returning it.
cmlenz
parents: 666
diff changeset
48 self.assertEqual(None, xml.render(encoding=None, out=strio))
88814cc26d2b The `Stream.render` now accepts an optional `out` parameter that can be used to pass in a writable file-like object to use for assembling the output, instead of building a big string and returning it.
cmlenz
parents: 666
diff changeset
49 self.assertEqual(u'<li>Über uns</li>', strio.getvalue())
88814cc26d2b The `Stream.render` now accepts an optional `out` parameter that can be used to pass in a writable file-like object to use for assembling the output, instead of building a big string and returning it.
cmlenz
parents: 666
diff changeset
50
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
51 def test_pickle(self):
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
52 xml = XML('<li>Foo</li>')
932
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
53 buf = BytesIO()
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
54 pickle.dump(xml, buf, 2)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
55 buf.seek(0)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
56 xml = pickle.load(buf)
862
37fb3988647a Make the output tests skip the encoding step.
cmlenz
parents: 857
diff changeset
57 self.assertEquals('<li>Foo</li>', xml.render(encoding=None))
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
58
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
59
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
60 class MarkupTestCase(unittest.TestCase):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
61
713
a58a50e89d04 The `Markup` class now supports mappings for right hand of the `%` (modulo) operator in the same way the Python string classes do, except that the substituted values are escape. Also, the special constructor which took positional arguments that would be substituted was removed. Thus the `Markup` class now supports the same arguments as that of its `unicode` base class. Closes #211. Many thanks to Christian Boos for the patch!
cmlenz
parents: 688
diff changeset
62 def test_new_with_encoding(self):
932
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
63 markup = Markup(u'Döner'.encode('utf-8'), encoding='utf-8')
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
64 # mimic Markup.__repr__ when constructing output for Python 2/3 compatibility
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
65 self.assertEquals("<Markup %r>" % u'D\u00f6ner', repr(markup))
713
a58a50e89d04 The `Markup` class now supports mappings for right hand of the `%` (modulo) operator in the same way the Python string classes do, except that the substituted values are escape. Also, the special constructor which took positional arguments that would be substituted was removed. Thus the `Markup` class now supports the same arguments as that of its `unicode` base class. Closes #211. Many thanks to Christian Boos for the patch!
cmlenz
parents: 688
diff changeset
66
116
88ac4c680120 Merged [135:138/branches/experimental/cspeedups].
cmlenz
parents: 113
diff changeset
67 def test_repr(self):
88ac4c680120 Merged [135:138/branches/experimental/cspeedups].
cmlenz
parents: 113
diff changeset
68 markup = Markup('foo')
382
d7da3fba7faf * Added documentation for the various stream event kinds.
cmlenz
parents: 326
diff changeset
69 self.assertEquals("<Markup u'foo'>", repr(markup))
116
88ac4c680120 Merged [135:138/branches/experimental/cspeedups].
cmlenz
parents: 113
diff changeset
70
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
71 def test_escape(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
72 markup = escape('<b>"&"</b>')
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
73 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
74 self.assertEquals('&lt;b&gt;&#34;&amp;&#34;&lt;/b&gt;', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
75
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
76 def test_escape_noquotes(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
77 markup = escape('<b>"&"</b>', quotes=False)
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
78 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
79 self.assertEquals('&lt;b&gt;"&amp;"&lt;/b&gt;', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
80
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
81 def test_unescape_markup(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
82 string = '<b>"&"</b>'
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
83 markup = Markup.escape(string)
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
84 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
85 self.assertEquals(string, unescape(markup))
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
86
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
87 def test_add_str(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
88 markup = Markup('<b>foo</b>') + '<br/>'
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
89 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
90 self.assertEquals('<b>foo</b>&lt;br/&gt;', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
91
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
92 def test_add_markup(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
93 markup = Markup('<b>foo</b>') + Markup('<br/>')
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
94 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
95 self.assertEquals('<b>foo</b><br/>', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
96
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
97 def test_add_reverse(self):
204
516a6cae0aa8 * Implement reverse add/mul operators for `Markup` class, so that the result is also a `Markup` instance.
cmlenz
parents: 147
diff changeset
98 markup = '<br/>' + Markup('<b>bar</b>')
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
99 assert type(markup) is Markup
204
516a6cae0aa8 * Implement reverse add/mul operators for `Markup` class, so that the result is also a `Markup` instance.
cmlenz
parents: 147
diff changeset
100 self.assertEquals('&lt;br/&gt;<b>bar</b>', markup)
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
101
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
102 def test_mod(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
103 markup = Markup('<b>%s</b>') % '&'
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
104 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
105 self.assertEquals('<b>&amp;</b>', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
106
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
107 def test_mod_multi(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
108 markup = Markup('<b>%s</b> %s') % ('&', 'boo')
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
109 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
110 self.assertEquals('<b>&amp;</b> boo', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
111
713
a58a50e89d04 The `Markup` class now supports mappings for right hand of the `%` (modulo) operator in the same way the Python string classes do, except that the substituted values are escape. Also, the special constructor which took positional arguments that would be substituted was removed. Thus the `Markup` class now supports the same arguments as that of its `unicode` base class. Closes #211. Many thanks to Christian Boos for the patch!
cmlenz
parents: 688
diff changeset
112 def test_mod_mapping(self):
a58a50e89d04 The `Markup` class now supports mappings for right hand of the `%` (modulo) operator in the same way the Python string classes do, except that the substituted values are escape. Also, the special constructor which took positional arguments that would be substituted was removed. Thus the `Markup` class now supports the same arguments as that of its `unicode` base class. Closes #211. Many thanks to Christian Boos for the patch!
cmlenz
parents: 688
diff changeset
113 markup = Markup('<b>%(foo)s</b>') % {'foo': '&'}
a58a50e89d04 The `Markup` class now supports mappings for right hand of the `%` (modulo) operator in the same way the Python string classes do, except that the substituted values are escape. Also, the special constructor which took positional arguments that would be substituted was removed. Thus the `Markup` class now supports the same arguments as that of its `unicode` base class. Closes #211. Many thanks to Christian Boos for the patch!
cmlenz
parents: 688
diff changeset
114 assert type(markup) is Markup
a58a50e89d04 The `Markup` class now supports mappings for right hand of the `%` (modulo) operator in the same way the Python string classes do, except that the substituted values are escape. Also, the special constructor which took positional arguments that would be substituted was removed. Thus the `Markup` class now supports the same arguments as that of its `unicode` base class. Closes #211. Many thanks to Christian Boos for the patch!
cmlenz
parents: 688
diff changeset
115 self.assertEquals('<b>&amp;</b>', markup)
a58a50e89d04 The `Markup` class now supports mappings for right hand of the `%` (modulo) operator in the same way the Python string classes do, except that the substituted values are escape. Also, the special constructor which took positional arguments that would be substituted was removed. Thus the `Markup` class now supports the same arguments as that of its `unicode` base class. Closes #211. Many thanks to Christian Boos for the patch!
cmlenz
parents: 688
diff changeset
116
a58a50e89d04 The `Markup` class now supports mappings for right hand of the `%` (modulo) operator in the same way the Python string classes do, except that the substituted values are escape. Also, the special constructor which took positional arguments that would be substituted was removed. Thus the `Markup` class now supports the same arguments as that of its `unicode` base class. Closes #211. Many thanks to Christian Boos for the patch!
cmlenz
parents: 688
diff changeset
117 def test_mod_noescape(self):
a58a50e89d04 The `Markup` class now supports mappings for right hand of the `%` (modulo) operator in the same way the Python string classes do, except that the substituted values are escape. Also, the special constructor which took positional arguments that would be substituted was removed. Thus the `Markup` class now supports the same arguments as that of its `unicode` base class. Closes #211. Many thanks to Christian Boos for the patch!
cmlenz
parents: 688
diff changeset
118 markup = Markup('<b>%(amp)s</b>') % {'amp': Markup('&amp;')}
a58a50e89d04 The `Markup` class now supports mappings for right hand of the `%` (modulo) operator in the same way the Python string classes do, except that the substituted values are escape. Also, the special constructor which took positional arguments that would be substituted was removed. Thus the `Markup` class now supports the same arguments as that of its `unicode` base class. Closes #211. Many thanks to Christian Boos for the patch!
cmlenz
parents: 688
diff changeset
119 assert type(markup) is Markup
a58a50e89d04 The `Markup` class now supports mappings for right hand of the `%` (modulo) operator in the same way the Python string classes do, except that the substituted values are escape. Also, the special constructor which took positional arguments that would be substituted was removed. Thus the `Markup` class now supports the same arguments as that of its `unicode` base class. Closes #211. Many thanks to Christian Boos for the patch!
cmlenz
parents: 688
diff changeset
120 self.assertEquals('<b>&amp;</b>', markup)
a58a50e89d04 The `Markup` class now supports mappings for right hand of the `%` (modulo) operator in the same way the Python string classes do, except that the substituted values are escape. Also, the special constructor which took positional arguments that would be substituted was removed. Thus the `Markup` class now supports the same arguments as that of its `unicode` base class. Closes #211. Many thanks to Christian Boos for the patch!
cmlenz
parents: 688
diff changeset
121
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
122 def test_mul(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
123 markup = Markup('<b>foo</b>') * 2
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
124 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
125 self.assertEquals('<b>foo</b><b>foo</b>', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
126
204
516a6cae0aa8 * Implement reverse add/mul operators for `Markup` class, so that the result is also a `Markup` instance.
cmlenz
parents: 147
diff changeset
127 def test_mul_reverse(self):
516a6cae0aa8 * Implement reverse add/mul operators for `Markup` class, so that the result is also a `Markup` instance.
cmlenz
parents: 147
diff changeset
128 markup = 2 * Markup('<b>foo</b>')
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
129 assert type(markup) is Markup
204
516a6cae0aa8 * Implement reverse add/mul operators for `Markup` class, so that the result is also a `Markup` instance.
cmlenz
parents: 147
diff changeset
130 self.assertEquals('<b>foo</b><b>foo</b>', markup)
516a6cae0aa8 * Implement reverse add/mul operators for `Markup` class, so that the result is also a `Markup` instance.
cmlenz
parents: 147
diff changeset
131
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
132 def test_join(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
133 markup = Markup('<br />').join(['foo', '<bar />', Markup('<baz />')])
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
134 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
135 self.assertEquals('foo<br />&lt;bar /&gt;<br /><baz />', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
136
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
137 def test_stripentities_all(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
138 markup = Markup('&amp; &#106;').stripentities()
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
139 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
140 self.assertEquals('& j', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
141
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
142 def test_stripentities_keepxml(self):
116
88ac4c680120 Merged [135:138/branches/experimental/cspeedups].
cmlenz
parents: 113
diff changeset
143 markup = Markup('&amp; &#106;').stripentities(keepxmlentities=True)
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
144 assert type(markup) is Markup
116
88ac4c680120 Merged [135:138/branches/experimental/cspeedups].
cmlenz
parents: 113
diff changeset
145 self.assertEquals('&amp; j', markup)
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
146
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
147 def test_striptags_empty(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
148 markup = Markup('<br />').striptags()
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
149 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
150 self.assertEquals('', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
151
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
152 def test_striptags_mid(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
153 markup = Markup('<a href="#">fo<br />o</a>').striptags()
212
e8c43127d9a9 Refactored the handling of empty tags in the serializer: use an `EmptyTagFilter` that combines adjacent start/end events, instead of the generic pushback-iterator.
cmlenz
parents: 204
diff changeset
154 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
155 self.assertEquals('foo', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
156
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
157 def test_pickle(self):
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
158 markup = Markup('foo')
932
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
159 buf = BytesIO()
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
160 pickle.dump(markup, buf, 2)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
161 buf.seek(0)
382
d7da3fba7faf * Added documentation for the various stream event kinds.
cmlenz
parents: 326
diff changeset
162 self.assertEquals("<Markup u'foo'>", repr(pickle.load(buf)))
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
163
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
164
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
165 class AttrsTestCase(unittest.TestCase):
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
166
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
167 def test_pickle(self):
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
168 attrs = Attrs([("attr1", "foo"), ("attr2", "bar")])
932
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
169 buf = BytesIO()
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
170 pickle.dump(attrs, buf, 2)
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
171 buf.seek(0)
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
172 unpickled = pickle.load(buf)
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
173 self.assertEquals("Attrs([('attr1', 'foo'), ('attr2', 'bar')])",
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
174 repr(unpickled))
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
175
852
04945cd67dad Remove usage of unicode literals in a couple of places where they were not strictly necessary.
cmlenz
parents: 715
diff changeset
176 def test_non_ascii(self):
04945cd67dad Remove usage of unicode literals in a couple of places where they were not strictly necessary.
cmlenz
parents: 715
diff changeset
177 attrs_tuple = Attrs([("attr1", u"föö"), ("attr2", u"bär")]).totuple()
04945cd67dad Remove usage of unicode literals in a couple of places where they were not strictly necessary.
cmlenz
parents: 715
diff changeset
178 self.assertEqual(u'fööbär', attrs_tuple[1])
04945cd67dad Remove usage of unicode literals in a couple of places where they were not strictly necessary.
cmlenz
parents: 715
diff changeset
179
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
180
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
181 class NamespaceTestCase(unittest.TestCase):
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
182
857
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
183 def test_repr(self):
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
184 self.assertEqual("Namespace('http://www.example.org/namespace')",
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
185 repr(Namespace('http://www.example.org/namespace')))
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
186
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
187 def test_repr_eval(self):
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
188 ns = Namespace('http://www.example.org/namespace')
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
189 self.assertEqual(eval(repr(ns)), ns)
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
190
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
191 def test_repr_eval_non_ascii(self):
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
192 ns = Namespace(u'http://www.example.org/nämespäcé')
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
193 self.assertEqual(eval(repr(ns)), ns)
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
194
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
195 def test_pickle(self):
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
196 ns = Namespace('http://www.example.org/namespace')
932
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
197 buf = BytesIO()
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
198 pickle.dump(ns, buf, 2)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
199 buf.seek(0)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
200 unpickled = pickle.load(buf)
857
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
201 self.assertEquals("Namespace('http://www.example.org/namespace')",
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
202 repr(unpickled))
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
203 self.assertEquals('http://www.example.org/namespace', unpickled.uri)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
204
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
205
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
206 class QNameTestCase(unittest.TestCase):
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
207
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
208 def test_pickle(self):
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
209 qname = QName('http://www.example.org/namespace}elem')
932
e53161c2773c Merge r1140 from py3k:
hodgestar
parents: 923
diff changeset
210 buf = BytesIO()
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
211 pickle.dump(qname, buf, 2)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
212 buf.seek(0)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
213 unpickled = pickle.load(buf)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
214 self.assertEquals('{http://www.example.org/namespace}elem', unpickled)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
215 self.assertEquals('http://www.example.org/namespace',
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
216 unpickled.namespace)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
217 self.assertEquals('elem', unpickled.localname)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
218
326
08ada6b4b767 Fixed `__repr__` of the `QName`, `Attrs`, and `Expression` classes so that the output can be used as code to instantiate the object again.
cmlenz
parents: 279
diff changeset
219 def test_repr(self):
857
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
220 self.assertEqual("QName('elem')", repr(QName('elem')))
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
221 self.assertEqual("QName('http://www.example.org/namespace}elem')",
326
08ada6b4b767 Fixed `__repr__` of the `QName`, `Attrs`, and `Expression` classes so that the output can be used as code to instantiate the object again.
cmlenz
parents: 279
diff changeset
222 repr(QName('http://www.example.org/namespace}elem')))
08ada6b4b767 Fixed `__repr__` of the `QName`, `Attrs`, and `Expression` classes so that the output can be used as code to instantiate the object again.
cmlenz
parents: 279
diff changeset
223
857
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
224 def test_repr_eval(self):
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
225 qn = QName('elem')
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
226 self.assertEqual(eval(repr(qn)), qn)
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
227
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
228 def test_repr_eval_non_ascii(self):
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
229 qn = QName(u'élem')
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
230 self.assertEqual(eval(repr(qn)), qn)
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
231
666
9729855cacf4 `QName` can now be constructed from a string with a leading curly brace, and some doc improvements. Closes #164.
cmlenz
parents: 382
diff changeset
232 def test_leading_curly_brace(self):
9729855cacf4 `QName` can now be constructed from a string with a leading curly brace, and some doc improvements. Closes #164.
cmlenz
parents: 382
diff changeset
233 qname = QName('{http://www.example.org/namespace}elem')
9729855cacf4 `QName` can now be constructed from a string with a leading curly brace, and some doc improvements. Closes #164.
cmlenz
parents: 382
diff changeset
234 self.assertEquals('http://www.example.org/namespace', qname.namespace)
9729855cacf4 `QName` can now be constructed from a string with a leading curly brace, and some doc improvements. Closes #164.
cmlenz
parents: 382
diff changeset
235 self.assertEquals('elem', qname.localname)
9729855cacf4 `QName` can now be constructed from a string with a leading curly brace, and some doc improvements. Closes #164.
cmlenz
parents: 382
diff changeset
236
923
8cef75b02ac1 Pull up r1145 to trunk.
jruigrok
parents: 862
diff changeset
237 def test_curly_brace_equality(self):
8cef75b02ac1 Pull up r1145 to trunk.
jruigrok
parents: 862
diff changeset
238 qname1 = QName('{http://www.example.org/namespace}elem')
8cef75b02ac1 Pull up r1145 to trunk.
jruigrok
parents: 862
diff changeset
239 qname2 = QName('http://www.example.org/namespace}elem')
8cef75b02ac1 Pull up r1145 to trunk.
jruigrok
parents: 862
diff changeset
240 self.assertEqual(qname1.namespace, qname2.namespace)
8cef75b02ac1 Pull up r1145 to trunk.
jruigrok
parents: 862
diff changeset
241 self.assertEqual(qname1.localname, qname2.localname)
8cef75b02ac1 Pull up r1145 to trunk.
jruigrok
parents: 862
diff changeset
242 self.assertEqual(qname1, qname2)
8cef75b02ac1 Pull up r1145 to trunk.
jruigrok
parents: 862
diff changeset
243
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
244
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
245 def suite():
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
246 suite = unittest.TestSuite()
147
f7fb556f2678 Use `xmlcharrefreplace` when encoding the output in `Stream.render()`, so that encoding the output to legacy encodings such as ASCII or ISO-8859-1 should always work.
cmlenz
parents: 116
diff changeset
247 suite.addTest(unittest.makeSuite(StreamTestCase, 'test'))
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
248 suite.addTest(unittest.makeSuite(MarkupTestCase, 'test'))
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
249 suite.addTest(unittest.makeSuite(NamespaceTestCase, 'test'))
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
250 suite.addTest(unittest.makeSuite(AttrsTestCase, 'test'))
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
251 suite.addTest(unittest.makeSuite(QNameTestCase, 'test'))
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
252 suite.addTest(doctest.DocTestSuite(core))
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
253 return suite
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
254
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
255 if __name__ == '__main__':
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
256 unittest.main(defaultTest='suite')
Copyright (C) 2012-2017 Edgewall Software