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.

     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;
     8 function run_test() {
    10   if(("@mozilla.org/windows-registry-key;1" in C) || ("nsILocalFileOS2" in I))
    11     LB = "\r\n";
    12   else
    13     LB = "\n";
    15   for (var i = 0; i < tests.length && tests[i]; ++i) {
    16     tests[i].call();
    17   }
    18 }
    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 ];
    34 function testString(str) {
    35   do_check_eq(roundtrip(str), str);
    36 }
    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 }
    55 function test2() {
    56   // Test setting of "xmlns" attribute in the null namespace
    58   // XXXbz are these tests needed?  What should happen here?  These
    59   // may be bogus.
    61   // Setting random "xmlns" attribute
    62   var doc = ParseXML('<root xmlns="ns1"/>');
    63   doc.documentElement.setAttribute("xmlns", "ns2");
    64   do_check_serialize(doc);
    65 }
    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>');
    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>');
    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>');
    95 }
    97 function test4() {
    98   // setAttributeNS tests
   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"/>');
   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"/>');
   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"/>');
   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"/>');
   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 }
   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 }
   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>');
   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>');
   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>');
   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 }
   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/>');
   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>');
   249   doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' +
   250                  '<child1 xmlns=""><child2/></child1></root>')
   251   root = doc.documentElement;
   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>');
   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 }
   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);
   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);
   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);
   296   p = Pipe();
   297   DOMSerializer().serializeToStream(doc1, p.outputStream, "UTF8");
   298   p.outputStream.close();
   299   do_check_eq(ScriptableInput(p).read(-1), str2);
   301   p = Pipe();
   302   DOMSerializer().serializeToStream(doc2, p.outputStream, "UTF8");
   303   p.outputStream.close();
   304   do_check_eq(ScriptableInput(p).read(-1), str2);
   305 }
   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);
   320   checkSerialization(doc1, "ISO-8859-1", str1);
   321   checkSerialization(doc2, "ISO-8859-1", str1);
   322   checkSerialization(doc3, "ISO-8859-1", str1);
   324   checkSerialization(doc1, "UTF8", str2);
   325   checkSerialization(doc2, "UTF8", str2);
   326   checkSerialization(doc3, "UTF8", str2);
   328   checkSerialization(doc1, "UTF-16", str3);
   329   checkSerialization(doc2, "UTF-16", str3);
   330   checkSerialization(doc3, "UTF-16", str3);
   331 }
   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);
   348   checkSerialization(doc1, "UTF8", str1);
   349   checkSerialization(doc2, "UTF8", str1);
   351   checkSerialization(doc1, "UTF-16", str2);
   352   checkSerialization(doc2, "UTF-16", str2);
   353 }
   355 function checkSerialization(doc, toCharset, expectedString) {
   356   var p = Pipe();
   357   DOMSerializer().serializeToStream(doc, p.outputStream, toCharset);
   358   p.outputStream.close();
   360   var cin = C["@mozilla.org/intl/converter-input-stream;1"]
   361              .createInstance(I.nsIConverterInputStream);
   362   cin.init(p.inputStream, toCharset, 1024, 0x0);
   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);
   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 }

mercurial