1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/test/unit/test_xml_serializer.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,373 @@ 1.4 + 1.5 +// The xml serializer uses the default line break of the plateform. 1.6 +// So we need to know the value of this default line break, in order 1.7 +// to build correctly the reference strings for tests. 1.8 +// This variable will contain this value. 1.9 +var LB; 1.10 + 1.11 +function run_test() { 1.12 + 1.13 + if(("@mozilla.org/windows-registry-key;1" in C) || ("nsILocalFileOS2" in I)) 1.14 + LB = "\r\n"; 1.15 + else 1.16 + LB = "\n"; 1.17 + 1.18 + for (var i = 0; i < tests.length && tests[i]; ++i) { 1.19 + tests[i].call(); 1.20 + } 1.21 +} 1.22 + 1.23 +var tests = [ 1.24 + test1, 1.25 + test2, 1.26 + test3, 1.27 + test4, 1.28 + test5, 1.29 + test6, 1.30 + test7, 1.31 + test8, 1.32 + test9, 1.33 + test10, 1.34 + null 1.35 +]; 1.36 + 1.37 +function testString(str) { 1.38 + do_check_eq(roundtrip(str), str); 1.39 +} 1.40 + 1.41 +function test1() { 1.42 + // Basic round-tripping which we expect to hand back the same text 1.43 + // as we passed in (not strictly required for correctness in some of 1.44 + // those cases, but best for readability of serializer output) 1.45 + testString('<root/>'); 1.46 + testString('<root><child/></root>'); 1.47 + testString('<root xmlns=""/>'); 1.48 + testString('<root xml:lang="en"/>'); 1.49 + testString('<root xmlns="ns1"><child xmlns="ns2"/></root>') 1.50 + testString('<root xmlns="ns1"><child xmlns=""/></root>') 1.51 + testString('<a:root xmlns:a="ns1"><child/></a:root>') 1.52 + testString('<a:root xmlns:a="ns1"><a:child/></a:root>') 1.53 + testString('<a:root xmlns:a="ns1"><b:child xmlns:b="ns1"/></a:root>') 1.54 + testString('<a:root xmlns:a="ns1"><a:child xmlns:a="ns2"/></a:root>') 1.55 + testString('<a:root xmlns:a="ns1"><b:child xmlns:b="ns1" b:attr=""/></a:root>') 1.56 +} 1.57 + 1.58 +function test2() { 1.59 + // Test setting of "xmlns" attribute in the null namespace 1.60 + 1.61 + // XXXbz are these tests needed? What should happen here? These 1.62 + // may be bogus. 1.63 + 1.64 + // Setting random "xmlns" attribute 1.65 + var doc = ParseXML('<root xmlns="ns1"/>'); 1.66 + doc.documentElement.setAttribute("xmlns", "ns2"); 1.67 + do_check_serialize(doc); 1.68 +} 1.69 + 1.70 +function test3() { 1.71 + // Test basic appending of kids. Again, we're making assumptions 1.72 + // about how our serializer will serialize simple DOMs. 1.73 + var doc = ParseXML('<root xmlns="ns1"/>'); 1.74 + var root = doc.documentElement; 1.75 + var child = doc.createElementNS("ns2", "child"); 1.76 + root.appendChild(child); 1.77 + do_check_serialize(doc); 1.78 + do_check_eq(SerializeXML(doc), 1.79 + '<root xmlns="ns1"><child xmlns="ns2"/></root>'); 1.80 + 1.81 + doc = ParseXML('<root xmlns="ns1"/>'); 1.82 + root = doc.documentElement; 1.83 + child = doc.createElementNS("ns2", "prefix:child"); 1.84 + root.appendChild(child); 1.85 + do_check_serialize(doc); 1.86 + do_check_eq(SerializeXML(doc), 1.87 + '<root xmlns="ns1"><prefix:child xmlns:prefix="ns2"/></root>'); 1.88 + 1.89 + doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>'); 1.90 + root = doc.documentElement; 1.91 + child = doc.createElementNS("ns2", "prefix:child"); 1.92 + root.appendChild(child); 1.93 + do_check_serialize(doc); 1.94 + do_check_eq(SerializeXML(doc), 1.95 + '<prefix:root xmlns:prefix="ns1"><a0:child xmlns:a0="ns2"/>'+ 1.96 + '</prefix:root>'); 1.97 + 1.98 +} 1.99 + 1.100 +function test4() { 1.101 + // setAttributeNS tests 1.102 + 1.103 + var doc = ParseXML('<root xmlns="ns1"/>'); 1.104 + var root = doc.documentElement; 1.105 + root.setAttributeNS("ns1", "prefix:local", "val"); 1.106 + do_check_serialize(doc); 1.107 + do_check_eq(SerializeXML(doc), 1.108 + '<root xmlns="ns1" prefix:local="val" xmlns:prefix="ns1"/>'); 1.109 + 1.110 + doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>'); 1.111 + root = doc.documentElement; 1.112 + root.setAttributeNS("ns1", "local", "val"); 1.113 + do_check_serialize(doc); 1.114 + do_check_eq(SerializeXML(doc), 1.115 + '<prefix:root xmlns:prefix="ns1" prefix:local="val"/>'); 1.116 + 1.117 + doc = ParseXML('<root xmlns="ns1"/>'); 1.118 + root = doc.documentElement; 1.119 + root.setAttributeNS("ns2", "local", "val"); 1.120 + do_check_serialize(doc); 1.121 + do_check_eq(SerializeXML(doc), 1.122 + '<root xmlns="ns1" a0:local="val" xmlns:a0="ns2"/>'); 1.123 + 1.124 + // Handling of prefix-generation for non-null-namespace attributes 1.125 + // which have the same namespace as the current default namespace 1.126 + // (bug 301260). 1.127 + doc = ParseXML('<root xmlns="ns1"/>'); 1.128 + root = doc.documentElement; 1.129 + root.setAttributeNS("ns1", "local", "val"); 1.130 + do_check_serialize(doc); 1.131 + do_check_eq(SerializeXML(doc), 1.132 + '<root xmlns="ns1" a0:local="val" xmlns:a0="ns1"/>'); 1.133 + 1.134 + // Tree-walking test 1.135 + doc = ParseXML('<root xmlns="ns1" xmlns:a="ns2">'+ 1.136 + '<child xmlns:b="ns2" xmlns:a="ns3">'+ 1.137 + '<child2/></child></root>'); 1.138 + root = doc.documentElement; 1.139 + // Have to QI here -- no classinfo flattening in xpcshell, apparently 1.140 + var node = root.firstChild.firstChild.QueryInterface(nsIDOMElement); 1.141 + node.setAttributeNS("ns4", "l1", "v1"); 1.142 + node.setAttributeNS("ns4", "p2:l2", "v2"); 1.143 + node.setAttributeNS("", "l3", "v3"); 1.144 + node.setAttributeNS("ns3", "l4", "v4"); 1.145 + node.setAttributeNS("ns3", "p5:l5", "v5"); 1.146 + node.setAttributeNS("ns3", "a:l6", "v6"); 1.147 + node.setAttributeNS("ns2", "l7", "v7"); 1.148 + node.setAttributeNS("ns2", "p8:l8", "v8"); 1.149 + node.setAttributeNS("ns2", "b:l9", "v9"); 1.150 + node.setAttributeNS("ns2", "a:l10", "v10"); 1.151 + node.setAttributeNS("ns1", "a:l11", "v11"); 1.152 + node.setAttributeNS("ns1", "b:l12", "v12"); 1.153 + node.setAttributeNS("ns1", "l13", "v13"); 1.154 + do_check_serialize(doc); 1.155 + // Note: we end up with "a2" as the prefix on "l11" and "l12" because we use 1.156 + // "a1" earlier, and discard it in favor of something we get off the 1.157 + // namespace stack, apparently 1.158 + do_check_eq(SerializeXML(doc), 1.159 + '<root xmlns="ns1" xmlns:a="ns2">'+ 1.160 + '<child xmlns:b="ns2" xmlns:a="ns3">'+ 1.161 + '<child2 a0:l1="v1" xmlns:a0="ns4"' + 1.162 + ' a0:l2="v2"' + 1.163 + ' l3="v3"' + 1.164 + ' a:l4="v4"' + 1.165 + ' a:l5="v5"' + 1.166 + ' a:l6="v6"' + 1.167 + ' b:l7="v7"' + 1.168 + ' b:l8="v8"' + 1.169 + ' b:l9="v9"' + 1.170 + ' b:l10="v10"' + 1.171 + ' a2:l11="v11" xmlns:a2="ns1"' + 1.172 + ' a2:l12="v12"' + 1.173 + ' a2:l13="v13"/></child></root>'); 1.174 +} 1.175 + 1.176 +function test5() { 1.177 + // Handling of kids in the null namespace when the default is a 1.178 + // different namespace (bug 301260). 1.179 + var doc = ParseXML('<root xmlns="ns1"/>') 1.180 + var child = doc.createElement('child'); 1.181 + doc.documentElement.appendChild(child); 1.182 + do_check_serialize(doc); 1.183 + do_check_eq(SerializeXML(doc), 1.184 + '<root xmlns="ns1"><child xmlns=""/></root>'); 1.185 +} 1.186 + 1.187 +function test6() { 1.188 + // Handling of not using a namespace prefix (or default namespace!) 1.189 + // that's not bound to our namespace in our scope (bug 301260). 1.190 + var doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>'); 1.191 + var root = doc.documentElement; 1.192 + var child1 = doc.createElementNS("ns2", "prefix:child1"); 1.193 + var child2 = doc.createElementNS("ns1", "prefix:child2"); 1.194 + child1.appendChild(child2); 1.195 + root.appendChild(child1); 1.196 + do_check_serialize(doc); 1.197 + do_check_eq(SerializeXML(doc), 1.198 + '<prefix:root xmlns:prefix="ns1"><a0:child1 xmlns:a0="ns2">'+ 1.199 + '<prefix:child2/></a0:child1></prefix:root>'); 1.200 + 1.201 + doc = ParseXML('<root xmlns="ns1"><prefix:child1 xmlns:prefix="ns2"/></root>'); 1.202 + root = doc.documentElement; 1.203 + child1 = root.firstChild; 1.204 + child2 = doc.createElementNS("ns1", "prefix:child2"); 1.205 + child1.appendChild(child2); 1.206 + do_check_serialize(doc); 1.207 + do_check_eq(SerializeXML(doc), 1.208 + '<root xmlns="ns1"><prefix:child1 xmlns:prefix="ns2">'+ 1.209 + '<child2/></prefix:child1></root>'); 1.210 + 1.211 + doc = ParseXML('<prefix:root xmlns:prefix="ns1">'+ 1.212 + '<prefix:child1 xmlns:prefix="ns2"/></prefix:root>'); 1.213 + root = doc.documentElement; 1.214 + child1 = root.firstChild; 1.215 + child2 = doc.createElementNS("ns1", "prefix:child2"); 1.216 + child1.appendChild(child2); 1.217 + do_check_serialize(doc); 1.218 + do_check_eq(SerializeXML(doc), 1.219 + '<prefix:root xmlns:prefix="ns1"><prefix:child1 xmlns:prefix="ns2">'+ 1.220 + '<a0:child2 xmlns:a0="ns1"/></prefix:child1></prefix:root>'); 1.221 + 1.222 + 1.223 + doc = ParseXML('<root xmlns="ns1"/>'); 1.224 + root = doc.documentElement; 1.225 + child1 = doc.createElementNS("ns2", "child1"); 1.226 + child2 = doc.createElementNS("ns1", "child2"); 1.227 + child1.appendChild(child2); 1.228 + root.appendChild(child1); 1.229 + do_check_serialize(doc); 1.230 + do_check_eq(SerializeXML(doc), 1.231 + '<root xmlns="ns1"><child1 xmlns="ns2"><child2 xmlns="ns1"/>'+ 1.232 + '</child1></root>'); 1.233 +} 1.234 + 1.235 +function test7() { 1.236 + // Handle xmlns attribute declaring a default namespace on a non-namespaced 1.237 + // element (bug 326994). 1.238 + var doc = ParseXML('<root xmlns=""/>') 1.239 + var root = doc.documentElement; 1.240 + root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", 1.241 + "http://www.w3.org/1999/xhtml"); 1.242 + do_check_serialize(doc); 1.243 + do_check_eq(SerializeXML(doc), '<root/>'); 1.244 + 1.245 + doc = ParseXML('<root xmlns=""><child1/></root>') 1.246 + root = doc.documentElement; 1.247 + root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", 1.248 + "http://www.w3.org/1999/xhtml"); 1.249 + do_check_serialize(doc); 1.250 + do_check_eq(SerializeXML(doc), '<root><child1/></root>'); 1.251 + 1.252 + doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' + 1.253 + '<child1 xmlns=""><child2/></child1></root>') 1.254 + root = doc.documentElement; 1.255 + 1.256 + // No interface flattening in xpcshell 1.257 + var child1 = root.firstChild.QueryInterface(nsIDOMElement); 1.258 + child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", 1.259 + "http://www.w3.org/1999/xhtml"); 1.260 + do_check_serialize(doc); 1.261 + do_check_eq(SerializeXML(doc), 1.262 + '<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' + 1.263 + '<child2/></child1></root>'); 1.264 + 1.265 + doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' + 1.266 + '<child1 xmlns="">' + 1.267 + '<child2 xmlns="http://www.w3.org/1999/xhtml"></child2>' + 1.268 + '</child1></root>') 1.269 + root = doc.documentElement; 1.270 + // No interface flattening in xpcshell 1.271 + child1 = root.firstChild.QueryInterface(nsIDOMElement); 1.272 + var child2 = child1.firstChild.QueryInterface(nsIDOMElement); 1.273 + child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", 1.274 + "http://www.w3.org/1999/xhtml"); 1.275 + child2.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", ""); 1.276 + do_check_serialize(doc); 1.277 + do_check_eq(SerializeXML(doc), 1.278 + '<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' + 1.279 + '<a0:child2 xmlns:a0="http://www.w3.org/1999/xhtml" xmlns=""></a0:child2></child1></root>'); 1.280 +} 1.281 + 1.282 +function test8() { 1.283 + // Test behavior of serializing with a given charset. 1.284 + var str1 = '<?xml version="1.0" encoding="ISO-8859-1"?>'+LB+'<root/>'; 1.285 + var str2 = '<?xml version="1.0" encoding="UTF8"?>'+LB+'<root/>'; 1.286 + var doc1 = ParseXML(str1); 1.287 + var doc2 = ParseXML(str2); 1.288 + 1.289 + var p = Pipe(); 1.290 + DOMSerializer().serializeToStream(doc1, p.outputStream, "ISO-8859-1"); 1.291 + p.outputStream.close(); 1.292 + do_check_eq(ScriptableInput(p).read(-1), str1); 1.293 + 1.294 + p = Pipe(); 1.295 + DOMSerializer().serializeToStream(doc2, p.outputStream, "ISO-8859-1"); 1.296 + p.outputStream.close(); 1.297 + do_check_eq(ScriptableInput(p).read(-1), str1); 1.298 + 1.299 + p = Pipe(); 1.300 + DOMSerializer().serializeToStream(doc1, p.outputStream, "UTF8"); 1.301 + p.outputStream.close(); 1.302 + do_check_eq(ScriptableInput(p).read(-1), str2); 1.303 + 1.304 + p = Pipe(); 1.305 + DOMSerializer().serializeToStream(doc2, p.outputStream, "UTF8"); 1.306 + p.outputStream.close(); 1.307 + do_check_eq(ScriptableInput(p).read(-1), str2); 1.308 +} 1.309 + 1.310 +function test9() { 1.311 + // Test behavior of serializing between given charsets, using 1.312 + // ISO-8859-1-representable text. 1.313 + var contents = '<root>' + 1.314 + '\u00BD + \u00BE == \u00BD\u00B2 + \u00BC + \u00BE' + 1.315 + '</root>'; 1.316 + var str1 = '<?xml version="1.0" encoding="ISO-8859-1"?>'+ LB + contents; 1.317 + var str2 = '<?xml version="1.0" encoding="UTF8"?>'+ LB + contents; 1.318 + var str3 = '<?xml version="1.0" encoding="UTF-16"?>'+ LB + contents; 1.319 + var doc1 = ParseXML(str1); 1.320 + var doc2 = ParseXML(str2); 1.321 + var doc3 = ParseXML(str3); 1.322 + 1.323 + checkSerialization(doc1, "ISO-8859-1", str1); 1.324 + checkSerialization(doc2, "ISO-8859-1", str1); 1.325 + checkSerialization(doc3, "ISO-8859-1", str1); 1.326 + 1.327 + checkSerialization(doc1, "UTF8", str2); 1.328 + checkSerialization(doc2, "UTF8", str2); 1.329 + checkSerialization(doc3, "UTF8", str2); 1.330 + 1.331 + checkSerialization(doc1, "UTF-16", str3); 1.332 + checkSerialization(doc2, "UTF-16", str3); 1.333 + checkSerialization(doc3, "UTF-16", str3); 1.334 +} 1.335 + 1.336 +function test10() { 1.337 + // Test behavior of serializing between given charsets, using 1.338 + // Unicode characters (XXX but only BMP ones because I don't know 1.339 + // how to create one with non-BMP characters, either with JS strings 1.340 + // or using DOM APIs). 1.341 + var contents = '<root>' + 1.342 + 'AZaz09 \u007F ' + // U+000000 to U+00007F 1.343 + '\u0080 \u0398 \u03BB \u0725 ' + // U+000080 to U+0007FF 1.344 + '\u0964 \u0F5F \u20AC \uFFFB' + // U+000800 to U+00FFFF 1.345 + '</root>'; 1.346 + var str1 = '<?xml version="1.0" encoding="UTF8"?>'+ LB + contents; 1.347 + var str2 = '<?xml version="1.0" encoding="UTF-16"?>'+ LB + contents; 1.348 + var doc1 = ParseXML(str1); 1.349 + var doc2 = ParseXML(str2); 1.350 + 1.351 + checkSerialization(doc1, "UTF8", str1); 1.352 + checkSerialization(doc2, "UTF8", str1); 1.353 + 1.354 + checkSerialization(doc1, "UTF-16", str2); 1.355 + checkSerialization(doc2, "UTF-16", str2); 1.356 +} 1.357 + 1.358 +function checkSerialization(doc, toCharset, expectedString) { 1.359 + var p = Pipe(); 1.360 + DOMSerializer().serializeToStream(doc, p.outputStream, toCharset); 1.361 + p.outputStream.close(); 1.362 + 1.363 + var cin = C["@mozilla.org/intl/converter-input-stream;1"] 1.364 + .createInstance(I.nsIConverterInputStream); 1.365 + cin.init(p.inputStream, toCharset, 1024, 0x0); 1.366 + 1.367 + // compare the first expectedString.length characters for equality 1.368 + var outString = {}; 1.369 + var count = cin.readString(expectedString.length, outString); 1.370 + do_check_true(count == expectedString.length); 1.371 + do_check_true(outString.value == expectedString); 1.372 + 1.373 + // if there's anything more in the stream, it's a bug 1.374 + do_check_eq(0, cin.readString(1, outString)); 1.375 + do_check_eq(outString.value, ""); 1.376 +}