1#!/usr/bin/perl 2 3use strict; 4use warnings; 5 6use Test::More tests => 37; 7use Test::Exception; 8 9BEGIN { 10 use_ok('Tree::Simple::Visitor'); 11}; 12 13use Tree::Simple; 14 15my $SIMPLE_SUB = sub { "test sub" }; 16# execute this otherwise Devel::Cover gives odd stats 17$SIMPLE_SUB->(); 18 19# check that we have a constructor 20can_ok("Tree::Simple::Visitor", 'new'); 21 22# ----------------------------------------------- 23# test the new style interface 24# ----------------------------------------------- 25 26my $visitor = Tree::Simple::Visitor->new(); 27isa_ok($visitor, 'Tree::Simple::Visitor'); 28 29my $tree = Tree::Simple->new(Tree::Simple->ROOT) 30 ->addChildren( 31 Tree::Simple->new("1") 32 ->addChildren( 33 Tree::Simple->new("1.1"), 34 Tree::Simple->new("1.2") 35 ->addChild(Tree::Simple->new("1.2.1")), 36 Tree::Simple->new("1.3") 37 ), 38 Tree::Simple->new("2"), 39 Tree::Simple->new("3"), 40 ); 41isa_ok($tree, 'Tree::Simple'); 42 43$tree->accept($visitor); 44 45can_ok($visitor, 'getResults'); 46is_deeply( 47 [ $visitor->getResults() ], 48 [ qw(1 1.1 1.2 1.2.1 1.3 2 3)], 49 '... got what we expected'); 50 51can_ok($visitor, 'setNodeFilter'); 52 53my $node_filter = sub { return "_" . $_[0]->getNodeValue() }; 54$visitor->setNodeFilter($node_filter); 55 56can_ok($visitor, 'getNodeFilter'); 57is($visitor->getNodeFilter(), "$node_filter", '... got back what we put in'); 58 59# visit the tree again to get new results now 60$tree->accept($visitor); 61 62is_deeply( 63 scalar $visitor->getResults(), 64 [ qw(_1 _1.1 _1.2 _1.2.1 _1.3 _2 _3)], 65 '... got what we expected'); 66 67# test some exceptions 68 69throws_ok { 70 $visitor->setNodeFilter(); 71} qr/Insufficient Arguments/, '... this should die'; 72 73throws_ok { 74 $visitor->setNodeFilter([]); 75} qr/Insufficient Arguments/, '... this should die'; 76 77# ----------------------------------------------- 78# test the old style interface for backwards 79# compatability 80# ----------------------------------------------- 81 82# and that our RECURSIVE constant is properly defined 83can_ok("Tree::Simple::Visitor", 'RECURSIVE'); 84# and that our CHILDREN_ONLY constant is properly defined 85can_ok("Tree::Simple::Visitor", 'CHILDREN_ONLY'); 86 87# no depth 88my $visitor1 = Tree::Simple::Visitor->new($SIMPLE_SUB); 89isa_ok($visitor1, 'Tree::Simple::Visitor'); 90 91# children only 92my $visitor2 = Tree::Simple::Visitor->new($SIMPLE_SUB, Tree::Simple::Visitor->CHILDREN_ONLY); 93isa_ok($visitor2, 'Tree::Simple::Visitor'); 94 95# recursive 96my $visitor3 = Tree::Simple::Visitor->new($SIMPLE_SUB, Tree::Simple::Visitor->RECURSIVE); 97isa_ok($visitor3, 'Tree::Simple::Visitor'); 98 99# ----------------------------------------------- 100# test constructor exceptions 101# ----------------------------------------------- 102 103# we pass a bad depth (string) 104throws_ok { 105 my $test = Tree::Simple::Visitor->new($SIMPLE_SUB, "Fail") 106} qr/Insufficient Arguments \: Depth arguement must be either RECURSIVE or CHILDREN_ONLY/, 107 '... we are expecting this error'; 108 109# we pass a bad depth (numeric) 110throws_ok { 111 my $test = Tree::Simple::Visitor->new($SIMPLE_SUB, 100) 112} qr/Insufficient Arguments \: Depth arguement must be either RECURSIVE or CHILDREN_ONLY/, 113 '... we are expecting this error'; 114 115# we pass a non-ref func argument 116throws_ok { 117 my $test = Tree::Simple::Visitor->new("Fail"); 118} qr/Insufficient Arguments \: filter function argument must be a subroutine reference/, 119 '... we are expecting this error'; 120 121# we pass a non-code-ref func arguement 122throws_ok { 123 my $test = Tree::Simple::Visitor->new([]); 124} qr/Insufficient Arguments \: filter function argument must be a subroutine reference/, 125 '... we are expecting this error'; 126 127# ----------------------------------------------- 128# test other exceptions 129# ----------------------------------------------- 130 131# and make sure we can call the visit method 132can_ok($visitor1, 'visit'); 133 134# test no arg 135throws_ok { 136 $visitor1->visit(); 137} qr/Insufficient Arguments \: You must supply a valid Tree\:\:Simple object/, 138 '... we are expecting this error'; 139 140# test non-ref arg 141throws_ok { 142 $visitor1->visit("Fail"); 143} qr/Insufficient Arguments \: You must supply a valid Tree\:\:Simple object/, 144 '... we are expecting this error'; 145 146# test non-object ref arg 147throws_ok { 148 $visitor1->visit([]); 149} qr/Insufficient Arguments \: You must supply a valid Tree\:\:Simple object/, 150 '... we are expecting this error'; 151 152my $BAD_OBJECT = bless({}, "Test"); 153 154# test non-Tree::Simple object arg 155throws_ok { 156 $visitor1->visit($BAD_OBJECT); 157} qr/Insufficient Arguments \: You must supply a valid Tree\:\:Simple object/, 158 '... we are expecting this error'; 159 160 161# ----------------------------------------------- 162# Test accept & visit 163# ----------------------------------------------- 164# Note: 165# this test could be made more robust by actually 166# getting results and testing them from the 167# Visitor object. But for right now it is good 168# enough to have the code coverage, and know 169# all the peices work. 170# ----------------------------------------------- 171 172# now make a tree 173my $tree1 = Tree::Simple->new(Tree::Simple->ROOT) 174 ->addChildren( 175 Tree::Simple->new("1.0"), 176 Tree::Simple->new("2.0"), 177 Tree::Simple->new("3.0"), 178 ); 179isa_ok($tree1, 'Tree::Simple'); 180 181cmp_ok($tree1->getChildCount(), '==', 3, '... there are 3 children here'); 182 183# and pass the visitor1 to accept 184lives_ok { 185 $tree1->accept($visitor1); 186} '.. this passes fine'; 187 188# and pass the visitor2 to accept 189lives_ok { 190 $tree1->accept($visitor2); 191} '.. this passes fine'; 192 193# and pass the visitor3 to accept 194lives_ok { 195 $tree1->accept($visitor3); 196} '.. this passes fine'; 197 198# ---------------------------------------------------- 199# test some misc. weirdness to get the coverage up :P 200# ---------------------------------------------------- 201 202# check that includeTrunk works as we expect it to 203{ 204 my $visitor = Tree::Simple::Visitor->new(); 205 ok(!$visitor->includeTrunk(), '... this should be false right now'); 206 207 $visitor->includeTrunk("true"); 208 ok($visitor->includeTrunk(), '... this should be true now'); 209 210 $visitor->includeTrunk(undef); 211 ok($visitor->includeTrunk(), '... this should be true still'); 212 213 $visitor->includeTrunk(""); 214 ok(!$visitor->includeTrunk(), '... this should be false again'); 215} 216 217# check that clearNodeFilter works as we expect it to 218{ 219 my $visitor = Tree::Simple::Visitor->new(); 220 221 my $filter = sub { "filter" }; 222 223 $visitor->setNodeFilter($filter); 224 is($visitor->getNodeFilter(), $filter, 'our node filter is set correctly'); 225 226 $visitor->clearNodeFilter(); 227 ok(! defined($visitor->getNodeFilter()), '... our node filter has now been undefined'); 228} 229 230 231