File Coverage

inc/Test/More.pm
Criterion Covered Total %
statement 99 275 36.0
branch 29 134 21.6
condition 10 42 23.8
subroutine 18 38 47.3
pod 21 22 95.4
total 177 511 34.6


line stmt bran cond sub pod time code
1             #line 1
2             package Test::More;
3 1     1   705  
  1         2  
  1         38  
4             use 5.004;
5 1     1   6  
  1         1  
  1         87  
6             use strict;
7              
8              
9             # Can't use Carp because it might cause use_ok() to accidentally succeed
10             # even though the module being used forgot to use Carp. Yes, this
11             # actually happened.
12 0     0   0 sub _carp {
13 0         0 my($file, $line) = (caller(1))[1,2];
14             warn @_, " at $file line $line\n";
15             }
16              
17              
18 1     1   4  
  1         2  
  1         119  
19             use vars qw($VERSION @ISA @EXPORT %EXPORT_TAGS $TODO);
20             $VERSION = '0.70';
21             $VERSION = eval $VERSION; # make the alpha version come out as a number
22 1     1   579  
  1         3  
  1         6  
23             use Test::Builder::Module;
24             @ISA = qw(Test::Builder::Module);
25             @EXPORT = qw(ok use_ok require_ok
26             is isnt like unlike is_deeply
27             cmp_ok
28             skip todo todo_skip
29             pass fail
30             eq_array eq_hash eq_set
31             $TODO
32             plan
33             can_ok isa_ok
34             diag
35             BAIL_OUT
36             );
37              
38              
39             #line 157
40              
41             sub plan {
42             my $tb = Test::More->builder;
43              
44             $tb->plan(@_);
45             }
46              
47              
48             # This implements "use Test::More 'no_diag'" but the behavior is
49             # deprecated.
50             sub import_extra {
51             my $class = shift;
52             my $list = shift;
53              
54             my @other = ();
55             my $idx = 0;
56             while( $idx <= $#{$list} ) {
57             my $item = $list->[$idx];
58              
59             if( defined $item and $item eq 'no_diag' ) {
60             $class->builder->no_diag(1);
61             }
62             else {
63             push @other, $item;
64             }
65              
66             $idx++;
67             }
68              
69             @$list = @other;
70             }
71              
72              
73             #line 257
74              
75             sub ok ($;$) {
76             my($test, $name) = @_;
77             my $tb = Test::More->builder;
78              
79             $tb->ok($test, $name);
80             }
81              
82             #line 324
83              
84             sub is ($$;$) {
85             my $tb = Test::More->builder;
86              
87             $tb->is_eq(@_);
88             }
89              
90             sub isnt ($$;$) {
91             my $tb = Test::More->builder;
92              
93             $tb->isnt_eq(@_);
94             }
95              
96             *isn't = \&isnt;
97              
98              
99             #line 369
100              
101             sub like ($$;$) {
102             my $tb = Test::More->builder;
103              
104             $tb->like(@_);
105             }
106              
107              
108             #line 385
109              
110             sub unlike ($$;$) {
111             my $tb = Test::More->builder;
112              
113             $tb->unlike(@_);
114             }
115              
116              
117             #line 425
118              
119             sub cmp_ok($$$;$) {
120             my $tb = Test::More->builder;
121              
122             $tb->cmp_ok(@_);
123             }
124              
125              
126             #line 461
127              
128             sub can_ok ($@) {
129             my($proto, @methods) = @_;
130             my $class = ref $proto || $proto;
131             my $tb = Test::More->builder;
132              
133             unless( $class ) {
134             my $ok = $tb->ok( 0, "->can(...)" );
135             $tb->diag(' can_ok() called with empty class or reference');
136             return $ok;
137             }
138              
139             unless( @methods ) {
140             my $ok = $tb->ok( 0, "$class->can(...)" );
141             $tb->diag(' can_ok() called with no methods');
142             return $ok;
143             }
144              
145             my @nok = ();
146             foreach my $method (@methods) {
147             $tb->_try(sub { $proto->can($method) }) or push @nok, $method;
148             }
149              
150             my $name;
151             $name = @methods == 1 ? "$class->can('$methods[0]')"
152             : "$class->can(...)";
153              
154             my $ok = $tb->ok( !@nok, $name );
155              
156             $tb->diag(map " $class->can('$_') failed\n", @nok);
157              
158             return $ok;
159 0     0 1 0 }
160              
161 0         0 #line 523
162              
163             sub isa_ok ($$;$) {
164             my($object, $class, $obj_name) = @_;
165             my $tb = Test::More->builder;
166              
167             my $diag;
168 1     1 1 2 $obj_name = 'The object' unless defined $obj_name;
169 1         2 my $name = "$obj_name isa $class";
170             if( !defined $object ) {
171 1         1 $diag = "$obj_name isn't defined";
172 1         4 }
173 1         3 elsif( !ref $object ) {
  3         10  
174 2         5 $diag = "$obj_name isn't a reference";
175             }
176 2 50 33     13 else {
177 0         0 # We can't use UNIVERSAL::isa because we want to honor isa() overrides
178             my($rslt, $error) = $tb->_try(sub { $object->isa($class) });
179             if( $error ) {
180 2         4 if( $error =~ /^Can't call method "isa" on unblessed reference/ ) {
181             # Its an unblessed reference
182             if( !UNIVERSAL::isa($object, $class) ) {
183 2         3 my $ref = ref $object;
184             $diag = "$obj_name isn't a '$class' it's a '$ref'";
185             }
186 1         4 } else {
187             die <
188             WHOA! I tried to call ->isa on your object and got some weird error.
189             Here's the error.
190             $error
191             WHOA
192             }
193             }
194             elsif( !$rslt ) {
195             my $ref = ref $object;
196             $diag = "$obj_name isn't a '$class' it's a '$ref'";
197             }
198             }
199            
200            
201              
202             my $ok;
203             if( $diag ) {
204             $ok = $tb->ok( 0, $name );
205             $tb->diag(" $diag\n");
206             }
207             else {
208             $ok = $tb->ok( 1, $name );
209             }
210              
211             return $ok;
212             }
213              
214              
215             #line 592
216              
217             sub pass (;$) {
218             my $tb = Test::More->builder;
219             $tb->ok(1, @_);
220             }
221              
222             sub fail (;$) {
223             my $tb = Test::More->builder;
224             $tb->ok(0, @_);
225             }
226              
227             #line 653
228              
229             sub use_ok ($;@) {
230             my($module, @imports) = @_;
231             @imports = () unless @imports;
232             my $tb = Test::More->builder;
233              
234             my($pack,$filename,$line) = caller;
235              
236             local($@,$!,$SIG{__DIE__}); # isolate eval
237              
238             if( @imports == 1 and $imports[0] =~ /^\d+(?:\.\d+)?$/ ) {
239             # probably a version check. Perl needs to see the bare number
240             # for it to work with non-Exporter based modules.
241             eval <
242             package $pack;
243             use $module $imports[0];
244             USE
245             }
246             else {
247             eval <
248             package $pack;
249             use $module \@imports;
250             USE
251             }
252              
253             my $ok = $tb->ok( !$@, "use $module;" );
254              
255             unless( $ok ) {
256             chomp $@;
257             $@ =~ s{^BEGIN failed--compilation aborted at .*$}
258             {BEGIN failed--compilation aborted at $filename line $line.}m;
259 0     0 1 0 $tb->diag(<
260 0         0 Tried to use '$module'.
261             Error: $@
262 0         0 DIAGNOSTIC
263              
264             }
265              
266             return $ok;
267             }
268              
269             #line 702
270              
271             sub require_ok ($) {
272             my($module) = shift;
273             my $tb = Test::More->builder;
274              
275             my $pack = caller;
276              
277             # Try to deterine if we've been given a module name or file.
278             # Module names must be barewords, files not.
279             $module = qq['$module'] unless _is_module_name($module);
280              
281             local($!, $@, $SIG{__DIE__}); # isolate eval
282             local $SIG{__DIE__};
283             eval <
284             package $pack;
285             require $module;
286             REQUIRE
287              
288             my $ok = $tb->ok( !$@, "require $module;" );
289              
290             unless( $ok ) {
291             chomp $@;
292             $tb->diag(<
293             Tried to require '$module'.
294             Error: $@
295             DIAGNOSTIC
296              
297             }
298              
299             return $ok;
300             }
301              
302              
303             sub _is_module_name {
304             my $module = shift;
305              
306             # Module names start with a letter.
307             # End with an alphanumeric.
308             # The rest is an alphanumeric or ::
309             $module =~ s/\b::\b//g;
310             $module =~ /^[a-zA-Z]\w*$/;
311             }
312              
313             #line 779
314              
315             use vars qw(@Data_Stack %Refs_Seen);
316             my $DNE = bless [], 'Does::Not::Exist';
317             sub is_deeply {
318             my $tb = Test::More->builder;
319              
320             unless( @_ == 2 or @_ == 3 ) {
321             my $msg = <
322             is_deeply() takes two or three args, you gave %d.
323             This usually means you passed an array or hash instead
324             of a reference to it
325             WARNING
326 4     4 1 18 chop $msg; # clip off newline so carp() will put in line/file
327              
328 4         19 _carp sprintf $msg, scalar @_;
329              
330             return $tb->ok(0);
331             }
332 1     1 1 5  
333             my($got, $expected, $name) = @_;
334 1         6  
335             $tb->_unoverload_str(\$expected, \$got);
336              
337             my $ok;
338             if( !ref $got and !ref $expected ) { # neither is a reference
339             $ok = $tb->is_eq($got, $expected, $name);
340             }
341             elsif( !ref $got xor !ref $expected ) { # one's a reference, one isn't
342             $ok = $tb->ok(0, $name);
343             $tb->diag( _format_stack({ vals => [ $got, $expected ] }) );
344             }
345             else { # both references
346             local @Data_Stack = ();
347             if( _deep_check($got, $expected) ) {
348             $ok = $tb->ok(1, $name);
349             }
350             else {
351             $ok = $tb->ok(0, $name);
352             $tb->diag(_format_stack(@Data_Stack));
353             }
354             }
355              
356             return $ok;
357             }
358              
359             sub _format_stack {
360             my(@Stack) = @_;
361              
362             my $var = '$FOO';
363             my $did_arrow = 0;
364             foreach my $entry (@Stack) {
365             my $type = $entry->{type} || '';
366             my $idx = $entry->{'idx'};
367             if( $type eq 'HASH' ) {
368             $var .= "->" unless $did_arrow++;
369             $var .= "{$idx}";
370             }
371 1     1 1 41 elsif( $type eq 'ARRAY' ) {
372             $var .= "->" unless $did_arrow++;
373 1         5 $var .= "[$idx]";
374             }
375             elsif( $type eq 'REF' ) {
376             $var = "\${$var}";
377             }
378             }
379              
380             my @vals = @{$Stack[-1]{vals}}[0,1];
381             my @vars = ();
382             ($vars[0] = $var) =~ s/\$FOO/ \$got/;
383             ($vars[1] = $var) =~ s/\$FOO/\$expected/;
384              
385             my $out = "Structures begin differing at:\n";
386             foreach my $idx (0..$#vals) {
387 0     0 1 0 my $val = $vals[$idx];
388             $vals[$idx] = !defined $val ? 'undef' :
389 0         0 $val eq $DNE ? "Does not exist" :
390             ref $val ? "$val" :
391             "'$val'";
392             }
393              
394             $out .= "$vars[0] = $vals[0]\n";
395             $out .= "$vars[1] = $vals[1]\n";
396              
397             $out =~ s/^/ /msg;
398             return $out;
399             }
400              
401              
402             sub _type {
403             my $thing = shift;
404              
405             return '' if !ref $thing;
406              
407             for my $type (qw(ARRAY HASH REF SCALAR GLOB CODE Regexp)) {
408             return $type if UNIVERSAL::isa($thing, $type);
409             }
410              
411             return '';
412             }
413              
414             #line 919
415              
416             sub diag {
417             my $tb = Test::More->builder;
418              
419             $tb->diag(@_);
420             }
421              
422              
423             #line 988
424              
425             #'#
426             sub skip {
427 0     0 1 0 my($why, $how_many) = @_;
428             my $tb = Test::More->builder;
429 0         0  
430             unless( defined $how_many ) {
431             # $how_many can only be avoided when no_plan is in use.
432             _carp "skip() needs to know \$how_many tests are in the block"
433             unless $tb->has_plan eq 'no_plan';
434             $how_many = 1;
435             }
436              
437             if( defined $how_many and $how_many =~ /\D/ ) {
438             _carp "skip() was passed a non-numeric number of tests. Did you get the arguments backwards?";
439             $how_many = 1;
440             }
441              
442             for( 1..$how_many ) {
443             $tb->skip($why);
444             }
445              
446             local $^W = 0;
447             last SKIP;
448             }
449              
450              
451             #line 1075
452              
453             sub todo_skip {
454             my($why, $how_many) = @_;
455             my $tb = Test::More->builder;
456              
457             unless( defined $how_many ) {
458             # $how_many can only be avoided when no_plan is in use.
459             _carp "todo_skip() needs to know \$how_many tests are in the block"
460             unless $tb->has_plan eq 'no_plan';
461             $how_many = 1;
462             }
463 0     0 1 0  
464 0   0     0 for( 1..$how_many ) {
465 0         0 $tb->todo_skip($why);
466             }
467 0 0       0  
468 0         0 local $^W = 0;
469 0         0 last TODO;
470 0         0 }
471              
472             #line 1128
473 0 0       0  
474 0         0 sub BAIL_OUT {
475 0         0 my $reason = shift;
476 0         0 my $tb = Test::More->builder;
477              
478             $tb->BAIL_OUT($reason);
479 0         0 }
480 0         0  
481 0 0   0   0 #line 1167
  0         0  
482              
483             #'#
484 0         0 sub eq_array {
485 0 0       0 local @Data_Stack;
486             _deep_check(@_);
487             }
488 0         0  
489             sub _eq_array {
490 0         0 my($a1, $a2) = @_;
491              
492 0         0 if( grep !_type($_) eq 'ARRAY', $a1, $a2 ) {
493             warn "eq_array passed a non-array ref";
494             return 0;
495             }
496              
497             return 1 if $a1 eq $a2;
498              
499             my $ok = 1;
500             my $max = $#$a1 > $#$a2 ? $#$a1 : $#$a2;
501             for (0..$max) {
502             my $e1 = $_ > $#$a1 ? $DNE : $a1->[$_];
503             my $e2 = $_ > $#$a2 ? $DNE : $a2->[$_];
504              
505             push @Data_Stack, { type => 'ARRAY', idx => $_, vals => [$e1, $e2] };
506             $ok = _deep_check($e1,$e2);
507             pop @Data_Stack if $ok;
508              
509             last unless $ok;
510             }
511              
512             return $ok;
513             }
514              
515             sub _deep_check {
516             my($e1, $e2) = @_;
517             my $tb = Test::More->builder;
518              
519             my $ok = 0;
520              
521             # Effectively turn %Refs_Seen into a stack. This avoids picking up
522             # the same referenced used twice (such as [\$a, \$a]) to be considered
523             # circular.
524             local %Refs_Seen = %Refs_Seen;
525 2     2 1 21  
526 2         20 {
527             # Quiet uninitialized value warnings when comparing undefs.
528 2         4 local $^W = 0;
529 2 50       8  
530 2         8 $tb->_unoverload_str(\$e1, \$e2);
531 2 50       14  
    50          
532 0         0 # Either they're both references or both not.
533             my $same_ref = !(!ref $e1 xor !ref $e2);
534             my $not_ref = (!ref $e1 and !ref $e2);
535 0         0  
536             if( defined $e1 xor defined $e2 ) {
537             $ok = 0;
538             }
539 2     2   17 elsif ( $e1 == $DNE xor $e2 == $DNE ) {
  2         16  
540 2 50       16 $ok = 0;
    50          
541 0 0       0 }
542             elsif ( $same_ref and ($e1 eq $e2) ) {
543 0 0       0 $ok = 1;
544 0         0 }
545 0         0 elsif ( $not_ref ) {
546             push @Data_Stack, { type => '', vals => [$e1, $e2] };
547             $ok = 0;
548 0         0 }
549             else {
550             if( $Refs_Seen{$e1} ) {
551             return $Refs_Seen{$e1} eq $e2;
552             }
553             else {
554             $Refs_Seen{$e1} = "$e2";
555             }
556 0         0  
557 0         0 my $type = _type($e1);
558             $type = 'DIFFERENT' unless _type($e2) eq $type;
559              
560             if( $type eq 'DIFFERENT' ) {
561             push @Data_Stack, { type => $type, vals => [$e1, $e2] };
562             $ok = 0;
563 2         4 }
564 2 50       6 elsif( $type eq 'ARRAY' ) {
565 0         0 $ok = _eq_array($e1, $e2);
566 0         0 }
567             elsif( $type eq 'HASH' ) {
568             $ok = _eq_hash($e1, $e2);
569 2         8 }
570             elsif( $type eq 'REF' ) {
571             push @Data_Stack, { type => $type, vals => [$e1, $e2] };
572 2         9 $ok = _deep_check($$e1, $$e2);
573             pop @Data_Stack if $ok;
574             }
575             elsif( $type eq 'SCALAR' ) {
576             push @Data_Stack, { type => 'REF', vals => [$e1, $e2] };
577             $ok = _deep_check($$e1, $$e2);
578             pop @Data_Stack if $ok;
579             }
580             elsif( $type ) {
581             push @Data_Stack, { type => $type, vals => [$e1, $e2] };
582             $ok = 0;
583             }
584             else {
585             _whoa(1, "No type in _deep_check");
586             }
587             }
588             }
589              
590             return $ok;
591             }
592              
593              
594 0     0 1 0 sub _whoa {
595 0         0 my($check, $desc) = @_;
596             if( $check ) {
597             die <
598             WHOA! $desc
599 0     0 1 0 This should never happen! Please contact the author immediately!
600 0         0 WHOA
601             }
602             }
603              
604              
605             #line 1298
606              
607             sub eq_hash {
608             local @Data_Stack;
609             return _deep_check(@_);
610             }
611              
612             sub _eq_hash {
613             my($a1, $a2) = @_;
614              
615             if( grep !_type($_) eq 'HASH', $a1, $a2 ) {
616             warn "eq_hash passed a non-hash ref";
617             return 0;
618             }
619              
620             return 1 if $a1 eq $a2;
621              
622             my $ok = 1;
623             my $bigger = keys %$a1 > keys %$a2 ? $a1 : $a2;
624             foreach my $k (keys %$bigger) {
625             my $e1 = exists $a1->{$k} ? $a1->{$k} : $DNE;
626             my $e2 = exists $a2->{$k} ? $a2->{$k} : $DNE;
627              
628             push @Data_Stack, { type => 'HASH', idx => $k, vals => [$e1, $e2] };
629             $ok = _deep_check($e1, $e2);
630             pop @Data_Stack if $ok;
631              
632             last unless $ok;
633             }
634              
635             return $ok;
636             }
637              
638             #line 1355
639              
640             sub eq_set {
641             my($a1, $a2) = @_;
642             return 0 unless @$a1 == @$a2;
643              
644             # There's faster ways to do this, but this is easiest.
645             local $^W = 0;
646              
647             # It really doesn't matter how we sort them, as long as both arrays are
648             # sorted with the same algorithm.
649             #
650             # Ensure that references are not accidentally treated the same as a
651             # string containing the reference.
652             #
653             # Have to inline the sort routine due to a threading/sort bug.
654             # See [rt.cpan.org 6782]
655 1     1 1 6 #
656 1 50       5 # I don't know how references would be sorted so we just don't sort
657 1         6 # them. This means eq_set doesn't really work with refs.
658             return eq_array(
659 1         4 [grep(ref, @$a1), sort( grep(!ref, @$a1) )],
660             [grep(ref, @$a2), sort( grep(!ref, @$a2) )],
661 1         14 );
662             }
663 1 50 33     5  
664             #line 1545
665              
666 0         0 1;