6
6
# monkey-patched when running the "test_xml_etree_c" test suite.
7
7
8
8
import copy
9
+ import itertools
9
10
import functools
10
11
import html
11
12
import io
@@ -102,6 +103,11 @@ def newtest(*args, **kwargs):
102
103
return decorator
103
104
104
105
106
+ #-----------------------------------------------------------------------------
107
+ # UNIT TESTS
108
+ #-----------------------------------------------------------------------------
109
+
110
+
105
111
class ModuleTest (unittest .TestCase ):
106
112
def test_sanity (self ):
107
113
# Import sanity.
@@ -115,6 +121,143 @@ def test_all(self):
115
121
support .check__all__ (self , ET , names , blacklist = ("HTML_EMPTY" ,))
116
122
117
123
124
+ class ElementTree_Element_UnitTest (unittest .TestCase ):
125
+
126
+ def test___init__ (self ):
127
+ tag = "foo"
128
+ attrib = { "zix" : "wyp" }
129
+
130
+ element_foo = ET .Element (tag , attrib )
131
+
132
+ with self .subTest ("traits of an element" ):
133
+ self .assertIsInstance (element_foo , ET .Element )
134
+ self .assertIn ("tag" , dir (element_foo ))
135
+ self .assertIn ("attrib" , dir (element_foo ))
136
+ self .assertIn ("text" , dir (element_foo ))
137
+ self .assertIn ("tail" , dir (element_foo ))
138
+
139
+ with self .subTest ("string attributes have expected values" ):
140
+ self .assertEqual (element_foo .tag , tag )
141
+ self .assertIsNone (element_foo .text )
142
+ self .assertIsNone (element_foo .tail )
143
+
144
+ with self .subTest ("attrib is a copy" ):
145
+ self .assertIsNot (element_foo .attrib , attrib )
146
+ self .assertEqual (element_foo .attrib , attrib )
147
+
148
+ with self .subTest ("attrib isn't linked" ):
149
+ attrib ["bar" ] = "baz"
150
+
151
+ self .assertIsNot (element_foo .attrib , attrib )
152
+ self .assertNotEqual (element_foo .attrib , attrib )
153
+
154
+ def test_copy (self ):
155
+ element_foo = ET .Element ("foo" , { "zix" : "wyp" })
156
+ element_foo .append (ET .Element ("bar" , { "baz" : "qix" }))
157
+
158
+ with self .assertWarns (DeprecationWarning ):
159
+ element_foo2 = element_foo .copy ()
160
+
161
+ with self .subTest ("elements are not the same" ):
162
+ self .assertIsNot (element_foo2 , element_foo )
163
+
164
+ with self .subTest ("string attributes are the same" ):
165
+ self .assertIs (element_foo2 .tag , element_foo .tag )
166
+ self .assertIs (element_foo2 .text , element_foo .text )
167
+ self .assertIs (element_foo2 .tail , element_foo .tail )
168
+
169
+ with self .subTest ("string attributes are equal" ):
170
+ self .assertEqual (element_foo2 .tag , element_foo .tag )
171
+ self .assertEqual (element_foo2 .text , element_foo .text )
172
+ self .assertEqual (element_foo2 .tail , element_foo .tail )
173
+
174
+ with self .subTest ("children are the same" ):
175
+ for (child1 , child2 ) in itertools .zip_longest (element_foo , element_foo2 ):
176
+ self .assertIs (child1 , child2 )
177
+
178
+ with self .subTest ("attrib is a copy" ):
179
+ self .assertIsNot (element_foo2 .attrib , element_foo .attrib )
180
+ self .assertEqual (element_foo2 .attrib , element_foo .attrib )
181
+
182
+ with self .subTest ("attrib isn't linked" ):
183
+ element_foo .attrib ["bar" ] = "baz"
184
+
185
+ self .assertIsNot (element_foo2 .attrib , element_foo .attrib )
186
+ self .assertNotEqual (element_foo2 .attrib , element_foo .attrib )
187
+
188
+ def test___copy__ (self ):
189
+ element_foo = ET .Element ("foo" , { "zix" : "wyp" })
190
+ element_foo .append (ET .Element ("bar" , { "baz" : "qix" }))
191
+
192
+ element_foo2 = copy .copy (element_foo )
193
+
194
+ with self .subTest ("elements are not the same" ):
195
+ self .assertIsNot (element_foo2 , element_foo )
196
+
197
+ with self .subTest ("string attributes are the same" ):
198
+ self .assertIs (element_foo2 .tag , element_foo .tag )
199
+ self .assertIs (element_foo2 .text , element_foo .text )
200
+ self .assertIs (element_foo2 .tail , element_foo .tail )
201
+
202
+ with self .subTest ("string attributes are equal" ):
203
+ self .assertEqual (element_foo2 .tag , element_foo .tag )
204
+ self .assertEqual (element_foo2 .text , element_foo .text )
205
+ self .assertEqual (element_foo2 .tail , element_foo .tail )
206
+
207
+ with self .subTest ("children are the same" ):
208
+ for (child1 , child2 ) in itertools .zip_longest (element_foo , element_foo2 ):
209
+ self .assertIs (child1 , child2 )
210
+
211
+ with self .subTest ("attrib is a copy" ):
212
+ self .assertIsNot (element_foo2 .attrib , element_foo .attrib )
213
+ self .assertEqual (element_foo2 .attrib , element_foo .attrib )
214
+
215
+ with self .subTest ("attrib isn't linked" ):
216
+ element_foo .attrib ["bar" ] = "baz"
217
+
218
+ self .assertIsNot (element_foo2 .attrib , element_foo .attrib )
219
+ self .assertNotEqual (element_foo2 .attrib , element_foo .attrib )
220
+
221
+ def test___deepcopy__ (self ):
222
+ element_foo = ET .Element ("foo" , { "zix" : "wyp" })
223
+ element_foo .append (ET .Element ("bar" , { "baz" : "qix" }))
224
+
225
+ element_foo2 = copy .deepcopy (element_foo )
226
+
227
+ with self .subTest ("elements are not the same" ):
228
+ self .assertIsNot (element_foo2 , element_foo )
229
+
230
+ # Strings should still be the same in a deep copy.
231
+ with self .subTest ("string attributes are the same" ):
232
+ self .assertIs (element_foo2 .tag , element_foo .tag )
233
+ self .assertIs (element_foo2 .text , element_foo .text )
234
+ self .assertIs (element_foo2 .tail , element_foo .tail )
235
+
236
+ with self .subTest ("string attributes are equal" ):
237
+ self .assertEqual (element_foo2 .tag , element_foo .tag )
238
+ self .assertEqual (element_foo2 .text , element_foo .text )
239
+ self .assertEqual (element_foo2 .tail , element_foo .tail )
240
+
241
+ with self .subTest ("children are not the same" ):
242
+ for (child1 , child2 ) in itertools .zip_longest (element_foo , element_foo2 ):
243
+ self .assertIsNot (child1 , child2 )
244
+
245
+ with self .subTest ("attrib is a copy" ):
246
+ self .assertIsNot (element_foo2 .attrib , element_foo .attrib )
247
+ self .assertEqual (element_foo2 .attrib , element_foo .attrib )
248
+
249
+ with self .subTest ("attrib isn't linked" ):
250
+ element_foo .attrib ["bar" ] = "baz"
251
+
252
+ self .assertIsNot (element_foo2 .attrib , element_foo .attrib )
253
+ self .assertNotEqual (element_foo2 .attrib , element_foo .attrib )
254
+
255
+
256
+ #-----------------------------------------------------------------------------
257
+ # INTEGRATION TESTS
258
+ #-----------------------------------------------------------------------------
259
+
260
+
118
261
def serialize (elem , to_string = True , encoding = 'unicode' , ** options ):
119
262
if encoding != 'unicode' :
120
263
file = io .BytesIO ()
@@ -1786,36 +1929,38 @@ def test_cyclic_gc(self):
1786
1929
class Dummy :
1787
1930
pass
1788
1931
1789
- # Test the shortest cycle: d->element->d
1790
- d = Dummy ()
1791
- d .dummyref = ET .Element ('joe' , attr = d )
1792
- wref = weakref .ref (d )
1793
- del d
1794
- gc_collect ()
1795
- self .assertIsNone (wref ())
1796
-
1797
- # A longer cycle: d->e->e2->d
1798
- e = ET .Element ('joe' )
1799
- d = Dummy ()
1800
- d .dummyref = e
1801
- wref = weakref .ref (d )
1802
- e2 = ET .SubElement (e , 'foo' , attr = d )
1803
- del d , e , e2
1804
- gc_collect ()
1805
- self .assertIsNone (wref ())
1806
-
1807
- # A cycle between Element objects as children of one another
1808
- # e1->e2->e3->e1
1809
- e1 = ET .Element ('e1' )
1810
- e2 = ET .Element ('e2' )
1811
- e3 = ET .Element ('e3' )
1812
- e1 .append (e2 )
1813
- e2 .append (e2 )
1814
- e3 .append (e1 )
1815
- wref = weakref .ref (e1 )
1816
- del e1 , e2 , e3
1817
- gc_collect ()
1818
- self .assertIsNone (wref ())
1932
+ with self .subTest ("Test the shortest cycle: d->element->d" ):
1933
+ d = Dummy ()
1934
+ d .dummyref = ET .Element ('joe' , attr = d )
1935
+ wref = weakref .ref (d )
1936
+ del d
1937
+ gc_collect ()
1938
+ self .assertIsNone (wref ())
1939
+
1940
+ with self .subTest ("A longer cycle: d->e->e2->d" ):
1941
+ e = ET .Element ('joe' )
1942
+ d = Dummy ()
1943
+ d .dummyref = e
1944
+ wref = weakref .ref (d )
1945
+ e2 = ET .SubElement (e , 'foo' , attr = d )
1946
+ del d , e , e2
1947
+ gc_collect ()
1948
+ self .assertIsNone (wref ())
1949
+
1950
+ with self .subTest (
1951
+ "A cycle between Element objects as children of one another: "
1952
+ "e1->e2->e3->e1"
1953
+ ):
1954
+ e1 = ET .Element ('e1' )
1955
+ e2 = ET .Element ('e2' )
1956
+ e3 = ET .Element ('e3' )
1957
+ e3 .append (e1 )
1958
+ e2 .append (e3 )
1959
+ e1 .append (e2 )
1960
+ wref = weakref .ref (e1 )
1961
+ del e1 , e2 , e3
1962
+ gc_collect ()
1963
+ self .assertIsNone (wref ())
1819
1964
1820
1965
def test_weakref (self ):
1821
1966
flag = False
@@ -3143,6 +3288,7 @@ def test_main(module=None):
3143
3288
3144
3289
test_classes = [
3145
3290
ModuleTest ,
3291
+ ElementTree_Element_UnitTest ,
3146
3292
ElementSlicingTest ,
3147
3293
BasicElementTest ,
3148
3294
BadElementTest ,
0 commit comments