1# Commands covered:  ::dom::nodeIterator
2#
3# This file contains a collection of tests for one or more of the
4# TclDOM commands.  Sourcing this file into Tcl runs the tests and
5# generates output for errors.  No output means no errors were found.
6#
7# Copyright (c) 2008 Explain
8# Copyright (c) 1999-2000 Ajuba Solutions
9#
10# $Id: iterator.test,v 1.4 2003/12/03 20:18:45 balls Exp $
11
12package require tcltest
13source [file join [tcltest::workingDirectory] tcldomutils.tcl]
14
15testPackage dom
16
17namespace eval ::dom::iteratorTest {
18    namespace import -force ::tcltest::*
19
20    proc IterateXML {xml showList} {
21        set document [::dom::DOMImplementation parse $xml]
22	set iterator [dom::DocumentTraversal createNodeIterator $document \
23		-show $showList]
24	set result {}
25	for {set i 0} {$i < 50} {incr i} {
26		set node [dom::nodeIterator nextNode $iterator]
27		if {$node == ""} break;
28		if {[dom::node cget $node -nodeName] != "#text"} {
29			lappend result [dom::node cget $node -nodeName]
30		} else {
31			lappend result [dom::node cget $node -nodeValue]
32		}
33	}
34	for {set i 0} {$i < 50} {incr i} {
35		set node [dom::nodeIterator previousNode $iterator]
36		if {$node == ""} break;
37		if {[dom::node cget $node -nodeName] != "#text"} {
38			lappend result [dom::node cget $node -nodeName]
39		} else {
40			lappend result [dom::node cget $node -nodeValue]
41		}
42	}
43	return $result
44    }
45
46    set xml1 {<?xml version="1.0"?>
47<!DOCTYPE Test>
48<Test>This <b>is</b>text.<A>aaa<B>bbb</B><C>ccc<D>ddd</D>ccc2</C>aaa2</A></Test>}
49
50    test iterator-1.1 {argument parsing} -constraints {dom_c} -body {
51        list [catch {dom::nodeIterator} msg] $msg
52} -result {1 {wrong # args: should be "dom::nodeIterator method handle ?arg ...?"}}
53    test iterator-1.2 {argument parsing} -constraints {dom_c} -body {
54        list [catch {dom::nodeIterator foo} msg] $msg
55} -result {1 {bad method "foo": must be cget, configure, previousNode, or nextNode}}
56    test iterator-1.3 {argument parsing} -constraints {dom_c} -body {
57        list [catch {dom::nodeIterator cget blah} msg] $msg
58} -result {1 {token not found}}
59
60    test iterator-2.1 {iterator creation} -constraints {dom_c} -body {
61        set document [::dom::DOMImplementation parse {<?xml version="1.0"?>
62<!DOCTYPE Test>
63<Test></Test>}]
64	set result [catch {dom::DocumentTraversal createNodeIterator $document} \
65	    iterator]
66	set handle [string range $iterator 0 7]
67	list $result $handle
68} -result {0 iterator}
69
70    test iterator-2.2 {iterator creation} -constraints {dom_c} -body {
71        set document [::dom::DOMImplementation parse {<?xml version="1.0"?>
72<!DOCTYPE Test>
73<Test></Test>}]
74	set iterator [dom::DocumentTraversal createNodeIterator $document]
75	set result [catch {dom::nodeIterator nextNode $iterator} first]
76	set handle [string range $first 0 3]
77	list $result $handle
78} -result {0 node}
79
80    test iterator-3.1 {iterator cget -show} -constraints {dom_c} -body {
81        set document [::dom::DOMImplementation parse {<?xml version="1.0"?><A></A>}]
82	set iterator [dom::DocumentTraversal createNodeIterator $document -show \
83		[list element textNode]]
84	set result [catch {::dom::nodeIterator cget $iterator -show} value]
85	list $result $value
86} -result {0 {element textNode}}
87
88    test iterator-3.2 {iterator configure -show} -constraints {dom_c} -body {
89        set document [::dom::DOMImplementation parse {<?xml version="1.0"?><A></A>}]
90	set iterator [dom::DocumentTraversal createNodeIterator $document -show \
91		[list element textNode]]
92	set result [catch {::dom::nodeIterator configure $iterator -show} value]
93	list $result $value
94} -result {0 {element textNode}}
95
96    test iterator-3.3 {iterator configure -show readonly} -constraints {dom_c} -body {
97        set document [::dom::DOMImplementation parse {<?xml version="1.0"?><A></A>}]
98	set iterator [dom::DocumentTraversal createNodeIterator $document -show \
99		[list element textNode]]
100	set result [catch {::dom::nodeIterator configure $iterator \
101		-show [list element]} value]
102	list $result $value
103} -result {1 {no modification allowed error: an attempt was made to modify an object where modifications are not allowed}}
104
105    test iterator-3.4 {iterator cget -filter} -constraints {dom_c} -body {
106        set document [::dom::DOMImplementation parse {<?xml version="1.0"?><A></A>}]
107	set iterator [dom::DocumentTraversal createNodeIterator $document \
108		-filter nodeFilter]
109	set result [catch {::dom::nodeIterator cget $iterator -filter} value]
110	list $result $value
111} -result {0 nodeFilter}
112
113    test iterator-3.5 {iterator configure -filter} -constraints {dom_c} -body {
114        set document [::dom::DOMImplementation parse {<?xml version="1.0"?><A></A>}]
115	set iterator [dom::DocumentTraversal createNodeIterator $document \
116		-filter nodeFilter]
117	set result [catch {::dom::nodeIterator configure $iterator -filter} value]
118	list $result $value
119} -result {0 nodeFilter}
120
121    test iterator-3.6 {iterator configure -filter readonly} -constraints {dom_c} -body {
122        set document [::dom::DOMImplementation parse {<?xml version="1.0"?><A></A>}]
123	set iterator [dom::DocumentTraversal createNodeIterator $document \
124		-filter nodeFilter]
125	set result [catch {::dom::nodeIterator configure $iterator \
126		-filter someFilter} value]
127	list $result $value
128} -result {1 {no modification allowed error: an attempt was made to modify an object where modifications are not allowed}}
129
130    test iterator-3.7 {iterator cget -expandEntities} -constraints {dom_c} -body {
131        set document [::dom::DOMImplementation parse {<?xml version="1.0"?><A></A>}]
132	set iterator [dom::DocumentTraversal createNodeIterator $document]
133	set result [catch {::dom::nodeIterator cget $iterator \
134		-expandEntities} value]
135	list $result $value
136} -result {0 0}
137
138    test iterator-3.8 {iterator configure -expandEntities} -constraints {dom_c} -body {
139        set document [::dom::DOMImplementation parse {<?xml version="1.0"?><A></A>}]
140	set iterator [dom::DocumentTraversal createNodeIterator $document]
141	set result [catch {::dom::nodeIterator configure $iterator \
142		-expandEntities} value]
143	list $result $value
144} -result {0 0}
145
146    test iterator-3.9 {iterator configure -expandEntities readonly} -constraints {dom_c} -body {
147        set document [::dom::DOMImplementation parse {<?xml version="1.0"?><A></A>}]
148	set iterator [dom::DocumentTraversal createNodeIterator $document]
149	set result [catch {::dom::nodeIterator configure $iterator \
150		-expandEntities 1} value]
151	list $result $value
152} -result {1 {no modification allowed error: an attempt was made to modify an object where modifications are not allowed}}
153
154    test iterator-4.1 {basic iteration} -constraints {dom_c} -body {
155        set document [::dom::DOMImplementation parse {<?xml version="1.0"?>
156<!DOCTYPE Test>
157<Test>This <b>is</b>text.</Test>}]
158	set iterator [dom::DocumentTraversal createNodeIterator $document]
159	set result {}
160	for {set i 0} {$i < 9} {incr i} {
161		set node [dom::nodeIterator nextNode $iterator]
162		if {$node == ""} break;
163		lappend result [dom::node cget $node -nodeType]
164		lappend result [dom::node cget $node -nodeName]
165		lappend result [dom::node cget $node -nodeValue]
166	}
167	set result
168} -result {document #document {} documentType Test {} element Test {} textNode #text {This } element b {} textNode #text is textNode #text text.}
169
170    test iterator-4.2 {basic iteration with -show} -constraints {dom_c} -body {
171        set document [::dom::DOMImplementation parse {<?xml version="1.0"?>
172<!DOCTYPE Test>
173<Test>This <b>is</b>text.</Test>}]
174	set iterator [dom::DocumentTraversal createNodeIterator $document \
175		-show [list element textNode]]
176	set result {}
177	for {set i 0} {$i < 9} {incr i} {
178		set node [dom::nodeIterator nextNode $iterator]
179		if {$node == ""} break;
180		lappend result [dom::node cget $node -nodeType]
181		lappend result [dom::node cget $node -nodeName]
182		lappend result [dom::node cget $node -nodeValue]
183	}
184	set result
185} -result {element Test {} textNode #text {This } element b {} textNode #text is textNode #text text.}
186
187    test iterator-4.3 {basic reverse iteration} -constraints {dom_c} -body {
188        set document [::dom::DOMImplementation parse {<?xml version="1.0"?>
189<!DOCTYPE Test>
190<Test>This <b>is</b>text.</Test>}]
191	set iterator [dom::DocumentTraversal createNodeIterator $document]
192	set result {}
193	for {set i 0} {$i < 9} {incr i} {
194		set node [dom::nodeIterator nextNode $iterator]
195		if {$node == ""} break;
196	}
197	for {set i 0} {$i < 9} {incr i} {
198		set node [dom::nodeIterator previousNode $iterator]
199		if {$node == ""} break;
200		lappend result [dom::node cget $node -nodeType]
201		lappend result [dom::node cget $node -nodeName]
202		lappend result [dom::node cget $node -nodeValue]
203	}
204	set result
205} -result {textNode #text text. textNode #text is element b {} textNode #text {This } element Test {} documentType Test {} document #document {}}
206
207    test iterator-4.4 {basic reverse iteration with -show} -constraints {dom_c} -body {
208        set document [::dom::DOMImplementation parse {<?xml version="1.0"?>
209<!DOCTYPE Test>
210<Test>This <b>is</b>text.</Test>}]
211	set iterator [dom::DocumentTraversal createNodeIterator $document \
212		-show [list element textNode]]
213	set result {}
214	for {set i 0} {$i < 9} {incr i} {
215		set node [dom::nodeIterator nextNode $iterator]
216		if {$node == ""} break;
217	}
218	for {set i 0} {$i < 9} {incr i} {
219		set node [dom::nodeIterator previousNode $iterator]
220		if {$node == ""} break;
221		lappend result [dom::node cget $node -nodeType]
222		lappend result [dom::node cget $node -nodeName]
223		lappend result [dom::node cget $node -nodeValue]
224	}
225	set result
226} -result {textNode #text text. textNode #text is element b {} textNode #text {This } element Test {}}
227
228    test iterator-4.5 {complex iteration} -constraints {dom_c} -body {
229        set document [::dom::DOMImplementation parse $xml1]
230	set iterator [dom::DocumentTraversal createNodeIterator $document]
231	set result {}
232	for {set i 0} {$i < 40} {incr i} {
233		set node [dom::nodeIterator nextNode $iterator]
234		if {$node == ""} break;
235		set name [dom::node cget $node -nodeName]
236		if {$name != "#text"} {
237			lappend result $name
238		} else {
239			lappend result [dom::node cget $node -nodeValue]
240		}
241	}
242	set result
243} -result {#document Test Test {This } b is text. A aaa B bbb C ccc D ddd ccc2 aaa2}
244
245    test iterator-4.6 {complex iteration} -constraints {dom_c} -body {
246        set document [::dom::DOMImplementation parse $xml1]
247	set iterator [dom::DocumentTraversal createNodeIterator $document]
248	set result {}
249	for {set i 0} {$i < 40} {incr i} {
250		set node [dom::nodeIterator nextNode $iterator]
251		if {$node == ""} break;
252	}
253	for {set i 0} {$i < 40} {incr i} {
254		set node [dom::nodeIterator previousNode $iterator]
255		if {$node == ""} break;
256		set name [dom::node cget $node -nodeName]
257		if {$name != "#text"} {
258			lappend result $name
259		} else {
260			lappend result [dom::node cget $node -nodeValue]
261		}
262	}
263	set result
264} -result {aaa2 ccc2 ddd D ccc C bbb B aaa A text. is b {This } Test Test #document}
265
266    test iterator-4.7 {basic iteration both directions} -constraints {dom_c} -body {
267        set document [::dom::DOMImplementation parse {<?xml version="1.0"?>
268<!DOCTYPE Test>
269<Test>This <b>is</b>text.</Test>}]
270	set iterator [dom::DocumentTraversal createNodeIterator $document]
271	set result {}
272	set node [dom::nodeIterator nextNode $iterator]
273	lappend result [dom::node cget $node -nodeName]
274	set node [dom::nodeIterator previousNode $iterator]
275	lappend result [dom::node cget $node -nodeName]
276	set result
277} -result {#document #document}
278
279    test iterator-4.8 {backup before start of list} -constraints {dom_c} -body {
280        set document [::dom::DOMImplementation parse {<?xml version="1.0"?>
281<!DOCTYPE Test>
282<Test>This <b>is</b>text.</Test>}]
283	set iterator [dom::DocumentTraversal createNodeIterator $document]
284	set result {}
285	set node [dom::nodeIterator previousNode $iterator]
286	set	node
287} -result {}
288
289    test iterator-4.9 {backup before start of list then forward} -constraints {dom_c} -body {
290        set document [::dom::DOMImplementation parse {<?xml version="1.0"?>
291<!DOCTYPE Test>
292<Test>This <b>is</b>text.</Test>}]
293	set iterator [dom::DocumentTraversal createNodeIterator $document]
294	set result {}
295	set node [dom::nodeIterator previousNode $iterator]
296	set node [dom::nodeIterator previousNode $iterator]
297	set node [dom::nodeIterator previousNode $iterator]
298	set node [dom::nodeIterator previousNode $iterator]
299	set node [dom::nodeIterator nextNode $iterator]
300	lappend result [dom::node cget $node -nodeName]
301	set	result
302} -result {#document}
303
304    test iterator-4.10 {inserts while iterating} -constraints {dom_c} -body {
305        set document [::dom::DOMImplementation parse $xml1]
306	set iterator [dom::DocumentTraversal createNodeIterator $document]
307	set result {}
308	for {set i 0} {$i < 40} {incr i} {
309		set node [dom::nodeIterator nextNode $iterator]
310		if {$node == ""} break
311		set name [dom::node cget $node -nodeName]
312		if {$name != "#text"} {
313			lappend result $name
314			if {$name == "A"} {
315				set new [dom::document createTextNode $document "New Text"]
316				dom::node insertBefore $node $new \
317					[dom::node cget $node -firstChild]
318			}
319		} else {
320			lappend result [dom::node cget $node -nodeValue]
321		}
322	}
323	set result
324} -result {#document Test Test {This } b is text. A {New Text} aaa B bbb C ccc D ddd ccc2 aaa2}
325
326    test iterator-4.11 {deletions while iterating} -constraints {dom_c} -body {
327        set document [::dom::DOMImplementation parse $xml1]
328	set iterator [dom::DocumentTraversal createNodeIterator $document]
329	set result {}
330	for {set i 0} {$i < 40} {incr i} {
331		set node [dom::nodeIterator nextNode $iterator]
332		if {$node == ""} break
333		set name [dom::node cget $node -nodeName]
334		if {$name != "#text"} {
335			lappend result $name
336			if {$name == "A"} {
337				dom::node removeChild $node [dom::node cget $node -firstChild]
338			}
339		} else {
340			lappend result [dom::node cget $node -nodeValue]
341		}
342	}
343	set result
344} -result {#document Test Test {This } b is text. A B bbb C ccc D ddd ccc2 aaa2}
345
346    test iterator-4.12 {reference node deletion while iterating} -constraints {dom_c} -body {
347        set document [::dom::DOMImplementation parse $xml1]
348	set iterator [dom::DocumentTraversal createNodeIterator $document]
349	set result {}
350	for {set i 0} {$i < 40} {incr i} {
351		set node [dom::nodeIterator nextNode $iterator]
352		if {$node == ""} break
353		set name [dom::node cget $node -nodeName]
354		if {$name != "#text"} {
355			lappend result $name
356			if {$name == "B"} {
357				dom::node removeChild [dom::node cget $node -parent] $node
358			}
359		} else {
360			lappend result [dom::node cget $node -nodeValue]
361		}
362	}
363	set result
364} -result {#document Test Test {This } b is text. A aaa B C ccc D ddd ccc2 aaa2}
365
366    test iterator-4.13 {reference node deletion while iterating II} -constraints {dom_c} -body {
367        set document [::dom::DOMImplementation parse $xml1]
368	set iterator [dom::DocumentTraversal createNodeIterator $document]
369	set result {}
370	for {set i 0} {$i < 40} {incr i} {
371		set node [dom::nodeIterator nextNode $iterator]
372		if {$node == ""} break
373		set name [dom::node cget $node -nodeName]
374		if {$name != "#text"} {
375			lappend result $name
376			if {$name == "C"} {
377				set nodeToDelete $node
378			} elseif {$name == "D"} {
379				dom::node removeChild [dom::node cget $nodeToDelete -parent] \
380					$nodeToDelete
381			}
382		} else {
383			lappend result [dom::node cget $node -nodeValue]
384		}
385	}
386	set result
387} -result {#document Test Test {This } b is text. A aaa B bbb C ccc D aaa2}
388
389    test iterator-4.14 {deletion of trailing reference node} -constraints {dom_c} -body {
390        set document [::dom::DOMImplementation parse {<?xml version="1.0"?>
391<!DOCTYPE Test><Test>xxx<A/></Test>}]
392	set iterator [dom::DocumentTraversal createNodeIterator $document]
393	set result {}
394	set node {}
395	for {set i 0} {$i < 9} {incr i} {
396		set refNode $node
397		set node [dom::nodeIterator nextNode $iterator]
398		if {$node == ""} break;
399	}
400	set node [dom::nodeIterator previousNode $iterator]
401	dom::node removeChild [dom::node cget $refNode -parent] $refNode
402	set node [dom::nodeIterator previousNode $iterator]
403	lappend result [dom::node cget $node -nodeName]
404	set result
405} -result {Test}
406
407    test iterator-4.15 {complex iteration with filter} -constraints {dom_c} -body {
408	proc nodeFilter {node} {
409		set value [dom::node cget $node -nodeValue]
410		if {$value == "aaa"} {
411			return $::dom::reject
412		} else {
413			return $::dom::accept
414		}
415	}
416
417        set document [::dom::DOMImplementation parse $xml1]
418	set iterator [dom::DocumentTraversal createNodeIterator $document \
419		-filter nodeFilter]
420	set result {}
421	for {set i 0} {$i < 40} {incr i} {
422		set node [dom::nodeIterator nextNode $iterator]
423		if {$node == ""} break;
424		set name [dom::node cget $node -nodeName]
425		if {$name != "#text"} {
426			lappend result $name
427		} else {
428			lappend result [dom::node cget $node -nodeValue]
429		}
430	}
431	rename nodeFilter {}
432	set result
433} -result {#document Test Test {This } b is text. A B bbb C ccc D ddd ccc2 aaa2}
434
435    test iterator-4.16 {complex iteration} -constraints {dom_c} -body {
436        set document [::dom::DOMImplementation parse $xml1]
437	set iterator [dom::DocumentTraversal createNodeIterator $document \
438		-show [list document textNode]]
439	set result {}
440	for {set i 0} {$i < 40} {incr i} {
441		set node [dom::nodeIterator nextNode $iterator]
442		if {$node == ""} break;
443	}
444	for {set i 0} {$i < 40} {incr i} {
445		set node [dom::nodeIterator previousNode $iterator]
446		if {$node == ""} break;
447		set name [dom::node cget $node -nodeName]
448		if {$name != "#text"} {
449			lappend result $name
450		} else {
451			lappend result [dom::node cget $node -nodeValue]
452		}
453	}
454	set result
455} -result {aaa2 ccc2 ddd ccc bbb aaa text. is {This } #document}
456
457    test iterator-4.17 {complex iteration} -constraints {dom_c} -body {
458	set xml1 {<?xml version="1.0"?><!DOCTYPE Test><A>a<B>b<C>c<D>d</D></C></B></A>}
459	IterateXML $xml1 [list document element]
460} -result {#document A B C D D C B A #document}
461
462    test iterator-4.18 {complex iteration} -constraints {dom_c} -body {
463	set xml1 {<?xml version="1.0"?><!DOCTYPE Test><Test><A>a</A><B>b</B><C>c</C><D>d</D></Test>}
464	IterateXML $xml1 [list document element]
465} -result {#document Test A B C D D C B A Test #document}
466
467    test iterator-4.19 {complex iteration} -constraints {dom_c} -body {
468	IterateXML $xml1 [list document element textNode]
469} -result {#document Test A a B b C c D d d D c C b B a A Test #document}
470
471    set xml1 {<?xml version="1.0"?>
472<!DOCTYPE Test>
473<Test>test<A><B><C><D><E>eee</E><F>fff</F><G>ggg</G></D>ccc<H><I>iii</I><J>jjj</J><K>kkk</K></H>ccc2</C></B></A></Test>}
474
475    test iterator-4.20 {complex iteration} -constraints {dom_c} -body {
476	IterateXML $xml1 [list document element textNode]
477} -result {#document Test test A B C D E eee F fff G ggg ccc H I iii J jjj K kkk ccc2 ccc2 kkk K jjj J iii I H ccc ggg G fff F eee E D C B A test Test #document}
478
479    test iterator-4.21 {complex iteration} -constraints {dom_c} -body {
480	IterateXML $xml1 [list document textNode]
481} -result {#document test eee fff ggg ccc iii jjj kkk ccc2 ccc2 kkk jjj iii ccc ggg fff eee test #document}
482
483    set xml1 {<?xml version="1.0"?>
484<!DOCTYPE Test><Test><A>a<B>b<C>c<D>d<E>e<F>f</F></E></D></C></B></A></Test>}
485
486    test iterator-4.22 {complex iteration} -constraints {dom_c} -body {
487	IterateXML $xml1 [list document element textNode]
488} -result {#document Test A a B b C c D d E e F f f F e E d D c C b B a A Test #document}
489
490    test iterator-4.23 {complex iteration} -constraints {dom_c} -body {
491	IterateXML $xml1 [list document textNode]
492} -result {#document a b c d e f f e d c b a #document}
493
494    set xml1 {<?xml version="1.0"?>
495<!DOCTYPE Test><Test><A><B><C><D><E><F>f</F>e</E>d</D>c</C>b</B>a</A></Test>}
496
497    test iterator-4.24 {complex iteration} -constraints {dom_c} -body {
498	IterateXML $xml1 [list document textNode]
499} -result {#document f e d c b a a b c d e f #document}
500
501    set xml1 {<?xml version="1.0"?>
502<!DOCTYPE Test>
503<Test>test
504<A><B><C>
505    <D2><D3><D><E>eee</E><F>fff</F><G>ggg</G></D></D3></D2>ccc
506    <H2><H3><H><I>iii</I><J>jjj</J><K2><K3><K4><K>kkk</K></K4></K3></K2></H></H3></H2>ccc2
507</C></B></A></Test>}
508
509    test iterator-4.25 {complex iteration} -constraints {dom_c} -body {
510	IterateXML $xml1 [list document element textNode]
511} -result {#document Test {test
512} A B C {
513    } D2 D3 D E eee F fff G ggg {ccc
514    } H2 H3 H I iii J jjj K2 K3 K4 K kkk {ccc2
515} {ccc2
516} kkk K K4 K3 K2 jjj J iii I H H3 H2 {ccc
517    } ggg G fff F eee E D D3 D2 {
518    } C B A {test
519} Test #document}
520
521    set xml1 {<?xml version="1.0"?>
522<!DOCTYPE Test><Test>test<A>a<B>b<C>c<D2><D3><D><E>e</E><F>f</F><G>g</G></D></D3></D2>c2<H2><H3><H><I>i</I><J>j</J><K2><K3><K4><K>k</K></K4></K3></K2></H></H3></H2>c3</C></B></A></Test>}
523
524    test iterator-4.26 {complex iteration} -constraints {dom_c} -body {
525	IterateXML $xml1 [list document element textNode]
526} -result {#document Test test A a B b C c D2 D3 D E e F f G g c2 H2 H3 H I i J j K2 K3 K4 K k c3 c3 k K K4 K3 K2 j J i I H H3 H2 c2 g G f F e E D D3 D2 c C b B a A test Test #document}
527
528    test iterator-4.27 {complex iteration} -constraints {dom_c} -body {
529	IterateXML $xml1 [list document textNode]
530} -result {#document test a b c e f g c2 i j k c3 c3 k j i c2 g f e c b a test #document}
531
532    set xml1 {<?xml version="1.0"?>
533<!DOCTYPE Test><Test><A><B><C><D><X><x1/><x2/><x3/><E><e1/><e2/><e3/></E>x</X><F><f1/><f2/>f</F></D><G><g1/><g2/>g</G></C><H><h1/><h2/>h</H></B></A></Test>}
534
535    test iterator-4.28 {complex iteration} -constraints {dom_c} -body {
536	IterateXML $xml1 [list document element textNode]
537} -result {#document Test A B C D X x1 x2 x3 E e1 e2 e3 x F f1 f2 f G g1 g2 g H h1 h2 h h h2 h1 H g g2 g1 G f f2 f1 F x e3 e2 e1 E x3 x2 x1 X D C B A Test #document}
538
539    test iterator-4.29 {complex iteration} -constraints {dom_c} -body {
540	IterateXML $xml1 [list document textNode]
541} -result {#document x f g h h g f x #document}
542
543    set xml1 {<?xml version="1.0"?>
544<!DOCTYPE Test>
545<Test>This <b>is</b>text.<A>aaa<B>bbb</B><C>ccc<D>ddd</D>ccc2</C>aaa2</A></Test>}
546
547    test iterator-4.30 {complex iteration with filter} -constraints {dom_c} -body {
548	proc nodeFilter {node} {
549		set value [dom::node cget $node -nodeName]
550		if {$value == "A"} {
551			return $::dom::reject
552		} else {
553			return $::dom::accept
554		}
555	}
556
557        set document [::dom::DOMImplementation parse $xml1]
558	set iterator [dom::DocumentTraversal createNodeIterator $document \
559		-filter nodeFilter]
560	set result {}
561	for {set i 0} {$i < 40} {incr i} {
562		set node [dom::nodeIterator nextNode $iterator]
563		if {$node == ""} break;
564		set name [dom::node cget $node -nodeName]
565		if {$name != "#text"} {
566			lappend result $name
567		} else {
568			lappend result [dom::node cget $node -nodeValue]
569		}
570	}
571	rename nodeFilter {}
572	set result
573} -result {#document Test Test {This } b is text. aaa B bbb C ccc D ddd ccc2 aaa2}
574
575    test iterator-4.31 {complex reverse iteration} -constraints {dom_c} -body {
576	proc nodeFilter {node} {
577		set value [dom::node cget $node -nodeName]
578		if {$value == "A"} {
579			return $::dom::reject
580		} else {
581			return $::dom::accept
582		}
583	}
584        set document [::dom::DOMImplementation parse $xml1]
585	set iterator [dom::DocumentTraversal createNodeIterator $document \
586		-filter nodeFilter]
587	set result {}
588	for {set i 0} {$i < 30} {incr i} {
589		set node [dom::nodeIterator nextNode $iterator]
590		if {$node == ""} break;
591	}
592	for {set i 0} {$i < 30} {incr i} {
593		set node [dom::nodeIterator previousNode $iterator]
594		if {$node == ""} break;
595		set name [dom::node cget $node -nodeName]
596		if {$name != "#text"} {
597			lappend result $name
598		} else {
599			lappend result [dom::node cget $node -nodeValue]
600		}
601	}
602	rename nodeFilter {}
603	set result
604} -result {aaa2 ccc2 ddd D ccc C bbb B aaa text. is b {This } Test Test #document}
605
606    test iterator-5.1 {iterator destruction} -constraints {dom_c} -body {
607	global xml1
608        set document [::dom::DOMImplementation parse $xml1]
609	set iterator [dom::DocumentTraversal createNodeIterator $document]
610	set result [catch {::dom::DocumentTraversal destroy $iterator} errmsg]
611	list $result $errmsg
612} -result {0 {}}
613
614    test iterator-6.1 {delete document in filter proc} -constraints {dom_c} -body {
615	proc nodeFilter {node} {
616		global document
617		dom::DOMImplementation destroy $document
618		return $::dom::accept
619	}
620        set document [::dom::DOMImplementation parse $xml1]
621	set iterator [dom::DocumentTraversal createNodeIterator $document \
622		-filter nodeFilter]
623	set node [::dom::nodeIterator nextNode $iterator]
624	set result [catch {::dom::nodeIterator nextNode $iterator} errmsg]
625	rename nodeFilter {}
626	list $result $errmsg
627} -result {0 {}}
628
629    test iterator-6.2 {delete document in filter proc} -constraints {dom_c} -body {
630	proc nodeFilter {node} {
631		global document
632		dom::DOMImplementation destroy $document
633		return $::dom::accept
634	}
635        set document [::dom::DOMImplementation parse $xml1]
636	set iterator [dom::DocumentTraversal createNodeIterator $document \
637		-filter nodeFilter]
638	set node [::dom::nodeIterator nextNode $iterator]
639	set result [catch {::dom::node cget $node -nodeName} errmsg]
640	rename nodeFilter {}
641	list $result $errmsg
642} -result {1 {token not found}}
643
644    test iterator-6.3 {delete iterator in filter proc} -constraints {dom_c} -body {
645	proc nodeFilter {node} {
646		global iterator
647		dom::DocumentTraversal destroy $iterator
648		return $::dom::accept
649	}
650        set document [::dom::DOMImplementation parse $xml1]
651	set iterator [dom::DocumentTraversal createNodeIterator $document \
652		-filter nodeFilter]
653	set node [::dom::nodeIterator nextNode $iterator]
654	set result [catch {::dom::nodeIterator nextNode $iterator} errmsg]
655	rename nodeFilter {}
656	list $result $errmsg
657} -result {1 {token not found}}
658
659    test iterator-6.4 {recursively invoke filter proc} -constraints {dom_c} -match glob -body {
660	proc nodeFilter {node} {
661		global iterator
662		set node [::dom::nodeIterator nextNode $iterator]
663		return $::dom::accept
664	}
665	set document [::dom::DOMImplementation parse $xml1]
666	set iterator [dom::DocumentTraversal createNodeIterator $document \
667		-filter nodeFilter]
668	expectError {
669	    ::dom::nodeIterator nextNode $iterator
670	}
671    } -cleanup {
672	rename nodeFilter {}
673    } -result {too many nested calls * (infinite loop?)}
674
675    ::tcltest::cleanupTests
676}
677
678namespace delete ::dom::iteratorTest
679
680return
681