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