Upgrade to Test::Harness 3.05
[p5sagit/p5-mst-13.2.git] / lib / Test / Harness / t / aggregator.t
1 #!/usr/bin/perl -wT
2
3
4 use strict;
5 use lib 't/lib';
6
7 use Test::More tests => 79;
8
9 use TAP::Parser;
10 use TAP::Parser::Iterator;
11 use TAP::Parser::Aggregator;
12
13 my $tap = <<'END_TAP';
14 1..5
15 ok 1 - input file opened
16 ... this is junk
17 not ok first line of the input valid # todo some data
18 # this is a comment
19 ok 3 - read the rest of the file
20 not ok 4 - this is a real failure
21 ok 5 # skip we have no description
22 END_TAP
23
24 my $stream = TAP::Parser::Iterator->new( [ split /\n/ => $tap ] );
25 isa_ok $stream, 'TAP::Parser::Iterator';
26
27 my $parser1 = TAP::Parser->new( { stream => $stream } );
28 isa_ok $parser1, 'TAP::Parser';
29
30 $parser1->run;
31
32 $tap = <<'END_TAP';
33 1..7
34 ok 1 - gentlemen, start your engines
35 not ok first line of the input valid # todo some data
36 # this is a comment
37 ok 3 - read the rest of the file
38 not ok 4 - this is a real failure
39 ok 5 
40 ok 6 - you shall not pass! # TODO should have failed
41 not ok 7 - Gandalf wins.  Game over.  # TODO 'bout time!
42 END_TAP
43
44 my $parser2 = TAP::Parser->new( { tap => $tap } );
45 isa_ok $parser2, 'TAP::Parser';
46 $parser2->run;
47
48 can_ok 'TAP::Parser::Aggregator', 'new';
49 my $agg = TAP::Parser::Aggregator->new;
50 isa_ok $agg, 'TAP::Parser::Aggregator';
51
52 can_ok $agg, 'add';
53 ok $agg->add( 'tap1', $parser1 ), '... and calling it should succeed';
54 ok $agg->add( 'tap2', $parser2 ), '... even if we add more than one parser';
55 eval { $agg->add( 'tap1', $parser1 ) };
56 like $@, qr/^You already have a parser for \Q(tap1)/,
57   '... but trying to reuse a description should be fatal';
58
59 can_ok $agg, 'parsers';
60 is scalar $agg->parsers, 2,
61   '... and it should report how many parsers it has';
62 is_deeply [ $agg->parsers ], [ $parser1, $parser2 ],
63   '... or which parsers it has';
64 is_deeply $agg->parsers('tap2'), $parser2, '... or reporting a single parser';
65 is_deeply [ $agg->parsers(qw(tap2 tap1)) ], [ $parser2, $parser1 ],
66   '... or a group';
67
68 # test aggregate results
69
70 can_ok $agg, 'passed';
71 is $agg->passed, 10,
72   '... and we should have the correct number of passed tests';
73 is_deeply [ $agg->passed ], [qw(tap1 tap2)],
74   '... and be able to get their descriptions';
75
76 can_ok $agg, 'failed';
77 is $agg->failed, 2,
78   '... and we should have the correct number of failed tests';
79 is_deeply [ $agg->failed ], [qw(tap1 tap2)],
80   '... and be able to get their descriptions';
81
82 can_ok $agg, 'todo';
83 is $agg->todo, 4, '... and we should have the correct number of todo tests';
84 is_deeply [ $agg->todo ], [qw(tap1 tap2)],
85   '... and be able to get their descriptions';
86
87 can_ok $agg, 'skipped';
88 is $agg->skipped, 1,
89   '... and we should have the correct number of skipped tests';
90 is_deeply [ $agg->skipped ], [qw(tap1)],
91   '... and be able to get their descriptions';
92
93 can_ok $agg, 'parse_errors';
94 is $agg->parse_errors, 0, '... and the correct number of parse errors';
95 is_deeply [ $agg->parse_errors ], [],
96   '... and be able to get their descriptions';
97
98 can_ok $agg, 'todo_passed';
99 is $agg->todo_passed, 1,
100   '... and the correct number of unexpectedly succeeded tests';
101 is_deeply [ $agg->todo_passed ], [qw(tap2)],
102   '... and be able to get their descriptions';
103
104 can_ok $agg, 'total';
105 is $agg->total, $agg->passed + $agg->failed,
106   '... and we should have the correct number of total tests';
107
108 can_ok $agg, 'has_problems';
109 ok $agg->has_problems, '... and it should report true if there are problems';
110
111 can_ok $agg, 'has_errors';
112 ok $agg->has_errors, '... and it should report true if there are errors';
113
114 can_ok $agg, 'get_status';
115 is $agg->get_status, 'FAIL', '... and it should tell us the tests failed';
116
117 can_ok $agg, 'all_passed';
118 ok !$agg->all_passed, '... and it should tell us not all tests passed';
119
120 # coverage testing
121
122 # _get_parsers
123 # bad descriptions
124 # currently the $agg object has descriptions tap1 and tap2
125 # call _get_parsers with another description.
126 # $agg will call  its _croak method
127 my @die;
128
129 eval {
130     local $SIG{__DIE__} = sub { push @die, @_ };
131
132     $agg->_get_parsers('no_such_parser_for');
133 };
134
135 is @die, 1,
136   'coverage tests for missing parsers... and we caught just one death message';
137 like pop(@die),
138   qr/^A parser for \(no_such_parser_for\) could not be found at /,
139   '... and it was the expected death message';
140
141 # _get_parsers in scalar context
142
143 my $gp = $agg->_get_parsers(qw(tap1 tap2))
144   ;    # should return ref to array containing parsers for tap1 and tap2
145
146 is @$gp, 2,
147   'coverage tests for _get_parser in scalar context... and we got the right number of parsers';
148 isa_ok( $_, 'TAP::Parser' ) foreach (@$gp);
149
150 # _get_parsers
151 # todo_failed - this is a deprecated method, so it  (and these tests)
152 # can be removed eventually.  However, it is showing up in the coverage
153 # as never tested.
154 my @warn;
155
156 eval {
157     local $SIG{__WARN__} = sub { push @warn, @_ };
158
159     $agg->todo_failed();
160 };
161
162 # check the warning, making sure to capture the fullstops correctly (not
163 # as "any char" matches)
164 is @warn, 1,
165   'coverage tests for deprecated todo_failed... and just one warning caught';
166 like pop(@warn),
167   qr/^"todo_failed" is deprecated[.]  Please use "todo_passed"[.]  See the docs[.] at/,
168   '... and it was the expected warning';
169
170 # has_problems
171 # this has a large number of conditions 'OR'd together, so the tests get
172 # a little complicated here
173
174 # currently, we have covered the cases of failed() being true and none
175 # of the summary methods failing
176
177 # we need to set up test cases for
178 # 1. !failed && todo_passed
179 # 2. !failed && !todo_passed && parse_errors
180 # 3. !failed && !todo_passed && !parse_errors && exit
181 # 4. !failed && !todo_passed && !parse_errors && !exit && wait
182
183 # note there is nothing wrong per se with the has_problems logic, these
184 # are simply coverage tests
185
186 # 1. !failed && todo_passed
187
188 $agg = TAP::Parser::Aggregator->new();
189 isa_ok $agg, 'TAP::Parser::Aggregator';
190
191 $tap = <<'END_TAP';
192 1..1
193 ok 1 - you shall not pass! # TODO should have failed
194 END_TAP
195
196 my $parser3 = TAP::Parser->new( { tap => $tap } );
197 isa_ok $parser3, 'TAP::Parser';
198 $parser3->run;
199
200 $agg->add( 'tap3', $parser3 );
201
202 is $agg->passed, 1,
203   'coverage tests for !failed && todo_passed... and we should have the correct number of passed tests';
204 is $agg->failed, 0,
205   '... and we should have the correct number of failed tests';
206 is $agg->todo_passed, 1,
207   '... and the correct number of unexpectedly succeeded tests';
208 ok $agg->has_problems,
209   '... and it should report true that there are problems';
210 is $agg->get_status, 'PASS',
211   '... and the status should be passing';
212 ok !$agg->has_errors,
213   '.... but it should not report any errors';
214 ok $agg->all_passed,
215   '... bonus tests should be passing tests, too';
216
217 # 2. !failed && !todo_passed && parse_errors
218
219 $agg = TAP::Parser::Aggregator->new();
220
221 $tap = <<'END_TAP';
222 1..-1
223 END_TAP
224
225 my $parser4 = TAP::Parser->new( { tap => $tap } );
226 isa_ok $parser4, 'TAP::Parser';
227 $parser4->run;
228
229 $agg->add( 'tap4', $parser4 );
230
231 is $agg->passed, 0,
232   'coverage tests for !failed && !todo_passed && parse_errors... and we should have the correct number of passed tests';
233 is $agg->failed, 0,
234   '... and we should have the correct number of failed tests';
235 is $agg->todo_passed, 0,
236   '... and the correct number of unexpectedly succeeded tests';
237 is $agg->parse_errors, 1, '... and the correct number of parse errors';
238 ok $agg->has_problems,
239   '... and it should report true that there are problems';
240
241 # 3. !failed && !todo_passed && !parse_errors && exit
242 # now this is a little harder to emulate cleanly through creating tap
243 # fragments and parsing, as exit and wait collect OS-status codes.
244 # so we'll get a little funky with $agg and push exit and wait descriptions
245 # in it - not very friendly to internal rep changes.
246
247 $agg = TAP::Parser::Aggregator->new();
248
249 $tap = <<'END_TAP';
250 1..1
251 ok 1 - you shall not pass!
252 END_TAP
253
254 my $parser5 = TAP::Parser->new( { tap => $tap } );
255 $parser5->run;
256
257 $agg->add( 'tap', $parser5 );
258
259 push @{ $agg->{descriptions_for_exit} }, 'one possible reason';
260 $agg->{exit}++;
261
262 is $agg->passed, 1,
263   'coverage tests for !failed && !todo_passed && !parse_errors... and we should have the correct number of passed tests';
264 is $agg->failed, 0,
265   '... and we should have the correct number of failed tests';
266 is $agg->todo_passed, 0,
267   '... and the correct number of unexpectedly succeeded tests';
268 is $agg->parse_errors, 0, '... and the correct number of parse errors';
269
270 my @exits = $agg->exit;
271
272 is @exits, 1, '... and the correct number of exits';
273 is pop(@exits), 'one possible reason',
274   '... and we collected the right exit reason';
275
276 ok $agg->has_problems,
277   '... and it should report true that there are problems';
278
279 # 4. !failed && !todo_passed && !parse_errors && !exit && wait
280
281 $agg = TAP::Parser::Aggregator->new();
282
283 $agg->add( 'tap', $parser5 );
284
285 push @{ $agg->{descriptions_for_wait} }, 'another possible reason';
286 $agg->{wait}++;
287
288 is $agg->passed, 1,
289   'coverage tests for !failed && !todo_passed && !parse_errors && !exit... and we should have the correct number of passed tests';
290 is $agg->failed, 0,
291   '... and we should have the correct number of failed tests';
292 is $agg->todo_passed, 0,
293   '... and the correct number of unexpectedly succeeded tests';
294 is $agg->parse_errors, 0, '... and the correct number of parse errors';
295 is $agg->exit,         0, '... and the correct number of exits';
296
297 my @waits = $agg->wait;
298
299 is @waits, 1, '... and the correct number of waits';
300 is pop(@waits), 'another possible reason',
301   '... and we collected the right wait reason';
302
303 ok $agg->has_problems,
304   '... and it should report true that there are problems';