File Coverage

inc/Test/Builder.pm
Criterion Covered Total %
statement 203 483 42.0
branch 58 256 22.6
condition 16 75 21.3
subroutine 40 70 57.1
pod 35 35 100.0
total 352 919 38.3


line stmt bran cond sub pod time code
1             #line 1
2             package Test::Builder;
3 2     2   39  
  2         6  
  2         78  
4 2     2   11 use 5.006;
  2         4  
  2         125  
5             use strict;
6              
7             our $VERSION = '0.75';
8             $VERSION = eval { $VERSION }; # make the alpha version come out as a number
9              
10             # Make Test::Builder thread-safe for ithreads.
11 2     2   19 BEGIN {
  2         43  
  2         981  
12             use Config;
13             # Load threads::shared when threads are turned on.
14 2 50 33 2   49 # 5.8.0's threads are so busted we no longer support them.
      33        
15 0         0 if( $] >= 5.008001 && $Config{useithreads} && $INC{'threads.pm'}) {
16             require threads::shared;
17              
18             # Hack around YET ANOTHER threads::shared bug. It would
19             # occassionally forget the contents of the variable when sharing it.
20             # So we first copy the data, then share, then put our copy back.
21 0         0 *share = sub (\[$@%]) {
22 0         0 my $type = ref $_[0];
23             my $data;
24 0 0       0  
    0          
    0          
25 0         0 if( $type eq 'HASH' ) {
  0         0  
26             %$data = %{$_[0]};
27             }
28 0         0 elsif( $type eq 'ARRAY' ) {
  0         0  
29             @$data = @{$_[0]};
30             }
31 0         0 elsif( $type eq 'SCALAR' ) {
  0         0  
32             $$data = ${$_[0]};
33             }
34 0         0 else {
35             die("Unknown type: ".$type);
36             }
37 0         0  
38             $_[0] = &threads::shared::share($_[0]);
39 0 0       0  
    0          
    0          
40 0         0 if( $type eq 'HASH' ) {
  0         0  
41             %{$_[0]} = %$data;
42             }
43 0         0 elsif( $type eq 'ARRAY' ) {
  0         0  
44             @{$_[0]} = @$data;
45             }
46 0         0 elsif( $type eq 'SCALAR' ) {
  0         0  
47             ${$_[0]} = $$data;
48             }
49 0         0 else {
50             die("Unknown type: ".$type);
51             }
52 0         0  
53 0         0 return $_[0];
54             };
55             }
56             # 5.8.0's threads::shared is busted when threads are off
57             # and earlier Perls just don't have that module at all.
58 2     6   9 else {
  6         19  
59 2     1   272 *share = sub { return $_[0] };
  1         1  
60             *lock = sub { 0 };
61             }
62             }
63              
64              
65             #line 123
66              
67             my $Test = Test::Builder->new;
68             sub new {
69             my($class) = shift;
70             $Test ||= $class->create;
71             return $Test;
72             }
73              
74              
75             #line 145
76              
77             sub create {
78             my $class = shift;
79              
80             my $self = bless {}, $class;
81             $self->reset;
82              
83             return $self;
84             }
85              
86             #line 164
87              
88             use vars qw($Level);
89              
90             sub reset {
91             my ($self) = @_;
92              
93             # We leave this a global because it has to be localized and localizing
94             # hash keys is just asking for pain. Also, it was documented.
95             $Level = 1;
96              
97             $self->{Test_Died} = 0;
98             $self->{Have_Plan} = 0;
99             $self->{No_Plan} = 0;
100             $self->{Original_Pid} = $$;
101              
102             share($self->{Curr_Test});
103             $self->{Curr_Test} = 0;
104             $self->{Test_Results} = &share([]);
105              
106             $self->{Exported_To} = undef;
107             $self->{Expected_Tests} = 0;
108              
109             $self->{Skip_All} = 0;
110              
111             $self->{Use_Nums} = 1;
112              
113             $self->{No_Header} = 0;
114             $self->{No_Ending} = 0;
115              
116             $self->_dup_stdhandles unless $^C;
117              
118             return;
119             }
120              
121             #line 216
122              
123             sub exported_to {
124             my($self, $pack) = @_;
125              
126 7     7 1 28 if( defined $pack ) {
127 7   66     50 $self->{Exported_To} = $pack;
128 7         21 }
129             return $self->{Exported_To};
130             }
131              
132             #line 238
133              
134             sub plan {
135             my($self, $cmd, $arg) = @_;
136              
137             return unless $cmd;
138              
139             local $Level = $Level + 1;
140              
141             if( $self->{Have_Plan} ) {
142             $self->croak("You tried to plan twice");
143             }
144              
145             if( $cmd eq 'no_plan' ) {
146             $self->no_plan;
147 2     2 1 6 }
148             elsif( $cmd eq 'skip_all' ) {
149 2         9 return $self->skip_all($arg);
150 2         10 }
151             elsif( $cmd eq 'tests' ) {
152 2         9 if( $arg ) {
153             local $Level = $Level + 1;
154             return $self->expected_tests($arg);
155             }
156             elsif( !defined $arg ) {
157             $self->croak("Got an undefined number of tests");
158             }
159             elsif( !$arg ) {
160             $self->croak("You said to run 0 tests");
161             }
162             }
163             else {
164             my @args = grep { defined } ($cmd, $arg);
165 2     2   14 $self->croak("plan() doesn't understand @args");
  2         3  
  2         10864  
166             }
167              
168 2     2 1 4 return 1;
169             }
170              
171             #line 285
172 2         5  
173             sub expected_tests {
174 2         114 my $self = shift;
175 2         6 my($max) = @_;
176 2         5  
177 2         36 if( @_ ) {
178             $self->croak("Number of tests must be a positive integer. You gave it '$max'")
179 2         11 unless $max =~ /^\+?\d+$/ and $max > 0;
180 2         6  
181 2         9 $self->{Expected_Tests} = $max;
182             $self->{Have_Plan} = 1;
183 2         9  
184 2         6 $self->_print("1..$max\n") unless $self->no_header;
185             }
186 2         6 return $self->{Expected_Tests};
187             }
188 2         5  
189              
190 2         6 #line 310
191 2         5  
192             sub no_plan {
193 2 50       15 my $self = shift;
194              
195 2         3 $self->{No_Plan} = 1;
196             $self->{Have_Plan} = 1;
197             }
198              
199             #line 325
200              
201             sub has_plan {
202             my $self = shift;
203              
204             return($self->{Expected_Tests}) if $self->{Expected_Tests};
205             return('no_plan') if $self->{No_Plan};
206             return(undef);
207             };
208              
209              
210             #line 343
211              
212             sub skip_all {
213             my($self, $reason) = @_;
214              
215             my $out = "1..0";
216             $out .= " # Skip $reason" if $reason;
217             $out .= "\n";
218 5     5 1 12  
219             $self->{Skip_All} = 1;
220 5 100       19  
221 4         12 $self->_print($out) unless $self->no_header;
222             exit(0);
223 5         23 }
224              
225             #line 377
226              
227             sub ok {
228             my($self, $test, $name) = @_;
229              
230             # $test might contain an object which we don't want to accidentally
231             # store, so we turn it into a boolean.
232             $test = $test ? 1 : 0;
233              
234             $self->_plan_check;
235              
236             lock $self->{Curr_Test};
237             $self->{Curr_Test}++;
238              
239             # In case $name is a string overloaded object, force it to stringify.
240 2     2 1 5 $self->_unoverload_str(\$name);
241              
242 2 100       9 $self->diag(<
243             You named your test '$name'. You shouldn't use numbers for your test names.
244 1         3 Very confusing.
245             ERR
246 1 50       5  
247 0         0 my $todo = $self->todo();
248             $self->_unoverload_str(\$todo);
249              
250 1 50       8 my $out;
    50          
    50          
251 0         0 my $result = &share({});
252              
253             unless( $test ) {
254 0         0 $out .= "not ";
255             @$result{ 'ok', 'actual_ok' } = ( ( $todo ? 1 : 0 ), 0 );
256             }
257 1 50       5 else {
    0          
    0          
258 1         4 @$result{ 'ok', 'actual_ok' } = ( 1, $test );
259 1         6 }
260              
261             $out .= "ok";
262 0         0 $out .= " $self->{Curr_Test}" if $self->use_numbers;
263              
264             if( defined $name ) {
265 0         0 $name =~ s|#|\\#|g; # # in a name can confuse Test::Harness.
266             $out .= " - $name";
267             $result->{name} = $name;
268             }
269 0         0 else {
  0         0  
270 0         0 $result->{name} = '';
271             }
272              
273 0         0 if( $todo ) {
274             $out .= " # TODO $todo";
275             $result->{reason} = $todo;
276             $result->{type} = 'todo';
277             }
278             else {
279             $result->{reason} = '';
280             $result->{type} = '';
281             }
282              
283             $self->{Test_Results}[$self->{Curr_Test}-1] = $result;
284             $out .= "\n";
285              
286             $self->_print($out);
287 1     1 1 3  
288 1         2 unless( $test ) {
289             my $msg = $todo ? "Failed (TODO)" : "Failed";
290 1 50       5 $self->_print_diag("\n") if $ENV{HARNESS_ACTIVE};
291 1 50 33     15  
292             my(undef, $file, $line) = $self->caller;
293             if( defined $name ) {
294 1         4 $self->diag(qq[ $msg test '$name'\n]);
295 1         2 $self->diag(qq[ at $file line $line.\n]);
296             }
297 1 50       6 else {
298             $self->diag(qq[ $msg test at $file line $line.\n]);
299 1         7 }
300             }
301              
302             return $test ? 1 : 0;
303             }
304              
305              
306             sub _unoverload {
307             my $self = shift;
308             my $type = shift;
309              
310             $self->_try(sub { require overload } ) || return;
311              
312 0     0 1 0 foreach my $thing (@_) {
313             if( $self->_is_object($$thing) ) {
314 0         0 if( my $string_meth = overload::Method($$thing, $type) ) {
315 0         0 $$thing = $$thing->$string_meth();
316             }
317             }
318             }
319             }
320              
321              
322             sub _is_object {
323             my($self, $thing) = @_;
324              
325             return $self->_try(sub { ref $thing && $thing->isa('UNIVERSAL') }) ? 1 : 0;
326             }
327 0     0 1 0  
328              
329 0 0       0 sub _unoverload_str {
330 0 0       0 my $self = shift;
331 0         0  
332             $self->_unoverload(q[""], @_);
333             }
334              
335             sub _unoverload_num {
336             my $self = shift;
337              
338             $self->_unoverload('0+', @_);
339              
340             for my $val (@_) {
341             next unless $self->_is_dualvar($$val);
342             $$val = $$val+0;
343             }
344             }
345 0     0 1 0  
346              
347 0         0 # This is a hack to detect a dualvar such as $!
348 0 0       0 sub _is_dualvar {
349 0         0 my($self, $val) = @_;
350              
351 0         0 local $^W = 0;
352             my $numval = $val+0;
353 0 0       0 return 1 if $numval != 0 and $numval ne $val;
354 0         0 }
355              
356              
357              
358             #line 524
359              
360             sub is_eq {
361             my($self, $got, $expect, $name) = @_;
362             local $Level = $Level + 1;
363              
364             $self->_unoverload_str(\$got, \$expect);
365              
366             if( !defined $got || !defined $expect ) {
367             # undef only matches undef and nothing else
368             my $test = !defined $got && !defined $expect;
369              
370             $self->ok($test, $name);
371             $self->_is_diag($got, 'eq', $expect) unless $test;
372             return $test;
373             }
374              
375             return $self->cmp_ok($got, 'eq', $expect, $name);
376             }
377              
378             sub is_num {
379 1     1 1 3 my($self, $got, $expect, $name) = @_;
380             local $Level = $Level + 1;
381              
382             $self->_unoverload_num(\$got, \$expect);
383 1 50       5  
384             if( !defined $got || !defined $expect ) {
385 1         6 # undef only matches undef and nothing else
386             my $test = !defined $got && !defined $expect;
387 1         5  
388 1         2 $self->ok($test, $name);
389             $self->_is_diag($got, '==', $expect) unless $test;
390             return $test;
391 1         6 }
392              
393 1 50 33     18 return $self->cmp_ok($got, '==', $expect, $name);
394             }
395              
396             sub _is_diag {
397             my($self, $got, $type, $expect) = @_;
398 1         6  
399 1         5 foreach my $val (\$got, \$expect) {
400             if( defined $$val ) {
401 1         3 if( $type eq 'eq' ) {
402 1         16 # quote and force string context
403             $$val = "'$$val'"
404 1 50       6 }
405 0         0 else {
406 0 0       0 # force numeric context
407             $self->_unoverload_num($val);
408             }
409 1         5 }
410             else {
411             $$val = 'undef';
412 1         3 }
413 1 50       5 }
414              
415 1 50       4 return $self->diag(sprintf <
416 1         4 got: %s
417 1         4 expected: %s
418 1         4 DIAGNOSTIC
419              
420             }
421 0         0  
422             #line 602
423              
424 1 50       53 sub isnt_eq {
425 0         0 my($self, $got, $dont_expect, $name) = @_;
426 0         0 local $Level = $Level + 1;
427 0         0  
428             if( !defined $got || !defined $dont_expect ) {
429             # undef only matches undef and nothing else
430 1         35 my $test = defined $got || defined $dont_expect;
431 1         4  
432             $self->ok($test, $name);
433             $self->_cmp_diag($got, 'ne', $dont_expect) unless $test;
434 1         6 return $test;
435 1         2 }
436              
437 1         6 return $self->cmp_ok($got, 'ne', $dont_expect, $name);
438             }
439 1 50       5  
440 0 0       0 sub isnt_num {
441 0 0       0 my($self, $got, $dont_expect, $name) = @_;
442             local $Level = $Level + 1;
443 0         0  
444 0 0       0 if( !defined $got || !defined $dont_expect ) {
445 0         0 # undef only matches undef and nothing else
446 0         0 my $test = defined $got || defined $dont_expect;
447              
448             $self->ok($test, $name);
449 0         0 $self->_cmp_diag($got, '!=', $dont_expect) unless $test;
450             return $test;
451             }
452              
453 1 50       7 return $self->cmp_ok($got, '!=', $dont_expect, $name);
454             }
455              
456              
457             #line 654
458 2     2   4  
459 2         5 sub like {
460             my($self, $this, $regex, $name) = @_;
461 2 50   2   13  
  2         2995  
462             local $Level = $Level + 1;
463 2         11 $self->_regex_ok($this, $regex, '=~', $name);
464 2 50       10 }
465 0 0       0  
466 0         0 sub unlike {
467             my($self, $this, $regex, $name) = @_;
468              
469             local $Level = $Level + 1;
470             $self->_regex_ok($this, $regex, '!~', $name);
471             }
472              
473              
474 2     2   4 #line 679
475              
476 2 50   2   14  
  2 50       10  
477             my %numeric_cmps = map { ($_, 1) }
478             ("<", "<=", ">", ">=", "==", "!=", "<=>");
479              
480             sub cmp_ok {
481 2     2   4 my($self, $got, $type, $expect, $name) = @_;
482              
483 2         7 # Treat overloaded objects as numbers if we're asked to do a
484             # numeric comparison.
485             my $unoverload = $numeric_cmps{$type} ? '_unoverload_num'
486             : '_unoverload_str';
487 0     0   0  
488             $self->$unoverload(\$got, \$expect);
489 0         0  
490              
491 0         0 my $test;
492 0 0       0 {
493 0         0 local($@,$!,$SIG{__DIE__}); # isolate eval
494              
495             my $code = $self->_caller_context;
496              
497             # Yes, it has to look like this or 5.4.5 won't see the #line
498             # directive.
499             # Don't ask me, man, I just work here.
500 0     0   0 $test = eval "
501             $code" . "\$got $type \$expect;";
502 0         0  
503 0         0 }
504 0 0 0     0 local $Level = $Level + 1;
505             my $ok = $self->ok($test, $name);
506              
507             unless( $ok ) {
508             if( $type =~ /^(eq|==)$/ ) {
509             $self->_is_diag($got, $type, $expect);
510             }
511             else {
512             $self->_cmp_diag($got, $type, $expect);
513             }
514             }
515             return $ok;
516             }
517              
518             sub _cmp_diag {
519             my($self, $got, $type, $expect) = @_;
520            
521             $got = defined $got ? "'$got'" : 'undef';
522             $expect = defined $expect ? "'$expect'" : 'undef';
523             return $self->diag(sprintf <
524             %s
525             %s
526 0     0 1 0 %s
527 0         0 DIAGNOSTIC
528             }
529 0         0  
530              
531 0 0 0     0 sub _caller_context {
532             my $self = shift;
533 0   0     0  
534             my($pack, $file, $line) = $self->caller(1);
535 0         0  
536 0 0       0 my $code = '';
537 0         0 $code .= "#line $line $file\n" if defined $file and defined $line;
538              
539             return $code;
540 0         0 }
541              
542             #line 766
543              
544 0     0 1 0 sub BAIL_OUT {
545 0         0 my($self, $reason) = @_;
546              
547 0         0 $self->{Bailed_Out} = 1;
548             $self->_print("Bail out! $reason");
549 0 0 0     0 exit 255;
550             }
551 0   0     0  
552             #line 779
553 0         0  
554 0 0       0 *BAILOUT = \&BAIL_OUT;
555 0         0  
556              
557             #line 791
558 0         0  
559             sub skip {
560             my($self, $why) = @_;
561             $why ||= '';
562 0     0   0 $self->_unoverload_str(\$why);
563              
564 0         0 $self->_plan_check;
565 0 0       0  
566 0 0       0 lock($self->{Curr_Test});
567             $self->{Curr_Test}++;
568 0         0  
569             $self->{Test_Results}[$self->{Curr_Test}-1] = &share({
570             'ok' => 1,
571             actual_ok => 1,
572 0         0 name => '',
573             type => 'skip',
574             reason => $why,
575             });
576 0         0  
577             my $out = "ok";
578             $out .= " $self->{Curr_Test}" if $self->use_numbers;
579             $out .= " # skip";
580 0         0 $out .= " $why" if length $why;
581             $out .= "\n";
582              
583             $self->_print($out);
584              
585             return 1;
586             }
587              
588              
589             #line 833
590              
591             sub todo_skip {
592             my($self, $why) = @_;
593             $why ||= '';
594              
595             $self->_plan_check;
596              
597             lock($self->{Curr_Test});
598             $self->{Curr_Test}++;
599              
600             $self->{Test_Results}[$self->{Curr_Test}-1] = &share({
601             'ok' => 1,
602             actual_ok => 0,
603             name => '',
604 0     0 1 0 type => 'todo_skip',
605 0         0 reason => $why,
606             });
607 0 0 0     0  
608             my $out = "not ok";
609 0   0     0 $out .= " $self->{Curr_Test}" if $self->use_numbers;
610             $out .= " # TODO & SKIP $why\n";
611 0         0  
612 0 0       0 $self->_print($out);
613 0         0  
614             return 1;
615             }
616 0         0  
617              
618             #line 911
619              
620 0     0 1 0  
621 0         0 sub maybe_regex {
622             my ($self, $regex) = @_;
623 0 0 0     0 my $usable_regex = undef;
624              
625 0   0     0 return $usable_regex unless defined $regex;
626              
627 0         0 my($re, $opts);
628 0 0       0  
629 0         0 # Check for qr/foo/
630             if( ref $regex eq 'Regexp' ) {
631             $usable_regex = $regex;
632 0         0 }
633             # Check for '/foo/' or 'm,foo,'
634             elsif( ($re, $opts) = $regex =~ m{^ /(.*)/ (\w*) $ }sx or
635             (undef, $re, $opts) = $regex =~ m,^ m([^\w\s]) (.+) \1 (\w*) $,sx
636             )
637             {
638             $usable_regex = length $opts ? "(?$opts)$re" : $re;
639             }
640              
641             return $usable_regex;
642             };
643              
644             sub _regex_ok {
645             my($self, $this, $regex, $cmp, $name) = @_;
646              
647             my $ok = 0;
648             my $usable_regex = $self->maybe_regex($regex);
649             unless (defined $usable_regex) {
650             $ok = $self->ok( 0, $name );
651             $self->diag(" '$regex' doesn't look much like a regex to me.");
652             return $ok;
653             }
654              
655             {
656 0     0 1 0 my $test;
657             my $code = $self->_caller_context;
658 0         0  
659 0         0 local($@, $!, $SIG{__DIE__}); # isolate eval
660              
661             # Yes, it has to look like this or 5.4.5 won't see the #line
662             # directive.
663 0     0 1 0 # Don't ask me, man, I just work here.
664             $test = eval "
665 0         0 $code" . q{$test = $this =~ /$usable_regex/ ? 1 : 0};
666 0         0  
667             $test = !$test if $cmp eq '!~';
668              
669             local $Level = $Level + 1;
670             $ok = $self->ok( $test, $name );
671             }
672              
673             unless( $ok ) {
674             $this = defined $this ? "'$this'" : 'undef';
675             my $match = $cmp eq '=~' ? "doesn't match" : "matches";
676             $self->diag(sprintf <
677             %s
678             %13s '%s'
679             DIAGNOSTIC
680              
681             }
682              
683             return $ok;
684             }
685 0     0 1 0  
686              
687             # I'm not ready to publish this. It doesn't deal with array return
688             # values from the code or context.
689 0 0       0  
690             #line 996
691              
692 0         0 sub _try {
693             my($self, $code) = @_;
694            
695 0         0 local $!; # eval can mess up $!
696             local $@; # don't set $@ in the test
697 0         0 local $SIG{__DIE__}; # don't trip an outside DIE handler.
  0         0  
698             my $return = eval { $code->() };
699 0         0
700             return wantarray ? ($return, $@) : $return;
701             }
702              
703             #line 1018
704 0         0  
705             sub is_fh {
706             my $self = shift;
707             my $maybe_fh = shift;
708 0         0 return 0 unless defined $maybe_fh;
709 0         0  
710             return 1 if ref $maybe_fh eq 'GLOB'; # its a glob ref
711 0 0       0 return 1 if ref \$maybe_fh eq 'GLOB'; # its a glob
712 0 0       0  
713 0         0 return eval { $maybe_fh->isa("IO::Handle") } ||
714             # 5.5.4's tied() and can() doesn't like getting undef
715             eval { (tied($maybe_fh) || '')->can('TIEHANDLE') };
716 0         0 }
717              
718              
719 0         0 #line 1063
720              
721             sub level {
722             my($self, $level) = @_;
723 0     0   0  
724             if( defined $level ) {
725 0 0       0 $Level = $level;
726 0 0       0 }
727 0         0 return $Level;
728             }
729              
730              
731             #line 1096
732              
733             sub use_numbers {
734             my($self, $use_nums) = @_;
735              
736 0     0   0 if( defined $use_nums ) {
737             $self->{Use_Nums} = $use_nums;
738 0         0 }
739             return $self->{Use_Nums};
740 0         0 }
741 0 0 0     0  
742              
743 0         0 #line 1130
744              
745             foreach my $attribute (qw(No_Header No_Ending No_Diag)) {
746             my $method = lc $attribute;
747              
748             my $code = sub {
749             my($self, $no) = @_;
750              
751             if( defined $no ) {
752             $self->{$attribute} = $no;
753             }
754             return $self->{$attribute};
755             };
756              
757             no strict 'refs'; ## no critic
758             *{__PACKAGE__.'::'.$method} = $code;
759             }
760              
761              
762             #line 1184
763              
764             sub diag {
765             my($self, @msgs) = @_;
766              
767             return if $self->no_diag;
768 0     0 1 0 return unless @msgs;
769              
770 0         0 # Prevent printing headers when compiling (i.e. -c)
771 0         0 return if $^C;
772 0         0  
773             # Smash args together like print does.
774             # Convert undef to 'undef' so its readable.
775             my $msg = join '', map { defined($_) ? $_ : 'undef' } @msgs;
776              
777             # Escape each line with a #.
778             $msg =~ s/^/# /gm;
779              
780             # Stick a newline on the end if it needs it.
781             $msg .= "\n" unless $msg =~ /\n\Z/;
782              
783             local $Level = $Level + 1;
784             $self->_print_diag($msg);
785              
786             return 0;
787             }
788              
789             #line 1221
790              
791             sub _print {
792             my($self, @msgs) = @_;
793 0     0 1 0  
794 0   0     0 # Prevent printing headers when only compiling. Mostly for when
795 0         0 # tests are deparsed with B::Deparse
796             return if $^C;
797 0         0  
798             my $msg = join '', @msgs;
799 0         0  
800 0         0 local($\, $", $,) = (undef, ' ', '');
801             my $fh = $self->output;
802 0         0  
803             # Escape each line after the first with a # so we don't
804             # confuse Test::Harness.
805             $msg =~ s/\n(.)/\n# $1/sg;
806              
807             # Stick a newline on the end if it needs it.
808             $msg .= "\n" unless $msg =~ /\n\Z/;
809              
810 0         0 print $fh $msg;
811 0 0       0 }
812 0         0  
813 0 0       0 #line 1255
814 0         0  
815             sub _print_diag {
816 0         0 my $self = shift;
817              
818 0         0 local($\, $", $,) = (undef, ' ', '');
819             my $fh = $self->todo ? $self->todo_output : $self->failure_output;
820             print $fh @_;
821             }
822              
823             #line 1292
824              
825             sub output {
826             my($self, $fh) = @_;
827              
828             if( defined $fh ) {
829             $self->{Out_FH} = $self->_new_fh($fh);
830             }
831             return $self->{Out_FH};
832             }
833              
834             sub failure_output {
835 0     0 1 0 my($self, $fh) = @_;
836 0   0     0  
837             if( defined $fh ) {
838 0         0 $self->{Fail_FH} = $self->_new_fh($fh);
839             }
840 0         0 return $self->{Fail_FH};
841 0         0 }
842              
843 0         0 sub todo_output {
844             my($self, $fh) = @_;
845              
846             if( defined $fh ) {
847             $self->{Todo_FH} = $self->_new_fh($fh);
848             }
849             return $self->{Todo_FH};
850             }
851 0         0  
852 0 0       0  
853 0         0 sub _new_fh {
854             my $self = shift;
855 0         0 my($file_or_fh) = shift;
856              
857 0         0 my $fh;
858             if( $self->is_fh($file_or_fh) ) {
859             $fh = $file_or_fh;
860             }
861             else {
862             open $fh, ">", $file_or_fh or
863             $self->croak("Can't open test output log $file_or_fh: $!");
864             _autoflush($fh);
865             }
866              
867             return $fh;
868             }
869              
870              
871             sub _autoflush {
872             my($fh) = shift;
873             my $old_fh = select $fh;
874             $| = 1;
875             select $old_fh;
876             }
877              
878              
879             sub _dup_stdhandles {
880             my $self = shift;
881              
882             $self->_open_testhandles;
883              
884             # Set everything to unbuffered else plain prints to STDOUT will
885             # come out in the wrong order from our own prints.
886             _autoflush(\*TESTOUT);
887             _autoflush(\*STDOUT);
888             _autoflush(\*TESTERR);
889             _autoflush(\*STDERR);
890              
891             $self->output(\*TESTOUT);
892             $self->failure_output(\*TESTERR);
893             $self->todo_output(\*TESTOUT);
894             }
895              
896              
897             my $Opened_Testhandles = 0;
898             sub _open_testhandles {
899             return if $Opened_Testhandles;
900             # We dup STDOUT and STDERR so people can change them in their
901             # test suites while still getting normal test output.
902             open(TESTOUT, ">&STDOUT") or die "Can't dup STDOUT: $!";
903             open(TESTERR, ">&STDERR") or die "Can't dup STDERR: $!";
904             $Opened_Testhandles = 1;
905             }
906              
907              
908             #line 1391
909              
910             sub _message_at_caller {
911             my $self = shift;
912              
913             local $Level = $Level + 1;
914 0     0 1 0 my($pack, $file, $line) = $self->caller;
915 0         0 return join("", @_) . " at $file line $line.\n";
916             }
917 0 0       0  
918             sub carp {
919 0         0 my $self = shift;
920             warn $self->_message_at_caller(@_);
921             }
922 0 0 0     0  
    0          
923 0         0 sub croak {
924             my $self = shift;
925             die $self->_message_at_caller(@_);
926             }
927              
928             sub _plan_check {
929             my $self = shift;
930 0 0       0  
931             unless( $self->{Have_Plan} ) {
932             local $Level = $Level + 2;
933 0         0 $self->croak("You tried to run a test without a plan");
934             }
935             }
936              
937 0     0   0 #line 1439
938              
939 0         0 sub current_test {
940 0         0 my($self, $num) = @_;
941 0 0       0  
942 0         0 lock($self->{Curr_Test});
943 0         0 if( defined $num ) {
944 0         0 unless( $self->{Have_Plan} ) {
945             $self->croak("Can't change the current test number without a plan!");
946             }
947              
948 0         0 $self->{Curr_Test} = $num;
  0         0  
949 0         0  
950             # If the test counter is being pushed forward fill in the details.
951 0         0 my $test_results = $self->{Test_Results};
952             if( $num > @$test_results ) {
953             my $start = @$test_results ? @$test_results : 0;
954             for ($start..$num-1) {
955             $test_results->[$_] = &share({
956 0         0 'ok' => 1,
957             actual_ok => undef,
958             reason => 'incrementing test number',
959 0 0       0 type => 'unknown',
960             name => undef
961 0         0 });
962 0         0 }
963             }
964             # If backward, wipe history. Its their funeral.
965 0 0       0 elsif( $num < @$test_results ) {
966 0 0       0 $#{$test_results} = $num - 1;
967 0 0       0 }
968 0         0 }
969             return $self->{Curr_Test};
970             }
971              
972              
973             #line 1484
974              
975 0         0 sub summary {
976             my($self) = shift;
977              
978             return map { $_->{'ok'} } @{ $self->{Test_Results} };
979             }
980              
981             #line 1539
982              
983             sub details {
984             my $self = shift;
985             return @{ $self->{Test_Results} };
986             }
987              
988             #line 1564
989              
990             sub todo {
991             my($self, $pack) = @_;
992              
993             $pack = $pack || $self->exported_to || $self->caller($Level);
994             return 0 unless $pack;
995              
996             no strict 'refs'; ## no critic
997             return defined ${$pack.'::TODO'} ? ${$pack.'::TODO'}
998 4     4   6 : 0;
999             }
1000 4         11  
1001 4         7 #line 1585
1002 4         13  
1003 4         6 sub caller {
  4         8  
1004             my($self, $height) = @_;
1005 4 50       2003 $height ||= 0;
1006              
1007             my @caller = CORE::caller($self->level + $height + 1);
1008             return wantarray ? @caller : $caller[0];
1009             }
1010              
1011             #line 1597
1012              
1013             #line 1611
1014              
1015             #'#
1016             sub _sanity_check {
1017             my $self = shift;
1018              
1019             $self->_whoa($self->{Curr_Test} < 0, 'Says here you ran a negative number of tests!');
1020 6     6 1 9 $self->_whoa(!$self->{Have_Plan} and $self->{Curr_Test},
1021 6         8 'Somehow your tests ran without a plan!');
1022 6 50       16 $self->_whoa($self->{Curr_Test} != @{ $self->{Test_Results} },
1023             'Somehow you got a different number of results than tests ran!');
1024 6 50       33 }
1025 0 0       0  
1026             #line 1632
1027              
1028             sub _whoa {
1029 0   0     0 my($self, $check, $desc) = @_;
1030             if( $check ) {
1031             local $Level = $Level + 1;
1032             $self->croak(<<"WHOA");
1033             WHOA! $desc
1034             This should never happen! Please contact the author immediately!
1035             WHOA
1036             }
1037             }
1038              
1039             #line 1654
1040              
1041             sub _my_exit {
1042             $? = $_[0];
1043              
1044             return 1;
1045             }
1046              
1047              
1048             #line 1667
1049              
1050             $SIG{__DIE__} = sub {
1051             # We don't want to muck with death in an eval, but $^S isn't
1052             # totally reliable. 5.005_03 and 5.6.1 both do the wrong thing
1053             # with it. Instead, we use caller. This also means it runs under
1054             # 5.004!
1055             my $in_eval = 0;
1056             for( my $stack = 1; my $sub = (CORE::caller($stack))[3]; $stack++ ) {
1057             $in_eval = 1 if $sub =~ /^\(eval\)/;
1058             }
1059             $Test->{Test_Died} = 1 unless $in_eval;
1060             };
1061              
1062             sub _ending {
1063             my $self = shift;
1064              
1065 0     0 1 0 $self->_sanity_check();
1066              
1067 0 0       0 # Don't bother with an ending if this is a forked copy. Only the parent
1068 0         0 # should do the ending.
1069             # Exit if plan() was never called. This is so "require Test::Simple"
1070 0         0 # doesn't puke.
1071             # Don't do an ending if we bailed out.
1072             if( ($self->{Original_Pid} != $$) or
1073             (!$self->{Have_Plan} && !$self->{Test_Died}) or
1074             $self->{Bailed_Out}
1075             )
1076             {
1077             _my_exit($?);
1078             return;
1079             }
1080              
1081             # Figure out if we passed or failed and print helpful messages.
1082             my $test_results = $self->{Test_Results};
1083             if( @$test_results ) {
1084             # The plan? We have no plan.
1085             if( $self->{No_Plan} ) {
1086             $self->_print("1..$self->{Curr_Test}\n") unless $self->no_header;
1087             $self->{Expected_Tests} = $self->{Curr_Test};
1088             }
1089              
1090             # Auto-extended arrays and elements which aren't explicitly
1091             # filled in with a shared reference will puke under 5.8.0
1092             # ithreads. So we have to fill them in by hand. :(
1093             my $empty_result = &share({});
1094             for my $idx ( 0..$self->{Expected_Tests}-1 ) {
1095             $test_results->[$idx] = $empty_result
1096             unless defined $test_results->[$idx];
1097             }
1098 1     1 1 3  
1099             my $num_failed = grep !$_->{'ok'},
1100 1 50       4 @{$test_results}[0..$self->{Curr_Test}-1];
1101 0         0  
1102             my $num_extra = $self->{Curr_Test} - $self->{Expected_Tests};
1103 1         8  
1104             if( $num_extra < 0 ) {
1105             my $s = $self->{Expected_Tests} == 1 ? '' : 's';
1106             $self->diag(<<"FAIL");
1107             Looks like you planned $self->{Expected_Tests} test$s but only ran $self->{Curr_Test}.
1108             FAIL
1109             }
1110             elsif( $num_extra > 0 ) {
1111             my $s = $self->{Expected_Tests} == 1 ? '' : 's';
1112             $self->diag(<<"FAIL");
1113             Looks like you planned $self->{Expected_Tests} test$s but ran $num_extra extra.
1114             FAIL
1115             }
1116              
1117             if ( $num_failed ) {
1118             my $num_tests = $self->{Curr_Test};
1119             my $s = $num_failed == 1 ? '' : 's';
1120              
1121             my $qualifier = $num_extra == 0 ? '' : ' run';
1122              
1123             $self->diag(<<"FAIL");
1124             Looks like you failed $num_failed test$s of $num_tests$qualifier.
1125             FAIL
1126             }
1127              
1128             if( $self->{Test_Died} ) {
1129             $self->diag(<<"FAIL");
1130             Looks like your test died just after $self->{Curr_Test}.
1131             FAIL
1132              
1133             _my_exit( 255 ) && return;
1134             }
1135 3     3   8  
1136             my $exit_code;
1137 3 50       12 if( $num_failed ) {
1138 0         0 $exit_code = $num_failed <= 254 ? $num_failed : 254;
1139             }
1140 3         45 elsif( $num_extra != 0 ) {
1141             $exit_code = 255;
1142             }
1143 2     2   28 else {
  2         4  
  2         7723  
1144             $exit_code = 0;
1145             }
1146              
1147             _my_exit( $exit_code ) && return;
1148             }
1149             elsif ( $self->{Skip_All} ) {
1150             _my_exit( 0 ) && return;
1151             }
1152             elsif ( $self->{Test_Died} ) {
1153             $self->diag(<<'FAIL');
1154             Looks like your test died before it could output anything.
1155             FAIL
1156             _my_exit( 255 ) && return;
1157             }
1158             else {
1159             $self->diag("No tests run!\n");
1160             _my_exit( 255 ) && return;
1161             }
1162             }
1163              
1164             END {
1165             $Test->_ending if defined $Test and !$Test->no_ending;
1166             }
1167              
1168             #line 1842
1169              
1170             1;