4 if ( $ENV{PERL_CORE} ) {
6 @INC = ( '../lib', '../ext/Test-Harness/t/lib' );
23 @ISA = qw( App::Prove );
27 my $self = $class->SUPER::new(@_);
32 sub _color_default {0}
36 push @{ $self->{_log} }, [ '_runtests', @_ ];
41 my @log = @{ $self->{_log} };
55 return [ map { File::Spec->rel2abs($_) } @$ar ];
60 sub test_log_import { push @import_log, [@_] }
63 my @log = @import_log;
68 my @plugin_load_log = ();
69 sub test_log_plugin_load { push @plugin_load_log, [@_] }
71 sub get_plugin_load_log {
72 my @log = @plugin_load_log;
73 @plugin_load_log = ();
78 my ( @ATTR, %DEFAULT_ASSERTION, @SCHEDULE );
80 # see the "ACTUAL TEST" section at the bottom
86 archive argv blib color directives exec extension failures
87 formatter harness includes lib merge parse quiet really_quiet
88 recurse backwards shuffle taint_fail taint_warn verbose
89 warnings_fail warnings_warn
92 # what we expect if the 'expect' hash does not define it
93 %DEFAULT_ASSERTION = map { $_ => undef } @ATTR;
95 $DEFAULT_ASSERTION{includes} = $DEFAULT_ASSERTION{argv}
96 = sub { 'ARRAY' eq ref shift };
98 my @dummy_tests = map { File::Spec->catdir( 't', 'sample-tests', $_ ) }
99 qw(simple simple_yaml);
100 my $dummy_test = $dummy_tests[0];
102 ########################################################################
103 # declarations - this drives all of the subtests.
104 # The cheatsheet follows.
105 # required: name, expect
107 # args - arguments to constructor
108 # switches - command-line switches
109 # runlog - expected results of internal calls to _runtests, must
110 # match FakeProve's _log attr
111 # run_error - depends on 'runlog' (if missing, asserts no error)
112 # extra - follow-up check to handle exceptional cleanup / verification
113 # class - The App::Prove subclass to test. Defaults to FakeProve
115 { name => 'Create empty',
118 { name => 'Set all options via constructor',
121 argv => [qw(one two three)],
129 includes => [qw(four five six)],
146 argv => [qw(one two three)],
154 includes => [qw(four five six)],
170 { name => 'Call with defaults',
171 args => { argv => [qw( one two three )] },
179 'one', 'two', 'three'
184 # Test all options individually
186 # { name => 'Just archive',
188 # argv => [qw( one two three )],
203 { name => 'Just argv',
205 argv => [qw( one two three )],
208 argv => [qw( one two three )],
212 { verbosity => 0, show_count => 1 },
219 { name => 'Just blib',
221 argv => [qw( one two three )],
229 { lib => mabs( [ 'blib/lib', 'blib/arch' ] ),
234 'one', 'two', 'three'
239 { name => 'Just color',
241 argv => [qw( one two three )],
254 'one', 'two', 'three'
259 { name => 'Just directives',
261 argv => [qw( one two three )],
274 'one', 'two', 'three'
278 { name => 'Just exec',
280 argv => [qw( one two three )],
293 'one', 'two', 'three'
297 { name => 'Just failures',
299 argv => [qw( one two three )],
312 'one', 'two', 'three'
317 { name => 'Just formatter',
319 argv => [qw( one two three )],
320 formatter => 'TAP::Harness',
323 formatter => 'TAP::Harness',
327 { formatter_class => 'TAP::Harness',
332 'one', 'two', 'three'
337 { name => 'Just includes',
339 argv => [qw( one two three )],
340 includes => [qw( four five six )],
343 includes => [qw( four five six )],
347 { lib => mabs( [qw( four five six )] ),
352 'one', 'two', 'three'
356 { name => 'Just lib',
358 argv => [qw( one two three )],
366 { lib => mabs( ['lib'] ),
371 'one', 'two', 'three'
375 { name => 'Just merge',
377 argv => [qw( one two three )],
390 'one', 'two', 'three'
394 { name => 'Just parse',
396 argv => [qw( one two three )],
409 'one', 'two', 'three'
413 { name => 'Just quiet',
415 argv => [qw( one two three )],
427 'one', 'two', 'three'
431 { name => 'Just really_quiet',
433 argv => [qw( one two three )],
445 'one', 'two', 'three'
449 { name => 'Just recurse',
451 argv => [qw( one two three )],
463 'one', 'two', 'three'
467 { name => 'Just reverse',
469 argv => [qw( one two three )],
481 'three', 'two', 'one'
486 { name => 'Just shuffle',
488 argv => [qw( one two three )],
505 { name => 'Just taint_fail',
507 argv => [qw( one two three )],
515 { switches => ['-T'],
520 'one', 'two', 'three'
524 { name => 'Just taint_warn',
526 argv => [qw( one two three )],
534 { switches => ['-t'],
539 'one', 'two', 'three'
543 { name => 'Just verbose',
545 argv => [qw( one two three )],
557 'one', 'two', 'three'
561 { name => 'Just warnings_fail',
563 argv => [qw( one two three )],
571 { switches => ['-W'],
576 'one', 'two', 'three'
580 { name => 'Just warnings_warn',
582 argv => [qw( one two three )],
590 { switches => ['-w'],
595 'one', 'two', 'three'
600 # Command line parsing
601 { name => 'Switch -v',
603 argv => [qw( one two three )],
605 switches => [ '-v', $dummy_test ],
620 { name => 'Switch --verbose',
622 argv => [qw( one two three )],
624 switches => [ '--verbose', $dummy_test ],
639 { name => 'Switch -f',
641 argv => [qw( one two three )],
643 switches => [ '-f', $dummy_test ],
644 expect => { failures => 1 },
657 { name => 'Switch --failures',
659 argv => [qw( one two three )],
661 switches => [ '--failures', $dummy_test ],
662 expect => { failures => 1 },
675 { name => 'Switch -l',
677 argv => [qw( one two three )],
679 switches => [ '-l', $dummy_test ],
680 expect => { lib => 1 },
683 { lib => mabs( ['lib'] ),
693 { name => 'Switch --lib',
695 argv => [qw( one two three )],
697 switches => [ '--lib', $dummy_test ],
698 expect => { lib => 1 },
701 { lib => mabs( ['lib'] ),
711 { name => 'Switch -b',
713 argv => [qw( one two three )],
715 switches => [ '-b', $dummy_test ],
716 expect => { blib => 1 },
719 { lib => mabs( [ 'blib/lib', 'blib/arch' ] ),
729 { name => 'Switch --blib',
731 argv => [qw( one two three )],
733 switches => [ '--blib', $dummy_test ],
734 expect => { blib => 1 },
737 { lib => mabs( [ 'blib/lib', 'blib/arch' ] ),
747 { name => 'Switch -s',
749 argv => [qw( one two three )],
751 switches => [ '-s', $dummy_test ],
752 expect => { shuffle => 1 },
764 { name => 'Switch --shuffle',
766 argv => [qw( one two three )],
768 switches => [ '--shuffle', $dummy_test ],
769 expect => { shuffle => 1 },
781 { name => 'Switch -c',
783 argv => [qw( one two three )],
785 switches => [ '-c', $dummy_test ],
786 expect => { color => 1 },
799 { name => 'Switch -r',
801 argv => [qw( one two three )],
803 switches => [ '-r', $dummy_test ],
804 expect => { recurse => 1 },
816 { name => 'Switch --recurse',
818 argv => [qw( one two three )],
820 switches => [ '--recurse', $dummy_test ],
821 expect => { recurse => 1 },
833 { name => 'Switch --reverse',
835 argv => [qw( one two three )],
837 switches => [ '--reverse', @dummy_tests ],
838 expect => { backwards => 1 },
850 { name => 'Switch -p',
852 argv => [qw( one two three )],
854 switches => [ '-p', $dummy_test ],
870 { name => 'Switch --parse',
872 argv => [qw( one two three )],
874 switches => [ '--parse', $dummy_test ],
890 { name => 'Switch -q',
892 argv => [qw( one two three )],
894 switches => [ '-q', $dummy_test ],
895 expect => { quiet => 1 },
907 { name => 'Switch --quiet',
909 argv => [qw( one two three )],
911 switches => [ '--quiet', $dummy_test ],
912 expect => { quiet => 1 },
924 { name => 'Switch -Q',
926 argv => [qw( one two three )],
928 switches => [ '-Q', $dummy_test ],
929 expect => { really_quiet => 1 },
941 { name => 'Switch --QUIET',
943 argv => [qw( one two three )],
945 switches => [ '--QUIET', $dummy_test ],
946 expect => { really_quiet => 1 },
958 { name => 'Switch -m',
960 argv => [qw( one two three )],
962 switches => [ '-m', $dummy_test ],
963 expect => { merge => 1 },
976 { name => 'Switch --merge',
978 argv => [qw( one two three )],
980 switches => [ '--merge', $dummy_test ],
981 expect => { merge => 1 },
994 { name => 'Switch --directives',
996 argv => [qw( one two three )],
998 switches => [ '--directives', $dummy_test ],
999 expect => { directives => 1 },
1013 { name => 'Empty exec in .proverc',
1015 argv => [qw( one two three )],
1017 proverc => $ENV{PERL_CORE} ? '../ext/Test-Harness/t/proverc/emptyexec' : 't/proverc/emptyexec',
1018 switches => [$dummy_test],
1019 expect => { exec => '' },
1032 # Executing one word (why would it be a -s though?)
1033 { name => 'Switch --exec -s',
1035 argv => [qw( one two three )],
1037 switches => [ '--exec', '-s', $dummy_test ],
1038 expect => { exec => '-s' },
1052 { name => 'Switch --exec "/foo/bar/perl -Ilib"',
1054 argv => [qw( one two three )],
1056 switches => [ '--exec', '/foo/bar/perl -Ilib', $dummy_test ],
1057 expect => { exec => '/foo/bar/perl -Ilib' },
1060 { exec => [qw(/foo/bar/perl -Ilib)],
1070 # null exec (run tests as compiled binaries)
1071 { name => 'Switch --exec ""',
1072 switches => [ '--exec', '', $dummy_test ],
1074 exec => # ick, must workaround the || default bit with a sub
1075 sub { my $val = shift; defined($val) and !length($val) }
1090 { name => 'Load plugin',
1091 switches => [ '-P', 'Dummy', $dummy_test ],
1093 argv => [qw( one two three )],
1096 plugins => ['Dummy'],
1099 my @loaded = get_import_log();
1100 is_deeply \@loaded, [ ['App::Prove::Plugin::Dummy'] ],
1115 { name => 'Load plugin (args)',
1116 switches => [ '-P', 'Dummy=cracking,cheese,gromit', $dummy_test ],
1118 argv => [qw( one two three )],
1121 plugins => ['Dummy'],
1124 my @loaded = get_import_log();
1126 [ [ 'App::Prove::Plugin::Dummy', 'cracking', 'cheese',
1144 { name => 'Load plugin (explicit path)',
1145 switches => [ '-P', 'App::Prove::Plugin::Dummy', $dummy_test ],
1147 argv => [qw( one two three )],
1150 plugins => ['Dummy'],
1153 my @loaded = get_import_log();
1154 is_deeply \@loaded, [ ['App::Prove::Plugin::Dummy'] ],
1169 { name => 'Load plugin (args + call load method)',
1170 switches => [ '-P', 'Dummy2=fou,du,fafa', $dummy_test ],
1172 argv => [qw( one two three )],
1175 plugins => ['Dummy2'],
1178 my @import = get_import_log();
1180 [ [ 'App::Prove::Plugin::Dummy2', 'fou', 'du', 'fafa' ] ],
1183 my @loaded = get_plugin_load_log();
1184 is( scalar @loaded, 1, 'Plugin->load called OK' );
1185 my ( $plugin_class, $args ) = @{ shift @loaded };
1186 is( $plugin_class, 'App::Prove::Plugin::Dummy2',
1187 'plugin_class passed'
1190 $args->{app_prove}, 'App::Prove',
1191 'app_prove object passed'
1194 $args->{args}, [qw( fou du fafa )],
1195 'expected args passed'
1210 { name => 'Load module',
1211 switches => [ '-M', 'App::Prove::Plugin::Dummy', $dummy_test ],
1213 argv => [qw( one two three )],
1216 plugins => ['Dummy'],
1219 my @loaded = get_import_log();
1220 is_deeply \@loaded, [ ['App::Prove::Plugin::Dummy'] ],
1236 # Hmm, that doesn't work...
1237 # { name => 'Switch -h',
1239 # argv => [qw( one two three )],
1241 # switches => [ '-h', $dummy_test ],
1252 # { name => 'Switch --help',
1254 # argv => [qw( one two three )],
1256 # switches => [ '--help', $dummy_test ],
1265 # { name => 'Switch -?',
1267 # argv => [qw( one two three )],
1269 # switches => [ '-?', $dummy_test ],
1279 # { name => 'Switch -H',
1281 # argv => [qw( one two three )],
1283 # switches => [ '-H', $dummy_test ],
1293 # { name => 'Switch --man',
1295 # argv => [qw( one two three )],
1297 # switches => [ '--man', $dummy_test ],
1307 # { name => 'Switch -V',
1309 # argv => [qw( one two three )],
1311 # switches => [ '-V', $dummy_test ],
1321 # { name => 'Switch --version',
1323 # argv => [qw( one two three )],
1325 # switches => [ '--version', $dummy_test ],
1335 # { name => 'Switch --color!',
1337 # argv => [qw( one two three )],
1339 # switches => [ '--color!', $dummy_test ],
1349 { name => 'Switch -I=s@',
1351 argv => [qw( one two three )],
1353 switches => [ '-Ilib', $dummy_test ],
1356 my ( $val, $attr ) = @_;
1360 && $val->[0] =~ /lib$/;
1365 # { name => 'Switch -a',
1367 # argv => [qw( one two three )],
1369 # switches => [ '-a', $dummy_test ],
1379 # { name => 'Switch --archive=-s',
1381 # argv => [qw( one two three )],
1383 # switches => [ '--archive=-s', $dummy_test ],
1393 # { name => 'Switch --formatter=-s',
1395 # argv => [qw( one two three )],
1397 # switches => [ '--formatter=-s', $dummy_test ],
1407 # { name => 'Switch -e',
1409 # argv => [qw( one two three )],
1411 # switches => [ '-e', $dummy_test ],
1421 # { name => 'Switch --harness=-s',
1423 # argv => [qw( one two three )],
1425 # switches => [ '--harness=-s', $dummy_test ],
1438 ########################################################################
1441 for my $test (@SCHEDULE) {
1442 $extra_plan += $test->{plan} || 0;
1443 $extra_plan += 2 if $test->{runlog};
1444 $extra_plan += 1 if $test->{switches};
1447 plan tests => @SCHEDULE * ( 3 + @ATTR ) + $extra_plan;
1451 for my $test (@SCHEDULE) {
1452 my $name = $test->{name};
1453 my $class = $test->{class} || 'FakeProve';
1455 local $ENV{HARNESS_TIMER};
1457 ok my $app = $class->new( exists $test->{args} ? $test->{args} : () ),
1458 "$name: App::Prove created OK";
1460 isa_ok $app, 'App::Prove';
1461 isa_ok $app, $class;
1463 # Optionally parse command args
1464 if ( my $switches = $test->{switches} ) {
1465 if ( my $proverc = $test->{proverc} ) {
1466 $app->add_rc_file( File::Spec->catfile( split /\//, $proverc ) );
1468 eval { $app->process_args( '--norc', @$switches ) };
1469 if ( my $err_pattern = $test->{parse_error} ) {
1470 like $@, $err_pattern, "$name: expected parse error";
1473 ok !$@, "$name: no parse error";
1477 my $expect = $test->{expect} || {};
1478 for my $attr ( sort @ATTR ) {
1479 my $val = $app->$attr();
1481 = exists $expect->{$attr}
1483 : $DEFAULT_ASSERTION{$attr};
1486 if ( 'CODE' eq ref $assertion ) {
1487 $is_ok = ok $assertion->( $val, $attr ),
1488 "$name: $attr has the expected value";
1490 elsif ( 'Regexp' eq ref $assertion ) {
1491 $is_ok = like $val, $assertion, "$name: $attr matches $assertion";
1494 $is_ok = is_deeply $val, $assertion,
1495 "$name: $attr has the expected value";
1499 diag "got $val for $attr";
1503 if ( my $runlog = $test->{runlog} ) {
1505 if ( my $err_pattern = $test->{run_error} ) {
1506 like $@, $err_pattern, "$name: expected error OK";
1508 pass for 1 .. $test->{plan};
1511 unless ( ok !$@, "$name: no error OK" ) {
1512 diag "$name: error: $@\n";
1515 my $gotlog = [ $app->get_log ];
1517 if ( my $extra = $test->{extra} ) {
1522 is_deeply $gotlog, $runlog,
1523 "$name: run results match"
1527 diag Dumper( { wanted => $runlog, got => $gotlog } );