content/test/unit/test_xml_serializer.js

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial