1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6use Test::More tests => 292;
7
8BEGIN { 
9	use_ok('Tree::Simple'); 
10};
11
12## ----------------------------------------------------------------------------
13## Test for Tree::Simple
14## ----------------------------------------------------------------------------
15# NOTE:
16# This test checks the base functionality of the Tree::Simple object. The test
17# is so large because (at the moment) each test relies upon the tree created 
18# by the previous tests. It is not the most efficient or sensible thing to do
19# i know, but its how it is for now. There are close to 300 tests here, so 
20# splitting them up would be a chore. 
21## ----------------------------------------------------------------------------
22
23# check that we have a constructor
24can_ok("Tree::Simple", 'new');
25# and that our ROOT constant is properly defined
26can_ok("Tree::Simple", 'ROOT');
27
28# make a root for our tree
29my $tree = Tree::Simple->new("root tree", Tree::Simple->ROOT);
30isa_ok($tree, 'Tree::Simple');
31
32# test the interface
33
34can_ok($tree, '_init');
35can_ok($tree, '_setParent');
36
37can_ok($tree, 'isRoot');
38can_ok($tree, 'isLeaf');
39
40can_ok($tree, 'setNodeValue');
41can_ok($tree, 'getNodeValue');
42
43can_ok($tree, 'getDepth');
44can_ok($tree, 'fixDepth');
45can_ok($tree, 'getParent');
46
47can_ok($tree, 'getChildCount');
48
49can_ok($tree, 'addChild');
50can_ok($tree, 'addChildren');
51can_ok($tree, 'insertChild');
52can_ok($tree, 'insertChildren');
53can_ok($tree, 'removeChildAt');
54can_ok($tree, 'removeChild');
55can_ok($tree, 'getChild');
56can_ok($tree, 'getAllChildren');
57
58can_ok($tree, 'addSibling');
59can_ok($tree, 'addSiblings');
60can_ok($tree, 'insertSibling');
61can_ok($tree, 'insertSiblings');
62can_ok($tree, 'getSibling');
63can_ok($tree, 'getAllSiblings');
64
65can_ok($tree, 'traverse');
66can_ok($tree, 'accept');
67can_ok($tree, 'clone');
68can_ok($tree, 'cloneShallow');
69
70can_ok($tree, 'DESTROY');
71
72# verfiy that it is a root
73ok($tree->isRoot());
74
75# and since it has no children
76# it is also a leaf node
77ok($tree->isLeaf());
78
79# check the value of the node,
80# it should be root
81is($tree->getNodeValue(), "root tree", '... this tree is a root');
82
83# we have no children yet
84cmp_ok($tree->getChildCount(), '==', 0, '... we have no children yet');
85
86# check the depth
87cmp_ok($tree->getDepth(), '==', -1, '... we have no depth yet');
88
89# check the index
90cmp_ok($tree->getIndex(), '==', -1, '... root trees have no index');
91
92can_ok($tree, 'getUID');
93
94is($tree->getUID(), $tree->getUID(), '... UIDs match for the same object');
95is("$tree", "Tree::Simple=HASH(" . $tree->getUID() . ")", '... our UID is derived from our hex address'); 
96
97can_ok($tree, 'setUID');
98$tree->setUID("This is our unique identifier");
99
100is($tree->getUID(), 'This is our unique identifier', '... UIDs match what we have set it to');
101isnt("$tree", "Tree::Simple=HASH(" . $tree->getUID() . ")", '... our UID is no longer derived from our hex address'); 
102
103## ----------------------------------------------------------------------------
104## testing adding children
105## ----------------------------------------------------------------------------
106
107# create a child
108my $sub_tree = Tree::Simple->new("1.0");
109isa_ok($sub_tree, 'Tree::Simple');
110
111# check the node value
112is($sub_tree->getNodeValue(), "1.0", '... this tree is 1.0');
113
114# since we have not assigned a parent it 
115# will still be considered a root
116ok($sub_tree->isRoot());
117
118# and since it has no children
119# it is also a leaf node
120ok($sub_tree->isLeaf());	
121
122# now add the child to our root
123$tree->addChild($sub_tree);
124
125# tree is no longer a leaf node
126# now that we have a child
127ok(!$tree->isLeaf());
128
129# now that we have assigned a parent it
130# will no longer be considered a root
131ok(!$sub_tree->isRoot());
132
133# check the depth of the sub_tree
134cmp_ok($sub_tree->getDepth(), '==', 0, '... depth should be 0 now');
135
136# check the index
137cmp_ok($sub_tree->getIndex(), '==', 0, '... index should be 0 now');
138
139# check the child count, 
140# it should be one now
141cmp_ok($tree->getChildCount(), '==', 1, '... we should have 1 children now');
142
143# get the child we inserted
144# and compare it with sub_tree
145# they should be the same
146is($tree->getChild(0), $sub_tree, '... make sure our sub_tree is fetchable');
147
148# get the parent of sub_tree
149my $sub_tree_parent = $sub_tree->getParent();
150
151# now test that the parent of
152# our sub_tree is the same as
153# our root	
154is($tree, $sub_tree_parent, '... make sure our sub_tree parent is tree');
155
156## ----------------------------------------------------------------------------
157## testing adding siblings
158## ----------------------------------------------------------------------------
159	
160# create another sub_tree
161my $sub_tree_2 = Tree::Simple->new("2.0");
162isa_ok($sub_tree_2, 'Tree::Simple');
163
164# check its node value
165is($sub_tree_2->getNodeValue(), "2.0", '... this tree is 2.0');
166
167# since we have not assigned a parent to 
168# the new sub_tree it will still be
169# considered a root
170ok($sub_tree_2->isRoot());
171
172# and since it has no children
173# it is also a leaf node
174ok($sub_tree_2->isLeaf());
175
176# add our new subtree as a sibling
177# of our first sub_tree
178$sub_tree->addSibling($sub_tree_2);
179
180# now that we have assigned a parent to
181# the new sub_tree, it will no longer be 
182# considered a root
183ok(!$sub_tree_2->isRoot());
184
185# check the depth of the sub_tree
186cmp_ok($sub_tree_2->getDepth(), '==', 0, '... depth should be 0 now');
187
188# check the index
189cmp_ok($sub_tree_2->getIndex(), '==', 1, '... index should be 1');
190
191# make sure that we now have 2 children in our root	
192cmp_ok($tree->getChildCount(), '==', 2, '... we should have 2 children now');	
193
194# and verify that the child at index 1
195# is actually our second sub_tree	
196is($tree->getChild(1), $sub_tree_2, '... make sure our sub_tree is fetchable');	
197	
198# get the parent of our second sub_tree
199my $sub_tree_2_parent = $sub_tree_2->getParent();
200
201# and make sure that it is the 
202# same as our root
203is($tree, $sub_tree_2_parent, '... make sure our sub_tree_2 parent is tree');
204	
205## ----------------------------------------------------------------------------
206## test adding child by giving parent as a constructor argument
207## ----------------------------------------------------------------------------	
208
209# we create our new sub_tree and attach it
210# to our root through its constructor
211my $sub_tree_4 = Tree::Simple->new("4.0", $tree); 	
212
213# check its node value
214is($sub_tree_4->getNodeValue(), "4.0", '... this tree is 4.0');
215
216# since we have assigned a parent to
217# the new sub_tree, it will no longer be 
218# considered a root
219ok(!$sub_tree_4->isRoot());
220
221# check the depth of the sub_tree
222cmp_ok($sub_tree_4->getDepth(), '==', 0, '... depth should be 0 now');
223
224# check the index
225cmp_ok($sub_tree_4->getIndex(), '==', 2, '... index should be 2 now');
226
227# but since it has no children
228# it is also a leaf node
229ok($sub_tree_4->isLeaf());
230
231# make sure that we now have 3 children in our root	
232cmp_ok($tree->getChildCount(), '==', 3, '... we should have 3 children now');
233
234# and verify that the child at index 2
235# is actually our latest sub_tree	
236is($tree->getChild(2), $sub_tree_4, '... make sure our sub_tree is fetchable');	
237
238# and make sure that the new sub-trees
239# parent is the same as our root
240is($tree, $sub_tree_4->getParent(), '... make sure our sub_tree_4 parent is tree');
241
242## ----------------------------------------------------------------------------
243## test inserting child 
244## ----------------------------------------------------------------------------	
245
246# we create our new sub_tree 
247my $sub_tree_3 = Tree::Simple->new("3.0"); 	
248
249# check its node value
250is($sub_tree_3->getNodeValue(), "3.0", '... this tree is 3.0');
251
252# since we have not assigned a parent to 
253# the new sub_tree it will still be
254# considered a root
255ok($sub_tree_3->isRoot());
256
257# but since it has no children
258# it is also a leaf node
259ok($sub_tree_3->isLeaf());
260
261# now insert the child at index 2
262$tree->insertChild(2, $sub_tree_3);
263
264# since we now have assigned a parent to
265# the new sub_tree, it will no longer be 
266# considered a root
267ok(!$sub_tree_3->isRoot());
268
269# check the depth of the sub_tree
270cmp_ok($sub_tree_3->getDepth(), '==', 0, '... depth should be 0 now');
271
272# check the index of 3
273cmp_ok($sub_tree_3->getIndex(), '==', 2, '... index should be 2 now');
274
275# check the index of 4 now
276cmp_ok($sub_tree_4->getIndex(), '==', 3, '... index should be 3 now');
277
278# make sure that we now have 3 children in our root	
279cmp_ok($tree->getChildCount(), '==', 4, '... we should have 4 children now');
280
281# and verify that the child at index 2
282# is actually our latest sub_tree	
283is($tree->getChild(2), $sub_tree_3, '... make sure our sub_tree is fetchable');	
284
285# and verify that the child that was 
286# at index 2 is actually now actually
287# at index 3	
288is($tree->getChild(3), $sub_tree_4, '... make sure our sub_tree is fetchable');	
289
290# and make sure that the new sub-trees
291# parent is the same as our root
292is($tree, $sub_tree_3->getParent(), '... make sure our sub_tree_3 parent is tree');	
293
294## ----------------------------------------------------------------------------
295## test getting all children and siblings
296## ----------------------------------------------------------------------------	
297
298# get it in scalar context and
299# check that our arrays are equal
300my $children = $tree->getAllChildren();
301ok eq_array($children, [ $sub_tree, $sub_tree_2, $sub_tree_3, $sub_tree_4 ]);
302
303# get it in array context and
304# check that our arrays are equal
305my @children = $tree->getAllChildren();
306ok eq_array(\@children, [ $sub_tree, $sub_tree_2, $sub_tree_3, $sub_tree_4 ]);
307
308# check that the values from both
309# contexts are equal to one another
310ok eq_array($children, \@children);
311
312# now check that the siblings of all the 
313# sub_trees are the same as the children
314foreach my $_sub_tree (@children) {
315	# test siblings in scalar context
316	my $siblings = $sub_tree->getAllSiblings();
317	ok eq_array($children, $siblings);
318	# and now in array context
319	my @siblings = $sub_tree->getAllSiblings();
320	ok eq_array($children, \@siblings);
321}
322
323## ----------------------------------------------------------------------------
324## test addChildren
325## ----------------------------------------------------------------------------	
326
327my @sub_children = (
328 			Tree::Simple->new("1.1"),
329			Tree::Simple->new("1.5"),
330			Tree::Simple->new("1.6")
331			);
332
333# now go through the children and test them
334foreach my $sub_child (@sub_children) {
335	# they should think they are root
336	ok($sub_child->isRoot());
337
338	# and they should all be leaves
339	ok($sub_child->isLeaf());
340
341	# and their node values
342	like($sub_child->getNodeValue(), qr/1\.[0-9]/, '... they at least have "1." followed by a digit');
343	
344	# and they should all have a depth of -1
345	cmp_ok($sub_child->getDepth(), '==', -1, '... depth should be -1');	
346}
347
348# check to see if we can add children
349$sub_tree->addChildren(@sub_children);
350
351# we are no longer a leaf node now
352ok(!$sub_tree->isLeaf());
353
354# make sure that we now have 3 children now	
355cmp_ok($sub_tree->getChildCount(), '==', 3, '... we should have 3 children now');
356
357# now check that sub_tree's children 
358# are the same as our list
359ok eq_array([ $sub_tree->getAllChildren() ], \@sub_children);
360
361# now go through the children again
362# and test them
363foreach my $sub_child (@sub_children) {
364	# they should no longer think
365	# they are root
366	ok(!$sub_child->isRoot());
367	
368	# but they should still think they 
369	# are leaves
370	ok($sub_child->isLeaf());
371	
372	# now we test their parental relationship
373	is($sub_tree, $sub_child->getParent(), '... their parent is the sub_tree');
374	
375	# and they should all have a depth of 1
376	cmp_ok($sub_child->getDepth(), '==', 1, '... depth should be 1');
377	
378	# now check that its siblings are the same 
379	# as the children of its parent			
380	ok eq_array([ $sub_tree->getAllChildren() ], [ $sub_child->getAllSiblings() ]);
381}
382
383## ----------------------------------------------------------------------------
384## test insertingChildren
385## ----------------------------------------------------------------------------	
386
387my @more_sub_children = (
388 			Tree::Simple->new("1.2"),
389			Tree::Simple->new("1.3"),
390			Tree::Simple->new("1.4")
391			);
392
393# now go through the children and test them
394foreach my $sub_child (@more_sub_children) {
395	# they should think they are root
396	ok($sub_child->isRoot());
397
398	# and they should all be leaves
399	ok($sub_child->isLeaf());
400
401	# and their node values
402	like($sub_child->getNodeValue(), qr/1\.[0-9]/, '... they at least have "1." followed by a digit');
403	
404	# and they should all have a depth of -1
405	cmp_ok($sub_child->getDepth(), '==', -1, '... depth should be -1');	
406}
407
408# check to see if we can insert children
409$sub_tree->insertChildren(1, @more_sub_children);
410
411# make sure that we now have 6 children now	
412cmp_ok($sub_tree->getChildCount(), '==', 6, '... we should have 6 children now');
413
414# now check that sub_tree's children 
415# are the same as our list
416ok eq_array([ $sub_tree->getAllChildren() ], [ $sub_children[0], @more_sub_children, @sub_children[1 .. $#sub_children] ]);
417
418# now go through the children again
419# and test them
420foreach my $sub_child (@more_sub_children) {
421	# they should no longer think
422	# they are roots
423	ok(!$sub_child->isRoot());
424	
425	# but they should still think they 
426	# are leaves
427	ok($sub_child->isLeaf());
428	
429	# now we test their parental relationship
430	is($sub_tree, $sub_child->getParent(), '... their parent is the sub_tree');
431	
432	# and they should all have a depth of 1
433	cmp_ok($sub_child->getDepth(), '==', 1, '... depth should be 1');
434	
435	# now check that its siblings are the same 
436	# as the children of its parent
437	ok eq_array([ $sub_tree->getAllChildren() ], [ $sub_child->getAllSiblings() ]);
438}
439
440## ----------------------------------------------------------------------------
441## test addingSiblings
442## ----------------------------------------------------------------------------	
443
444my @more_children = (
445 			Tree::Simple->new("5.0"),
446			Tree::Simple->new("9.0")
447			);
448
449# now go through the children and test them
450foreach my $sub_child (@more_children) {
451	# they should think they are root
452	ok($sub_child->isRoot());
453
454	# and they should all be leaves
455	ok($sub_child->isLeaf());
456
457	# and their node values
458	like($sub_child->getNodeValue(), qr/[0-9]\.0/, '... they at least have digit followed by ".0"');
459	
460	# and they should all have a depth of -1
461	cmp_ok($sub_child->getDepth(), '==', -1, '... depth should be -1');	
462}
463
464# check to see if we can insert children
465$sub_tree->addSiblings(@more_children);
466
467# make sure that we now have 6 children now	
468cmp_ok($tree->getChildCount(), '==', 6, '... we should have 6 children now');
469
470# now check that tree's new children 
471# are the same as our list
472is($tree->getChild(4), $more_children[0], '... they are the same');
473is($tree->getChild(5), $more_children[1], '... they are the same');
474
475# now go through the children again
476# and test them
477foreach my $sub_child (@more_children) {
478	# they should no longer think
479	# they are roots
480	ok(!$sub_child->isRoot());
481	
482	# but they should still think they 
483	# are leaves
484	ok($sub_child->isLeaf());
485	
486	# now we test their parental relationship
487	is($tree, $sub_child->getParent(), '... their parent is the tree');
488	
489	# and they should all have a depth of 1
490	cmp_ok($sub_child->getDepth(), '==', 0, '... depth should be 0');
491	
492	# now check that its siblings are the same 
493	# as the children of its parent			
494	ok eq_array([ $tree->getAllChildren() ], [ $sub_child->getAllSiblings() ]);
495}
496
497## ----------------------------------------------------------------------------
498## test insertSibling
499## ----------------------------------------------------------------------------	
500
501my $new_sibling = Tree::Simple->new("8.0"); 
502
503# they should think they are root
504ok($new_sibling->isRoot());
505
506# and they should all be leaves
507ok($new_sibling->isLeaf());
508
509# and their node values
510is($new_sibling->getNodeValue(), "8.0", '... node value should be 6.0');
511
512# and they should all have a depth of -1
513cmp_ok($new_sibling->getDepth(), '==', -1, '... depth should be -1');	
514
515# check to see if we can insert children
516$sub_tree->insertSibling(5, $new_sibling);
517
518# make sure that we now have 6 children now	
519cmp_ok($tree->getChildCount(), '==', 7, '... we should have 7 children now');
520
521# now check that sub_tree's new sibling
522# is in the right place and that it 
523# should have displaced the old value at
524# that index to index + 1 
525is($tree->getChild(4), $more_children[0], '... they are the same');
526is($tree->getChild(5), $new_sibling, '... they are the same');
527is($tree->getChild(6), $more_children[1], '... they are the same');
528
529# they should no longer think
530# they are roots
531ok(!$new_sibling->isRoot());
532
533# but they should still think they 
534# are leaves
535ok($new_sibling->isLeaf());
536
537# now we test their parental relationship
538is($tree, $new_sibling->getParent(), '... their parent is the tree');
539
540# and they should all have a depth of 1
541cmp_ok($new_sibling->getDepth(), '==', 0, '... depth should be 0');
542	
543# now check that its siblings are the same 
544# as the children of its parent			
545ok eq_array([ $tree->getAllChildren() ], [ $new_sibling->getAllSiblings() ]);
546
547## ----------------------------------------------------------------------------
548## test inserting Siblings
549## ----------------------------------------------------------------------------	
550
551my @even_more_children = (
552 			Tree::Simple->new("6.0"),
553			Tree::Simple->new("7.0")
554			);
555
556# now go through the children and test them
557foreach my $sub_child (@even_more_children) {
558	# they should think they are root
559	ok($sub_child->isRoot());
560
561	# and they should all be leaves
562	ok($sub_child->isLeaf());
563
564	# and their node values
565	like($sub_child->getNodeValue(), qr/[0-9]\.0/, '... they at least have digit followed by ".0"');
566	
567	# and they should all have a depth of -1
568	cmp_ok($sub_child->getDepth(), '==', -1, '... depth should be -1');	
569}
570
571# check to see if we can insert children
572$sub_tree->insertSiblings(5, @even_more_children);
573
574# make sure that we now have 6 children now	
575cmp_ok($tree->getChildCount(), '==', 9, '... we should have 6 children now');
576
577# now check that tree's new children 
578# are the same as our list
579is($tree->getChild(4), $more_children[0], '... they are the same');
580is($tree->getChild(5), $even_more_children[0], '... they are the same');
581is($tree->getChild(6), $even_more_children[1], '... they are the same');
582is($tree->getChild(7), $new_sibling, '... they are the same');
583is($tree->getChild(8), $more_children[1], '... they are the same');
584
585# now go through the children again
586# and test them
587foreach my $sub_child (@even_more_children) {
588	# they should no longer think
589	# they are roots
590	ok(!$sub_child->isRoot());
591	
592	# but they should still think they 
593	# are leaves
594	ok($sub_child->isLeaf());
595	
596	# now we test their parental relationship
597	is($tree, $sub_child->getParent(), '... their parent is the tree');
598	
599	# and they should all have a depth of 1
600	cmp_ok($sub_child->getDepth(), '==', 0, '... depth should be 0');
601	
602	# now check that its siblings are the same 
603	# as the children of its parent			
604	ok eq_array([ $tree->getAllChildren() ], [ $sub_child->getAllSiblings() ]);
605}
606
607## ----------------------------------------------------------------------------
608## test getChild and getSibling
609## ----------------------------------------------------------------------------	
610
611# make sure that getChild returns the
612# same as getSibling
613is($tree->getChild($_), $sub_tree->getSibling($_), '... siblings are the same as children') 
614	foreach (0 .. $tree->getChildCount());
615
616## ----------------------------------------------------------------------------
617## test self referential returns
618## ----------------------------------------------------------------------------	
619
620# addChildren's return value is actually $self
621# so that method calls can be chained
622my $self_ref_tree_test = Tree::Simple->new("3.1", $sub_tree_3)
623								->addChildren(
624									Tree::Simple->new("3.1.1"),
625									Tree::Simple->new("3.1.2")
626								);
627# make sure that it true
628isa_ok($self_ref_tree_test, 'Tree::Simple');
629
630# it shouldnt be a root
631ok(!$self_ref_tree_test->isRoot());
632
633# and it shouldnt be a leaf
634ok(!$self_ref_tree_test->isLeaf());
635
636# make sure that the parent in the constructor worked
637is($sub_tree_3, $self_ref_tree_test->getParent(), '... should be the same');
638
639# and the parents count should be 1
640cmp_ok($sub_tree_3->getChildCount(), '==', 1, '... we should have 1 child here');
641
642# make sure they show up in the count test
643cmp_ok($self_ref_tree_test->getChildCount(), '==', 2, '... we should have 2 children here');
644
645foreach my $sub_child ($self_ref_tree_test->getAllChildren()) {
646	# they should not think
647	# they are roots
648	ok(!$sub_child->isRoot());
649	
650	# but they should think they 
651	# are leaves
652	ok($sub_child->isLeaf());
653	
654	# now we test their parental relationship
655	is($self_ref_tree_test, $sub_child->getParent(), '... their parent is the tree');
656	
657	# and they should all have a depth of 1
658	cmp_ok($sub_child->getDepth(), '==', 2, '... depth should be 0');
659	
660	# now check that its siblings are the same 
661	# as the children of its parent			
662	ok eq_array([ $self_ref_tree_test->getAllChildren() ], [ $sub_child->getAllSiblings() ]);
663}
664
665## ----------------------------------------------------------------------------	
666## Test self-referential version of addChild
667## ----------------------------------------------------------------------------
668
669# addChild's return value is actually $self
670# so that method calls can be chained
671my $self_ref_tree_test_2 = Tree::Simple->new("2.1", $sub_tree_2)
672								->addChild(
673									Tree::Simple->new("2.1.1")
674								);
675# make sure that it true
676isa_ok($self_ref_tree_test_2, 'Tree::Simple');
677
678# it shouldnt be a root
679ok(!$self_ref_tree_test_2->isRoot());
680
681# and it shouldnt be a leaf
682ok(!$self_ref_tree_test_2->isLeaf());
683
684# make sure that the parent in the constructor worked
685is($sub_tree_2, $self_ref_tree_test_2->getParent(), '... should be the same');
686
687# and the parents count should be 1
688cmp_ok($sub_tree_2->getChildCount(), '==', 1, '... we should have 1 child here');
689
690# make sure they show up in the count test
691cmp_ok($self_ref_tree_test_2->getChildCount(), '==', 1, '... we should have 1 child here');
692
693my $sub_child = $self_ref_tree_test_2->getChild(0);
694
695# they should not think
696# they are roots
697ok(!$sub_child->isRoot());
698
699# but they should think they 
700# are leaves
701ok($sub_child->isLeaf());
702
703# now we test their parental relationship
704is($self_ref_tree_test_2, $sub_child->getParent(), '... their parent is the tree');
705
706# and they should all have a depth of 1
707cmp_ok($sub_child->getDepth(), '==', 2, '... depth should be 0');
708
709# now check that its siblings are the same 
710# as the children of its parent		
711ok eq_array([ $self_ref_tree_test_2->getAllChildren() ], [ $sub_child->getAllSiblings() ]);
712
713## ----------------------------------------------------------------------------
714## test removeChildAt
715## ----------------------------------------------------------------------------	
716
717my $sub_tree_of_tree_to_remove = Tree::Simple->new("1.1.a.1");
718# make a node to remove
719my $tree_to_remove = Tree::Simple->new("1.1.a")->addChild($sub_tree_of_tree_to_remove);
720
721# test that its a root
722ok($tree_to_remove->isRoot());
723
724# and that its depth is -1
725cmp_ok($tree_to_remove->getDepth(), '==', -1, '... the depth should be -1'); 
726# and the sub-trees depth is 0
727cmp_ok($sub_tree_of_tree_to_remove->getDepth(), '==', 0, '... the depth should be 0'); 
728
729# insert it into the sub_tree
730$sub_tree->insertChild(1, $tree_to_remove);
731
732# test that it no longer thinks its a root
733ok(!$tree_to_remove->isRoot());
734
735# check thats its depth is now 1
736cmp_ok($tree_to_remove->getDepth(), '==', 1, '... the depth should be 1'); 
737# and the sub-trees depth is 2
738cmp_ok($sub_tree_of_tree_to_remove->getDepth(), '==', 2, '... the depth should be 2'); 
739
740# make sure it is there
741is($sub_tree->getChild(1), $tree_to_remove, '... these tree should be equal');		
742
743# remove the subtree (it will be returned)
744my $removed_tree = $sub_tree->removeChildAt(1);
745
746# now check that the one removed it the one 
747# we inserted origianlly
748is($removed_tree, $tree_to_remove, '... these tree should be equal');
749
750# it should think its a root again
751ok($tree_to_remove->isRoot());
752# and its depth should be back to -1
753cmp_ok($tree_to_remove->getDepth(), '==', -1, '... the depth should be -1'); 
754# and the sub-trees depth is 0
755cmp_ok($sub_tree_of_tree_to_remove->getDepth(), '==', 0, '... the depth should be 0'); 	
756
757## ----------------------------------------------------------------------------
758## test removeChild
759## ----------------------------------------------------------------------------	
760
761my $sub_tree_of_tree_to_remove2 = Tree::Simple->new("1.1.a.1");
762# make a node to remove
763my $tree_to_remove2 = Tree::Simple->new("1.1.a")->addChild($sub_tree_of_tree_to_remove2);
764
765# test that its a root
766ok($tree_to_remove2->isRoot());
767
768# and that its depth is -1
769cmp_ok($tree_to_remove2->getDepth(), '==', -1, '... the depth should be -1'); 
770# and the sub-trees depth is 0
771cmp_ok($sub_tree_of_tree_to_remove2->getDepth(), '==', 0, '... the depth should be 0'); 
772
773# insert it into the sub_tree
774$sub_tree->insertChild(1, $tree_to_remove2);
775
776# test that it no longer thinks its a root
777ok(!$tree_to_remove2->isRoot());
778
779# check thats its depth is now 1
780cmp_ok($tree_to_remove2->getDepth(), '==', 1, '... the depth should be 1'); 
781# and the sub-trees depth is 2
782cmp_ok($sub_tree_of_tree_to_remove2->getDepth(), '==', 2, '... the depth should be 2'); 
783
784# make sure it is there
785is($sub_tree->getChild(1), $tree_to_remove2, '... these tree should be equal');		
786
787# remove the subtree (it will be returned)
788my $removed_tree2 = $sub_tree->removeChild($tree_to_remove2);
789
790# now check that the one removed it the one 
791# we inserted origianlly
792is($removed_tree2, $tree_to_remove2, '... these tree should be equal');
793
794# it should think its a root again
795ok($tree_to_remove2->isRoot());
796# and its depth should be back to -1
797cmp_ok($tree_to_remove2->getDepth(), '==', -1, '... the depth should be -1'); 
798# and the sub-trees depth is 0
799cmp_ok($sub_tree_of_tree_to_remove2->getDepth(), '==', 0, '... the depth should be 0'); 	
800
801## ----------------------------------------------------------------------------
802## test removeChild backwards compatability
803## ----------------------------------------------------------------------------	
804
805# make a node to remove
806my $tree_to_remove3 = Tree::Simple->new("1.1.a");
807
808# test that its a root
809ok($tree_to_remove3->isRoot());
810
811# and that its depth is -1
812cmp_ok($tree_to_remove3->getDepth(), '==', -1, '... the depth should be -1'); 
813
814# insert it into the sub_tree
815$sub_tree->insertChild(1, $tree_to_remove3);
816
817# test that it no longer thinks its a root
818ok(!$tree_to_remove3->isRoot());
819
820# check thats its depth is now 1
821cmp_ok($tree_to_remove3->getDepth(), '==', 1, '... the depth should be 1'); 
822
823# make sure it is there
824is($sub_tree->getChild(1), $tree_to_remove3, '... these tree should be equal');		
825
826# remove the subtree (it will be returned)
827my $removed_tree3 = $sub_tree->removeChild(1);
828
829# now check that the one removed it the one 
830# we inserted origianlly
831is($removed_tree3, $tree_to_remove3, '... these tree should be equal');
832
833# it should think its a root again
834ok($tree_to_remove3->isRoot());
835# and its depth should be back to -1
836cmp_ok($tree_to_remove3->getDepth(), '==', -1, '... the depth should be -1'); 
837
838## ----------------------------------------------
839## now test the edge cases
840## ----------------------------------------------
841
842# trees at the end
843
844# make a node to remove
845my $tree_to_remove_2 = Tree::Simple->new("1.7");
846
847# add it into the sub_tree
848$sub_tree->addChild($tree_to_remove_2);
849
850# make sure it is there
851is($sub_tree->getChild($sub_tree->getChildCount() - 1), $tree_to_remove_2, '... these tree should be equal');		
852
853# remove the subtree (it will be returned)
854my $removed_tree_2 = $sub_tree->removeChildAt($sub_tree->getChildCount() - 1);
855
856# now check that the one removed it the one 
857# we inserted origianlly
858is($removed_tree_2, $tree_to_remove_2, '... these tree should be equal');
859
860# trees at the beginging
861
862# make a node to remove
863my $tree_to_remove_3 = Tree::Simple->new("1.1.-1");
864
865# add it into the sub_tree
866$sub_tree->insertChild(0, $tree_to_remove_3);
867
868# make sure it is there
869is($sub_tree->getChild(0), $tree_to_remove_3, '... these tree should be equal');		
870
871# remove the subtree (it will be returned)
872my $removed_tree_3 = $sub_tree->removeChildAt(0);
873
874# now check that the one removed it the one 
875# we inserted origianlly
876is($removed_tree_3, $tree_to_remove_3, '... these tree should be equal');		
877
878## ----------------------------------------------------------------------------
879## test traverse
880## ----------------------------------------------------------------------------	
881
882# make a control set of 
883# all the nodes we have
884my @_all_node_values = qw(
885	1.0 
886		1.1 
887		1.2
888		1.3
889		1.4
890		1.5
891		1.6
892	2.0
893		2.1
894			2.1.1
895	3.0
896		3.1
897			3.1.1
898			3.1.2
899	4.0
900	5.0
901	6.0
902	7.0
903	8.0
904	9.0
905	);
906
907my @all_node_values;
908# now collect the nodes in the actual tree
909$tree->traverse(sub {
910	my ($_tree) = @_;
911	push @all_node_values => $_tree->getNodeValue();
912	});
913
914# and compare the two
915is_deeply(\@_all_node_values, \@all_node_values, '... our nodes match our control nodes');
916
917# test traverse with both pre- and post- methods
918# make a control set of 
919# all the nodes we have with XML-style
920my @_all_node_values_post_traverse = qw(
921	1.0 
922		1.1 
923        1.1
924		1.2
925        1.2
926		1.3
927        1.3
928		1.4
929        1.4
930		1.5
931        1.5
932		1.6
933        1.6
934    1.0
935	2.0
936		2.1
937			2.1.1
938            2.1.1
939        2.1
940    2.0
941	3.0
942		3.1
943			3.1.1
944            3.1.1
945			3.1.2
946            3.1.2
947        3.1
948    3.0
949	4.0
950    4.0
951	5.0
952    5.0
953	6.0
954    6.0
955	7.0
956    7.0
957	8.0
958	8.0
959	9.0
960	9.0
961	);
962
963
964my @all_node_values_post_traverse;
965# now collect the nodes in the actual tree
966$tree->traverse(sub {
967	    my ($_tree) = @_;
968	    push @all_node_values_post_traverse => $_tree->getNodeValue();
969	},
970    sub {
971        my ($_tree) = @_;
972        push @all_node_values_post_traverse => $_tree->getNodeValue();
973    }
974);
975
976# and compare the two
977is_deeply(\@_all_node_values_post_traverse, \@all_node_values_post_traverse,
978  '... our nodes match our control nodes for post traverse method');
979
980
981## ----------------------------------------------------------------------------
982## test size
983## ----------------------------------------------------------------------------	
984
985cmp_ok($tree->size(), '==', (scalar(@_all_node_values) + 1), '... our size is as we expect it to be');
986
987# NOTE:
988# it is (scalar(@_all_node_values) + 1) so that 
989# we account for the root node which is not in 
990# the list.
991
992## ----------------------------------------------------------------------------
993## test height
994## ----------------------------------------------------------------------------	
995
996cmp_ok($tree->height(), '==', 4, '... our height is as we expect it to be');
997
998## ----------------------------------------------------------------------------
999## test clone
1000## ----------------------------------------------------------------------------	
1001
1002# clone the whole tree
1003my $tree_clone = $tree->clone();
1004
1005my @all_cloned_node_values;
1006# collect all the cloned values
1007$tree_clone->traverse(sub {
1008	my ($_tree) = @_;
1009	push @all_cloned_node_values => $_tree->getNodeValue();
1010	});
1011
1012# make sure that our cloned values equal to our control
1013ok eq_array(\@_all_node_values, \@all_cloned_node_values);
1014# and make sure they also match the original tree
1015ok eq_array(\@all_node_values, \@all_cloned_node_values);
1016
1017# now change all the node values
1018$tree_clone->traverse(sub {
1019	my ($_tree) = @_;
1020	$_tree->setNodeValue("-> " . $_tree->getNodeValue());
1021	});
1022
1023my @all_cloned_node_values_changed;
1024# collect them again	
1025$tree_clone->traverse(sub {
1026	my ($_tree) = @_;
1027	push @all_cloned_node_values_changed => $_tree->getNodeValue();
1028	});	
1029
1030# make a copy of our control and cange it too	
1031my @_all_node_values_changed = map { "-> $_" } @_all_node_values;	
1032
1033# now both our changed values should be correct
1034ok eq_array(\@_all_node_values_changed, \@all_cloned_node_values_changed);
1035
1036my @all_node_values_check;
1037# now traverse the original tree again and make sure
1038# that the nodes are not changed
1039$tree->traverse(sub {
1040	my ($_tree) = @_;
1041	push @all_node_values_check => $_tree->getNodeValue();
1042	});
1043
1044# this can be accomplished by checking them 
1045# against our control again
1046ok eq_array(\@_all_node_values, \@all_node_values_check);	
1047	
1048## ----------------------------------------------------------------------------
1049## end test for Tree::Simple
1050## ----------------------------------------------------------------------------	
1051