1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6use Test::More;
7
8eval "use Test::Memory::Cycle 1.02";
9plan skip_all => "Test::Memory::Cycle required for testing memory leaks" if $@;
10
11plan tests => 43;
12
13use_ok('Tree::Simple', 'use_weak_refs');
14
15#diag "parental connections are weak";
16
17{
18
19    my $tree2 = Tree::Simple->new("2");
20    ok($tree2->isRoot(), '... tree2 is a ROOT');    
21    
22    {
23        my $tree1 = Tree::Simple->new("1");
24        $tree1->addChild($tree2);
25        ok(!$tree2->isRoot(), '... now tree2 is not a ROOT');
26
27        weakened_memory_cycle_exists($tree2, '... there is a weakened cycle in tree2');
28    }
29    
30    weakened_memory_cycle_ok($tree2, '... tree2 is no longer connected to tree1');
31    ok($tree2->isRoot(), '... now tree2 is a ROOT again');
32    ok(!defined($tree2->getParent()), '... now tree2s parent is no longer defined');    
33}
34
35#diag "expand the problem to check child connections";
36
37{ 
38
39    my $tree2 = Tree::Simple->new("2");
40    ok($tree2->isRoot(), '... tree2 is a ROOT');  
41    ok($tree2->isLeaf(), '... tree2 is a Leaf');      
42    my $tree3 = Tree::Simple->new("3");  
43    ok($tree3->isRoot(), '... tree3 is a ROOT');  
44    ok($tree3->isLeaf(), '... tree3 is a Leaf'); 
45    
46    {
47        my $tree1 = Tree::Simple->new("1");
48        $tree1->addChild($tree2);
49        ok(!$tree2->isRoot(), '... now tree2 is not a ROOT');
50        $tree2->addChild($tree3);
51        ok(!$tree2->isLeaf(), '... now tree2 is not a Leaf');
52        ok(!$tree3->isRoot(), '... tree3 is no longer a ROOT');  
53        ok($tree3->isLeaf(), '... but tree3 is still a Leaf'); 
54
55        weakened_memory_cycle_exists($tree1, '... there is a cycle in tree1');
56        weakened_memory_cycle_exists($tree2, '... there is a cycle in tree2');
57        weakened_memory_cycle_exists($tree3, '... there is a cycle in tree3'); 
58    }
59    
60    weakened_memory_cycle_exists($tree2, '... calling DESTORY on tree1 broke the connection with tree2');
61    ok($tree2->isRoot(), '... now tree2 is a ROOT again');
62    ok(!$tree2->isLeaf(), '... now tree2 is a not a leaf again');    
63    ok(!defined($tree2->getParent()), '... now tree2s parent is no longer defined');    
64    cmp_ok($tree2->getChildCount(), '==', 1, '... now tree2 has one child');    
65    weakened_memory_cycle_exists($tree3, '... calling DESTORY on tree1 did not break the connection betwee tree2 and tree3');
66    ok(!$tree3->isRoot(), '... now tree3 is not a ROOT');
67    ok($tree3->isLeaf(), '... now tree3 is still a leaf');    
68    ok(defined($tree3->getParent()), '... now tree3s parent is still defined');   
69    is($tree3->getParent(), $tree2, '... now tree3s parent is still tree2');        
70}
71
72#diag "child connections are strong";
73{
74    my $tree1 = Tree::Simple->new("1");
75    my $tree2_UID;
76
77    {
78        my $tree2 = Tree::Simple->new("2");    
79        $tree1->addChild($tree2);
80        $tree2_UID = $tree2->getUID();
81        
82        weakened_memory_cycle_exists($tree1, '... tree1 is connected to tree2');
83        weakened_memory_cycle_exists($tree2, '... tree2 is connected to tree1');        
84    }
85
86    weakened_memory_cycle_exists($tree1, '... tree2 is still connected to tree1 because child connections are strong');
87    is($tree1->getChild(0)->getUID(), $tree2_UID, '... tree2 is still connected to tree1');
88    is($tree1->getChild(0)->getParent(), $tree1, '... tree2s parent is tree1');
89    cmp_ok($tree1->getChildCount(), '==', 1, '... tree1 has a child count of 1');        
90}
91
92#diag "expand upon this issue";
93{
94    my $tree1 = Tree::Simple->new("1");
95    my $tree2_UID;
96    my $tree3 = Tree::Simple->new("3");    
97
98    {
99        my $tree2 = Tree::Simple->new("2");    
100        $tree1->addChild($tree2);
101        $tree2_UID = $tree2->getUID();
102        $tree2->addChild($tree3);
103        
104        weakened_memory_cycle_exists($tree1, '... tree1 is connected to tree2');
105        weakened_memory_cycle_exists($tree2, '... tree2 is connected to tree1');    
106        weakened_memory_cycle_exists($tree3, '... tree3 is connected to tree2');            
107    }
108
109    weakened_memory_cycle_exists($tree1, '... tree2 is still connected to tree1 because child connections are strong');
110    is($tree1->getChild(0)->getUID(), $tree2_UID, '... tree2 is still connected to tree1');
111    is($tree1->getChild(0)->getParent(), $tree1, '... tree2s parent is tree1');
112    cmp_ok($tree1->getChildCount(), '==', 1, '... tree1 has a child count of 1');        
113    cmp_ok($tree1->getChild(0)->getChildCount(), '==', 1, '... tree2 is still connected to tree3');
114    is($tree1->getChild(0)->getChild(0), $tree3, '... tree2 is still connected to tree3');    
115}
116
117