annotate genshi/tests/core.py @ 926:5dcabf565db1 stable-0.6.x

Merge r1148 from trunk (fix for qname equality issue #413).
author hodgestar
date Thu, 10 Mar 2011 08:16:29 +0000
parents 37fb3988647a
children e53161c2773c
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
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
16 from StringIO import StringIO
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
17 try:
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
18 from cStringIO import StringIO as cStringIO
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
19 except ImportError:
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
20 cStringIO = StringIO
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
21 import unittest
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
22
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
23 from genshi import core
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
24 from genshi.core import Markup, Attrs, Namespace, QName, escape, unescape
230
24757b771651 Renamed Markup to Genshi in repository.
cmlenz
parents: 212
diff changeset
25 from genshi.input import XML, ParseError
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
26
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
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
28 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
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_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
31 xml = XML('<li>Über uns</li>')
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
32 self.assertEqual('<li>Über uns</li>', xml.render())
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
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 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
35 xml = XML('<li>Über uns</li>')
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 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
37
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
38 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
39 xml = XML('<li>Über uns</li>')
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
40 self.assertEqual('<li>&#220;ber uns</li>', xml.render(encoding='ascii'))
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
41
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
42 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
43 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
44 strio = cStringIO()
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 self.assertEqual(None, xml.render(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
46 self.assertEqual('<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
47
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 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
49 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
50 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
51 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
52 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
53
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
54 def test_pickle(self):
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
55 xml = XML('<li>Foo</li>')
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
56 buf = StringIO()
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
57 pickle.dump(xml, buf, 2)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
58 buf.seek(0)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
59 xml = pickle.load(buf)
862
37fb3988647a Make the output tests skip the encoding step.
cmlenz
parents: 857
diff changeset
60 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
61
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
62
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
63 class MarkupTestCase(unittest.TestCase):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
64
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
65 def test_new_with_encoding(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
66 markup = Markup('Döner', encoding='utf-8')
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
67 self.assertEquals("<Markup u'D\\xf6ner'>", repr(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
68
116
88ac4c680120 Merged [135:138/branches/experimental/cspeedups].
cmlenz
parents: 113
diff changeset
69 def test_repr(self):
88ac4c680120 Merged [135:138/branches/experimental/cspeedups].
cmlenz
parents: 113
diff changeset
70 markup = Markup('foo')
382
d7da3fba7faf * Added documentation for the various stream event kinds.
cmlenz
parents: 326
diff changeset
71 self.assertEquals("<Markup u'foo'>", repr(markup))
116
88ac4c680120 Merged [135:138/branches/experimental/cspeedups].
cmlenz
parents: 113
diff changeset
72
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
73 def test_escape(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
74 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
75 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
76 self.assertEquals('&lt;b&gt;&#34;&amp;&#34;&lt;/b&gt;', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
77
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
78 def test_escape_noquotes(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
79 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
80 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
81 self.assertEquals('&lt;b&gt;"&amp;"&lt;/b&gt;', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
82
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
83 def test_unescape_markup(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
84 string = '<b>"&"</b>'
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
85 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
86 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
87 self.assertEquals(string, unescape(markup))
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
88
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
89 def test_add_str(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
90 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
91 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
92 self.assertEquals('<b>foo</b>&lt;br/&gt;', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
93
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
94 def test_add_markup(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
95 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
96 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
97 self.assertEquals('<b>foo</b><br/>', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
98
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
99 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
100 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
101 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
102 self.assertEquals('&lt;br/&gt;<b>bar</b>', markup)
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
103
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
104 def test_mod(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
105 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
106 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
107 self.assertEquals('<b>&amp;</b>', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
108
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
109 def test_mod_multi(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
110 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
111 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
112 self.assertEquals('<b>&amp;</b> boo', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
113
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
114 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
115 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
116 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
117 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
118
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 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
120 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
121 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
122 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
123
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
124 def test_mul(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
125 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
126 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
127 self.assertEquals('<b>foo</b><b>foo</b>', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
128
204
516a6cae0aa8 * Implement reverse add/mul operators for `Markup` class, so that the result is also a `Markup` instance.
cmlenz
parents: 147
diff changeset
129 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
130 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
131 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
132 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
133
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
134 def test_join(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
135 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
136 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
137 self.assertEquals('foo<br />&lt;bar /&gt;<br /><baz />', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
138
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
139 def test_stripentities_all(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
140 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
141 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
142 self.assertEquals('& j', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
143
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
144 def test_stripentities_keepxml(self):
116
88ac4c680120 Merged [135:138/branches/experimental/cspeedups].
cmlenz
parents: 113
diff changeset
145 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
146 assert type(markup) is Markup
116
88ac4c680120 Merged [135:138/branches/experimental/cspeedups].
cmlenz
parents: 113
diff changeset
147 self.assertEquals('&amp; j', markup)
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
148
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
149 def test_striptags_empty(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
150 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
151 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
152 self.assertEquals('', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
153
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
154 def test_striptags_mid(self):
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
155 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
156 assert type(markup) is Markup
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
157 self.assertEquals('foo', markup)
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
158
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
159 def test_pickle(self):
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
160 markup = Markup('foo')
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
161 buf = StringIO()
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
162 pickle.dump(markup, buf, 2)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
163 buf.seek(0)
382
d7da3fba7faf * Added documentation for the various stream event kinds.
cmlenz
parents: 326
diff changeset
164 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
165
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
166
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
167 class AttrsTestCase(unittest.TestCase):
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
168
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
169 def test_pickle(self):
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
170 attrs = Attrs([("attr1", "foo"), ("attr2", "bar")])
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
171 buf = StringIO()
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
172 pickle.dump(attrs, buf, 2)
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
173 buf.seek(0)
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
174 unpickled = pickle.load(buf)
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
175 self.assertEquals("Attrs([('attr1', 'foo'), ('attr2', 'bar')])",
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
176 repr(unpickled))
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
177
852
04945cd67dad Remove usage of unicode literals in a couple of places where they were not strictly necessary.
cmlenz
parents: 715
diff changeset
178 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
179 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
180 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
181
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
182
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
183 class NamespaceTestCase(unittest.TestCase):
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
184
857
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
185 def test_repr(self):
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
186 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
187 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
188
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
189 def test_repr_eval(self):
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
190 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
191 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
192
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
193 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
194 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
195 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
196
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
197 def test_pickle(self):
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
198 ns = Namespace('http://www.example.org/namespace')
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
199 buf = StringIO()
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
200 pickle.dump(ns, buf, 2)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
201 buf.seek(0)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
202 unpickled = pickle.load(buf)
857
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
203 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
204 repr(unpickled))
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
205 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
206
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 class QNameTestCase(unittest.TestCase):
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
209
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
210 def test_pickle(self):
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
211 qname = QName('http://www.example.org/namespace}elem')
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
212 buf = StringIO()
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
213 pickle.dump(qname, buf, 2)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
214 buf.seek(0)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
215 unpickled = pickle.load(buf)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
216 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
217 self.assertEquals('http://www.example.org/namespace',
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
218 unpickled.namespace)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
219 self.assertEquals('elem', unpickled.localname)
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
220
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
221 def test_repr(self):
857
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
222 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
223 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
224 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
225
857
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
226 def test_repr_eval(self):
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
227 qn = QName('elem')
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
228 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
229
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
230 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
231 qn = QName(u'élem')
24733a5854d9 Avoid unicode literals in `repr`s of `QName` and `Namespace` when not necessary.
cmlenz
parents: 854
diff changeset
232 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
233
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
234 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
235 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
236 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
237 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
238
926
5dcabf565db1 Merge r1148 from trunk (fix for qname equality issue #413).
hodgestar
parents: 862
diff changeset
239 def test_curly_brace_equality(self):
5dcabf565db1 Merge r1148 from trunk (fix for qname equality issue #413).
hodgestar
parents: 862
diff changeset
240 qname1 = QName('{http://www.example.org/namespace}elem')
5dcabf565db1 Merge r1148 from trunk (fix for qname equality issue #413).
hodgestar
parents: 862
diff changeset
241 qname2 = QName('http://www.example.org/namespace}elem')
5dcabf565db1 Merge r1148 from trunk (fix for qname equality issue #413).
hodgestar
parents: 862
diff changeset
242 self.assertEqual(qname1.namespace, qname2.namespace)
5dcabf565db1 Merge r1148 from trunk (fix for qname equality issue #413).
hodgestar
parents: 862
diff changeset
243 self.assertEqual(qname1.localname, qname2.localname)
5dcabf565db1 Merge r1148 from trunk (fix for qname equality issue #413).
hodgestar
parents: 862
diff changeset
244 self.assertEqual(qname1, qname2)
5dcabf565db1 Merge r1148 from trunk (fix for qname equality issue #413).
hodgestar
parents: 862
diff changeset
245
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
246
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
247 def suite():
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
248 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
249 suite.addTest(unittest.makeSuite(StreamTestCase, 'test'))
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
250 suite.addTest(unittest.makeSuite(MarkupTestCase, 'test'))
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
251 suite.addTest(unittest.makeSuite(NamespaceTestCase, 'test'))
715
09715f868a73 Enable pickling of `Template` and `Code` objects.
cmlenz
parents: 713
diff changeset
252 suite.addTest(unittest.makeSuite(AttrsTestCase, 'test'))
279
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
253 suite.addTest(unittest.makeSuite(QNameTestCase, 'test'))
4b5b4653d41e Some adjustments to make core data structures picklable (requires protocol 2).
cmlenz
parents: 230
diff changeset
254 suite.addTest(doctest.DocTestSuite(core))
1
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
255 return suite
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
256
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
257 if __name__ == '__main__':
821114ec4f69 Initial import.
cmlenz
parents:
diff changeset
258 unittest.main(defaultTest='suite')
Copyright (C) 2012-2017 Edgewall Software