Add Root back, plus some test and doc fixes
[bioperl-live.git] / t / Root / RootI.t
blob48d6e8aed9eef86debbfe68397d7f4b455c997f3
1 # -*-Perl-*- Test Harness script for Bioperl
2 # $Id$
4 use strict;
6 BEGIN {
7     use lib '.';
8     use Bio::Root::Test;
10     test_begin(-tests => 62);
12     use_ok 'Bio::Root::Root';
15 ok my $obj = Bio::Root::Root->new();
16 isa_ok $obj, 'Bio::Root::RootI';
18 throws_ok { $obj->throw('Testing throw') } qr/Testing throw/;# 'throw failed';
20 # test throw_not_implemented()
21 throws_ok { $obj->throw_not_implemented() } qr/EXCEPTION: Bio::Root::NotImplemented/;
24     package Bio::FooI;
25     use base qw(Bio::Root::RootI);
26     sub new {
27             my $class = shift;
28             my $self = {};
29             bless $self, ref($class) || $class;
30             return $self;
31     };
33 $obj = Bio::FooI->new();
34 throws_ok { $obj->throw_not_implemented() } qr/EXCEPTION /;
35 $obj = Bio::Root::Root->new();
37 # doesn't work in perl 5.00405
38 #my $val;
39 #eval {
40 #    my ($tfh,$tfile) = $obj->tempfile();
41 #    local * STDERR = $tfh;
42 #    $obj->warn('Testing warn');
43 #    close $tfh;
44 #    open(IN, $tfile) or die("cannot open $tfile");
45 #    $val = join("", <IN>) ;
46 #    close IN;
47 #    unlink $tfile;
48 #};
49 #ok $val =~ /Testing warn/;
50 #'verbose(0) warn did not work properly' . $val;
52 $obj->verbose(-1);
53 throws_ok { $obj->throw('Testing throw') } qr/Testing throw/;# 'verbose(-1) throw did not work properly' . $@;
55 lives_ok { $obj->warn('Testing warn') };
57 $obj->verbose(1);
58 throws_ok { $obj->throw('Testing throw') } qr/Testing throw/;# 'verbose(1) throw did not work properly' . $@;
60 # doesn't work in perl 5.00405
61 #undef $val;
62 #eval {
63 #    my ($tfh,$tfile) = $obj->tempfile();
64 #    local * STDERR = $tfh;
65 #    $obj->warn('Testing warn');
66 #    close $tfh;
67 #    open(IN, $tfile) or die("cannot open $tfile");
68 #    $val = join("", <IN>);
69 #    close IN;
70 #    unlink $tfile;
71 #};
72 #ok $val =~ /Testing warn/;# 'verbose(1) warn did not work properly' . $val;
74 my @stack = $obj->stack_trace();
75 is scalar @stack, 2;
77 my $verbobj = Bio::Root::Root->new(-verbose=>1,-strict=>1);
78 is $verbobj->verbose(), 1;
80 $Bio::Root::Root::DEBUG = 1;
81 my $seq = Bio::Root::Root->new();
82 is $seq->verbose, 1;
84 # test for bug #1343
85 my @vals = Bio::Root::RootI->_rearrange([qw(apples pears)],
86                                         -apples => 'up the',
87                                         -pears  => 'stairs');
88 is shift @vals, 'up the';
89 is shift @vals, 'stairs';
91 # test deprecated()
93 # class method
95     local $Bio::Root::Root::VERSION = 8.9;
96     warning_like{ Bio::Root::Root->deprecated('Test1') } qr/Test1/, 'simple';
97     warning_like{ Bio::Root::Root->deprecated(-message => 'Test2') } qr/Test2/;
98     warning_like{ Bio::Root::Root->deprecated('Test3', 999.999) } qr/Test3/,
99         'warns for versions below current version';
100     warning_like{ Bio::Root::Root->deprecated(-message => 'Test4',
101                                               -version => 999.999) } qr/Test4/,
102         'warns for versions below current version';
103     throws_ok{ Bio::Root::Root->deprecated('Test5', 0.001) } qr/Test5/,
104         'throws for versions above current version';
105     throws_ok{ Bio::Root::Root->deprecated(-message => 'Test6',
106                                        -version => 0.001) } qr/Test6/,
107         'throws for versions above current version';
109     throws_ok{ Bio::Root::Root->deprecated(-message => 'Test6',
110                                            -version => $Bio::Root::Root::VERSION) } qr/Test6/,
111         'throws for versions equal to current version';
113     # object method
114     my $root = Bio::Root::Root->new();
115     warning_like{ $root->deprecated('Test1') } qr/Test1/, 'simple';
116     warning_like{ $root->deprecated(-message => 'Test2') } qr/Test2/, 'simple';
117     warning_like{ $root->deprecated('Test3', 999.999) } qr/Test3/,
118         'warns for versions below current version';
119     warning_like{ $root->deprecated(-message => 'Test4',
120                                     -version => 999.999) } qr/Test4/,
121                                 'warns for versions below current version';
122     throws_ok{ $root->deprecated('Test5', 0.001) } qr/Test5/,
123       'throws for versions above current version';
124     throws_ok{ $root->deprecated(-message => 'Test6',
125                                  -version => 0.001) } qr/Test6/,
126                              'throws for versions above current version';
130 # tests for _set_from_args()
131 # Let's not pollute Bio::Root::Root namespace if possible
132 # Create temp classes instead which inherit Bio::Root::Root, then test
136     package Bio::Foo1;
137     use base qw(Bio::Root::Root);
138     our $VERSION = '2.00';
139     sub new {
140         my $class = shift;
141         my $self = {};
142         bless $self, ref($class) || $class;
144         $self->_set_from_args(\@_);
146         return $self;
147     };
150 $obj = Bio::Foo1->new(-verbose => 1, t1 => 1, '--Test-2' => 2);
151 #ok ! $obj->can('t1'), 'arg not callable';
155     package Bio::Foo2;
156     use base qw(Bio::Root::Root);
157     sub new {
158         my $class = shift;
159         my $self = {};
160         bless $self, ref($class) || $class;
162         $self->_set_from_args(\@_, -create => 1);
164         return $self;
165     };
169 $obj = Bio::Foo2->new(-verbose => 1, t3 => 1, '--Test-4' => 2);
170 ok $obj->can('t3'), 'arg callable since method was created';
171 ok $obj->can('test_4'), 'mal-formed arg callable since method was created with good name';
172 for my $m (qw(t3 test_4)) {
173     can_ok('Bio::Foo2',$m);
174     ok ! Bio::Root::Root->can($m), "Methods don't pollute original Bio::Root::Root namespace";
178     package Bio::Foo3;
179     use base qw(Bio::Root::Root);
180     sub new {
181         my $class = shift;
182         my $self = {};
183         bless $self, ref($class) || $class;
185         $self->_set_from_args(\@_, -methods => ['verbose', 't5'], -create => 1);
187         return $self;
188     };
191 $obj = Bio::Foo3->new(-verbose => 1, t5 => 1, '--Test-6' => 2);
192 can_ok $obj, 't5';
193 ok ! $obj->can('test_6'), 'arg not in method list not created';
195 can_ok ('Bio::Foo3','t5');
196 ok ! UNIVERSAL::can('Bio::Root::Root','t5'), "Methods don't pollute original Bio::Root::Root namespace";
199     package Bio::Foo4;
200     use base qw(Bio::Root::Root);
201     sub new {
202             my $class = shift;
203             my $self = {};
204             bless $self, ref($class) || $class;
206             my %args = @_;
208             $self->_set_from_args(\%args, -methods => {(verbose => 'v',
209                                                         test7 => 't7',
210                                                         test_8 => 't8')},
211                                           -create => 1);
213             return $self;
214     };
217 # with synonyms
219 $obj = Bio::Foo4->new(-verbose => 1, t7 => 1, '--Test-8' => 2);
220 is $obj->verbose, 1, 'verbose was set correctly';
221 is $obj->t7, 1, 'synonym was set correctly';
222 is $obj->test7, 1, 'real method of synonym was set correctly';
223 is $obj->test_8, 2, 'mal-formed arg correctly resolved to created method';
224 is $obj->t8, 2, 'synonym of set method was set correctly';
226 for my $m (qw(t7 test7 test_8 t8)) {
227     can_ok 'Bio::Foo4', $m;
228     ok ! UNIVERSAL::can('Bio::Root::Root','t7'), "Methods don't pollute original Bio::Root::Root namespace";
231 # test basic Root::clone()
233 my $clone = $obj->clone;
235 is $clone->t7, $obj->t7, 'clone';
236 is $clone->test7, $obj->test7, 'clone';
237 is $clone->test_8, $obj->test_8, 'clone';
238 $clone->test_8('xyz');
239 isnt $clone->test_8, $obj->test_8, 'clone changed, original didn\'t';
241 # test Root::clone() with parameter passing, only works for methods
242 # (introspection via can())
244 my $clone2 = $obj->clone(-t7 => 'foo');
246 is $clone2->t7, 'foo', 'parameters passed to clone() modify object';
247 is $obj->t7, 1, 'original is not modified';
251 # test deprecations using start_version
253     package Bio::Foo5;
254     use base qw(Bio::Root::Root);
256     our $v = '18.001';
257     our $VERSION = $v;
259     sub not_good {
260         my $self = shift;
261         $self->deprecated(-message => 'This is not good',
262                           -warn_version  => $v,
263                           -throw_version => $v + 0.001);
264     }
266     sub not_good2 {
267         my $self = shift;
268         # note, due to _rearrange, ordering is throw version, then warn version
269         $self->deprecated('This is not good',$v + 0.001,$v);
270     }
272     sub really_not_good {
273         my $self = shift;
274         $self->deprecated(-message => 'This is really not good',
275                           -warn_version  => $v - 0.001,
276                           -throw_version => $v,);
277     }
279     # version is the same as throw_version (and vice versa)
280     sub still_very_bad {
281         my $self = shift;
282         $self->deprecated(-message => 'This is still very bad',
283                           -warn_version  => $v - 0.001,
284                           -version => $v);
285     }
287     sub okay_for_now {
288         my $self = shift;
289         $self->deprecated(-message => 'This is okay for now',
290                           -warn_version  => $v + 0.001,
291                           -throw_version => $v + 0.002);
292     }
294     sub plain_incorrect {
295         my $self = shift;
296         $self->deprecated(-message => 'This is not going to work',
297                           -warn_version  => '1.2.3.4',
298                           -throw_version => 'a.b.c.d');
299     }
302 my $foo = Bio::Foo5->new();
304 throws_ok { $foo->plain_incorrect } qr/Version must be numerical/,
305     'must use proper versioning scheme';
307 warning_like{ $foo->not_good } qr/This is not good/,
308     'warns for versions >= current version';
309 # this tests the three-arg (non-named) form just to make sure it works, even
310 # though we probably won't support it
311 warning_like{ $foo->not_good2 } qr/This is not good/,
312     'warns for versions >= current version';
314 throws_ok { $foo->really_not_good } qr/This is really not good/,
315     'throws for versions >= current version';
316 throws_ok { $foo->still_very_bad } qr/This is still very bad/,
317     'throws for versions >= current version';
318 lives_ok { $foo->okay_for_now } 'No warnings/exceptions below current version';