File Coverage

blib/lib/Test/Tester/Capture.pm
Criterion Covered Total %
statement 80 87 91.9
branch 22 30 73.3
condition 3 7 42.8
subroutine 16 18 88.8
pod 10 11 90.9
total 131 153 85.6


line stmt bran cond sub pod time code
1 5     5   25 use strict;
  5         9  
  5         183  
2              
3             package Test::Tester::Capture;
4              
5 5     5   23 use Test::Builder;
  5         10  
  5         112  
6              
7 5     5   24 use vars qw( @ISA );
  5         7  
  5         368  
8             @ISA = qw( Test::Builder );
9              
10             # Make Test::Tester::Capture thread-safe for ithreads.
11             BEGIN {
12 5     5   26 use Config;
  5         19  
  5         483  
13 5 50 33 5   94 if( $] >= 5.008 && $Config{useithreads} ) {
14 0         0 require threads::shared;
15 0         0 threads::shared->import;
16             }
17             else {
18 5     38   25 *share = sub { 0 };
  38         56  
19 5     23   4506 *lock = sub { 0 };
  23         31  
20             }
21             }
22              
23             my $Curr_Test = 0; share($Curr_Test);
24             my @Test_Results = (); share(@Test_Results);
25             my $Prem_Diag = {diag => ""}; share($Curr_Test);
26              
27             sub new
28             {
29             # Test::Tester::Capgture::new used to just return __PACKAGE__
30             # because Test::Builder::new enforced it's singleton nature by
31             # return __PACKAGE__. That has since changed, Test::Builder::new now
32             # returns a blessed has and around version 0.78, Test::Builder::todo
33             # started wanting to modify $self. To cope with this, we now return
34             # a blessed hash. This is a short-term hack, the correct thing to do
35             # is to detect which style of Test::Builder we're dealing with and
36             # act appropriately.
37              
38 56     56 1 77 my $class = shift;
39 56         252 return bless {}, $class;
40             }
41              
42             sub ok {
43 17     17 1 300 my($self, $test, $name) = @_;
44              
45             # $test might contain an object which we don't want to accidentally
46             # store, so we turn it into a boolean.
47 17 100       40 $test = $test ? 1 : 0;
48              
49 17         36 lock $Curr_Test;
50 17         17 $Curr_Test++;
51              
52 17         66 my($pack, $file, $line) = $self->caller;
53              
54 17         404 my $todo = $self->todo($pack);
55              
56 17         274 my $result = {};
57 17         37 share($result);
58              
59 17 100       33 unless( $test ) {
60 5 50       26 @$result{ 'ok', 'actual_ok' } = ( ( $todo ? 1 : 0 ), 0 );
61             }
62             else {
63 12         44 @$result{ 'ok', 'actual_ok' } = ( 1, $test );
64             }
65              
66 17 100       38 if( defined $name ) {
67 15         28 $name =~ s|#|\\#|g; # # in a name can confuse Test::Harness.
68 15         26 $result->{name} = $name;
69             }
70             else {
71 2         3 $result->{name} = '';
72             }
73              
74 17 50       30 if( $todo ) {
75 0         0 my $what_todo = $todo;
76 0         0 $result->{reason} = $what_todo;
77 0         0 $result->{type} = 'todo';
78             }
79             else {
80 17         28 $result->{reason} = '';
81 17         29 $result->{type} = '';
82             }
83              
84 17         27 $Test_Results[$Curr_Test-1] = $result;
85              
86 17 100       40 unless( $test ) {
87 5 50       16 my $msg = $todo ? "Failed (TODO)" : "Failed";
88 5         22 $result->{fail_diag} = (" $msg test ($file at line $line)\n");
89             }
90              
91 17         32 $result->{diag} = "";
92 17         30 $result->{_level} = $Test::Builder::Level;
93 17         43 $result->{_depth} = Test::Tester::find_run_tests();
94              
95 17 100       145 return $test ? 1 : 0;
96             }
97              
98             sub skip {
99 3     3 1 16 my($self, $why) = @_;
100 3   50     13 $why ||= '';
101              
102 3         10 lock($Curr_Test);
103 3         4 $Curr_Test++;
104              
105 3         7 my %result;
106 3         13 share(%result);
107 3         13 %result = (
108             'ok' => 1,
109             actual_ok => 1,
110             name => '',
111             type => 'skip',
112             reason => $why,
113             diag => "",
114             _level => $Test::Builder::Level,
115             _depth => Test::Tester::find_run_tests(),
116             );
117 3         11 $Test_Results[$Curr_Test-1] = \%result;
118              
119 3         23 return 1;
120             }
121              
122             sub todo_skip {
123 3     3 1 16 my($self, $why) = @_;
124 3   50     11 $why ||= '';
125              
126 3         8 lock($Curr_Test);
127 3         3 $Curr_Test++;
128              
129 3         6 my %result;
130 3         10 share(%result);
131 3         11 %result = (
132             'ok' => 1,
133             actual_ok => 0,
134             name => '',
135             type => 'todo_skip',
136             reason => $why,
137             diag => "",
138             _level => $Test::Builder::Level,
139             _depth => Test::Tester::find_run_tests(),
140             );
141              
142 3         8 $Test_Results[$Curr_Test-1] = \%result;
143              
144 3         22 return 1;
145             }
146              
147             sub diag {
148 14     14 1 58 my($self, @msgs) = @_;
149 14 50       32 return unless @msgs;
150              
151             # Prevent printing headers when compiling (i.e. -c)
152 14 50       30 return if $^C;
153              
154             # Escape each line with a #.
155 14         26 foreach (@msgs) {
156 14 50       38 $_ = 'undef' unless defined;
157             }
158              
159 14 50       72 push @msgs, "\n" unless $msgs[-1] =~ /\n\Z/;
160              
161 14 100       32 my $result = $Curr_Test ? $Test_Results[$Curr_Test - 1] : $Prem_Diag;
162              
163 14         29 $result->{diag} .= join("", @msgs);
164              
165 14         110 return 0;
166             }
167              
168             sub details {
169 17     17 1 56 return @Test_Results;
170             }
171              
172              
173             # Stub. Feel free to send me a patch to implement this.
174 0     0 1 0 sub note {
175             }
176              
177             sub explain {
178 0     0 1 0 return Test::Builder::explain(@_);
179             }
180              
181             sub premature
182             {
183 16     16 0 70 return $Prem_Diag->{diag};
184             }
185              
186             sub current_test
187             {
188 2 100   2 1 371 if (@_ > 1)
189             {
190 1         9 die "Don't try to change the test number!";
191             }
192             else
193             {
194 1         3 return $Curr_Test;
195             }
196             }
197              
198             sub reset
199             {
200 16     16 1 36 $Curr_Test = 0;
201 16         45 @Test_Results = ();
202 16         57 $Prem_Diag = {diag => ""};
203             }
204              
205             1;
206              
207             __END__