1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6use Test::More tests => 49;
7use Test::Exception;
8
9BEGIN { 
10    use_ok('Tree::Simple::Visitor::FindByNodeValue');
11    use_ok('Tree::Simple::Visitor::BreadthFirstTraversal');
12}
13
14use Tree::Simple;
15
16my $first_search = Tree::Simple->new("1.2.2");
17isa_ok($first_search, 'Tree::Simple');
18
19my $first_search_NodeValue = '1.2.2';
20
21my $second_search = Tree::Simple->new("3.2.1");
22isa_ok($second_search, 'Tree::Simple');
23
24my $second_search_NodeValue = '3.2.1';
25my $second_search_UID = $second_search->getUID();
26
27my $tree = Tree::Simple->new(Tree::Simple->ROOT)
28                       ->addChildren(
29                            Tree::Simple->new("1")
30                                        ->addChildren(
31                                            Tree::Simple->new("1.1"),
32                                            Tree::Simple->new("1.2")
33                                                        ->addChildren(
34                                                            Tree::Simple->new("1.2.1"),
35                                                            $first_search
36                                                        ),
37                                            Tree::Simple->new("1.3")                                                                                                
38                                        ),
39                            Tree::Simple->new("2")
40                                        ->addChildren(
41                                            Tree::Simple->new("2.1"),
42                                            Tree::Simple->new("2.2")
43                                        ),                            
44                            Tree::Simple->new("3")
45                                        ->addChildren(
46                                            Tree::Simple->new("3.1"),
47                                            Tree::Simple->new("3.2")->addChild($second_search),
48                                            Tree::Simple->new("3.3")                                                                                                
49                                        ),                            
50                            Tree::Simple->new("4")                                                        
51                                        ->addChildren(
52                                            Tree::Simple->new("4.1")
53                                        )                            
54                       );
55isa_ok($tree, 'Tree::Simple');
56
57can_ok("Tree::Simple::Visitor::FindByNodeValue", 'new');
58
59# check the normal behavior
60{
61    my $visitor = Tree::Simple::Visitor::FindByNodeValue->new();
62    isa_ok($visitor, 'Tree::Simple::Visitor::FindByNodeValue');
63    isa_ok($visitor, 'Tree::Simple::Visitor');
64    
65    can_ok($visitor, 'searchForNodeValue');
66    can_ok($visitor, 'visit');
67    can_ok($visitor, 'getResult');
68    
69    $visitor->searchForNodeValue($first_search_NodeValue);
70    $tree->accept($visitor);
71    
72    my $match = $visitor->getResult();
73    ok(defined($match), '... we got a result');
74    is($match, $first_search, '... and it is our first search tree');
75}
76
77# test the node filter and make it fail
78{
79    my $visitor = Tree::Simple::Visitor::FindByNodeValue->new();
80    isa_ok($visitor, 'Tree::Simple::Visitor::FindByNodeValue');
81    isa_ok($visitor, 'Tree::Simple::Visitor');
82    
83    $visitor->searchForNodeValue($first_search_NodeValue);
84    # make our search fail
85    $visitor->setNodeFilter(sub {
86        my ($tree) = @_;
87        return $tree->getNodeValue() ne "1.2.2";
88    });
89    
90    $tree->accept($visitor);
91    
92    my $match = $visitor->getResult();
93    ok(!defined($match), '... match failed as expected');
94}
95
96# test the second match
97{
98    my $visitor = Tree::Simple::Visitor::FindByNodeValue->new();
99    isa_ok($visitor, 'Tree::Simple::Visitor::FindByNodeValue');
100    isa_ok($visitor, 'Tree::Simple::Visitor');
101    
102    $visitor->searchForNodeValue($second_search_NodeValue);
103    # make our search succed
104    $visitor->setNodeFilter(sub {
105        my ($tree) = @_;
106        return $tree->getUID() eq $second_search_UID;
107    });
108    
109    $tree->accept($visitor);
110    
111    my $match = $visitor->getResult();
112    ok(defined($match), '... match succedded as expected');
113    is($match, $second_search, '... and it is our second search tree');    
114}
115
116# check the normal behavior with includeTrunk
117{
118    my $visitor = Tree::Simple::Visitor::FindByNodeValue->new();
119    isa_ok($visitor, 'Tree::Simple::Visitor::FindByNodeValue');
120    isa_ok($visitor, 'Tree::Simple::Visitor');
121    
122    can_ok($visitor, 'includeTrunk');
123    $visitor->includeTrunk(1);
124    
125    $visitor->searchForNodeValue($tree->getNodeValue());
126    $tree->accept($visitor);
127    
128    my $match = $visitor->getResult();
129    ok(defined($match), '... we got a result');
130    is($match, $tree, '... and it is our base tree');
131}
132
133# check the traversal method behavior
134{
135    my $visitor = Tree::Simple::Visitor::FindByNodeValue->new();
136    isa_ok($visitor, 'Tree::Simple::Visitor::FindByNodeValue');
137    isa_ok($visitor, 'Tree::Simple::Visitor');
138    
139    can_ok($visitor, 'setTraversalMethod');
140    $visitor->setTraversalMethod(Tree::Simple::Visitor::BreadthFirstTraversal->new());    
141    
142    $visitor->searchForNodeValue($first_search_NodeValue);
143    $tree->accept($visitor);
144    
145    my $match = $visitor->getResult();
146    ok(defined($match), '... we got a result');
147    is($match, $first_search, '... and it is our first search tree');
148}
149
150# check the traversal method behavior with includeTrunk
151{
152    my $visitor = Tree::Simple::Visitor::FindByNodeValue->new();
153    isa_ok($visitor, 'Tree::Simple::Visitor::FindByNodeValue');
154    isa_ok($visitor, 'Tree::Simple::Visitor');
155    
156    $visitor->setTraversalMethod(Tree::Simple::Visitor::BreadthFirstTraversal->new());    
157    $visitor->includeTrunk(1);
158    $visitor->searchForNodeValue($tree->getNodeValue());
159    
160    $tree->accept($visitor);
161    
162    my $match = $visitor->getResult();
163    ok(defined($match), '... we got a result');
164    is($match, $tree, '... and it is our base tree');
165}
166
167
168# check errors
169{
170    my $visitor = Tree::Simple::Visitor::FindByNodeValue->new();
171    isa_ok($visitor, 'Tree::Simple::Visitor::FindByNodeValue');
172    isa_ok($visitor, 'Tree::Simple::Visitor');
173    
174    
175    # check visit
176    throws_ok {
177        $visitor->visit();
178    } qr/Insufficient Arguments/, '... got the error we expected';  
179    
180    throws_ok {
181        $visitor->visit("Fail");
182    } qr/Insufficient Arguments/, '... got the error we expected';                           
183
184    throws_ok {
185        $visitor->visit([]);
186    } qr/Insufficient Arguments/, '... got the error we expected'; 
187    
188    throws_ok {
189        $visitor->visit(bless({}, "Fail"));
190    } qr/Insufficient Arguments/, '... got the error we expected'; 
191    
192    # check UID
193    throws_ok {
194        $visitor->searchForNodeValue();
195    } qr/Insufficient Arguments/, '... got the error we expected';      
196    
197    # try to visit without a UID
198    throws_ok {
199        $visitor->visit($tree);
200    } qr/Illegal Operation/, '... got the error we expected';     
201    
202    # check setTraversalMethod
203    throws_ok {
204        $visitor->setTraversalMethod();
205    } qr/Insufficient Arguments/, '... got the error we expected';  
206    
207    throws_ok {
208        $visitor->setTraversalMethod("Fail");
209    } qr/Insufficient Arguments/, '... got the error we expected';                           
210
211    throws_ok {
212        $visitor->setTraversalMethod([]);
213    } qr/Insufficient Arguments/, '... got the error we expected'; 
214    
215    throws_ok {
216        $visitor->setTraversalMethod(bless({}, "Fail"));
217    } qr/Insufficient Arguments/, '... got the error we expected';  
218    
219    throws_ok {
220        $visitor->searchForNodeValue();
221    } qr/Insufficient Arguments/, '... got the error we expected';    
222    
223    # test some edge cases
224    $visitor->searchForNodeValue($first_search_NodeValue);
225    
226    $visitor->setNodeFilter(sub { die "Nothing really" });
227    throws_ok {
228        $visitor->visit($tree);
229    } qr/Nothing really/, '... got the error we expected';  
230    
231    $visitor->setNodeFilter(sub { die bless({}, "NothingReally") });
232    throws_ok {
233        $visitor->visit($tree);
234    } "NothingReally", '... got the error we expected';                    
235        
236}
237
238