4 if ( $ENV{PERL_CORE} ) {
6 @INC = ( '../lib', '../ext/Test-Harness/t/lib' );
20 my $HARNESS = 'TAP::Harness';
23 = $ENV{PERL_CORE} ? '../ext/Test-Harness/t/source_tests' : 't/source_tests';
25 = $ENV{PERL_CORE} ? '../ext/Test-Harness/t/sample-tests' : 't/sample-tests';
29 # note that this test will always pass when run through 'prove'
30 ok $ENV{HARNESS_ACTIVE}, 'HARNESS_ACTIVE env variable should be set';
31 ok $ENV{HARNESS_VERSION}, 'HARNESS_VERSION env variable should be set';
33 #### For color tests ####
37 sub new { bless {}, shift }
41 my ( $self, $output, $color ) = @_;
42 $output->("[[$color]]");
49 $harness->formatter->_colorizer( Colorizer->new );
52 can_ok $HARNESS, 'new';
54 eval { $HARNESS->new( { no_such_key => 1 } ) };
55 like $@, qr/\QUnknown arguments to TAP::Harness::new (no_such_key)/,
56 '... and calling it with bad keys should fail';
58 eval { $HARNESS->new( { lib => 'aint_no_such_lib' } ) };
59 is $@, '', '... and calling it with a non-existent lib is fine';
61 eval { $HARNESS->new( { lib => [qw/bad_lib_1 bad_lib_2/] } ) };
62 is $@, '', '... and calling it with non-existent libs is fine';
64 ok my $harness = $HARNESS->new,
65 'Calling new() without arguments should succeed';
67 foreach my $test_args ( get_arg_sets() ) {
68 my %args = %$test_args;
69 foreach my $key ( sort keys %args ) {
70 $args{$key} = $args{$key}{in};
72 ok my $harness = $HARNESS->new( {%args} ),
73 'Calling new() with valid arguments should succeed';
74 isa_ok $harness, $HARNESS, '... and the object it returns';
76 while ( my ( $property, $test ) = each %$test_args ) {
77 my $value = $test->{out};
78 can_ok $harness, $property;
79 is_deeply scalar $harness->$property(), $value, $test->{test_name};
86 local *TAP::Formatter::Base::_output = sub {
88 push @output => grep { $_ ne '' }
95 my $harness = TAP::Harness->new(
96 { verbosity => 1, formatter_class => "TAP::Formatter::Console" } );
97 my $harness_whisper = TAP::Harness->new(
98 { verbosity => -1, formatter_class => "TAP::Formatter::Console" } );
99 my $harness_mute = TAP::Harness->new(
100 { verbosity => -2, formatter_class => "TAP::Formatter::Console" } );
101 my $harness_directives = TAP::Harness->new(
102 { directives => 1, formatter_class => "TAP::Formatter::Console" } );
103 my $harness_failures = TAP::Harness->new(
104 { failures => 1, formatter_class => "TAP::Formatter::Console" } );
108 can_ok $harness, 'runtests';
110 # normal tests in verbose mode
112 ok my $aggregate = _runtests( $harness, "$source_tests/harness" ),
113 '... runtests returns the aggregate';
115 isa_ok $aggregate, 'TAP::Parser::Aggregator';
120 "$source_tests/harness ..",
123 'ok 1 - this is a test',
127 'All tests successful.',
130 my $status = pop @output;
131 my $expected_status = qr{^Result: PASS$};
132 my $summary = pop @output;
133 my $expected_summary = qr{^Files=1, Tests=1, \d+ wallclock secs};
135 is_deeply \@output, \@expected, '... and the output should be correct';
136 like $status, $expected_status,
137 '... and the status line should be correct';
138 like $summary, $expected_summary,
139 '... and the report summary should look correct';
141 # use an alias for test name
145 = _runtests( $harness, [ "$source_tests/harness", 'My Nice Test' ] ),
146 '... runtests returns the aggregate';
148 isa_ok $aggregate, 'TAP::Parser::Aggregator';
156 'ok 1 - this is a test',
160 'All tests successful.',
163 $status = pop @output;
164 $expected_status = qr{^Result: PASS$};
165 $summary = pop @output;
166 $expected_summary = qr{^Files=1, Tests=1, \d+ wallclock secs};
168 is_deeply \@output, \@expected, '... and the output should be correct';
169 like $status, $expected_status,
170 '... and the status line should be correct';
171 like $summary, $expected_summary,
172 '... and the report summary should look correct';
174 # run same test twice
177 ok $aggregate = _runtests(
178 $harness, [ "$source_tests/harness", 'My Nice Test' ],
179 [ "$source_tests/harness", 'My Nice Test Again' ]
181 '... runtests returns the aggregate';
183 isa_ok $aggregate, 'TAP::Parser::Aggregator';
188 'My Nice Test ........',
191 'ok 1 - this is a test',
194 'My Nice Test Again ..',
197 'ok 1 - this is a test',
201 'All tests successful.',
204 $status = pop @output;
205 $expected_status = qr{^Result: PASS$};
206 $summary = pop @output;
207 $expected_summary = qr{^Files=2, Tests=2, \d+ wallclock secs};
209 is_deeply \@output, \@expected, '... and the output should be correct';
210 like $status, $expected_status,
211 '... and the status line should be correct';
212 like $summary, $expected_summary,
213 '... and the report summary should look correct';
215 # normal tests in quiet mode
218 _runtests( $harness_whisper, "$source_tests/harness" );
222 "$source_tests/harness ..",
224 'All tests successful.',
227 $status = pop @output;
228 $expected_status = qr{^Result: PASS$};
229 $summary = pop @output;
230 $expected_summary = qr/^Files=1, Tests=1, \d+ wallclock secs/;
232 is_deeply \@output, \@expected, '... and the output should be correct';
233 like $status, $expected_status,
234 '... and the status line should be correct';
235 like $summary, $expected_summary,
236 '... and the report summary should look correct';
238 # normal tests in really_quiet mode
241 _runtests( $harness_mute, "$source_tests/harness" );
245 'All tests successful.',
248 $status = pop @output;
249 $expected_status = qr{^Result: PASS$};
250 $summary = pop @output;
251 $expected_summary = qr/^Files=1, Tests=1, \d+ wallclock secs/;
253 is_deeply \@output, \@expected, '... and the output should be correct';
254 like $status, $expected_status,
255 '... and the status line should be correct';
256 like $summary, $expected_summary,
257 '... and the report summary should look correct';
259 # normal tests with failures
262 _runtests( $harness, "$source_tests/harness_failure" );
264 $status = pop @output;
265 $summary = pop @output;
267 like $status, qr{^Result: FAIL$},
268 '... and the status line should be correct';
270 my @summary = @output[ 18 .. $#output ];
271 @output = @output[ 0 .. 17 ];
274 "$source_tests/harness_failure ..",
277 'ok 1 - this is a test',
280 'not ok 2 - this is another test',
282 q{# Failed test 'this is another test'},
284 '# in harness_failure.t at line 5.',
288 q{# expected: 'yarblokos'},
291 'Failed 1/2 subtests',
294 is_deeply \@output, \@expected,
295 '... and failing test output should be correct';
297 my @expected_summary = (
299 'Test Summary Report',
300 '-------------------',
302 "$source_tests/harness_failure (Wstat: 0 Tests: 2 Failed: 1)",
312 is_deeply \@summary, \@expected_summary,
313 '... and the failure summary should also be correct';
315 # quiet tests with failures
318 _runtests( $harness_whisper, "$source_tests/harness_failure" );
320 $status = pop @output;
321 $summary = pop @output;
323 "$source_tests/harness_failure ..",
324 'Failed 1/2 subtests',
325 'Test Summary Report',
326 '-------------------',
327 "$source_tests/harness_failure (Wstat: 0 Tests: 2 Failed: 1)",
332 like $status, qr{^Result: FAIL$},
333 '... and the status line should be correct';
335 is_deeply \@output, \@expected,
336 '... and failing test output should be correct';
338 # really quiet tests with failures
341 _runtests( $harness_mute, "$source_tests/harness_failure" );
343 $status = pop @output;
344 $summary = pop @output;
346 'Test Summary Report',
347 '-------------------',
348 "$source_tests/harness_failure (Wstat: 0 Tests: 2 Failed: 1)",
353 like $status, qr{^Result: FAIL$},
354 '... and the status line should be correct';
356 is_deeply \@output, \@expected,
357 '... and failing test output should be correct';
359 # only show directives
364 "$source_tests/harness_directives"
370 "$source_tests/harness_directives ..",
371 'not ok 2 - we have a something # TODO some output',
372 "ok 3 houston, we don't have liftoff # SKIP no funding",
374 'All tests successful.',
376 # ~TODO {{{ this should be an option
377 #'Test Summary Report',
378 #'-------------------',
379 #"$source_tests/harness_directives (Wstat: 0 Tests: 3 Failed: 0)",
385 $status = pop @output;
386 $summary = pop @output;
387 $expected_summary = qr/^Files=1, Tests=3, \d+ wallclock secs/;
389 is_deeply \@output, \@expected, '... and the output should be correct';
390 like $summary, $expected_summary,
391 '... and the report summary should look correct';
393 like $status, qr{^Result: PASS$},
394 '... and the status line should be correct';
396 # normal tests with bad tap
398 # install callback handler
400 my $callback_count = 0;
402 my @callback_log = ();
404 for my $evt (qw(parser_args made_parser before_runtests after_runtests)) {
407 push @callback_log, $evt;
420 _runtests( $harness, "$source_tests/harness_badtap" );
423 @output = map { trim($_) } @output;
424 $status = pop @output;
425 @summary = @output[ 12 .. ( $#output - 1 ) ];
426 @output = @output[ 0 .. 11 ];
428 "$source_tests/harness_badtap ..",
431 'ok 1 - this is a test',
434 'not ok 2 - this is another test',
439 'Failed 1/2 subtests',
441 is_deeply \@output, \@expected,
442 '... and failing test output should be correct';
443 like $status, qr{^Result: FAIL$},
444 '... and the status line should be correct';
445 @expected_summary = (
447 'Test Summary Report',
448 '-------------------',
450 "$source_tests/harness_badtap (Wstat: 0 Tests: 2 Failed: 1)",
459 'Parse errors: More than one plan found in TAP output',
462 is_deeply \@summary, \@expected_summary,
463 '... and the badtap summary should also be correct';
465 cmp_ok( $callback_count, '==', 1, 'callback called once' );
468 [ 'before_runtests', 'parser_args', 'made_parser', 'after_runtests' ],
469 'callback log matches'
471 isa_ok $parser, 'TAP::Parser';
473 # coverage testing for _should_show_failures
477 _runtests( $harness_failures, "$source_tests/harness_failure" );
482 "$source_tests/harness_failure ..",
483 'not ok 2 - this is another test',
484 'Failed 1/2 subtests',
485 'Test Summary Report',
486 '-------------------',
487 "$source_tests/harness_failure (Wstat: 0 Tests: 2 Failed: 1)",
492 $status = pop @output;
493 $summary = pop @output;
495 like $status, qr{^Result: FAIL$},
496 '... and the status line should be correct';
497 $expected_summary = qr/^Files=1, Tests=2, \d+ wallclock secs/;
498 is_deeply \@output, \@expected, '... and the output should be correct';
500 # check the status output for no tests
503 _runtests( $harness_failures, "$sample_tests/no_output" );
508 "$sample_tests/no_output ..",
510 'Test Summary Report',
511 '-------------------',
512 "$sample_tests/no_output (Wstat: 0 Tests: 0 Failed: 0)",
513 'Parse errors: No plan found in TAP output',
516 $status = pop @output;
517 $summary = pop @output;
519 like $status, qr{^Result: FAIL$},
520 '... and the status line should be correct';
521 $expected_summary = qr/^Files=1, Tests=2, \d+ wallclock secs/;
522 is_deeply \@output, \@expected, '... and the output should be correct';
527 # make sure we can exec something ... anything!
530 my $cat = '/bin/cat';
535 my $capture = IO::c55Capture->new_handle;
536 my $harness = TAP::Harness->new(
547 ? '../ext/Test-Harness/t/data/catme.1'
552 my @output = tied($$capture)->dump;
553 my $status = pop @output;
554 like $status, qr{^Result: PASS$},
555 '... and the status line should be correct';
556 pop @output; # get rid of summary line
557 my $answer = pop @output;
558 is( $answer, "All tests successful.\n", 'cat meows' );
561 # make sure that we can exec with a code ref.
563 my $capture = IO::c55Capture->new_handle;
564 my $harness = TAP::Harness->new(
571 _runtests( $harness, "$source_tests/harness" );
573 my @output = tied($$capture)->dump;
574 my $status = pop @output;
575 like $status, qr{^Result: PASS$},
576 '... and the status line should be correct';
577 pop @output; # get rid of summary line
578 my $answer = pop @output;
579 is( $answer, "All tests successful.\n", 'cat meows' );
582 # Exec with a coderef that returns an arrayref
584 my $cat = '/bin/cat';
589 my $capture = IO::c55Capture->new_handle;
590 my $harness = TAP::Harness->new(
597 ? '../ext/Test-Harness/t/data/catme.1'
604 _runtests( $harness, "$source_tests/harness" );
606 my @output = tied($$capture)->dump;
607 my $status = pop @output;
608 like $status, qr{^Result: PASS$},
609 '... and the status line should be correct';
610 pop @output; # get rid of summary line
611 my $answer = pop @output;
612 is( $answer, "All tests successful.\n", 'cat meows' );
615 # Exec with a coderef that returns raw TAP
617 my $capture = IO::c55Capture->new_handle;
618 my $harness = TAP::Harness->new(
622 return "1..1\nok 1 - raw TAP\n";
627 _runtests( $harness, "$source_tests/harness" );
629 my @output = tied($$capture)->dump;
630 my $status = pop @output;
631 like $status, qr{^Result: PASS$},
632 '... and the status line should be correct';
633 pop @output; # get rid of summary line
634 my $answer = pop @output;
635 is( $answer, "All tests successful.\n", 'cat meows' );
638 # Exec with a coderef that returns a filehandle
640 my $capture = IO::c55Capture->new_handle;
641 my $harness = TAP::Harness->new(
647 ? '../ext/Test-Harness/t/data/catme.1'
654 _runtests( $harness, "$source_tests/harness" );
656 my @output = tied($$capture)->dump;
657 my $status = pop @output;
658 like $status, qr{^Result: PASS$},
659 '... and the status line should be correct';
660 pop @output; # get rid of summary line
661 my $answer = pop @output;
662 is( $answer, "All tests successful.\n", 'cat meows' );
665 # catches "exec accumulates arguments" issue (r77)
667 my $capture = IO::c55Capture->new_handle;
668 my $harness = TAP::Harness->new(
677 "$source_tests/harness_complain"
678 , # will get mad if run with args
679 "$source_tests/harness",
682 my @output = tied($$capture)->dump;
683 my $status = pop @output;
684 like $status, qr{^Result: PASS$},
685 '... and the status line should be correct';
686 pop @output; # get rid of summary line
687 is( $output[-1], "All tests successful.\n",
688 'No exec accumulation'
693 $_[0] =~ s/^\s+|\s+$//g;
698 return [ map {"-I$_"} @_ ];
703 # keys are keys to new()
707 out => liblist('lib'),
708 test_name => '... a single lib switch should be correct'
713 test_name => '... and we should be able to set verbosity to 1'
719 # test_name => '... and we should be able to set verbose to true'
723 in => [ 'lib', 't' ],
724 out => liblist( 'lib', 't' ),
725 test_name => '... multiple lib dirs should be correct'
730 test_name => '... and we should be able to set verbosity to 0'
736 # test_name => '... and we should be able to set verbose to false'
740 in => [ '-T', '-w', '-T' ],
741 out => [ '-T', '-w', '-T' ],
742 test_name => '... duplicate switches should remain',
748 '... and we should be able to set failures to true',
753 test_name => '... and we should be able to set verbosity to -1'
759 # test_name => '... and we should be able to set quiet to false'
766 test_name => '... and we should be able to set verbosity to -2'
773 # '... and we should be able to set really_quiet to true',
779 '... and we should be able to set the executable',
786 '... leading dashes (-) on switches are not optional',
792 test_name => '... we should be able to set switches',
797 test_name => '... and we should be able to set failures to true'
803 my ( $harness, @tests ) = @_;
804 local $ENV{PERL_TEST_HARNESS_DUMP_TAP} = 0;
805 my $aggregate = $harness->runtests(@tests);
811 # coverage tests for ctor
813 my $harness = TAP::Harness->new(
822 is $harness->timer(), 0, 'timer getter';
823 is $harness->timer(10), 10, 'timer setter';
824 is $harness->errors(), 1, 'errors getter';
825 is $harness->errors(10), 10, 'errors setter';
826 is $harness->merge(), 2, 'merge getter';
827 is $harness->merge(10), 10, 'merge setter';
830 is $harness->jobs(), 1, 'jobs';
835 # coverage tests for the stdout key of VALIDATON_FOR, used by _initialize() in the ctor
837 # the coverage tests are
838 # 1. ref $ref => false
839 # 2. ref => ! GLOB and ref->can(print)
840 # 3. ref $ref => GLOB
847 local $SIG{__DIE__} = sub { push @die, @_ };
849 my $harness = TAP::Harness->new(
850 { stdout => bless {}, '0', # how evil is THAT !!!
855 is @die, 1, 'bad filehandle to stdout';
856 like pop @die, qr/option 'stdout' needs a filehandle/,
857 '... and we died as expected';
865 sub new { return bless {}, shift }
871 my $harness = TAP::Harness->new(
872 { stdout => Printable->new(),
876 isa_ok $harness, 'TAP::Harness';
882 $harness = TAP::Harness->new(
883 { stdout => bless {}, 'GLOB', # again with the evil
887 isa_ok $harness, 'TAP::Harness';
892 # coverage testing of lib/switches accessor
893 my $harness = TAP::Harness->new;
898 local $SIG{__DIE__} = sub { push @die, @_ };
900 $harness->switches(qw( too many arguments));
903 is @die, 1, 'too many arguments to accessor';
905 like pop @die, qr/Too many arguments to method 'switches'/,
906 '...and we died as expected';
908 $harness->switches('simple scalar');
910 my $arrref = $harness->switches;
911 is_deeply $arrref, ['simple scalar'], 'scalar wrapped in arr ref';
916 # coverage tests for the basically untested T::H::_open_spool
920 ? ( File::Spec->updir(), 'ext', 'Test-Harness' )
925 $ENV{PERL_TEST_HARNESS_DUMP_TAP} = File::Spec->catfile(@spool);
927 # now given that we're going to be writing stuff to the file system, make sure we have
933 # remove the tree if we made it this far
934 rmtree( $ENV{PERL_TEST_HARNESS_DUMP_TAP} )
935 if $ENV{PERL_TEST_HARNESS_DUMP_TAP};
938 my $harness = TAP::Harness->new( { verbosity => -2 } );
940 can_ok $harness, 'runtests';
942 # normal tests in verbose mode
945 = $harness->runtests( File::Spec->catfile( $source_tests, 'harness' ) );
947 isa_ok $parser, 'TAP::Parser::Aggregator',
948 '... runtests returns the aggregate';
950 ok -e File::Spec->catfile(
951 $ENV{PERL_TEST_HARNESS_DUMP_TAP},
952 $source_tests, 'harness'
960 { name => 'all the same',
961 input => [ 'foo.t', 'bar.t', 'fletz.t' ],
963 [ 'foo.t', 'foo.t' ], [ 'bar.t', 'bar.t' ],
964 [ 'fletz.t', 'fletz.t' ]
967 { name => 'all the same, already cooked',
968 input => [ 'foo.t', [ 'bar.t', 'brip' ], 'fletz.t' ],
970 [ 'foo.t', 'foo.t' ], [ 'bar.t', 'brip' ],
971 [ 'fletz.t', 'fletz.t' ]
974 { name => 'different exts',
975 input => [ 'foo.t', 'bar.u', 'fletz.v' ],
977 [ 'foo.t', 'foo.t' ], [ 'bar.u', 'bar.u' ],
978 [ 'fletz.v', 'fletz.v' ]
981 { name => 'different exts, one already cooked',
982 input => [ 'foo.t', [ 'bar.u', 'bam' ], 'fletz.v' ],
984 [ 'foo.t', 'foo.t' ], [ 'bar.u', 'bam' ],
985 [ 'fletz.v', 'fletz.v' ]
988 { name => 'different exts, two already cooked',
989 input => [ 'foo.t', [ 'bar.u', 'bam.q' ], [ 'fletz.v', 'boo' ] ],
991 [ 'foo.t', 'foo.t' ], [ 'bar.u', 'bam.q' ],
997 for my $case (@cases) {
998 is_deeply [ TAP::Harness->_add_descriptions( @{ $case->{input} } ) ],
999 $case->{output}, '_add_descriptions: ' . $case->{name};