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