|
1 |
|
2 // The xml serializer uses the default line break of the plateform. |
|
3 // So we need to know the value of this default line break, in order |
|
4 // to build correctly the reference strings for tests. |
|
5 // This variable will contain this value. |
|
6 var LB; |
|
7 |
|
8 function run_test() { |
|
9 |
|
10 if(("@mozilla.org/windows-registry-key;1" in C) || ("nsILocalFileOS2" in I)) |
|
11 LB = "\r\n"; |
|
12 else |
|
13 LB = "\n"; |
|
14 |
|
15 for (var i = 0; i < tests.length && tests[i]; ++i) { |
|
16 tests[i].call(); |
|
17 } |
|
18 } |
|
19 |
|
20 var tests = [ |
|
21 test1, |
|
22 test2, |
|
23 test3, |
|
24 test4, |
|
25 test5, |
|
26 test6, |
|
27 test7, |
|
28 test8, |
|
29 test9, |
|
30 test10, |
|
31 null |
|
32 ]; |
|
33 |
|
34 function testString(str) { |
|
35 do_check_eq(roundtrip(str), str); |
|
36 } |
|
37 |
|
38 function test1() { |
|
39 // Basic round-tripping which we expect to hand back the same text |
|
40 // as we passed in (not strictly required for correctness in some of |
|
41 // those cases, but best for readability of serializer output) |
|
42 testString('<root/>'); |
|
43 testString('<root><child/></root>'); |
|
44 testString('<root xmlns=""/>'); |
|
45 testString('<root xml:lang="en"/>'); |
|
46 testString('<root xmlns="ns1"><child xmlns="ns2"/></root>') |
|
47 testString('<root xmlns="ns1"><child xmlns=""/></root>') |
|
48 testString('<a:root xmlns:a="ns1"><child/></a:root>') |
|
49 testString('<a:root xmlns:a="ns1"><a:child/></a:root>') |
|
50 testString('<a:root xmlns:a="ns1"><b:child xmlns:b="ns1"/></a:root>') |
|
51 testString('<a:root xmlns:a="ns1"><a:child xmlns:a="ns2"/></a:root>') |
|
52 testString('<a:root xmlns:a="ns1"><b:child xmlns:b="ns1" b:attr=""/></a:root>') |
|
53 } |
|
54 |
|
55 function test2() { |
|
56 // Test setting of "xmlns" attribute in the null namespace |
|
57 |
|
58 // XXXbz are these tests needed? What should happen here? These |
|
59 // may be bogus. |
|
60 |
|
61 // Setting random "xmlns" attribute |
|
62 var doc = ParseXML('<root xmlns="ns1"/>'); |
|
63 doc.documentElement.setAttribute("xmlns", "ns2"); |
|
64 do_check_serialize(doc); |
|
65 } |
|
66 |
|
67 function test3() { |
|
68 // Test basic appending of kids. Again, we're making assumptions |
|
69 // about how our serializer will serialize simple DOMs. |
|
70 var doc = ParseXML('<root xmlns="ns1"/>'); |
|
71 var root = doc.documentElement; |
|
72 var child = doc.createElementNS("ns2", "child"); |
|
73 root.appendChild(child); |
|
74 do_check_serialize(doc); |
|
75 do_check_eq(SerializeXML(doc), |
|
76 '<root xmlns="ns1"><child xmlns="ns2"/></root>'); |
|
77 |
|
78 doc = ParseXML('<root xmlns="ns1"/>'); |
|
79 root = doc.documentElement; |
|
80 child = doc.createElementNS("ns2", "prefix:child"); |
|
81 root.appendChild(child); |
|
82 do_check_serialize(doc); |
|
83 do_check_eq(SerializeXML(doc), |
|
84 '<root xmlns="ns1"><prefix:child xmlns:prefix="ns2"/></root>'); |
|
85 |
|
86 doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>'); |
|
87 root = doc.documentElement; |
|
88 child = doc.createElementNS("ns2", "prefix:child"); |
|
89 root.appendChild(child); |
|
90 do_check_serialize(doc); |
|
91 do_check_eq(SerializeXML(doc), |
|
92 '<prefix:root xmlns:prefix="ns1"><a0:child xmlns:a0="ns2"/>'+ |
|
93 '</prefix:root>'); |
|
94 |
|
95 } |
|
96 |
|
97 function test4() { |
|
98 // setAttributeNS tests |
|
99 |
|
100 var doc = ParseXML('<root xmlns="ns1"/>'); |
|
101 var root = doc.documentElement; |
|
102 root.setAttributeNS("ns1", "prefix:local", "val"); |
|
103 do_check_serialize(doc); |
|
104 do_check_eq(SerializeXML(doc), |
|
105 '<root xmlns="ns1" prefix:local="val" xmlns:prefix="ns1"/>'); |
|
106 |
|
107 doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>'); |
|
108 root = doc.documentElement; |
|
109 root.setAttributeNS("ns1", "local", "val"); |
|
110 do_check_serialize(doc); |
|
111 do_check_eq(SerializeXML(doc), |
|
112 '<prefix:root xmlns:prefix="ns1" prefix:local="val"/>'); |
|
113 |
|
114 doc = ParseXML('<root xmlns="ns1"/>'); |
|
115 root = doc.documentElement; |
|
116 root.setAttributeNS("ns2", "local", "val"); |
|
117 do_check_serialize(doc); |
|
118 do_check_eq(SerializeXML(doc), |
|
119 '<root xmlns="ns1" a0:local="val" xmlns:a0="ns2"/>'); |
|
120 |
|
121 // Handling of prefix-generation for non-null-namespace attributes |
|
122 // which have the same namespace as the current default namespace |
|
123 // (bug 301260). |
|
124 doc = ParseXML('<root xmlns="ns1"/>'); |
|
125 root = doc.documentElement; |
|
126 root.setAttributeNS("ns1", "local", "val"); |
|
127 do_check_serialize(doc); |
|
128 do_check_eq(SerializeXML(doc), |
|
129 '<root xmlns="ns1" a0:local="val" xmlns:a0="ns1"/>'); |
|
130 |
|
131 // Tree-walking test |
|
132 doc = ParseXML('<root xmlns="ns1" xmlns:a="ns2">'+ |
|
133 '<child xmlns:b="ns2" xmlns:a="ns3">'+ |
|
134 '<child2/></child></root>'); |
|
135 root = doc.documentElement; |
|
136 // Have to QI here -- no classinfo flattening in xpcshell, apparently |
|
137 var node = root.firstChild.firstChild.QueryInterface(nsIDOMElement); |
|
138 node.setAttributeNS("ns4", "l1", "v1"); |
|
139 node.setAttributeNS("ns4", "p2:l2", "v2"); |
|
140 node.setAttributeNS("", "l3", "v3"); |
|
141 node.setAttributeNS("ns3", "l4", "v4"); |
|
142 node.setAttributeNS("ns3", "p5:l5", "v5"); |
|
143 node.setAttributeNS("ns3", "a:l6", "v6"); |
|
144 node.setAttributeNS("ns2", "l7", "v7"); |
|
145 node.setAttributeNS("ns2", "p8:l8", "v8"); |
|
146 node.setAttributeNS("ns2", "b:l9", "v9"); |
|
147 node.setAttributeNS("ns2", "a:l10", "v10"); |
|
148 node.setAttributeNS("ns1", "a:l11", "v11"); |
|
149 node.setAttributeNS("ns1", "b:l12", "v12"); |
|
150 node.setAttributeNS("ns1", "l13", "v13"); |
|
151 do_check_serialize(doc); |
|
152 // Note: we end up with "a2" as the prefix on "l11" and "l12" because we use |
|
153 // "a1" earlier, and discard it in favor of something we get off the |
|
154 // namespace stack, apparently |
|
155 do_check_eq(SerializeXML(doc), |
|
156 '<root xmlns="ns1" xmlns:a="ns2">'+ |
|
157 '<child xmlns:b="ns2" xmlns:a="ns3">'+ |
|
158 '<child2 a0:l1="v1" xmlns:a0="ns4"' + |
|
159 ' a0:l2="v2"' + |
|
160 ' l3="v3"' + |
|
161 ' a:l4="v4"' + |
|
162 ' a:l5="v5"' + |
|
163 ' a:l6="v6"' + |
|
164 ' b:l7="v7"' + |
|
165 ' b:l8="v8"' + |
|
166 ' b:l9="v9"' + |
|
167 ' b:l10="v10"' + |
|
168 ' a2:l11="v11" xmlns:a2="ns1"' + |
|
169 ' a2:l12="v12"' + |
|
170 ' a2:l13="v13"/></child></root>'); |
|
171 } |
|
172 |
|
173 function test5() { |
|
174 // Handling of kids in the null namespace when the default is a |
|
175 // different namespace (bug 301260). |
|
176 var doc = ParseXML('<root xmlns="ns1"/>') |
|
177 var child = doc.createElement('child'); |
|
178 doc.documentElement.appendChild(child); |
|
179 do_check_serialize(doc); |
|
180 do_check_eq(SerializeXML(doc), |
|
181 '<root xmlns="ns1"><child xmlns=""/></root>'); |
|
182 } |
|
183 |
|
184 function test6() { |
|
185 // Handling of not using a namespace prefix (or default namespace!) |
|
186 // that's not bound to our namespace in our scope (bug 301260). |
|
187 var doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>'); |
|
188 var root = doc.documentElement; |
|
189 var child1 = doc.createElementNS("ns2", "prefix:child1"); |
|
190 var child2 = doc.createElementNS("ns1", "prefix:child2"); |
|
191 child1.appendChild(child2); |
|
192 root.appendChild(child1); |
|
193 do_check_serialize(doc); |
|
194 do_check_eq(SerializeXML(doc), |
|
195 '<prefix:root xmlns:prefix="ns1"><a0:child1 xmlns:a0="ns2">'+ |
|
196 '<prefix:child2/></a0:child1></prefix:root>'); |
|
197 |
|
198 doc = ParseXML('<root xmlns="ns1"><prefix:child1 xmlns:prefix="ns2"/></root>'); |
|
199 root = doc.documentElement; |
|
200 child1 = root.firstChild; |
|
201 child2 = doc.createElementNS("ns1", "prefix:child2"); |
|
202 child1.appendChild(child2); |
|
203 do_check_serialize(doc); |
|
204 do_check_eq(SerializeXML(doc), |
|
205 '<root xmlns="ns1"><prefix:child1 xmlns:prefix="ns2">'+ |
|
206 '<child2/></prefix:child1></root>'); |
|
207 |
|
208 doc = ParseXML('<prefix:root xmlns:prefix="ns1">'+ |
|
209 '<prefix:child1 xmlns:prefix="ns2"/></prefix:root>'); |
|
210 root = doc.documentElement; |
|
211 child1 = root.firstChild; |
|
212 child2 = doc.createElementNS("ns1", "prefix:child2"); |
|
213 child1.appendChild(child2); |
|
214 do_check_serialize(doc); |
|
215 do_check_eq(SerializeXML(doc), |
|
216 '<prefix:root xmlns:prefix="ns1"><prefix:child1 xmlns:prefix="ns2">'+ |
|
217 '<a0:child2 xmlns:a0="ns1"/></prefix:child1></prefix:root>'); |
|
218 |
|
219 |
|
220 doc = ParseXML('<root xmlns="ns1"/>'); |
|
221 root = doc.documentElement; |
|
222 child1 = doc.createElementNS("ns2", "child1"); |
|
223 child2 = doc.createElementNS("ns1", "child2"); |
|
224 child1.appendChild(child2); |
|
225 root.appendChild(child1); |
|
226 do_check_serialize(doc); |
|
227 do_check_eq(SerializeXML(doc), |
|
228 '<root xmlns="ns1"><child1 xmlns="ns2"><child2 xmlns="ns1"/>'+ |
|
229 '</child1></root>'); |
|
230 } |
|
231 |
|
232 function test7() { |
|
233 // Handle xmlns attribute declaring a default namespace on a non-namespaced |
|
234 // element (bug 326994). |
|
235 var doc = ParseXML('<root xmlns=""/>') |
|
236 var root = doc.documentElement; |
|
237 root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", |
|
238 "http://www.w3.org/1999/xhtml"); |
|
239 do_check_serialize(doc); |
|
240 do_check_eq(SerializeXML(doc), '<root/>'); |
|
241 |
|
242 doc = ParseXML('<root xmlns=""><child1/></root>') |
|
243 root = doc.documentElement; |
|
244 root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", |
|
245 "http://www.w3.org/1999/xhtml"); |
|
246 do_check_serialize(doc); |
|
247 do_check_eq(SerializeXML(doc), '<root><child1/></root>'); |
|
248 |
|
249 doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' + |
|
250 '<child1 xmlns=""><child2/></child1></root>') |
|
251 root = doc.documentElement; |
|
252 |
|
253 // No interface flattening in xpcshell |
|
254 var child1 = root.firstChild.QueryInterface(nsIDOMElement); |
|
255 child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", |
|
256 "http://www.w3.org/1999/xhtml"); |
|
257 do_check_serialize(doc); |
|
258 do_check_eq(SerializeXML(doc), |
|
259 '<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' + |
|
260 '<child2/></child1></root>'); |
|
261 |
|
262 doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' + |
|
263 '<child1 xmlns="">' + |
|
264 '<child2 xmlns="http://www.w3.org/1999/xhtml"></child2>' + |
|
265 '</child1></root>') |
|
266 root = doc.documentElement; |
|
267 // No interface flattening in xpcshell |
|
268 child1 = root.firstChild.QueryInterface(nsIDOMElement); |
|
269 var child2 = child1.firstChild.QueryInterface(nsIDOMElement); |
|
270 child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", |
|
271 "http://www.w3.org/1999/xhtml"); |
|
272 child2.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", ""); |
|
273 do_check_serialize(doc); |
|
274 do_check_eq(SerializeXML(doc), |
|
275 '<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' + |
|
276 '<a0:child2 xmlns:a0="http://www.w3.org/1999/xhtml" xmlns=""></a0:child2></child1></root>'); |
|
277 } |
|
278 |
|
279 function test8() { |
|
280 // Test behavior of serializing with a given charset. |
|
281 var str1 = '<?xml version="1.0" encoding="ISO-8859-1"?>'+LB+'<root/>'; |
|
282 var str2 = '<?xml version="1.0" encoding="UTF8"?>'+LB+'<root/>'; |
|
283 var doc1 = ParseXML(str1); |
|
284 var doc2 = ParseXML(str2); |
|
285 |
|
286 var p = Pipe(); |
|
287 DOMSerializer().serializeToStream(doc1, p.outputStream, "ISO-8859-1"); |
|
288 p.outputStream.close(); |
|
289 do_check_eq(ScriptableInput(p).read(-1), str1); |
|
290 |
|
291 p = Pipe(); |
|
292 DOMSerializer().serializeToStream(doc2, p.outputStream, "ISO-8859-1"); |
|
293 p.outputStream.close(); |
|
294 do_check_eq(ScriptableInput(p).read(-1), str1); |
|
295 |
|
296 p = Pipe(); |
|
297 DOMSerializer().serializeToStream(doc1, p.outputStream, "UTF8"); |
|
298 p.outputStream.close(); |
|
299 do_check_eq(ScriptableInput(p).read(-1), str2); |
|
300 |
|
301 p = Pipe(); |
|
302 DOMSerializer().serializeToStream(doc2, p.outputStream, "UTF8"); |
|
303 p.outputStream.close(); |
|
304 do_check_eq(ScriptableInput(p).read(-1), str2); |
|
305 } |
|
306 |
|
307 function test9() { |
|
308 // Test behavior of serializing between given charsets, using |
|
309 // ISO-8859-1-representable text. |
|
310 var contents = '<root>' + |
|
311 '\u00BD + \u00BE == \u00BD\u00B2 + \u00BC + \u00BE' + |
|
312 '</root>'; |
|
313 var str1 = '<?xml version="1.0" encoding="ISO-8859-1"?>'+ LB + contents; |
|
314 var str2 = '<?xml version="1.0" encoding="UTF8"?>'+ LB + contents; |
|
315 var str3 = '<?xml version="1.0" encoding="UTF-16"?>'+ LB + contents; |
|
316 var doc1 = ParseXML(str1); |
|
317 var doc2 = ParseXML(str2); |
|
318 var doc3 = ParseXML(str3); |
|
319 |
|
320 checkSerialization(doc1, "ISO-8859-1", str1); |
|
321 checkSerialization(doc2, "ISO-8859-1", str1); |
|
322 checkSerialization(doc3, "ISO-8859-1", str1); |
|
323 |
|
324 checkSerialization(doc1, "UTF8", str2); |
|
325 checkSerialization(doc2, "UTF8", str2); |
|
326 checkSerialization(doc3, "UTF8", str2); |
|
327 |
|
328 checkSerialization(doc1, "UTF-16", str3); |
|
329 checkSerialization(doc2, "UTF-16", str3); |
|
330 checkSerialization(doc3, "UTF-16", str3); |
|
331 } |
|
332 |
|
333 function test10() { |
|
334 // Test behavior of serializing between given charsets, using |
|
335 // Unicode characters (XXX but only BMP ones because I don't know |
|
336 // how to create one with non-BMP characters, either with JS strings |
|
337 // or using DOM APIs). |
|
338 var contents = '<root>' + |
|
339 'AZaz09 \u007F ' + // U+000000 to U+00007F |
|
340 '\u0080 \u0398 \u03BB \u0725 ' + // U+000080 to U+0007FF |
|
341 '\u0964 \u0F5F \u20AC \uFFFB' + // U+000800 to U+00FFFF |
|
342 '</root>'; |
|
343 var str1 = '<?xml version="1.0" encoding="UTF8"?>'+ LB + contents; |
|
344 var str2 = '<?xml version="1.0" encoding="UTF-16"?>'+ LB + contents; |
|
345 var doc1 = ParseXML(str1); |
|
346 var doc2 = ParseXML(str2); |
|
347 |
|
348 checkSerialization(doc1, "UTF8", str1); |
|
349 checkSerialization(doc2, "UTF8", str1); |
|
350 |
|
351 checkSerialization(doc1, "UTF-16", str2); |
|
352 checkSerialization(doc2, "UTF-16", str2); |
|
353 } |
|
354 |
|
355 function checkSerialization(doc, toCharset, expectedString) { |
|
356 var p = Pipe(); |
|
357 DOMSerializer().serializeToStream(doc, p.outputStream, toCharset); |
|
358 p.outputStream.close(); |
|
359 |
|
360 var cin = C["@mozilla.org/intl/converter-input-stream;1"] |
|
361 .createInstance(I.nsIConverterInputStream); |
|
362 cin.init(p.inputStream, toCharset, 1024, 0x0); |
|
363 |
|
364 // compare the first expectedString.length characters for equality |
|
365 var outString = {}; |
|
366 var count = cin.readString(expectedString.length, outString); |
|
367 do_check_true(count == expectedString.length); |
|
368 do_check_true(outString.value == expectedString); |
|
369 |
|
370 // if there's anything more in the stream, it's a bug |
|
371 do_check_eq(0, cin.readString(1, outString)); |
|
372 do_check_eq(outString.value, ""); |
|
373 } |