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