This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update Test-Simple to CPAN version 1.302170
[perl5.git] / cpan / Test-Simple / lib / Test / Tester / Capture.pm
1 use strict;
2
3 package Test::Tester::Capture;
4
5 our $VERSION = '1.302170';
6
7
8 use Test::Builder;
9
10 use vars qw( @ISA );
11 @ISA = qw( Test::Builder );
12
13 # Make Test::Tester::Capture thread-safe for ithreads.
14 BEGIN {
15         use Config;
16         *share = sub { 0 };
17         *lock  = sub { 0 };
18 }
19
20 my $Curr_Test = 0;      share($Curr_Test);
21 my @Test_Results = ();  share(@Test_Results);
22 my $Prem_Diag = {diag => ""};    share($Curr_Test);
23
24 sub new
25 {
26   # Test::Tester::Capgture::new used to just return __PACKAGE__
27   # because Test::Builder::new enforced it's singleton nature by
28   # return __PACKAGE__. That has since changed, Test::Builder::new now
29   # returns a blessed has and around version 0.78, Test::Builder::todo
30   # started wanting to modify $self. To cope with this, we now return
31   # a blessed hash. This is a short-term hack, the correct thing to do
32   # is to detect which style of Test::Builder we're dealing with and
33   # act appropriately.
34
35   my $class = shift;
36   return bless {}, $class;
37 }
38
39 sub ok {
40         my($self, $test, $name) = @_;
41
42         my $ctx = $self->ctx;
43
44         # $test might contain an object which we don't want to accidentally
45         # store, so we turn it into a boolean.
46         $test = $test ? 1 : 0;
47
48         lock $Curr_Test;
49         $Curr_Test++;
50
51         my($pack, $file, $line) = $self->caller;
52
53         my $todo = $self->todo();
54
55         my $result = {};
56         share($result);
57
58         unless( $test ) {
59                 @$result{ 'ok', 'actual_ok' } = ( ( $todo ? 1 : 0 ), 0 );
60         }
61         else {
62                 @$result{ 'ok', 'actual_ok' } = ( 1, $test );
63         }
64
65         if( defined $name ) {
66                 $name =~ s|#|\\#|g;      # # in a name can confuse Test::Harness.
67                 $result->{name} = $name;
68         }
69         else {
70                 $result->{name} = '';
71         }
72
73         if( $todo ) {
74                 my $what_todo = $todo;
75                 $result->{reason} = $what_todo;
76                 $result->{type}   = 'todo';
77         }
78         else {
79                 $result->{reason} = '';
80                 $result->{type}   = '';
81         }
82
83         $Test_Results[$Curr_Test-1] = $result;
84
85         unless( $test ) {
86                 my $msg = $todo ? "Failed (TODO)" : "Failed";
87                 $result->{fail_diag} = ("       $msg test ($file at line $line)\n");
88         } 
89
90         $result->{diag} = "";
91         $result->{_level} = $Test::Builder::Level;
92         $result->{_depth} = Test::Tester::find_run_tests();
93
94         $ctx->release;
95
96         return $test ? 1 : 0;
97 }
98
99 sub skip {
100         my($self, $why) = @_;
101         $why ||= '';
102
103         my $ctx = $self->ctx;
104
105         lock($Curr_Test);
106         $Curr_Test++;
107
108         my %result;
109         share(%result);
110         %result = (
111                 'ok'      => 1,
112                 actual_ok => 1,
113                 name      => '',
114                 type      => 'skip',
115                 reason  => $why,
116                 diag    => "",
117                 _level   => $Test::Builder::Level,
118                 _depth => Test::Tester::find_run_tests(),
119         );
120         $Test_Results[$Curr_Test-1] = \%result;
121
122         $ctx->release;
123         return 1;
124 }
125
126 sub todo_skip {
127         my($self, $why) = @_;
128         $why ||= '';
129
130         my $ctx = $self->ctx;
131
132         lock($Curr_Test);
133         $Curr_Test++;
134
135         my %result;
136         share(%result);
137         %result = (
138                 'ok'      => 1,
139                 actual_ok => 0,
140                 name      => '',
141                 type      => 'todo_skip',
142                 reason  => $why,
143                 diag    => "",
144                 _level   => $Test::Builder::Level,
145                 _depth => Test::Tester::find_run_tests(),
146         );
147
148         $Test_Results[$Curr_Test-1] = \%result;
149
150         $ctx->release;
151         return 1;
152 }
153
154 sub diag {
155         my($self, @msgs) = @_;
156         return unless @msgs;
157
158         # Prevent printing headers when compiling (i.e. -c)
159         return if $^C;
160
161         my $ctx = $self->ctx;
162
163         # Escape each line with a #.
164         foreach (@msgs) {
165                 $_ = 'undef' unless defined;
166         }
167
168         push @msgs, "\n" unless $msgs[-1] =~ /\n\Z/;
169
170         my $result = $Curr_Test ? $Test_Results[$Curr_Test - 1] : $Prem_Diag;
171
172         $result->{diag} .= join("", @msgs);
173
174         $ctx->release;
175         return 0;
176 }
177
178 sub details {
179         return @Test_Results;
180 }
181
182
183 # Stub. Feel free to send me a patch to implement this.
184 sub note {
185 }
186
187 sub explain {
188         return Test::Builder::explain(@_);
189 }
190
191 sub premature
192 {
193         return $Prem_Diag->{diag};
194 }
195
196 sub current_test
197 {
198         if (@_ > 1)
199         {
200                 die "Don't try to change the test number!";
201         }
202         else
203         {
204                 return $Curr_Test;
205         }
206 }
207
208 sub reset
209 {
210         $Curr_Test = 0;
211         @Test_Results = ();
212         $Prem_Diag = {diag => ""};
213 }
214
215 1;
216
217 __END__
218
219 =head1 NAME
220
221 Test::Tester::Capture - Help testing test modules built with Test::Builder
222
223 =head1 DESCRIPTION
224
225 This is a subclass of Test::Builder that overrides many of the methods so
226 that they don't output anything. It also keeps track of it's own set of test
227 results so that you can use Test::Builder based modules to perform tests on
228 other Test::Builder based modules.
229
230 =head1 AUTHOR
231
232 Most of the code here was lifted straight from Test::Builder and then had
233 chunks removed by Fergal Daly <fergal@esatclear.ie>.
234
235 =head1 LICENSE
236
237 Under the same license as Perl itself
238
239 See http://www.perl.com/perl/misc/Artistic.html
240
241 =cut