2 // Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 // Test case for XML ActionScript class
21 // compile this test case with Ming makeswf, and then
22 // execute it like this gnash -1 -r 0 -v out.swf
31 #if OUTPUT_VERSION
< 6
32 XMLNode.prototype
.hasOwnProperty
= ASnative
(101, 5);
35 check
(XMLNode.prototype
.hasOwnProperty
("appendChild"));
36 check
(XMLNode.prototype
.hasOwnProperty
("cloneNode"));
37 check
(XMLNode.prototype
.hasOwnProperty
("hasChildNodes"));
38 check
(XMLNode.prototype
.hasOwnProperty
("insertBefore"));
39 check
(XMLNode.prototype
.hasOwnProperty
("removeNode"));
40 check
(XMLNode.prototype
.hasOwnProperty
("toString"));
42 check
(XMLNode.prototype
.hasOwnProperty
("getPrefixForNamespace"));
43 check
(XMLNode.prototype
.hasOwnProperty
("getNamespaceForPrefix"));
45 check
(XMLNode.prototype
.hasOwnProperty
("firstChild"));
46 check
(XMLNode.prototype
.hasOwnProperty
("lastChild"));
47 check
(XMLNode.prototype
.hasOwnProperty
("namespaceURI"));
48 check
(XMLNode.prototype
.hasOwnProperty
("localName"));
49 check
(XMLNode.prototype
.hasOwnProperty
("attributes"));
50 check
(XMLNode.prototype
.hasOwnProperty
("childNodes"));
51 check
(XMLNode.prototype
.hasOwnProperty
("nextSibling"));
52 check
(XMLNode.prototype
.hasOwnProperty
("nodeName"));
53 check
(XMLNode.prototype
.hasOwnProperty
("nodeType"));
54 check
(XMLNode.prototype
.hasOwnProperty
("nodeValue"));
55 check
(XMLNode.prototype
.hasOwnProperty
("parentNode"));
56 check
(XMLNode.prototype
.hasOwnProperty
("prefix"));
57 check
(XMLNode.prototype
.hasOwnProperty
("previousSibling"));
59 check_equals
(typeof(XMLNode.prototype
.attributes
), "undefined");
64 var textnode
= doc
.createTextNode
("text content");
65 check_equals
(typeOf
(textnode
), 'object');
67 check_equals
(typeof(textnode
.attributes
), "object");
68 check_equals
(textnode
.attributes
.toString
(), undefined);
69 check
(textnode
.appendChild
);
70 check
(textnode
.cloneNode
);
71 check
(textnode
.hasChildNodes
);
72 check
(textnode
.insertBefore
);
73 check
(textnode
.removeNode
);
74 check
(textnode
.toString
);
76 // functionality of the properties
78 textnode
.nodeName
= "foo";
79 check_equals
(textnode
.nodeName
, "foo");
81 check_equals
(textnode
.nodeValue
, "text content");
82 textnode
.nodeValue
= "bar";
83 check_equals
(textnode
.nodeValue
, "bar");
85 // The read only properties. These should all return NULL, because
86 // there are no children.
87 check_equals
(textnode
.hasChildNodes
(), false);
88 check_equals
(typeof(textnode
.firstChild
), 'null');
89 check_equals
(typeof(textnode
.lastChild
), 'null');
90 check_equals
(typeof(textnode
.parentNode
), 'null');
91 check_equals
(typeof(textnode
.nextSibling
), 'null');
92 check_equals
(typeof(textnode
.previousSibling
), 'null');
94 //note("Now test the functionality of the methods");
97 var node1
= doc
.createElement
("node1");
98 var node2
= doc
.createElement
("node2");
99 var textnode1
= doc
.createTextNode
("first text node");
100 var textnode2
= doc
.createTextNode
("second text node");
101 check_equals
(textnode1
.nodeType
, 3);
102 node1
.appendChild
(textnode1
);
103 node2
.appendChild
(textnode2
);
104 node1
.appendChild
(node2
);
105 check_equals
(node1
.hasChildNodes
(), true);
107 check_equals
(node1
.firstChild
.nodeValue
, "first text node");
108 check_equals
(typeof(node1
.lastChild
.nodeValue
), 'null');
109 check_equals
(node2
.lastChild
.toString
(), "second text node");
111 var node3
= doc
.createElement
("node3");
112 var textnode3
= doc
.createTextNode
("third text node");
113 node3
.appendChild
(textnode3
);
114 node1
.appendChild
(node3
);
117 // Childnodes is an array.
118 check_equals
(typeOf
(node1
.childNodes
), "object");
119 check
(node1
.childNodes
.push
);
120 check
(node1
.childNodes instanceOf
Array);
122 // node1 has three children (textnode1, node2, node 3)
123 check_equals
(node1
.childNodes
.length
, 3);
125 // Now it has 4, but the latest element is not an XMLNode
126 node1
.childNodes
.push
("not a node");
127 check_equals
(node1
.childNodes
.length
, 4);
128 check
(!node1
.childNodes
[3] instanceOf
XMLNode);
130 // Now 5. The latest element is an XMLNode, but it does not become
132 node1
.childNodes
.push
(new XMLNode (1, "an XMLNode"));
133 check_equals
(node1
.childNodes
.length
, 5);
134 check
(node1
.childNodes
[4] instanceOf
XMLNode);
135 check_equals
(node1
.lastChild
.toString
(), "<node3>third text node</node3>");
137 // childNodes really is just an array: it can be sorted
138 check_equals
(node1
.childNodes
[0].toString
(), "first text node");
139 check_equals
(node1
.childNodes
[2].toString
(), "<node3>third text node</node3>");
140 check_equals
(node1
.childNodes
[3].toString
(), "not a node");
141 node1
.childNodes
.sort
();
142 xcheck_equals
(node1
.childNodes
[0].toString
(), "<an XMLNode />");
143 check_equals
(node1
.childNodes
[2].toString
(), "<node3>third text node</node3>");
144 check_equals
(node1
.childNodes
[3].toString
(), "first text node");
146 // It can store anything
147 node1
.childNodes
.push
(new Date());
148 check_equals
(node1
.childNodes
.length
, 6);
149 check
(node1
.childNodes
[5] instanceOf
Date);
150 check_equals
(node1
.childNodes
.childNodes
[5].hasChildNodes
(), undefined);
152 node1
.childNodes
.lastChild
.appendChild
(new XMLNode(1, "datenode"));
153 check_equals
(node1
.childNodes
.childNodes
[5].hasChildNodes
(), undefined);
156 o
.toString
= function() {
157 return "o.toString()";
160 check_equals
(node1
.childNodes
.length
, 6);
161 node1
.childNodes
.push
(o
);
162 check_equals
(node1
.childNodes
.length
, 7);
163 check_equals
(node1
.childNodes
[6].toString
(), "o.toString()");
165 // The last child is still node3
166 check
(node1
.lastChild
!= node1
.childNodes
[6]);
167 check_equals
(node1
.lastChild
.nodeName
, "node3");
168 check_equals
(node1
.firstChild
.toString
(), "first text node");
170 // Only when a new valid element is added does the lastChild change, and the 'fake'
172 var node4
= doc
.createElement
("4node");
173 node1
.appendChild
(node4
);
174 check_equals
(node1
.lastChild
.toString
(), "<4node />");
175 check_equals
(node1
.childNodes
.length
, 4);
176 check_equals
(node1
.childNodes
[node1
.childNodes
.length
- 1].toString
(), "<4node />")
178 // And sorting makes no difference to the lastChild, only to the last in the
179 // array of childNodes.
180 node1
.childNodes
.sort
();
181 check_equals
(node1
.lastChild
.toString
(), "<4node />");
182 xcheck_equals
(node1
.childNodes
[node1
.childNodes
.length
- 1].toString
(), "first text node")
187 check_equals
(node1
.firstChild
.nodeValue
, "first text node");
188 check_equals
(typeof(node1
.lastChild
.nodeValue
), 'null');
190 check_equals
(typeof(node1
.firstChild
.nodeName
), "null");
191 check_equals
(node1
.lastChild
.nodeName
, "4node");
193 check_equals
(node2
.previousSibling
.nodeValue
, "first text node");
195 // TODO: test removeNode, insertNode
197 // Test attributes. It's just a normal object.
199 // FIXME: This is how it is now.
200 #if OUTPUT_VERSION
> 5
201 check_equals
(node2
.attributes
, undefined);
203 check_equals
(node2
.attributes
, undefined);
206 check_equals
(typeof(node2
.attributes
), "object");
207 node2
.attributes
[3] = "a3";
208 check_equals
(node2
.attributes
[3], "a3");
209 check_equals
(node2
.attributes
["3"], "a3");
210 node2
.attributes
.a
= "aa";
211 check_equals
(node2
.attributes
.a
, "aa");
212 check_equals
(node2
.attributes
["a"], "aa");
213 check_equals
(node2
.toString
(), '<node2 a="aa" 3="a3">second text node</node2>');
215 // Seems not to be overwritable
216 node2
.attributes
= 3;
217 check_equals
(node2
.toString
(), '<node2 a="aa" 3="a3">second text node</node2>');
219 ASSetPropFlags
(XMLNode.prototype
, "attributes", 0, 1);
220 node77
= doc
.createElement
("tag");
221 node77
.attributes
.a1
= "at1";
222 check_equals
(node77
.toString
(), '<tag a1="at1" />');
223 node77
.attributes
= 5;
224 check_equals
(node77
.toString
(), '<tag a1="at1" />');
226 // Check order of attributes:
228 node77
.attributes
.z
= "z";
229 node77
.attributes
.x
= "x";
230 node77
.attributes
.c
= "c";
231 node77
.attributes
.y
= "y";
232 node77
.attributes
.f
= "f";
233 node77
.attributes
[5] = "5";
234 node77
.attributes
["$"] = "$";
235 node77
.attributes
.x
= "x2";
236 check_equals
(node77
.toString
(), '<tag $="$" 5="5" f="f" y="y" c="c" x="x2" z="z" a1="at1" />');
238 // Check namespace functions.
240 // Standard namespace
241 x
= new XML('<tag xmlns="standard" att="u">text</tag>');
243 check_equals
(ns
.nodeName
, "tag");
244 check_equals
(ns
.attributes
["att"], "u");
245 check_equals
(ns
.attributes
["xmlns"], "standard");
246 check_equals
(ns
.namespaceURI
, "standard");
247 check_equals
(ns
.getNamespaceForPrefix
(), undefined);
248 check_equals
(ns
.getNamespaceForPrefix
(""), "standard");
249 check_equals
(ns
.getPrefixForNamespace
("standard"), "");
251 ns
.attributes
["xmlns"] = "standard2";
252 check_equals
(ns
.namespaceURI
, "standard");
253 check_equals
(ns
.getNamespaceForPrefix
(""), "standard2");
256 check_equals
(ns
.nodeName
, null);
257 check_equals
(ns
.nodeValue
, "text");
258 check_equals
(ns
.namespaceURI
, null);
259 check_equals
(ns
.prefix
, null);
261 x
= new XML('<tag xmlns:t="standard"></tag>');
263 check_equals
(ns
.namespaceURI
, "");
264 check_equals
(ns
.getNamespaceForPrefix
(), undefined);
265 check_equals
(ns
.getNamespaceForPrefix
("t"), "standard");
266 check_equals
(ns
.getPrefixForNamespace
("standard"), "t");
268 x
= new XML('<tag xmlns:t="nst"><tag2 xmlns="nss"><tag3 xmlns:r="nsr"></tag3></tag2></tag>');
271 check_equals
(n
.nodeName
, "tag");
272 check_equals
(n
.namespaceURI
, "");
273 check_equals
(n
.getNamespaceForPrefix
("r"), undefined);
274 check_equals
(n
.getPrefixForNamespace
("nsr"), undefined);
275 check_equals
(n
.getNamespaceForPrefix
(), undefined);
276 check_equals
(n
.getNamespaceForPrefix
("t"), "nst");
277 check_equals
(n
.getPrefixForNamespace
("nst"), "t");
280 check_equals
(n
.nodeName
, "tag2");
281 check_equals
(n
.namespaceURI
, "nss");
282 check_equals
(n
.getNamespaceForPrefix
(), undefined);
283 check_equals
(n
.getNamespaceForPrefix
("r"), undefined);
284 check_equals
(n
.getPrefixForNamespace
("nsr"), undefined);
285 check_equals
(n
.getNamespaceForPrefix
("t"), "nst");
286 check_equals
(n
.getPrefixForNamespace
("nst"), "t");
289 check_equals
(n
.nodeName
, "tag3");
290 check_equals
(n
.namespaceURI
, "nss");
291 check_equals
(n
.getNamespaceForPrefix
(), undefined);
292 check_equals
(n
.getNamespaceForPrefix
("r"), "nsr");
293 check_equals
(n
.getPrefixForNamespace
("nsr"), "r");
294 check_equals
(n
.getNamespaceForPrefix
("t"), "nst");
295 check_equals
(n
.getPrefixForNamespace
("nst"), "t");
297 // Poorly formed prefix namespaces: become standard namespaces
298 x
= new XML('<tag xmlns:="nst"><tag2 xmlns="nss"><tag3 xmlns:="nsr"></tag3></tag2></tag>');
300 n
= x
.firstChild
.firstChild
.firstChild
;
301 check_equals
(n
.nodeName
, "tag3");
302 check_equals
(n
.namespaceURI
, "nsr");
303 check_equals
(n
.getPrefixForNamespace
("nsr"), "");
304 check_equals
(n
.getNamespaceForPrefix
(), undefined);
305 check_equals
(n
.getPrefixForNamespace
("nst"), "");
308 // Multiple definition of standard namespace (first one counts, second never
310 x
= new XML('<tag xmlns="standard" xmlns="standard2"></tag>');
312 check_equals
(ns
.nodeName
, "tag");
313 check_equals
(ns
.attributes
["xmlns"], "standard");
314 check_equals
(ns
.namespaceURI
, "standard");
315 check_equals
(ns
.getNamespaceForPrefix
(""), "standard");
317 check_equals
(ns
.getPrefixForNamespace
("standard"), "");
318 check_equals
(ns
.getPrefixForNamespace
("standard2"), undefined);
320 // Multiple definition of prefix during parsing (first one counts,
321 // second never defined). Can be changed later using attributes.
322 x
= new XML('<tag xmlns:n1="ns1" xmlns:n1="ns2"></tag>');
324 check_equals
(ns
.nodeName
, "tag");
325 check_equals
(ns
.attributes
["xmlns"], undefined);
326 check_equals
(ns
.attributes
["xmlns:n1"], "ns1");
327 check_equals
(ns
.namespaceURI
, "");
328 check_equals
(ns
.getNamespaceForPrefix
("n1"), "ns1");
329 check_equals
(ns
.getPrefixForNamespace
("ns1"), "n1");
330 check_equals
(ns
.getPrefixForNamespace
("ns2"), undefined);
332 ns
.attributes
["xmlns:n1"] = "ns2";
333 check_equals
(ns
.attributes
["xmlns:n1"], "ns2");
334 check_equals
(ns
.getNamespaceForPrefix
("n1"), "ns2");
335 check_equals
(ns
.getPrefixForNamespace
("ns1"), undefined);
336 check_equals
(ns
.getPrefixForNamespace
("ns2"), "n1");
338 // Setting via attributes
339 x
= new XML('<tag></tag>');
341 check_equals
(ns
.nodeName
, "tag");
342 check_equals
(ns
.attributes
["xmlns"], undefined);
343 check_equals
(ns
.namespaceURI
, "");
344 ns
.attributes
["xmlns"] = "nss";
345 check_equals
(ns
.attributes
["xmlns"], "nss");
346 check_equals
(ns
.namespaceURI
, "");
348 /// Prefix, localName
349 x
= new XML('<fr:tag/>');
351 check_equals
(ns
.nodeName
, "fr:tag");
352 check_equals
(ns
.localName
, "tag");
353 check_equals
(ns
.prefix
, "fr");
355 x
= new XML('<fr:pr:tag/>');
357 check_equals
(ns
.nodeName
, "fr:pr:tag");
358 check_equals
(ns
.localName
, "pr:tag");
359 check_equals
(ns
.prefix
, "fr");
361 x
= new XML('<:fr:tag/>');
363 check_equals
(ns
.nodeName
, ":fr:tag");
364 check_equals
(ns
.localName
, "fr:tag");
365 check_equals
(ns
.prefix
, "");
367 x
= new XML('<:tag/>');
369 check_equals
(ns
.nodeName
, ":tag");
370 check_equals
(ns
.localName
, "tag");
371 check_equals
(ns
.prefix
, "");
373 x
= new XML('<tag:/>');
375 check_equals
(ns
.nodeName
, "tag:");
376 check_equals
(ns
.localName
, "tag:");
377 check_equals
(ns
.prefix
, "");
379 x
= new XML('<tag/>');
381 check_equals
(ns
.nodeName
, "tag");
382 check_equals
(ns
.localName
, "tag");
383 check_equals
(ns
.prefix
, "");
385 // xmlDecl and docTypeDecl don't work for XMLNode
386 xn
= new XMLNode(1, "");
387 xn
.xmlDecl
= "hello";
388 xn
.docTypeDecl
= "dtd";
389 check_equals
(xn
.toString
(), "< />");
391 xn
= new XMLNode(2, "");
392 check_equals
(xn
.toString
(), "");
394 xn
= new XMLNode(3, "");
395 check_equals
(xn
.toString
(), "");
397 xn
= new XMLNode(4, "");
398 check_equals
(xn
.toString
(), "");
400 xn
= new XMLNode(5, "");
401 check_equals
(xn
.toString
(), "");
403 xn
= new XMLNode(6, "");
404 check_equals
(xn
.toString
(), "");
406 xn
= new XMLNode(7, "");
407 check_equals
(xn
.toString
(), "");
409 // Test for https://savannah.gnu.org/bugs/index.php?39404
410 // NOTE: you need to run under valgrind to determine
411 // if the test was successful or not...
412 x
= new XML('<t></t>'); x
.appendChild
(new XML('<t></t>'));
413 var x2
= new XML('<t></t>'); x2
.appendChild
(x
); delete x2
;
415 // many allocations force GC run
416 for (var i
=0; i
<256; ++i
) x
= {};
418 // Test infinite loop: https://savannah.gnu.org/bugs/index.php?40440
419 // will crash when affected
420 xl1
= new XML('<t></t>');
421 xl2
= new XML('<t></t>');
422 xl1
.appendChild
(xl2
);
423 xl2
.appendChild
(xl1
);
425 check_equals
(xl2
.parentNode
, xl1
);
426 check_equals
(xl1
.parentNode
, null); // Nothing happened.
428 doc
= new XML('<t></t>');
429 parent
= doc
.createElement
("parent");
430 child
= doc
.createElement
("child");
431 parent
.appendChild
(child
);
432 doc
.appendChild
(parent
);
434 check_equals
(doc
.toString
(), "<t /><parent><child /></parent>");
436 child
.appendChild
(parent
);
437 check_equals
(doc
.toString
(), "<t /><parent><child /></parent>");
438 check_equals
(child
.hasChildNodes
(), false);
440 sibling
= doc
.createElement
("sibling");
441 parent
.insertBefore
(sibling
, child
);
442 check_equals
(doc
.toString
(), "<t /><parent><sibling /><child /></parent>");
443 doc
.insertBefore
(sibling
, parent
); // Should move sibling
444 check_equals
(doc
.toString
(), "<t /><sibling /><parent><child /></parent>");
445 parent
.appendChild
(sibling
);
446 check_equals
(doc
.toString
(), "<t /><parent><child /><sibling /></parent>");
447 parent
.appendChild
(parent
);
448 check_equals
(doc
.toString
(), "<t /><parent><child /><sibling /></parent>");
449 child
.appendChild
(parent
);
450 check_equals
(doc
.toString
(), "<t /><parent><child /><sibling /></parent>");
451 grandchild
= doc
.createElement
("grandchild");
452 child
.appendChild
(grandchild
);
453 check_equals
(doc
.toString
(), "<t /><parent><child><grandchild /></child><sibling /></parent>");
454 child
.appendChild
(parent
);
455 check_equals
(doc
.toString
(), "<t /><parent><child><grandchild /></child><sibling /></parent>");
456 child
.insertBefore
(child
, parent
);
457 check_equals
(doc
.toString
(), "<t /><parent><child><grandchild /></child><sibling /></parent>");
458 grandchild
.appendChild
(parent
);
459 check_equals
(doc
.toString
(), "<t /><parent><child><grandchild /></child><sibling /></parent>");
460 grandchild
.insertBefore
(grandchild
, parent
);
461 check_equals
(doc
.toString
(), "<t /><parent><child><grandchild /></child><sibling /></parent>");
462 grandchild
.insertBefore
(grandchild
, child
);
463 check_equals
(doc
.toString
(), "<t /><parent><child><grandchild /></child><sibling /></parent>");
465 doc1
= new XML("<t />");
466 doc1
.appendChild
(parent
);
467 check_equals
(doc1
.toString
(), "<t /><parent><child><grandchild /></child><sibling /></parent>");
468 check_equals
(doc
.toString
(), "<t />");
469 doc1
.appendChild
(child
);
470 check_equals
(doc1
.toString
(), "<t /><parent><sibling /></parent><child><grandchild /></child>");