1//
2//   Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software
3//   Foundation, Inc
4//
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.
9//
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.
14//
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
18//
19
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
23
24
25rcsid="XML.as";
26#include "check.as"
27//#include "dejagnu.as"
28#include "utils.as"
29
30#if OUTPUT_VERSION < 6
31Object.prototype.hasOwnProperty = ASnative(101, 5);
32#endif
33
34var existtests = true;
35
36check(XML);
37
38check(! XML.prototype.hasOwnProperty("appendChild") );
39check(! XML.prototype.hasOwnProperty("cloneNode") );
40check(! XML.prototype.hasOwnProperty("hasChildNodes") );
41check(! XML.prototype.hasOwnProperty("insertBefore") );
42check(! XML.prototype.hasOwnProperty("removeNode") );
43check(! XML.prototype.hasOwnProperty("cloneNode") );
44check(! XML.prototype.hasOwnProperty("toString") );
45check(! XML.prototype.hasOwnProperty("length") );
46check(! XML.prototype.hasOwnProperty("status"));
47check(! XML.prototype.hasOwnProperty("loaded"));
48check(! XML.prototype.hasOwnProperty("attributes"));
49check(! XML.prototype.hasOwnProperty("nodeValue"));
50check(XML.prototype.hasOwnProperty("onData"));
51check(XML.prototype.hasOwnProperty("onLoad")); // it seems it wouldn't do anything anyway, would it ?
52check(XML.prototype.hasOwnProperty("createElement") );
53check(XML.prototype.hasOwnProperty("addRequestHeader") );
54check(XML.prototype.hasOwnProperty("createTextNode") );
55check(XML.prototype.hasOwnProperty("getBytesLoaded") );
56check(XML.prototype.hasOwnProperty("getBytesTotal") );
57check(!XML.prototype.hasOwnProperty("_bytesTotal") );
58check(!XML.prototype.hasOwnProperty("_bytesLoaded") );
59check(XML.prototype.hasOwnProperty("load") );
60check(XML.prototype.hasOwnProperty("parseXML") );
61check(XML.prototype.hasOwnProperty("send") );
62check(XML.prototype.hasOwnProperty("sendAndLoad") );
63
64check(!XML.prototype.hasOwnProperty("docTypeDecl") );
65check(!XML.prototype.hasOwnProperty("xmlDecl") );
66// ignoreWhite is undefined by default, but is used when set to true
67check(!XML.prototype.hasOwnProperty("ignoreWhite") );
68
69check(!XML.hasOwnProperty("createElement") );
70check(!XML.hasOwnProperty("addRequestHeader") );
71check(!XML.hasOwnProperty("createTextNode") );
72check(!XML.hasOwnProperty("getBytesLoaded") );
73check(!XML.hasOwnProperty("getBytesTotal") );
74check(!XML.hasOwnProperty("load") );
75check(!XML.hasOwnProperty("parseXML") );
76check(!XML.hasOwnProperty("send") );
77check(!XML.hasOwnProperty("sendAndLoad") );
78check(!XML.hasOwnProperty("nodeValue"));
79check(!XML.hasOwnProperty("_customHeaders"));
80check(!XML.hasOwnProperty("docTypeDecl") );
81check(!XML.hasOwnProperty("xmlDecl") );
82
83check(XMLNode.prototype.hasOwnProperty("appendChild") );
84check(XMLNode.prototype.hasOwnProperty("cloneNode") );
85check(XMLNode.prototype.hasOwnProperty("hasChildNodes") );
86check(XMLNode.prototype.hasOwnProperty("insertBefore") );
87check(XMLNode.prototype.hasOwnProperty("removeNode") );
88check(XMLNode.prototype.hasOwnProperty("toString") );
89check(XMLNode.prototype.hasOwnProperty("cloneNode") );
90check(XMLNode.prototype.hasOwnProperty("attributes") );
91check(XMLNode.prototype.hasOwnProperty("parentNode") );
92check(XMLNode.prototype.hasOwnProperty("nodeValue"));
93check(! XMLNode.prototype.hasOwnProperty("onData") );
94check(! XMLNode.prototype.hasOwnProperty("length") );
95check(! XMLNode.prototype.hasOwnProperty("createElement") );
96check(! XMLNode.prototype.hasOwnProperty("addRequestHeader") );
97check(! XMLNode.prototype.hasOwnProperty("createTextNode") );
98check(! XMLNode.prototype.hasOwnProperty("getBytesLoaded") );
99check(! XMLNode.prototype.hasOwnProperty("getBytesTotal") );
100check(! XMLNode.prototype.hasOwnProperty("load") );
101check(! XMLNode.prototype.hasOwnProperty("parseXML") );
102check(! XMLNode.prototype.hasOwnProperty("send") );
103check(! XMLNode.prototype.hasOwnProperty("sendAndLoad") );
104check(! XMLNode.prototype.hasOwnProperty("status"));
105check(! XMLNode.prototype.hasOwnProperty("loaded"));
106
107check(! XMLNode.hasOwnProperty("appendChild") );
108check(! XMLNode.hasOwnProperty("cloneNode") );
109check(! XMLNode.hasOwnProperty("hasChildNodes") );
110check(! XMLNode.hasOwnProperty("insertBefore") );
111check(! XMLNode.hasOwnProperty("removeNode") );
112check(! XMLNode.hasOwnProperty("toString") );
113check(! XMLNode.hasOwnProperty("cloneNode") );
114check(! XMLNode.hasOwnProperty("nodeValue"));
115
116check(XML.prototype instanceof XMLNode);
117
118var tmp = new XML();
119
120
121// These properties are added to the prototype here.
122check(!tmp.hasOwnProperty("docTypeDecl") );
123check(!tmp.hasOwnProperty("xmlDecl") );
124check(XML.prototype.hasOwnProperty("docTypeDecl") );
125check(XML.prototype.hasOwnProperty("xmlDecl") );
126check(XML.prototype.hasOwnProperty("contentType") );
127check(XML.prototype.hasOwnProperty("ignoreWhite") );
128
129#if OUTPUT_VERSION >= 6
130 check( ! tmp.hasOwnProperty("nodeValue") );
131#endif
132
133check(tmp instanceof XML);
134check(tmp instanceof XMLNode);
135
136check_equals(typeof(tmp.length), 'undefined');
137check(! tmp.hasOwnProperty("length"));
138
139check_equals(typeof(tmp.status), 'number');
140check(! tmp.hasOwnProperty("status"));
141check(tmp.__proto__.hasOwnProperty('status') );
142
143tmp = new XML();
144
145// These are added on construction
146check(tmp.__proto__.hasOwnProperty("status"));
147check(tmp.__proto__.hasOwnProperty("loaded"));
148
149// These aren't
150check(!tmp.__proto__.hasOwnProperty("toString"));
151check(!tmp.hasOwnProperty("toString"));
152
153/// Setting status always results in a number.
154check_equals(tmp.status, 0);
155tmp.status = -1;
156check_equals(tmp.status, -1);
157tmp.status = 1000;
158check_equals(tmp.status, 1000);
159o = new Object;
160tmp.status = o;
161check_equals(typeof(tmp.status), 'number');
162check_equals(tmp.status, -2147483648.0); // 0xFFFFFFFF
163tmp.status = 7;
164check_equals(tmp.status, 7);
165
166returnFour = function() { return 4; };
167o.toString = returnFour;
168tmp.status = o;
169check_equals(typeof(tmp.status), 'number');
170check_equals(tmp.status, -2147483648.0); // 0xFFFFFFFF
171
172o.valueOf = function() { return 5; };
173tmp.status = o;
174check_equals(typeof(tmp.status), 'number');
175check_equals(tmp.status, 5);
176
177tmp.status = 34e+45;
178check_equals(typeof(tmp.status), 'number');
179check_equals(tmp.status, -2147483648.0); // 0xFFFFFFFF
180
181tmp.status = -100000;
182check_equals(tmp.status, -100000);
183
184check_equals(typeof(tmp.loaded), 'undefined');
185check(! tmp.hasOwnProperty("loaded"));
186
187tmp.loaded = 5;
188check_equals(typeof(tmp.loaded), 'boolean');
189check(tmp.loaded);
190tmp.loaded = 0;
191check_equals(typeof(tmp.loaded), 'boolean');
192check(!tmp.loaded);
193check(! tmp.hasOwnProperty("loaded"));
194check(tmp.__proto__.hasOwnProperty("loaded"));
195
196tmp.loaded = true;
197check_equals(tmp.loaded, true);
198check_equals(tmp.__proto__.loaded, undefined);
199
200// test the XML constuctor
201if (tmp) {
202    pass("XML::XML() constructor");
203} else {
204    fail("XML::XML()");
205}
206
207check(XML);
208
209if (existtests) {
210
211    // test the XML::addrequestheader method
212    if (tmp.addRequestHeader) {
213        pass("XML::addRequestHeader() exists");
214    } else {
215        fail("XML::addRequestHeader() doesn't exist");
216    }
217// test the XML::appendchild method
218    if (tmp.appendChild) {
219	pass("XML::appendChild() exists");
220    } else {
221	fail("XML::appendChild() doesn't exist");
222    }
223// test the XML::clonenode method
224    if (tmp.cloneNode) {
225	pass("XML::cloneNode() exists");
226    } else {
227	fail("XML::cloneNode() doesn't exist");
228    }
229// test the XML::createelement method
230    if (tmp.createElement) {
231	pass("XML::createElement() exists");
232    } else {
233	fail("XML::createElement() doesn't exist");
234    }
235// test the XML::createtextnode method
236    if (tmp.createTextNode) {
237	pass("XML::createTextNode() exists");
238    } else {
239	fail("XML::createTextNode() doesn't exist");
240    }
241// test the XML::getbytesloaded method
242    if (tmp.getBytesLoaded) {
243        pass("XML::getBytesLoaded() exists");
244    } else {
245        fail("XML::getBytesLoaded() doesn't exist");
246    }
247// test the XML::getbytestotal method
248    if (tmp.getBytesTotal) {
249	pass("XML::getBytesTotal() exists");
250    } else {
251	fail("XML::getBytesTotal() doesn't exist");
252    }
253// test the XML::haschildnodes method
254    if (tmp.hasChildNodes) {
255	pass("XML::hasChildNodes() exists");
256    } else {
257	fail("XML::hasChildNodes() doesn't exist");
258    }
259// test the XML::insertbefore method
260    if (tmp.insertBefore) {
261	pass("XML::insertBefore() exists");
262    } else {
263	fail("XML::insertBefore() doesn't exist");
264    }
265// test the XML::load method
266    if (tmp.load) {
267	pass("XML::load() exists");
268    } else {
269	fail("XML::load() doesn't exist");
270    }
271// This doesn't seem to exist in the real player
272// test the XML::loaded method
273    if (tmp.loaded) {
274	unresolved("XML::loaded() exists, it shouldn't!");
275    } else {
276	unresolved("XML::loaded() doesn't exist yet");
277    }
278
279//test the XML::parse method
280    if (tmp.parseXML) {
281	pass("XML::parseXML() exists");
282    } else {
283	fail("XML::parseXML() doesn't exist");
284    }
285// test the XML::removenode method
286    if (tmp.removeNode) {
287	pass("XML::removeNode() exists");
288    } else {
289	fail("XML::removeNode() doesn't exist");
290    }
291// test the XML::send method
292    if (tmp.send) {
293	pass("XML::send() exists");
294    } else {
295	fail("XML::send() doesn't exist");
296    }
297// test the XML::sendandload method
298    if (tmp.sendAndLoad) {
299	pass("XML::sendAndLoad() exists");
300    } else {
301	fail("XML::sendAndLoad() doesn't exist");
302    }
303// test the XML::tostring method
304    if (tmp.toString) {
305	pass("XML::toString() exists");
306    } else {
307	fail("XML::toString() doesn't exist");
308    }
309
310} // end of existtests
311/////////////////////////////////////////////////////
312
313check(XML);
314newXML = new XML();
315check(XML);
316
317// Load
318// if (tmp.load("testin.xml")) {
319// 	pass("XML::load() works");
320// } else {
321// 	fail("XML::load() doesn't work");
322// }
323check(XML);
324
325// Use escaped " instead of ' so that it matches xml_out (comments and CDATA tags stripped).
326var xml_in = "<TOPNODE tna1=\"tna1val\" tna2=\"tna2val\" tna3=\"tna3val\"><SUBNODE1 sna1=\"sna1val\" sna2=\"sna2val\"><SUBSUBNODE1 ssna1=\"ssna1val\" ssna2=\"ssna2val\"><!-- comment should be ignored-->sub sub1 node data 1</SUBSUBNODE1><SUBSUBNODE2><!--comment: cdata with illegal characters --><![CDATA[sub /\sub1 <br>\"node data 2\"]]></SUBSUBNODE2></SUBNODE1><SUBNODE2><SUBSUBNODE1>sub sub2 node data 1</SUBSUBNODE1><SUBSUBNODE2>sub sub2 node data 2</SUBSUBNODE2></SUBNODE2></TOPNODE>";
327// with comments stripped out.
328var xml_out = '<TOPNODE tna1="tna1val" tna2="tna2val" tna3="tna3val"><SUBNODE1 sna1="sna1val" sna2="sna2val"><SUBSUBNODE1 ssna1="ssna1val" ssna2="ssna2val">sub sub1 node data 1</SUBSUBNODE1><SUBSUBNODE2>sub /sub1 &lt;br&gt;&quot;node data 2&quot;</SUBSUBNODE2></SUBNODE1><SUBNODE2><SUBSUBNODE1>sub sub2 node data 1</SUBSUBNODE1><SUBSUBNODE2>sub sub2 node data 2</SUBSUBNODE2></SUBNODE2></TOPNODE>';
329//var xml_out = "<TOPNODE tna1=\"tna1val\" tna2=\"tna2val\" tna3=\"tna3val\"><SUBNODE1 sna1=\"sna1val\" sna2=\"sna2val\"><SUBSUBNODE1 ssna1=\"ssna1val\" ssna2=\"ssna2val\">sub sub1 node data 1</SUBSUBNODE1><SUBSUBNODE2>sub /\sub1 \<br\>\"node data 2\"</SUBSUBNODE2></SUBNODE1><SUBNODE2><SUBSUBNODE1>sub sub2 node data 1</SUBSUBNODE1><SUBSUBNODE2>sub sub2 node data 2</SUBSUBNODE2></SUBNODE2></TOPNODE>";
330
331check(XML);
332tmp.checkParsed = function ()
333{
334	//note("tmp.checkParsed called");
335
336	// Since we didn't *load* the XML, but we
337	// just *parsed* it, expect getBytesLoaded
338	// and getBytesTotal to return undefined
339	check_equals(this.getBytesLoaded(), undefined);
340	check_equals(this.getBytesTotal(), undefined);
341
342	check(this.hasChildNodes());
343	check_equals(typeof(this.nodeName), 'null');
344	check_equals(typeof(this.nodeValue), 'null');
345	check(this.childNodes instanceof Array);
346	check_equals(this.firstChild, this.lastChild);
347	check(this.firstChild instanceof XMLNode);
348	check_equals(typeof(this.length), 'undefined');
349	check_equals(typeof(this.childNodes.length), 'number');
350	check_equals(this.childNodes.length, 1);
351	check_equals(this.childNodes[0], this.firstChild);
352	check_equals(this.childNodes[0], this.lastChild);
353
354	check(this.childNodes.hasOwnProperty('length'));
355	check(this.childNodes[0] === this.firstChild);
356	check(this.childNodes[0] === this.lastChild);
357
358	// childNodes is a read-only property !
359	this.childNodes = 5;
360	check(this.childNodes instanceof Array);
361
362        with (this.firstChild)
363	{
364		check_equals(nodeName, 'TOPNODE');
365		check_equals(typeof(nodeValue), 'null');
366		check_equals(typeof(nextSibling), 'null');
367		check_equals(typeof(previousSibling), 'null');
368
369		// Check attributes
370		check_equals(typeof(attributes), 'object');
371		check_equals(attributes.tna1, 'tna1val');
372		check_equals(attributes.tna2, 'tna2val');
373		// Check attributes enumerability
374		var attrcopy = {};
375		for (var i in attributes) attrcopy[i] = attributes[i];
376		check_equals(attrcopy.tna1, 'tna1val');
377		check_equals(attrcopy.tna2, 'tna2val');
378
379
380		// Check that nodeValue is overridable
381		nodeValue = 4;
382		check_equals(typeof(nodeValue), 'string');
383		check_equals(nodeValue, '4');
384
385		check_equals(nodeType, 1); // element
386		check_equals(childNodes.length, 2);
387
388		with (firstChild)
389		{
390			check_equals(nodeName, 'SUBNODE1');
391			check_equals(typeof(nodeValue), 'null');
392
393			check_equals(typeof(nextSibling), 'object');
394			check_equals(nextSibling.nodeName, 'SUBNODE2');
395			check_equals(typeof(previousSibling), 'null');
396
397			check_equals(typeof(attributes), 'object');
398			check_equals(attributes.sna1, 'sna1val');
399			check_equals(attributes.sna2, 'sna2val');
400
401			check_equals(nodeType, 1); // element
402			check_equals(childNodes.length, 2);
403			with (firstChild)
404			{
405				check_equals(nodeName, 'SUBSUBNODE1');
406				check_equals(typeof(nodeValue), 'null');
407				check_equals(nodeType, 1); // element
408				check_equals(typeof(nextSibling), 'object');
409				check_equals(nextSibling.nodeName, 'SUBSUBNODE2');
410				check_equals(typeof(previousSibling), 'null');
411				check_equals(typeof(attributes), 'object');
412				check_equals(attributes.ssna1, 'ssna1val');
413				check_equals(attributes.ssna2, 'ssna2val');
414				check_equals(childNodes.length, 1);
415				with (firstChild)
416				{
417					check_equals(typeof(nodeName), 'null')
418					check_equals(nodeValue, 'sub sub1 node data 1')
419					check_equals(nodeType, 3); // text
420				}
421			}
422			with (lastChild)
423			{
424				check_equals(nodeName, 'SUBSUBNODE2');
425				check_equals(typeof(nodeValue), 'null');
426				check_equals(nodeType, 1); // element
427				check_equals(typeof(nextSibling), 'null');
428				check_equals(typeof(previousSibling), 'object');
429				check_equals(previousSibling.nodeName, 'SUBSUBNODE1');
430				check_equals(childNodes.length, 1);
431				with (firstChild)
432				{
433					check_equals(typeof(nodeName), 'null')
434					check_equals(nodeValue, 'sub /\sub1 <br>"node data 2"')
435					check_equals(nodeType, 3); // text
436				}
437			}
438		}
439
440		with (lastChild)
441		{
442			check_equals(nodeName, 'SUBNODE2');
443			check_equals(typeof(nodeValue), 'null');
444			check_equals(nodeType, 1); // element
445
446			check_equals(typeof(nextSibling), 'null');
447			check_equals(typeof(previousSibling), 'object');
448			check_equals(previousSibling.nodeName, 'SUBNODE1');
449
450			check_equals(childNodes.length, 2);
451			with (firstChild)
452			{
453				check_equals(nodeName, 'SUBSUBNODE1');
454				check_equals(typeof(nodeValue), 'null');
455				check_equals(nodeType, 1); // element
456				check_equals(childNodes.length, 1);
457				with (firstChild)
458				{
459					check_equals(typeof(nodeName), 'null')
460					check_equals(nodeValue, 'sub sub2 node data 1')
461					check_equals(nodeType, 3); // text
462				}
463			}
464			with (lastChild)
465			{
466				check_equals(nodeName, 'SUBSUBNODE2');
467				check_equals(typeof(nodeValue), 'null');
468				check_equals(nodeType, 1); // element
469				check_equals(childNodes.length, 1);
470				with (firstChild)
471				{
472					check_equals(typeof(nodeName), 'null')
473					check_equals(nodeValue, 'sub sub2 node data 2')
474					check_equals(nodeType, 3); // text
475				}
476			}
477		}
478        }
479	check_equals(this.firstChild.nodeValue, '4');
480};
481
482check_equals( typeof(tmp.parseXML), 'function');
483check(tmp.childNodes instanceOf Array);
484check_equals(tmp.childNodes.length, 0);
485
486// parseXML doesn't return anything
487ret = tmp.parseXML(xml_in);
488check_equals(typeof(ret), 'undefined');
489
490tmp.checkParsed(); // onLoad won't be called
491//note("Parsed XML: "+tmp.toString());
492
493// TODO: FIX THIS !
494check_equals(tmp.toString(), xml_out);
495
496//------------------------------------------------
497// Test XML editing
498//------------------------------------------------
499xml1 = new XML("<X1T><X1C1></X1C1><X1C2></X1C2></X1T>");
500xml2 = new XML("<X2T><X2C1></X2C1><X2C2></X2C2></X2T>");
501check_equals(xml1.childNodes.length, 1);
502check_equals(xml1.firstChild.childNodes.length, 2);
503check_equals(xml2.childNodes.length, 1);
504check_equals(xml2.firstChild.childNodes.length, 2);
505
506// Now move X1C1 to X2T
507movingchild = xml2.firstChild.lastChild;
508
509check_equals(movingchild.parentNode, xml2.firstChild);
510check(movingchild.parentNode != xml1.firstChild);
511xml1.firstChild.appendChild(movingchild);
512check_equals(movingchild.parentNode, xml1.firstChild);
513check(movingchild.parentNode != xml2.firstChild);
514
515check_equals(xml1.firstChild.childNodes.length, 3);
516check_equals(xml1.firstChild.childNodes[0].nodeName, "X1C1");
517check_equals(xml1.firstChild.childNodes[1].nodeName, "X1C2");
518check_equals(xml1.firstChild.childNodes[2].nodeName, "X2C2");
519
520check_equals(xml2.firstChild.childNodes.length, 1); // firstChild has been moved
521check_equals(xml2.firstChild.childNodes[0].nodeName, "X2C1");
522
523// Now insert X2C1 from xml2 before X1C2 in xml1
524xml1.firstChild.insertBefore(
525	xml2.firstChild.lastChild, // what to insert
526	xml1.firstChild.childNodes[1] // before what to insert it
527);
528check_equals(xml1.firstChild.childNodes.length, 4);
529check_equals(xml1.firstChild.childNodes[0].nodeName, "X1C1");
530check_equals(xml1.firstChild.childNodes[1].nodeName, "X2C1");
531check_equals(xml1.firstChild.childNodes[2].nodeName, "X1C2");
532check_equals(xml1.firstChild.childNodes[3].nodeName, "X2C2");
533
534// XMLNode.removeNode
535check_equals(xml2.firstChild.childNodes.length, 0); // lastChild has been moved
536xml2.firstChild.removeNode();
537check_equals(xml2.childNodes.length, 0); // it's only child has been dropped
538
539x1c1_node = xml1.firstChild.childNodes[0];
540x2c1_node = xml1.firstChild.childNodes[1];
541check_equals(x1c1_node.nodeName, "X1C1");
542check_equals(x1c1_node.nextSibling, x2c1_node);
543check_equals(x2c1_node.nodeName, "X2C1");
544check_equals(x2c1_node.previousSibling, x1c1_node);
545xml1.firstChild.removeNode(); // removeNode removes all childrens !!
546check_equals(xml1.childNodes.length, 0);
547// so these become orphaned (no parent)
548check_equals(x1c1_node.nodeName, "X1C1");
549check_equals(x1c1_node.nextSibling(), null);
550check_equals(x2c1_node.nodeName, "X2C1");
551check_equals(x2c1_node.previousSibling(), null);
552
553xml1.appendChild(x1c1_node);
554xml1.appendChild(x2c1_node);
555check_equals(x1c1_node.nextSibling, x2c1_node);
556check_equals(x2c1_node.previousSibling, x1c1_node);
557
558check_equals(xml1.childNodes.length, 2);
559x1c1_node.appendChild(x2c1_node);
560check_equals(xml1.childNodes.length, 1);
561check_equals(xml1.firstChild.lastChild.nodeName, 'X2C1');
562
563src_node = xml1.firstChild;
564cln_node = src_node.cloneNode(); // ! deep
565deepcln_node = src_node.cloneNode(true); // deep
566
567check_equals(src_node.childNodes.length, 1);
568check_equals(cln_node.childNodes.length, 0); // non-deep clone doesn't clone childs !
569check_equals(deepcln_node.childNodes.length, 1);
570
571check_equals(src_node.firstChild.nodeName, 'X2C1');
572check_equals(deepcln_node.firstChild.nodeName, 'X2C1');
573src_node.firstChild.nodeName = 'X2C1_modified';
574check_equals(src_node.firstChild.nodeName, 'X2C1_modified');
575check_equals(deepcln_node.firstChild.nodeName, 'X2C1');
576
577check_equals(deepcln_node.parentNode, null);
578deepcln_node.parentNode = src_node;
579check_equals(deepcln_node.parentNode, null);
580
581
582xml1 = new XML("<X1T><X1C1><X1C1C1></X1C1C1></X1C1><X1C2></X1C2></X1T>");
583check_equals(xml1.firstChild.childNodes.length, 2);
584fc = xml1.firstChild.firstChild;
585check_equals(fc.nodeName, 'X1C1');
586check_equals(fc.childNodes.length, 1);
587check_equals(fc.parentNode, xml1.firstChild);
588fc.removeNode(); // removes xml1.firstChild.firstChil (X1C1)
589check_equals(xml1.firstChild.childNodes.length, 1);
590check_equals(fc.parentNode, null);
591check_equals(fc.nodeName, 'X1C1');
592check_equals(fc.childNodes.length, 1); // childs of the removed child are still alive !
593check_equals(fc.childNodes[0].parentNode, fc); // and still point to the removed child !
594
595//------------------------------------------------
596// Other tests..
597//------------------------------------------------
598
599myXML = new XML();
600check(myXML != undefined);
601check(myXML.createElement);
602
603//    file.puts("function: dodo()");
604// create three XML nodes using createElement()
605var element1 = myXML.createElement("element1");
606check(element1.nodeName == "element1");
607
608var element2 = myXML.createElement("element2");
609check_equals(element2.nodeName, "element2");
610
611var element3 = myXML.createElement("element3");
612check_equals(element3.nodeName, "element3");
613
614check(myXML.createTextNode);
615
616// create two XML text nodes using createTextNode()
617var textNode1 = myXML.createTextNode("textNode1 String value");
618check(textNode1.nodeValue == "textNode1 String value");
619
620var textNode2 = myXML.createTextNode("textNode2 String value");
621check(textNode2.nodeValue == "textNode2 String value");
622
623// place the new nodes into the XML tree
624check(!element2.hasChildNodes());
625ret = element2.appendChild(textNode1);
626check_equals(typeof(ret), 'undefined');
627check(element2.hasChildNodes());
628
629check_equals(element2.nodeValue, null);
630check_equals(typeof(element2.lastChild), 'object');
631check_equals(element2.lastChild.nodeValue, "textNode1 String value");
632element2.lastChild = 4;
633check_equals(typeof(element2.lastChild), 'object');
634
635element3.appendChild(textNode2);
636check_equals(element3.nodeValue, null);
637check_equals(typeof(element3.lastChild), 'object');
638check_equals(element3.lastChild.nodeValue, "textNode2 String value");
639
640// place the new nodes into the XML tree
641doc.appendChild(element1);
642//check(doc.firstChild.nodeName == "element1");
643
644element1.appendChild(element2);
645check(element1.hasChildNodes());
646// trace(element1.nodeName);
647// trace(element1.firstChild.nodeName);
648check(element1.firstChild.nodeName == "element2");
649
650element2.appendChild(element3);
651check(element2.hasChildNodes());
652
653trace(doc.toString());
654
655// // trace(myXML.toString());
656
657// newnode = myXML.cloneNode(false);
658
659// //trace(myXML.nodeName);
660// //trace(newnode.nodeValue);
661
662// //trace("Child1" + _global.child1);
663// //trace("Child2" + _global.child2);
664
665// // This won't work as onLoad is not called unless you
666// // actually *load* the XML, we're using parseXML that
667// // does *not* trigger loading (see also getBytesLoaded
668// // and getBytesTotal) and does *not* trigger onLoad
669// // event to execute.
670// #if 0
671// if ((_global.child1 == "sub sub1 node data 1")
672//     && (global.child2 == "sub sub1 node data 2")) {
673// 	pass("XML::onLoad works");
674// } else {
675// 	fail("XML::onLoad doesn't work");
676// }
677// #endif
678
679
680// Test sendAndLoad return;
681// Any object can be passed as second argument.
682
683x = new XML;
684r = new Object;
685check(!r.hasOwnProperty("loaded"));
686check_equals(x.sendAndLoad("some server name", r), true);
687check(r.hasOwnProperty("loaded"));
688
689r = new XML;
690check(!r.hasOwnProperty("loaded"));
691check_equals(x.sendAndLoad("some server name", r), true);
692check(!r.hasOwnProperty("loaded"));
693check_equals(typeof(r.loaded), "boolean");
694check_equals(r.loaded, false);
695
696#if OUTPUT_VERSION > 5
697// No LoadVars in SWF 5.
698r = new LoadVars;
699check(!r.hasOwnProperty("loaded"));
700check_equals(x.sendAndLoad("some server name", r), true);
701check(r.hasOwnProperty("loaded"));
702check_equals(typeof(r.loaded), "boolean");
703check_equals(r.loaded, false);
704#endif
705
706r = new Date(1);
707check(!r.hasOwnProperty("loaded"));
708check_equals(x.sendAndLoad("some server name", r), true);
709check(r.hasOwnProperty("loaded"));
710check_equals(typeof(r.loaded), "boolean");
711check_equals(r.loaded, false);
712t = new Date(1);
713check_equals(r.toString(), t.toString());
714check(r instanceOf Date);
715
716r = 3;
717check(!r.hasOwnProperty("loaded"));
718check_equals(x.sendAndLoad("some server name", r), false);
719check(!r.hasOwnProperty("loaded"));
720check_equals(typeof(r.loaded), "undefined");
721check_equals(r.loaded, undefined);
722
723r = "string";
724check(!r.hasOwnProperty("loaded"));
725check_equals(x.sendAndLoad("some server name", r), false);
726check(!r.hasOwnProperty("loaded"));
727check_equals(typeof(r.loaded), "undefined");
728check_equals(r.loaded, undefined);
729
730r = {};
731check(!r.hasOwnProperty("loaded"));
732check_equals(x.sendAndLoad("some server name", r), true);
733check(r.hasOwnProperty("loaded"));
734check_equals(typeof(r.loaded), "boolean");
735check_equals(r.loaded, false);
736
737
738/// Test addRequestHeaders
739
740#if OUTPUT_VERSION > 5
741
742check(!x.hasOwnProperty("_customHeaders"));
743
744x.addRequestHeader("header1", "value1");
745check(x.hasOwnProperty("_customHeaders"));
746check(x._customHeaders instanceOf Array);
747check_equals(x._customHeaders.toString(), "header1,value1");
748
749x.addRequestHeader("header2", "value2");
750check_equals(x._customHeaders.toString(), "header1,value1,header2,value2");
751
752x.addRequestHeader(["header3", "value3", "header4", "value4"]);
753check_equals(x._customHeaders.toString(), "header1,value1,header2,value2,header3,value3,header4,value4");
754
755x._customHeaders.pop();
756check_equals(x._customHeaders.toString(), "header1,value1,header2,value2,header3,value3,header4");
757
758x._customHeaders[8] = "value4";
759#if OUTPUT_VERSION < 7
760check_equals(x._customHeaders.toString(), "header1,value1,header2,value2,header3,value3,header4,,value4");
761#else
762check_equals(x._customHeaders.toString(), "header1,value1,header2,value2,header3,value3,header4,undefined,value4");
763#endif
764
765x._customHeaders[7] = "shoved in";
766
767x.addRequestHeader("header5", "value5");
768check_equals(x._customHeaders.toString(), "header1,value1,header2,value2,header3,value3,header4,shoved in,value4,header5,value5");
769
770x.addRequestHeader("GET", "should not be sent");
771check_equals(x._customHeaders.toString(), "header1,value1,header2,value2,header3,value3,header4,shoved in,value4,header5,value5,GET,should not be sent");
772
773x.addRequestHeader("Public", "should not be sent");
774check_equals(x._customHeaders.toString(), "header1,value1,header2,value2,header3,value3,header4,shoved in,value4,header5,value5,GET,should not be sent,Public,should not be sent");
775
776/// Shouldn't change _customHeaders
777x.contentType="Odd Content Type";
778check_equals(x._customHeaders.toString(), "header1,value1,header2,value2,header3,value3,header4,shoved in,value4,header5,value5,GET,should not be sent,Public,should not be sent");
779
780x._customHeaders = 3;
781check_equals(x._customHeaders.toString(), "3");
782
783x.addRequestHeader("header0", "value0");
784check_equals(x._customHeaders.toString(), "3");
785
786
787// Only strings work.
788x = new XML;
789check(!x.hasOwnProperty("_customHeaders"));
790x.addRequestHeader(3);
791check(x.hasOwnProperty("_customHeaders"));
792check_equals(x._customHeaders.toString(), "");
793
794x = new XML;
795check(!x.hasOwnProperty("_customHeaders"));
796x.addRequestHeader();
797check(x.hasOwnProperty("_customHeaders"));
798check_equals(x._customHeaders.toString(), "");
799
800
801
802x.addRequestHeader(3, 5);
803check_equals(x._customHeaders.toString(), "");
804
805x.addRequestHeader(new Date, new Object);
806check_equals(x._customHeaders.toString(), "");
807
808x.addRequestHeader("string", 6);
809check_equals(x._customHeaders.toString(), "");
810
811x.addRequestHeader("string", "string");
812check_equals(x._customHeaders.toString(), "string,string");
813
814#endif
815
816//--------------------------------------------------------------------
817// Test loading an XML locally
818//--------------------------------------------------------------------
819
820myxml = new XML;
821
822check_equals(typeof(myxml.onData), 'function');
823#if OUTPUT_VERSION > 5
824check(myxml.onData != XML.prototype.parseXML);
825#endif
826
827check(!myxml.hasOwnProperty('onLoad'));
828
829myxml.onLoadCalls = 0;
830
831myxml.onLoad = function(success)
832{
833	//note("myxml.onLoad("+success+") called");
834
835	check_equals(typeof(myxml.status), 'number');
836	check_equals(typeof(myxml.loaded), 'boolean');
837#if OUTPUT_VERSION >= 6
838	check(! myxml.hasOwnProperty('status'));
839	check(! myxml.hasOwnProperty('loaded'));
840#endif // OUTPUT_VERSION >= 6
841
842	if ( ! success )
843	{
844		note("No success loading gnash.xml");
845		check_equals(myxml.status, 0);
846		check(! myxml.loaded);
847		return;
848	}
849	note("gnash.xml successfully loaded");
850	note("myxml status is "+myxml.status);
851	check_equals(myxml.status, 0);
852	check(myxml.loaded);
853
854	// Check 'loaded' and 'status' to be "overridable"
855
856	var loaded_backup = myxml.loaded;
857	myxml.loaded = 'a string';
858	check_equals(typeof(myxml.loaded), 'boolean');
859	myxml.loaded = ! loaded_backup;
860	check(myxml.loaded != loaded_backup);
861	myxml.loaded = loaded_backup;
862
863	var status_backup = myxml.status;
864	myxml.status = 'a string';
865	check_equals(typeof(myxml.status), 'number');
866	check(myxml.status != status_backup);
867	//note("myxml.status is == "+myxml.status+" after being set to 'a string'");
868	myxml.status = status_backup;
869
870
871	//note("myxml.toString(): "+myxml.toString());
872	check_equals(typeof(myxml.attributes), 'object');
873	check(! myxml.attributes instanceof Object);
874	check_equals(typeof(myxml.attributes.__proto__), 'undefined');
875
876	check(myxml.hasChildNodes());
877	check_equals(myxml.nodeName, null);
878
879	topnode = myxml.firstChild;
880#if OUTPUT_VERSION == 5
881	xcheck_equals(topnode.nodeName, null);
882	xcheck_equals(topnode.attributes.attr1, undefined);
883#else
884	check_equals(topnode.nodeName, 'XML');
885	check_equals(topnode.attributes.attr1, 'attr1 value');
886#endif
887
888	// XML, comment, NULL
889	if ( typeof(myxml.lastChildNodesCount) == 'undefined' )
890	{
891		myxml.lastChildNodesCount = myxml.childNodes.length;
892	}
893	else
894	{
895		check_equals(myxml.childNodes.length, myxml.lastChildNodesCount);
896	}
897#if OUTPUT_VERSION == 5
898	xcheck_equals(myxml.childNodes.length, 4); // gnash fails discarding the comment and the ending blanks
899#else
900	check_equals(myxml.childNodes.length, 3); // gnash fails discarding the comment and the ending blanks
901#endif
902
903	// We're done
904	++this.onLoadCalls;
905	//note("onLoad called "+this.onLoadCalls+" times");
906#if OUTPUT_VERSION < 8
907	if ( this.onLoadCalls == 2 )
908#else
909	if ( this.onLoadCalls == 1 )
910#endif
911	{
912#if OUTPUT_VERSION < 6
913		check_totals(438);
914#else
915# if OUTPUT_VERSION < 8
916		check_totals(475);
917# else
918		check_totals(456);
919# endif
920#endif
921		play();
922	}
923
924};
925
926check_equals(typeof(myxml.status), 'number');
927#if OUTPUT_VERSION < 7
928check_equals(typeof(myxml.STATUS), 'number');
929#else // OUTPUT_VERSION >= 7
930check_equals(typeof(myxml.STATUS), 'undefined');
931#endif // OUTPUT_VERSION >= 7
932
933check_equals(typeof(myxml.__proto__.status), 'undefined');
934check_equals(typeof(myxml.loaded), 'undefined');
935check_equals(typeof(myxml._bytesLoaded), 'undefined');
936check_equals(typeof(myxml._bytesTotal), 'undefined');
937
938check(!myxml.hasOwnProperty('status'));
939check(!myxml.hasOwnProperty('loaded'));
940check(!myxml.hasOwnProperty('_bytesLoaded'));
941check(!myxml.hasOwnProperty('_bytesTotal'));
942
943ret = myxml.load( MEDIA(gnash.xml) );
944
945check(myxml.hasOwnProperty('_bytesLoaded'));
946check(myxml.hasOwnProperty('_bytesTotal'));
947
948check_equals(typeof(myxml.loaded), 'boolean');
949#if OUTPUT_VERSION < 7
950check_equals(typeof(myxml.LOADED), 'boolean');
951#else // OUTPUT_VERSION >= 7
952check_equals(typeof(myxml.LOADED), 'undefined');
953#endif // OUTPUT_VERSION >= 7
954check(! myxml.loaded ); // is really loaded in a background thread
955
956check_equals(myxml.loaded, false ); // is really loaded in a background thread
957//note("myxml.loaded = "+myxml.loaded);
958//note("myxml.load() returned "+ret);
959
960// Load again, to verify new parsing doesn't get appended to the old
961ret = myxml.load( MEDIA(gnash.xml) );
962
963//------------------------------------------------
964// Test XML.ignoreWhite
965//------------------------------------------------
966
967myxml2 = new XML();
968xmlin = "<X1T> <X1C1> </X1C1> <X1C2>\n</X1C2> 	</X1T>";
969xmlin2 = "<X0><X1/></X0>";
970xmlin2_out = "<X0><X1 /></X0>";
971xmlin_stripwhite = "<X1T><X1C1 /><X1C2 /></X1T>";
972
973myxml2.ignoreWhite = false;
974myxml2.parseXML(xmlin);
975check_equals(myxml2.childNodes.length, 1);
976check_equals(myxml2.toString(), xmlin);
977myxml2.parseXML(xmlin2); // parsing twice doesn't append !
978check_equals(myxml2.childNodes.length, 1);
979check_equals(myxml2.toString(), xmlin2_out);
980
981myxml2.ignoreWhite = true;
982myxml2.parseXML(xmlin);
983check_equals(myxml2.toString(), xmlin_stripwhite);
984
985myxml2.ignoreWhite = true;
986myxml2.parseXML("<X1> </X1>");
987check_equals(myxml2.childNodes.length, 1);
988check(!myxml2.childNodes[0].hasChildNodes());
989check_equals(myxml2.toString(), "<X1 />");
990
991myxml2.ignoreWhite = false;
992myxml2.parseXML("<X1> </X1>");
993check_equals(myxml2.childNodes.length, 1);
994check(myxml2.childNodes[0].hasChildNodes());
995check_equals(myxml2.childNodes[0].childNodes[0].nodeType, 3); // text node
996check_equals(myxml2.childNodes[0].childNodes[0].nodeValue, ' '); // text node
997check_equals(myxml2.toString(), "<X1> </X1>");
998
999myxml2.ignoreWhite = true;
1000myxml2.parseXML("<X1>\n</X1>");
1001check_equals(myxml2.childNodes.length, 1);
1002check(!myxml2.childNodes[0].hasChildNodes());
1003check_equals(myxml2.toString(), "<X1 />");
1004
1005myxml2.ignoreWhite = true;
1006myxml2.parseXML("<X1> t </X1>");
1007check_equals(myxml2.toString(), "<X1> t </X1>");
1008
1009myxml2.ignoreWhite = 8;
1010check_equals(myxml2.ignoreWhite, true);
1011
1012myxml2.ignoreWhite = 0;
1013check_equals(myxml2.ignoreWhite, false);
1014
1015/// Check various malformed XMLs
1016
1017h = new XML("<open>");
1018check_equals(h.toString(), "<open />");
1019
1020h = new XML("<open></close>");
1021check_equals(h.toString(), "<open />");
1022
1023h = new XML("<open><open2></open>");
1024check_equals(h.toString(), "<open><open2 /></open>");
1025
1026h = new XML("<open att='");
1027check_equals(h.toString(), "");
1028
1029h = new XML("<open att      r='kk'");
1030check_equals(h.toString(), "");
1031
1032h = new XML("<open>& ' \"<");
1033check_equals(h.toString(), "<open>&amp; &apos; &quot;</open>");
1034
1035// A non-breaking space (honest).
1036h = new XML("<open> </open>");
1037check_equals(h.toString(), "<open> </open>");
1038
1039h = new XML("</open><open>node with \"</open>");
1040check_equals(h.toString(), "");
1041
1042h = new XML("<open/><open><!-- lkjsdcölkj<hello>");
1043check_equals(h.toString(), "<open /><open />");
1044
1045h = new XML("<open><![CDATA[jlkjdc</open>");
1046check_equals(h.toString(), "<open />");
1047
1048// Check DOCTYPE and xml declarations.
1049
1050check_equals(h.docTypeDecl, undefined);
1051check_equals(h.xmlDecl, undefined);
1052
1053h = new XML("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'><tag></tag>");
1054check_equals(h.toString(), "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'><tag />");
1055check_equals(h.docTypeDecl, "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>");
1056
1057h = new XML("<!DOcTyPE text><tag></tag>");
1058check_equals(h.toString(), "<!DOcTyPE text><tag />");
1059check_equals(h.docTypeDecl, "<!DOcTyPE text>");
1060
1061h = new XML("<?xml declaration goes here?><tag>content</tag>");
1062check_equals(h.toString(), "<?xml declaration goes here?><tag>content</tag>");
1063check_equals(h.xmlDecl, "<?xml declaration goes here?>");
1064
1065h = new XML("<?xMl declaration goes here?><tag>content</tag>");
1066check_equals(h.toString(), "<?xMl declaration goes here?><tag>content</tag>");
1067check_equals(h.xmlDecl, "<?xMl declaration goes here?>");
1068
1069// Check order
1070h = new XML("<!doctype d><?xMl declaration goes here?><tag>content</tag>");
1071check_equals(h.toString(), "<?xMl declaration goes here?><!doctype d><tag>content</tag>");
1072check_equals(h.xmlDecl, "<?xMl declaration goes here?>");
1073check_equals(h.docTypeDecl, "<!doctype d>");
1074
1075// Check order
1076h = new XML("<tag></tag><!doctype d><?xMl declaration goes here?><tag>content</tag>");
1077check_equals(h.toString(), "<?xMl declaration goes here?><!doctype d><tag /><tag>content</tag>");
1078
1079// Check multiple declarations
1080h = new XML("<tag></tag><!doctype d><?xMl decl?><!dOcType new><?XMl new?>");
1081check_equals(h.toString(), "<?xMl decl?><?XMl new?><!dOcType new><tag />");
1082check_equals(h.xmlDecl, "<?xMl decl?><?XMl new?>");
1083
1084h.xmlDecl = 7;
1085check_equals(typeof(h.xmlDecl), "string");
1086check_equals(h.xmlDecl, "7");
1087check_equals(h.toString(), "7<!dOcType new><tag />");
1088
1089h.docTypeDecl = 98;
1090check_equals(typeof(h.docTypeDecl), "string");
1091check_equals(h.docTypeDecl, "98");
1092check_equals(h.toString(), "798<tag />");
1093
1094check_equals(h.contentType, "application/x-www-form-urlencoded");
1095
1096h.contentType = 88;
1097check_equals(typeof(h.contentType), "string");
1098check_equals(h.contentType, "88");
1099check_equals(h.toString(), "798<tag />");
1100
1101h.contentType = "";
1102check_equals(typeof(h.contentType), "string");
1103check_equals(h.contentType, "");
1104check_equals(h.toString(), "798<tag />");
1105
1106
1107#if OUTPUT_VERSION > 5
1108
1109/// Check special characters
1110r = new XML("1: &#229; 2: &#228; 3: &#1025; 4: &#02312; 5: &#0228;");
1111xcheck_equals(r.toString(), "1: å 2: ä 3: Ё 4: ई 5: ä");
1112
1113r = new XML("1: &#229e2; 2: &#76e9; 3: &#ee229; 4: &#fee; 5: &#97;");
1114xcheck_equals(r.toString(), "1: å 2: L 3: &amp;#ee229; 4: &amp;#fee; 5: a");
1115
1116#endif
1117
1118stop();
1119
1120