2008-10-22 00:30:09 +04:00
|
|
|
|
|
|
|
// The xml serializer uses the default line break of the plateform.
|
|
|
|
// So we need to know the value of this default line break, in order
|
|
|
|
// to build correctly the reference strings for tests.
|
|
|
|
// This variable will contain this value.
|
|
|
|
var LB;
|
|
|
|
|
2005-11-29 19:24:42 +03:00
|
|
|
function run_test() {
|
2008-10-22 00:30:09 +04:00
|
|
|
|
|
|
|
if(("@mozilla.org/windows-registry-key;1" in C) || ("nsILocalFileOS2" in I))
|
|
|
|
LB = "\r\n";
|
|
|
|
else
|
|
|
|
LB = "\n";
|
|
|
|
|
2005-11-29 19:24:42 +03:00
|
|
|
for (var i = 0; i < tests.length && tests[i]; ++i) {
|
|
|
|
tests[i].call();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var tests = [
|
|
|
|
test1,
|
|
|
|
test2,
|
|
|
|
test3,
|
|
|
|
test4,
|
|
|
|
test5,
|
|
|
|
test6,
|
2006-02-18 16:01:59 +03:00
|
|
|
test7,
|
2006-11-30 09:39:47 +03:00
|
|
|
test8,
|
2007-01-29 23:05:07 +03:00
|
|
|
test9,
|
|
|
|
test10,
|
2005-11-29 19:24:42 +03:00
|
|
|
null
|
|
|
|
];
|
|
|
|
|
|
|
|
function testString(str) {
|
|
|
|
do_check_eq(roundtrip(str), str);
|
|
|
|
}
|
|
|
|
|
|
|
|
function test1() {
|
|
|
|
// Basic round-tripping which we expect to hand back the same text
|
|
|
|
// as we passed in (not strictly required for correctness in some of
|
|
|
|
// those cases, but best for readability of serializer output)
|
|
|
|
testString('<root/>');
|
|
|
|
testString('<root><child/></root>');
|
|
|
|
testString('<root xmlns=""/>');
|
|
|
|
testString('<root xml:lang="en"/>');
|
|
|
|
testString('<root xmlns="ns1"><child xmlns="ns2"/></root>')
|
|
|
|
testString('<root xmlns="ns1"><child xmlns=""/></root>')
|
|
|
|
testString('<a:root xmlns:a="ns1"><child/></a:root>')
|
|
|
|
testString('<a:root xmlns:a="ns1"><a:child/></a:root>')
|
|
|
|
testString('<a:root xmlns:a="ns1"><b:child xmlns:b="ns1"/></a:root>')
|
|
|
|
testString('<a:root xmlns:a="ns1"><a:child xmlns:a="ns2"/></a:root>')
|
|
|
|
testString('<a:root xmlns:a="ns1"><b:child xmlns:b="ns1" b:attr=""/></a:root>')
|
|
|
|
}
|
|
|
|
|
|
|
|
function test2() {
|
|
|
|
// Test setting of "xmlns" attribute in the null namespace
|
|
|
|
|
|
|
|
// XXXbz are these tests needed? What should happen here? These
|
|
|
|
// may be bogus.
|
|
|
|
|
|
|
|
// Setting random "xmlns" attribute
|
|
|
|
var doc = ParseXML('<root xmlns="ns1"/>');
|
|
|
|
doc.documentElement.setAttribute("xmlns", "ns2");
|
|
|
|
do_check_serialize(doc);
|
|
|
|
}
|
|
|
|
|
|
|
|
function test3() {
|
|
|
|
// Test basic appending of kids. Again, we're making assumptions
|
|
|
|
// about how our serializer will serialize simple DOMs.
|
|
|
|
var doc = ParseXML('<root xmlns="ns1"/>');
|
|
|
|
var root = doc.documentElement;
|
|
|
|
var child = doc.createElementNS("ns2", "child");
|
|
|
|
root.appendChild(child);
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<root xmlns="ns1"><child xmlns="ns2"/></root>');
|
|
|
|
|
|
|
|
doc = ParseXML('<root xmlns="ns1"/>');
|
|
|
|
root = doc.documentElement;
|
|
|
|
child = doc.createElementNS("ns2", "prefix:child");
|
|
|
|
root.appendChild(child);
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<root xmlns="ns1"><prefix:child xmlns:prefix="ns2"/></root>');
|
|
|
|
|
|
|
|
doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>');
|
|
|
|
root = doc.documentElement;
|
|
|
|
child = doc.createElementNS("ns2", "prefix:child");
|
|
|
|
root.appendChild(child);
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<prefix:root xmlns:prefix="ns1"><a0:child xmlns:a0="ns2"/>'+
|
|
|
|
'</prefix:root>');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function test4() {
|
|
|
|
// setAttributeNS tests
|
|
|
|
|
|
|
|
var doc = ParseXML('<root xmlns="ns1"/>');
|
|
|
|
var root = doc.documentElement;
|
|
|
|
root.setAttributeNS("ns1", "prefix:local", "val");
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<root xmlns="ns1" prefix:local="val" xmlns:prefix="ns1"/>');
|
|
|
|
|
|
|
|
doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>');
|
|
|
|
root = doc.documentElement;
|
|
|
|
root.setAttributeNS("ns1", "local", "val");
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<prefix:root xmlns:prefix="ns1" prefix:local="val"/>');
|
|
|
|
|
|
|
|
doc = ParseXML('<root xmlns="ns1"/>');
|
|
|
|
root = doc.documentElement;
|
|
|
|
root.setAttributeNS("ns2", "local", "val");
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<root xmlns="ns1" a0:local="val" xmlns:a0="ns2"/>');
|
|
|
|
|
|
|
|
// Handling of prefix-generation for non-null-namespace attributes
|
|
|
|
// which have the same namespace as the current default namespace
|
|
|
|
// (bug 301260).
|
|
|
|
doc = ParseXML('<root xmlns="ns1"/>');
|
|
|
|
root = doc.documentElement;
|
|
|
|
root.setAttributeNS("ns1", "local", "val");
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<root xmlns="ns1" a0:local="val" xmlns:a0="ns1"/>');
|
|
|
|
|
|
|
|
// Tree-walking test
|
|
|
|
doc = ParseXML('<root xmlns="ns1" xmlns:a="ns2">'+
|
|
|
|
'<child xmlns:b="ns2" xmlns:a="ns3">'+
|
|
|
|
'<child2/></child></root>');
|
|
|
|
root = doc.documentElement;
|
|
|
|
// Have to QI here -- no classinfo flattening in xpcshell, apparently
|
|
|
|
var node = root.firstChild.firstChild.QueryInterface(nsIDOMElement);
|
|
|
|
node.setAttributeNS("ns4", "l1", "v1");
|
|
|
|
node.setAttributeNS("ns4", "p2:l2", "v2");
|
2006-05-09 21:02:00 +04:00
|
|
|
node.setAttributeNS("", "l3", "v3");
|
2005-11-29 19:24:42 +03:00
|
|
|
node.setAttributeNS("ns3", "l4", "v4");
|
|
|
|
node.setAttributeNS("ns3", "p5:l5", "v5");
|
|
|
|
node.setAttributeNS("ns3", "a:l6", "v6");
|
|
|
|
node.setAttributeNS("ns2", "l7", "v7");
|
|
|
|
node.setAttributeNS("ns2", "p8:l8", "v8");
|
|
|
|
node.setAttributeNS("ns2", "b:l9", "v9");
|
|
|
|
node.setAttributeNS("ns2", "a:l10", "v10");
|
|
|
|
node.setAttributeNS("ns1", "a:l11", "v11");
|
|
|
|
node.setAttributeNS("ns1", "b:l12", "v12");
|
|
|
|
node.setAttributeNS("ns1", "l13", "v13");
|
|
|
|
do_check_serialize(doc);
|
|
|
|
// Note: we end up with "a2" as the prefix on "l11" and "l12" because we use
|
|
|
|
// "a1" earlier, and discard it in favor of something we get off the
|
|
|
|
// namespace stack, apparently
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<root xmlns="ns1" xmlns:a="ns2">'+
|
|
|
|
'<child xmlns:b="ns2" xmlns:a="ns3">'+
|
|
|
|
'<child2 a0:l1="v1" xmlns:a0="ns4"' +
|
|
|
|
' a0:l2="v2"' +
|
|
|
|
' l3="v3"' +
|
|
|
|
' a:l4="v4"' +
|
|
|
|
' a:l5="v5"' +
|
|
|
|
' a:l6="v6"' +
|
|
|
|
' b:l7="v7"' +
|
|
|
|
' b:l8="v8"' +
|
|
|
|
' b:l9="v9"' +
|
|
|
|
' b:l10="v10"' +
|
|
|
|
' a2:l11="v11" xmlns:a2="ns1"' +
|
|
|
|
' a2:l12="v12"' +
|
|
|
|
' a2:l13="v13"/></child></root>');
|
|
|
|
}
|
|
|
|
|
|
|
|
function test5() {
|
|
|
|
// Handling of kids in the null namespace when the default is a
|
|
|
|
// different namespace (bug 301260).
|
|
|
|
var doc = ParseXML('<root xmlns="ns1"/>')
|
|
|
|
var child = doc.createElement('child');
|
|
|
|
doc.documentElement.appendChild(child);
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<root xmlns="ns1"><child xmlns=""/></root>');
|
|
|
|
}
|
|
|
|
|
|
|
|
function test6() {
|
|
|
|
// Handling of not using a namespace prefix (or default namespace!)
|
|
|
|
// that's not bound to our namespace in our scope (bug 301260).
|
|
|
|
var doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>');
|
|
|
|
var root = doc.documentElement;
|
|
|
|
var child1 = doc.createElementNS("ns2", "prefix:child1");
|
|
|
|
var child2 = doc.createElementNS("ns1", "prefix:child2");
|
|
|
|
child1.appendChild(child2);
|
|
|
|
root.appendChild(child1);
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<prefix:root xmlns:prefix="ns1"><a0:child1 xmlns:a0="ns2">'+
|
|
|
|
'<prefix:child2/></a0:child1></prefix:root>');
|
|
|
|
|
|
|
|
doc = ParseXML('<root xmlns="ns1"><prefix:child1 xmlns:prefix="ns2"/></root>');
|
|
|
|
root = doc.documentElement;
|
|
|
|
child1 = root.firstChild;
|
|
|
|
child2 = doc.createElementNS("ns1", "prefix:child2");
|
|
|
|
child1.appendChild(child2);
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<root xmlns="ns1"><prefix:child1 xmlns:prefix="ns2">'+
|
|
|
|
'<child2/></prefix:child1></root>');
|
|
|
|
|
|
|
|
doc = ParseXML('<prefix:root xmlns:prefix="ns1">'+
|
|
|
|
'<prefix:child1 xmlns:prefix="ns2"/></prefix:root>');
|
|
|
|
root = doc.documentElement;
|
|
|
|
child1 = root.firstChild;
|
|
|
|
child2 = doc.createElementNS("ns1", "prefix:child2");
|
|
|
|
child1.appendChild(child2);
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<prefix:root xmlns:prefix="ns1"><prefix:child1 xmlns:prefix="ns2">'+
|
|
|
|
'<a0:child2 xmlns:a0="ns1"/></prefix:child1></prefix:root>');
|
|
|
|
|
|
|
|
|
|
|
|
doc = ParseXML('<root xmlns="ns1"/>');
|
|
|
|
root = doc.documentElement;
|
|
|
|
child1 = doc.createElementNS("ns2", "child1");
|
|
|
|
child2 = doc.createElementNS("ns1", "child2");
|
|
|
|
child1.appendChild(child2);
|
|
|
|
root.appendChild(child1);
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<root xmlns="ns1"><child1 xmlns="ns2"><child2 xmlns="ns1"/>'+
|
|
|
|
'</child1></root>');
|
|
|
|
}
|
2006-02-18 16:01:59 +03:00
|
|
|
|
|
|
|
function test7() {
|
|
|
|
// Handle xmlns attribute declaring a default namespace on a non-namespaced
|
|
|
|
// element (bug 326994).
|
|
|
|
var doc = ParseXML('<root xmlns=""/>')
|
|
|
|
var root = doc.documentElement;
|
|
|
|
root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
|
|
|
|
"http://www.w3.org/1999/xhtml");
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc), '<root/>');
|
|
|
|
|
|
|
|
doc = ParseXML('<root xmlns=""><child1/></root>')
|
|
|
|
root = doc.documentElement;
|
|
|
|
root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
|
|
|
|
"http://www.w3.org/1999/xhtml");
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc), '<root><child1/></root>');
|
|
|
|
|
|
|
|
doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' +
|
|
|
|
'<child1 xmlns=""><child2/></child1></root>')
|
|
|
|
root = doc.documentElement;
|
2006-05-09 21:02:00 +04:00
|
|
|
|
|
|
|
// No interface flattening in xpcshell
|
|
|
|
var child1 = root.firstChild.QueryInterface(nsIDOMElement);
|
2006-02-18 16:01:59 +03:00
|
|
|
child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
|
|
|
|
"http://www.w3.org/1999/xhtml");
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' +
|
|
|
|
'<child2/></child1></root>');
|
|
|
|
|
|
|
|
doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' +
|
|
|
|
'<child1 xmlns="">' +
|
2009-09-28 11:59:52 +04:00
|
|
|
'<child2 xmlns="http://www.w3.org/1999/xhtml"></child2>' +
|
2006-02-18 16:01:59 +03:00
|
|
|
'</child1></root>')
|
|
|
|
root = doc.documentElement;
|
2006-05-09 21:02:00 +04:00
|
|
|
// No interface flattening in xpcshell
|
|
|
|
child1 = root.firstChild.QueryInterface(nsIDOMElement);
|
|
|
|
var child2 = child1.firstChild.QueryInterface(nsIDOMElement);
|
2006-02-18 16:01:59 +03:00
|
|
|
child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
|
|
|
|
"http://www.w3.org/1999/xhtml");
|
|
|
|
child2.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "");
|
|
|
|
do_check_serialize(doc);
|
|
|
|
do_check_eq(SerializeXML(doc),
|
|
|
|
'<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' +
|
2009-09-28 11:59:52 +04:00
|
|
|
'<a0:child2 xmlns:a0="http://www.w3.org/1999/xhtml" xmlns=""></a0:child2></child1></root>');
|
2006-02-18 16:01:59 +03:00
|
|
|
}
|
2006-11-30 09:39:47 +03:00
|
|
|
|
|
|
|
function test8() {
|
|
|
|
// Test behavior of serializing with a given charset.
|
2008-10-22 00:30:09 +04:00
|
|
|
var str1 = '<?xml version="1.0" encoding="ISO-8859-1"?>'+LB+'<root/>';
|
|
|
|
var str2 = '<?xml version="1.0" encoding="UTF8"?>'+LB+'<root/>';
|
2006-11-30 09:39:47 +03:00
|
|
|
var doc1 = ParseXML(str1);
|
|
|
|
var doc2 = ParseXML(str2);
|
|
|
|
|
|
|
|
var p = Pipe();
|
|
|
|
DOMSerializer().serializeToStream(doc1, p.outputStream, "ISO-8859-1");
|
|
|
|
p.outputStream.close();
|
|
|
|
do_check_eq(ScriptableInput(p).read(-1), str1);
|
|
|
|
|
|
|
|
p = Pipe();
|
|
|
|
DOMSerializer().serializeToStream(doc2, p.outputStream, "ISO-8859-1");
|
|
|
|
p.outputStream.close();
|
|
|
|
do_check_eq(ScriptableInput(p).read(-1), str1);
|
|
|
|
|
|
|
|
p = Pipe();
|
|
|
|
DOMSerializer().serializeToStream(doc1, p.outputStream, "UTF8");
|
|
|
|
p.outputStream.close();
|
|
|
|
do_check_eq(ScriptableInput(p).read(-1), str2);
|
|
|
|
|
|
|
|
p = Pipe();
|
|
|
|
DOMSerializer().serializeToStream(doc2, p.outputStream, "UTF8");
|
|
|
|
p.outputStream.close();
|
|
|
|
do_check_eq(ScriptableInput(p).read(-1), str2);
|
|
|
|
}
|
2007-01-29 23:05:07 +03:00
|
|
|
|
|
|
|
function test9() {
|
|
|
|
// Test behavior of serializing between given charsets, using
|
|
|
|
// ISO-8859-1-representable text.
|
|
|
|
var contents = '<root>' +
|
|
|
|
'\u00BD + \u00BE == \u00BD\u00B2 + \u00BC + \u00BE' +
|
|
|
|
'</root>';
|
2008-10-22 00:30:09 +04:00
|
|
|
var str1 = '<?xml version="1.0" encoding="ISO-8859-1"?>'+ LB + contents;
|
|
|
|
var str2 = '<?xml version="1.0" encoding="UTF8"?>'+ LB + contents;
|
|
|
|
var str3 = '<?xml version="1.0" encoding="UTF-16"?>'+ LB + contents;
|
2007-01-29 23:05:07 +03:00
|
|
|
var doc1 = ParseXML(str1);
|
|
|
|
var doc2 = ParseXML(str2);
|
|
|
|
var doc3 = ParseXML(str3);
|
|
|
|
|
|
|
|
checkSerialization(doc1, "ISO-8859-1", str1);
|
|
|
|
checkSerialization(doc2, "ISO-8859-1", str1);
|
|
|
|
checkSerialization(doc3, "ISO-8859-1", str1);
|
|
|
|
|
|
|
|
checkSerialization(doc1, "UTF8", str2);
|
|
|
|
checkSerialization(doc2, "UTF8", str2);
|
|
|
|
checkSerialization(doc3, "UTF8", str2);
|
|
|
|
|
|
|
|
checkSerialization(doc1, "UTF-16", str3);
|
|
|
|
checkSerialization(doc2, "UTF-16", str3);
|
|
|
|
checkSerialization(doc3, "UTF-16", str3);
|
|
|
|
}
|
|
|
|
|
|
|
|
function test10() {
|
|
|
|
// Test behavior of serializing between given charsets, using
|
|
|
|
// Unicode characters (XXX but only BMP ones because I don't know
|
|
|
|
// how to create one with non-BMP characters, either with JS strings
|
|
|
|
// or using DOM APIs).
|
|
|
|
var contents = '<root>' +
|
|
|
|
'AZaz09 \u007F ' + // U+000000 to U+00007F
|
|
|
|
'\u0080 \u0398 \u03BB \u0725 ' + // U+000080 to U+0007FF
|
|
|
|
'\u0964 \u0F5F \u20AC \uFFFB' + // U+000800 to U+00FFFF
|
|
|
|
'</root>';
|
2008-10-22 00:30:09 +04:00
|
|
|
var str1 = '<?xml version="1.0" encoding="UTF8"?>'+ LB + contents;
|
|
|
|
var str2 = '<?xml version="1.0" encoding="UTF-16"?>'+ LB + contents;
|
2007-01-29 23:05:07 +03:00
|
|
|
var doc1 = ParseXML(str1);
|
|
|
|
var doc2 = ParseXML(str2);
|
|
|
|
|
|
|
|
checkSerialization(doc1, "UTF8", str1);
|
|
|
|
checkSerialization(doc2, "UTF8", str1);
|
|
|
|
|
|
|
|
checkSerialization(doc1, "UTF-16", str2);
|
|
|
|
checkSerialization(doc2, "UTF-16", str2);
|
|
|
|
}
|
|
|
|
|
|
|
|
function checkSerialization(doc, toCharset, expectedString) {
|
|
|
|
var p = Pipe();
|
|
|
|
DOMSerializer().serializeToStream(doc, p.outputStream, toCharset);
|
|
|
|
p.outputStream.close();
|
|
|
|
|
|
|
|
var cin = C["@mozilla.org/intl/converter-input-stream;1"]
|
|
|
|
.createInstance(I.nsIConverterInputStream);
|
|
|
|
cin.init(p.inputStream, toCharset, 1024, 0x0);
|
|
|
|
|
|
|
|
// compare the first expectedString.length characters for equality
|
|
|
|
var outString = {};
|
|
|
|
var count = cin.readString(expectedString.length, outString);
|
|
|
|
do_check_true(count == expectedString.length);
|
|
|
|
do_check_true(outString.value == expectedString);
|
|
|
|
|
|
|
|
// if there's anything more in the stream, it's a bug
|
|
|
|
do_check_eq(0, cin.readString(1, outString));
|
|
|
|
do_check_eq(outString.value, "");
|
|
|
|
}
|