1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6use Test::More tests => 46;
7use Test::Exception;
8
9BEGIN { 
10    use_ok('Tree::Simple::Visitor::FindByPath');
11}
12
13use Tree::Simple;
14
15my $first_search = Tree::Simple->new("1.2.2");
16isa_ok($first_search, 'Tree::Simple');
17
18my $second_search = Tree::Simple->new("3.2.1");
19isa_ok($second_search, 'Tree::Simple');
20
21my $tree = Tree::Simple->new(Tree::Simple->ROOT)
22                       ->addChildren(
23                            Tree::Simple->new("1")
24                                        ->addChildren(
25                                            Tree::Simple->new("1.1"),
26                                            Tree::Simple->new("1.2")
27                                                        ->addChildren(
28                                                            Tree::Simple->new("1.2.1"),
29                                                            $first_search
30                                                        ),
31                                            Tree::Simple->new("1.3")                                                                                                
32                                        ),
33                            Tree::Simple->new("2")
34                                        ->addChildren(
35                                            Tree::Simple->new("2.1"),
36                                            Tree::Simple->new("2.2")
37                                        ),                            
38                            Tree::Simple->new("3")
39                                        ->addChildren(
40                                            Tree::Simple->new("3.1"),
41                                            Tree::Simple->new("3.2")->addChild($second_search),
42                                            Tree::Simple->new("3.3")                                                                                                
43                                        ),                            
44                            Tree::Simple->new("4")                                                        
45                                        ->addChildren(
46                                            Tree::Simple->new("4.1")
47                                        )                            
48                       );
49isa_ok($tree, 'Tree::Simple');
50
51can_ok("Tree::Simple::Visitor::FindByPath", 'new');
52
53my $visitor = Tree::Simple::Visitor::FindByPath->new();
54isa_ok($visitor, 'Tree::Simple::Visitor::FindByPath');
55isa_ok($visitor, 'Tree::Simple::Visitor');
56
57can_ok($visitor, 'setSearchPath');
58can_ok($visitor, 'visit');
59can_ok($visitor, 'getResult');
60
61# test our first search path
62$visitor->setSearchPath(qw(1 1.2 1.2.2));
63$tree->accept($visitor);
64is($visitor->getResult(), $first_search, '... this should be what we got back');
65
66{
67    my @results = $visitor->getResults();
68    is(scalar(@results), 4, '... go four results (including root)');
69    is($results[0], $tree, '... got the right first result');
70    is($results[1], $tree->getChild(0), '... got the right next result');    
71    is($results[2], $tree->getChild(0)->getChild(1), '... got the right next result');  
72    is($results[3], $first_search, '... got the right next result');            
73}
74
75# test our first failing search path
76$visitor->setSearchPath(qw(1 1.2 1.2.3));
77$tree->accept($visitor);
78ok(!defined($visitor->getResult()), '... match failed so we get undef back');
79
80{
81    my @results = $visitor->getResults();
82    is(scalar(@results), 3, '... go three results (including root)');
83    is($results[0], $tree, '... got the right first result');
84    is($results[1], $tree->getChild(0), '... got the right next result');    
85    is($results[2], $tree->getChild(0)->getChild(1), '... got the right next result');            
86}
87
88# test our next failing search path
89$visitor->setSearchPath(qw(1 1.5 1.2.3));
90$tree->accept($visitor);
91ok(!defined($visitor->getResult()), '... match failed so we get undef back');
92
93{
94    my @results = $visitor->getResults();
95    is(scalar(@results), 2, '... go two results (including root)');
96    is($results[0], $tree, '... got the right first result');
97    is($results[1], $tree->getChild(0), '... got the right next result');    
98}
99
100# test our next failing search path
101$visitor->setSearchPath(qw(100 1.5 1.2.3));
102$tree->accept($visitor);
103ok(!defined($visitor->getResult()), '... match failed so we get undef back');
104
105{
106    my @results = $visitor->getResults();
107    is(scalar(@results), 0, '... go no results (including root)');
108}
109
110# add a node filter
111can_ok($visitor, 'setNodeFilter');
112$visitor->setNodeFilter(sub { "Tree_" . $_[0]->getNodeValue() });
113
114# test our new search path with filter
115$visitor->setSearchPath(qw(Tree_3 Tree_3.2 Tree_3.2.1));
116$tree->accept($visitor);
117is($visitor->getResult(), $second_search, '... this should be what we got back');
118
119{
120    my @results = $visitor->getResults();
121    is(scalar(@results), 4, '... go four results (including root)');
122    is($results[0], $tree, '... got the right first result');
123    is($results[1], $tree->getChild(2), '... got the right next result');    
124    is($results[2], $tree->getChild(2)->getChild(1), '... got the right next result');  
125    is($results[3], $second_search, '... got the right next result');            
126}
127
128# use the trunk
129can_ok($visitor, 'includeTrunk');
130$visitor->includeTrunk(1);
131
132# test path failure
133$visitor->setSearchPath(qw(Tree_root Tree_1 Tree_5 Tree_35));
134$tree->accept($visitor);
135ok(!defined($visitor->getResult()), '... should fail, and we get back undef');
136
137{
138    my @results = $visitor->getResults();
139    is(scalar(@results), 2, '... we should have gotten the root, and 1');
140    is($results[0], $tree, '... we should not have gotten farther than the 1');
141    is($results[1], $tree->getChild(0), '... we should not have gotten farther than the 1');
142}
143
144# test total path failure
145$visitor->setSearchPath(qw(8 5 35));
146$tree->accept($visitor);
147ok(!defined($visitor->getResult()), '... should fail, and we get back undef');
148
149{
150    my @results = $visitor->getResults();
151    is(scalar(@results), 0, '... we should have gotten nothing at all');
152}
153
154# test some error conditions
155
156throws_ok {
157    $visitor->visit();
158} qr/Insufficient Arguments/, '... this should die';
159
160throws_ok {
161    $visitor->visit("Fail");
162} qr/Insufficient Arguments/, '... this should die';
163
164throws_ok {
165    $visitor->visit([]);
166} qr/Insufficient Arguments/, '... this should die';
167
168throws_ok {
169    $visitor->visit(bless({}, "Fail"));
170} qr/Insufficient Arguments/, '... this should die';
171
172throws_ok {
173    $visitor->setSearchPath();
174} qr/Insufficient Arguments/, '... this should die';
175