Upgrade to Test::Harness 3.05
[p5sagit/p5-mst-13.2.git] / lib / Test / Harness / t / prove.t
1 #!/usr/bin/perl -w
2
3 BEGIN {
4     if ($ENV{PERL_CORE}) {
5         # FIXME
6         print "1..0 # Skip, needs fixing. Probably an -I issue\n";
7         exit 0;
8     }
9 }
10
11 use strict;
12 use lib 't/lib';
13
14 use Test::More;
15 use File::Spec;
16
17 use App::Prove;
18
19 package FakeProve;
20 use vars qw( @ISA );
21
22 @ISA = qw( App::Prove );
23
24 sub new {
25     my $class = shift;
26     my $self  = $class->SUPER::new(@_);
27     $self->{_log} = [];
28     return $self;
29 }
30
31 sub _color_default {0}
32
33 sub _runtests {
34     my $self = shift;
35     push @{ $self->{_log} }, [ '_runtests', @_ ];
36 }
37
38 sub get_log {
39     my $self = shift;
40     my @log  = @{ $self->{_log} };
41     $self->{_log} = [];
42     return @log;
43 }
44
45 sub _shuffle {
46     my $self = shift;
47     s/^/xxx/ for @_;
48 }
49
50 package main;
51
52 sub mabs {
53     my $ar = shift;
54     return [ map { File::Spec->rel2abs($_) } @$ar ];
55 }
56
57 {
58     my @import_log = ();
59
60     sub test_log_import { push @import_log, [@_] }
61
62     sub get_import_log {
63         my @log = @import_log;
64         @import_log = ();
65         return @log;
66     }
67 }
68
69 my ( @ATTR, %DEFAULT_ASSERTION, @SCHEDULE );
70
71 # see the "ACTUAL TEST" section at the bottom
72
73 BEGIN {    # START PLAN
74
75     # list of attributes
76     @ATTR = qw(
77       archive argv blib color directives exec failures formatter harness
78       includes lib merge parse quiet really_quiet recurse backwards
79       shuffle taint_fail taint_warn verbose warnings_fail warnings_warn
80     );
81
82     # what we expect if the 'expect' hash does not define it
83     %DEFAULT_ASSERTION = map { $_ => undef } @ATTR;
84
85     $DEFAULT_ASSERTION{includes} = $DEFAULT_ASSERTION{argv}
86       = sub { 'ARRAY' eq ref shift };
87
88     my @dummy_tests = map { File::Spec->catdir( 't', 'sample-tests', $_ ) }
89       qw(simple simple_yaml);
90     my $dummy_test = $dummy_tests[0];
91
92     ########################################################################
93  # declarations - this drives all of the subtests.
94  # The cheatsheet follows.
95  # required: name, expect
96  # optional:
97  #   args       - arguments to constructor
98  #   switches   - command-line switches
99  #   runlog     - expected results of internal calls to _runtests, must
100  #                match FakeProve's _log attr
101  #   run_error  - depends on 'runlog' (if missing, asserts no error)
102  #   extra      - follow-up check to handle exceptional cleanup / verification
103  #   class      - The App::Prove subclass to test. Defaults to FakeProve
104     @SCHEDULE = (
105         {   name   => 'Create empty',
106             expect => {}
107         },
108         {   name => 'Set all options via constructor',
109             args => {
110                 archive       => 1,
111                 argv          => [qw(one two three)],
112                 blib          => 2,
113                 color         => 3,
114                 directives    => 4,
115                 exec          => 5,
116                 failures      => 7,
117                 formatter     => 8,
118                 harness       => 9,
119                 includes      => [qw(four five six)],
120                 lib           => 10,
121                 merge         => 11,
122                 parse         => 13,
123                 quiet         => 14,
124                 really_quiet  => 15,
125                 recurse       => 16,
126                 backwards     => 17,
127                 shuffle       => 18,
128                 taint_fail    => 19,
129                 taint_warn    => 20,
130                 verbose       => 21,
131                 warnings_fail => 22,
132                 warnings_warn => 23,
133             },
134             expect => {
135                 archive       => 1,
136                 argv          => [qw(one two three)],
137                 blib          => 2,
138                 color         => 3,
139                 directives    => 4,
140                 exec          => 5,
141                 failures      => 7,
142                 formatter     => 8,
143                 harness       => 9,
144                 includes      => [qw(four five six)],
145                 lib           => 10,
146                 merge         => 11,
147                 parse         => 13,
148                 quiet         => 14,
149                 really_quiet  => 15,
150                 recurse       => 16,
151                 backwards     => 17,
152                 shuffle       => 18,
153                 taint_fail    => 19,
154                 taint_warn    => 20,
155                 verbose       => 21,
156                 warnings_fail => 22,
157                 warnings_warn => 23,
158             }
159         },
160         {   name   => 'Call with defaults',
161             args   => { argv => [qw( one two three )] },
162             expect => {},
163             runlog => [
164                 [   '_runtests',
165                     { verbosity => 0 },
166                     'TAP::Harness',
167                     'one',
168                     'two',
169                     'three'
170                 ]
171             ],
172         },
173
174         # Test all options individually
175
176         # {   name => 'Just archive',
177         #     args => {
178         #         argv    => [qw( one two three )],
179         #         archive => 1,
180         #     },
181         #     expect => {
182         #         archive => 1,
183         #     },
184         #     runlog => [
185         #         [   {   archive => 1,
186         #             },
187         #             'TAP::Harness',
188         #             'one', 'two',
189         #             'three'
190         #         ]
191         #     ],
192         # },
193         {   name => 'Just argv',
194             args => {
195                 argv => [qw( one two three )],
196             },
197             expect => {
198                 argv => [qw( one two three )],
199             },
200             runlog => [
201                 [   '_runtests',
202                     { verbosity => 0 },
203                     'TAP::Harness',
204                     'one', 'two',
205                     'three'
206                 ]
207             ],
208         },
209         {   name => 'Just blib',
210             args => {
211                 argv => [qw( one two three )],
212                 blib => 1,
213             },
214             expect => {
215                 blib => 1,
216             },
217             runlog => [
218                 [   '_runtests',
219                     {   lib => mabs( [ 'blib/lib', 'blib/arch' ] ),
220                         verbosity => 0
221                     },
222                     'TAP::Harness',
223                     'one', 'two', 'three'
224                 ]
225             ],
226         },
227
228         {   name => 'Just color',
229             args => {
230                 argv  => [qw( one two three )],
231                 color => 1,
232             },
233             expect => {
234                 color => 1,
235             },
236             runlog => [
237                 [   '_runtests',
238                     {   color     => 1,
239                         verbosity => 0
240                     },
241                     'TAP::Harness',
242                     'one', 'two', 'three'
243                 ]
244             ],
245         },
246
247         {   name => 'Just directives',
248             args => {
249                 argv       => [qw( one two three )],
250                 directives => 1,
251             },
252             expect => {
253                 directives => 1,
254             },
255             runlog => [
256                 [   '_runtests',
257                     {   directives => 1,
258                         verbosity  => 0
259                     },
260                     'TAP::Harness',
261                     'one', 'two', 'three'
262                 ]
263             ],
264         },
265         {   name => 'Just exec',
266             args => {
267                 argv => [qw( one two three )],
268                 exec => 1,
269             },
270             expect => {
271                 exec => 1,
272             },
273             runlog => [
274                 [   '_runtests',
275                     {   exec      => [1],
276                         verbosity => 0
277                     },
278                     'TAP::Harness',
279                     'one', 'two', 'three'
280                 ]
281             ],
282         },
283         {   name => 'Just failures',
284             args => {
285                 argv     => [qw( one two three )],
286                 failures => 1,
287             },
288             expect => {
289                 failures => 1,
290             },
291             runlog => [
292                 [   '_runtests',
293                     {   failures  => 1,
294                         verbosity => 0
295                     },
296                     'TAP::Harness',
297                     'one', 'two', 'three'
298                 ]
299             ],
300         },
301
302         {   name => 'Just formatter',
303             args => {
304                 argv      => [qw( one two three )],
305                 formatter => 'TAP::Harness',
306             },
307             expect => {
308                 formatter => 'TAP::Harness',
309             },
310             runlog => [
311                 [   '_runtests',
312                     {   formatter_class => 'TAP::Harness',
313                         verbosity       => 0
314                     },
315                     'TAP::Harness',
316                     'one', 'two', 'three'
317                 ]
318             ],
319         },
320
321         {   name => 'Just includes',
322             args => {
323                 argv     => [qw( one two three )],
324                 includes => [qw( four five six )],
325             },
326             expect => {
327                 includes => [qw( four five six )],
328             },
329             runlog => [
330                 [   '_runtests',
331                     {   lib => mabs( [qw( four five six )] ),
332                         verbosity => 0
333                     },
334                     'TAP::Harness',
335                     'one', 'two', 'three'
336                 ]
337             ],
338         },
339         {   name => 'Just lib',
340             args => {
341                 argv => [qw( one two three )],
342                 lib  => 1,
343             },
344             expect => {
345                 lib => 1,
346             },
347             runlog => [
348                 [   '_runtests',
349                     {   lib => mabs( ['lib'] ),
350                         verbosity => 0
351                     },
352                     'TAP::Harness',
353                     'one', 'two', 'three'
354                 ]
355             ],
356         },
357         {   name => 'Just merge',
358             args => {
359                 argv  => [qw( one two three )],
360                 merge => 1,
361             },
362             expect => {
363                 merge => 1,
364             },
365             runlog => [
366                 [   '_runtests',
367                     {   merge     => 1,
368                         verbosity => 0
369                     },
370                     'TAP::Harness',
371                     'one', 'two', 'three'
372                 ]
373             ],
374         },
375         {   name => 'Just parse',
376             args => {
377                 argv  => [qw( one two three )],
378                 parse => 1,
379             },
380             expect => {
381                 parse => 1,
382             },
383             runlog => [
384                 [   '_runtests',
385                     {   errors    => 1,
386                         verbosity => 0
387                     },
388                     'TAP::Harness',
389                     'one', 'two', 'three'
390                 ]
391             ],
392         },
393         {   name => 'Just quiet',
394             args => {
395                 argv  => [qw( one two three )],
396                 quiet => 1,
397             },
398             expect => {
399                 quiet => 1,
400             },
401             runlog => [
402                 [   '_runtests',
403                     { verbosity => -1
404                     },
405                     'TAP::Harness',
406                     'one', 'two', 'three'
407                 ]
408             ],
409         },
410         {   name => 'Just really_quiet',
411             args => {
412                 argv         => [qw( one two three )],
413                 really_quiet => 1,
414             },
415             expect => {
416                 really_quiet => 1,
417             },
418             runlog => [
419                 [   '_runtests',
420                     { verbosity => -2
421                     },
422                     'TAP::Harness',
423                     'one', 'two', 'three'
424                 ]
425             ],
426         },
427         {   name => 'Just recurse',
428             args => {
429                 argv    => [qw( one two three )],
430                 recurse => 1,
431             },
432             expect => {
433                 recurse => 1,
434             },
435             runlog => [
436                 [   '_runtests',
437                     { verbosity => 0 },
438                     'TAP::Harness',
439                     'one', 'two', 'three'
440                 ]
441             ],
442         },
443         {   name => 'Just reverse',
444             args => {
445                 argv      => [qw( one two three )],
446                 backwards => 1,
447             },
448             expect => {
449                 backwards => 1,
450             },
451             runlog => [
452                 [   '_runtests',
453                     { verbosity => 0 },
454                     'TAP::Harness',
455                     'three', 'two', 'one'
456                 ]
457             ],
458         },
459
460         {   name => 'Just shuffle',
461             args => {
462                 argv    => [qw( one two three )],
463                 shuffle => 1,
464             },
465             expect => {
466                 shuffle => 1,
467             },
468             runlog => [
469                 [   '_runtests',
470                     { verbosity => 0 },
471                     'TAP::Harness',
472                     'xxxone', 'xxxtwo',
473                     'xxxthree'
474                 ]
475             ],
476         },
477         {   name => 'Just taint_fail',
478             args => {
479                 argv       => [qw( one two three )],
480                 taint_fail => 1,
481             },
482             expect => {
483                 taint_fail => 1,
484             },
485             runlog => [
486                 [   '_runtests',
487                     {   switches  => ['-T'],
488                         verbosity => 0
489                     },
490                     'TAP::Harness',
491                     'one', 'two', 'three'
492                 ]
493             ],
494         },
495         {   name => 'Just taint_warn',
496             args => {
497                 argv       => [qw( one two three )],
498                 taint_warn => 1,
499             },
500             expect => {
501                 taint_warn => 1,
502             },
503             runlog => [
504                 [   '_runtests',
505                     {   switches  => ['-t'],
506                         verbosity => 0
507                     },
508                     'TAP::Harness',
509                     'one', 'two', 'three'
510                 ]
511             ],
512         },
513         {   name => 'Just verbose',
514             args => {
515                 argv    => [qw( one two three )],
516                 verbose => 1,
517             },
518             expect => {
519                 verbose => 1,
520             },
521             runlog => [
522                 [   '_runtests',
523                     { verbosity => 1
524                     },
525                     'TAP::Harness',
526                     'one', 'two', 'three'
527                 ]
528             ],
529         },
530         {   name => 'Just warnings_fail',
531             args => {
532                 argv          => [qw( one two three )],
533                 warnings_fail => 1,
534             },
535             expect => {
536                 warnings_fail => 1,
537             },
538             runlog => [
539                 [   '_runtests',
540                     {   switches  => ['-W'],
541                         verbosity => 0
542                     },
543                     'TAP::Harness',
544                     'one', 'two', 'three'
545                 ]
546             ],
547         },
548         {   name => 'Just warnings_warn',
549             args => {
550                 argv          => [qw( one two three )],
551                 warnings_warn => 1,
552             },
553             expect => {
554                 warnings_warn => 1,
555             },
556             runlog => [
557                 [   '_runtests',
558                     {   switches  => ['-w'],
559                         verbosity => 0
560                     },
561                     'TAP::Harness',
562                     'one', 'two', 'three'
563                 ]
564             ],
565         },
566
567         # Command line parsing
568         {   name => 'Switch -v',
569             args => {
570                 argv => [qw( one two three )],
571             },
572             switches => [ '-v', $dummy_test ],
573             expect   => {
574                 verbose => 1,
575             },
576             runlog => [
577                 [   '_runtests',
578                     { verbosity => 1
579                     },
580                     'TAP::Harness',
581                     $dummy_test
582                 ]
583             ],
584         },
585
586         {   name => 'Switch --verbose',
587             args => {
588                 argv => [qw( one two three )],
589             },
590             switches => [ '--verbose', $dummy_test ],
591             expect   => {
592                 verbose => 1,
593             },
594             runlog => [
595                 [   '_runtests',
596                     { verbosity => 1
597                     },
598                     'TAP::Harness',
599                     $dummy_test
600                 ]
601             ],
602         },
603
604         {   name => 'Switch -f',
605             args => {
606                 argv => [qw( one two three )],
607             },
608             switches => [ '-f', $dummy_test ],
609             expect => { failures => 1 },
610             runlog => [
611                 [   '_runtests',
612                     {   failures  => 1,
613                         verbosity => 0
614                     },
615                     'TAP::Harness',
616                     $dummy_test
617                 ]
618             ],
619         },
620
621         {   name => 'Switch --failures',
622             args => {
623                 argv => [qw( one two three )],
624             },
625             switches => [ '--failures', $dummy_test ],
626             expect => { failures => 1 },
627             runlog => [
628                 [   '_runtests',
629                     {   failures  => 1,
630                         verbosity => 0
631                     },
632                     'TAP::Harness',
633                     $dummy_test
634                 ]
635             ],
636         },
637
638         {   name => 'Switch -l',
639             args => {
640                 argv => [qw( one two three )],
641             },
642             switches => [ '-l', $dummy_test ],
643             expect => { lib => 1 },
644             runlog => [
645                 [   '_runtests',
646                     {   lib => mabs( ['lib'] ),
647                         verbosity => 0
648                     },
649                     'TAP::Harness',
650                     $dummy_test
651                 ]
652             ],
653         },
654
655         {   name => 'Switch --lib',
656             args => {
657                 argv => [qw( one two three )],
658             },
659             switches => [ '--lib', $dummy_test ],
660             expect => { lib => 1 },
661             runlog => [
662                 [   '_runtests',
663                     {   lib => mabs( ['lib'] ),
664                         verbosity => 0
665                     },
666                     'TAP::Harness',
667                     $dummy_test
668                 ]
669             ],
670         },
671
672         {   name => 'Switch -b',
673             args => {
674                 argv => [qw( one two three )],
675             },
676             switches => [ '-b', $dummy_test ],
677             expect => { blib => 1 },
678             runlog => [
679                 [   '_runtests',
680                     {   lib => mabs( [ 'blib/lib', 'blib/arch' ] ),
681                         verbosity => 0
682                     },
683                     'TAP::Harness',
684                     $dummy_test
685                 ]
686             ],
687         },
688
689         {   name => 'Switch --blib',
690             args => {
691                 argv => [qw( one two three )],
692             },
693             switches => [ '--blib', $dummy_test ],
694             expect => { blib => 1 },
695             runlog => [
696                 [   '_runtests',
697                     {   lib => mabs( [ 'blib/lib', 'blib/arch' ] ),
698                         verbosity => 0
699                     },
700                     'TAP::Harness',
701                     $dummy_test
702                 ]
703             ],
704         },
705
706         {   name => 'Switch -s',
707             args => {
708                 argv => [qw( one two three )],
709             },
710             switches => [ '-s', $dummy_test ],
711             expect => { shuffle => 1 },
712             runlog => [
713                 [   '_runtests',
714                     { verbosity => 0 },
715                     'TAP::Harness',
716                     "xxx$dummy_test"
717                 ]
718             ],
719         },
720
721         {   name => 'Switch --shuffle',
722             args => {
723                 argv => [qw( one two three )],
724             },
725             switches => [ '--shuffle', $dummy_test ],
726             expect => { shuffle => 1 },
727             runlog => [
728                 [   '_runtests',
729                     { verbosity => 0 },
730                     'TAP::Harness',
731                     "xxx$dummy_test"
732                 ]
733             ],
734         },
735
736         {   name => 'Switch -c',
737             args => {
738                 argv => [qw( one two three )],
739             },
740             switches => [ '-c', $dummy_test ],
741             expect => { color => 1 },
742             runlog => [
743                 [   '_runtests',
744                     {   color     => 1,
745                         verbosity => 0
746                     },
747                     'TAP::Harness',
748                     $dummy_test
749                 ]
750             ],
751         },
752
753         {   name => 'Switch -r',
754             args => {
755                 argv => [qw( one two three )],
756             },
757             switches => [ '-r', $dummy_test ],
758             expect => { recurse => 1 },
759             runlog => [
760                 [   '_runtests',
761                     { verbosity => 0 },
762                     'TAP::Harness',
763                     $dummy_test
764                 ]
765             ],
766         },
767
768         {   name => 'Switch --recurse',
769             args => {
770                 argv => [qw( one two three )],
771             },
772             switches => [ '--recurse', $dummy_test ],
773             expect => { recurse => 1 },
774             runlog => [
775                 [   '_runtests',
776                     { verbosity => 0 },
777                     'TAP::Harness',
778                     $dummy_test
779                 ]
780             ],
781         },
782
783         {   name => 'Switch --reverse',
784             args => {
785                 argv => [qw( one two three )],
786             },
787             switches => [ '--reverse', @dummy_tests ],
788             expect => { backwards => 1 },
789             runlog => [
790                 [   '_runtests',
791                     { verbosity => 0 },
792                     'TAP::Harness',
793                     reverse @dummy_tests
794                 ]
795             ],
796         },
797
798         {   name => 'Switch -p',
799             args => {
800                 argv => [qw( one two three )],
801             },
802             switches => [ '-p', $dummy_test ],
803             expect   => {
804                 parse => 1,
805             },
806             runlog => [
807                 [   '_runtests',
808                     {   errors    => 1,
809                         verbosity => 0
810                     },
811                     'TAP::Harness',
812                     $dummy_test
813                 ]
814             ],
815         },
816
817         {   name => 'Switch --parse',
818             args => {
819                 argv => [qw( one two three )],
820             },
821             switches => [ '--parse', $dummy_test ],
822             expect   => {
823                 parse => 1,
824             },
825             runlog => [
826                 [   '_runtests',
827                     {   errors    => 1,
828                         verbosity => 0
829                     },
830                     'TAP::Harness',
831                     $dummy_test
832                 ]
833             ],
834         },
835
836         {   name => 'Switch -q',
837             args => {
838                 argv => [qw( one two three )],
839             },
840             switches => [ '-q', $dummy_test ],
841             expect => { quiet => 1 },
842             runlog => [
843                 [   '_runtests',
844                     { verbosity => -1
845                     },
846                     'TAP::Harness',
847                     $dummy_test
848                 ]
849             ],
850         },
851
852         {   name => 'Switch --quiet',
853             args => {
854                 argv => [qw( one two three )],
855             },
856             switches => [ '--quiet', $dummy_test ],
857             expect => { quiet => 1 },
858             runlog => [
859                 [   '_runtests',
860                     { verbosity => -1
861                     },
862                     'TAP::Harness',
863                     $dummy_test
864                 ]
865             ],
866         },
867
868         {   name => 'Switch -Q',
869             args => {
870                 argv => [qw( one two three )],
871             },
872             switches => [ '-Q', $dummy_test ],
873             expect => { really_quiet => 1 },
874             runlog => [
875                 [   '_runtests',
876                     { verbosity => -2
877                     },
878                     'TAP::Harness',
879                     $dummy_test
880                 ]
881             ],
882         },
883
884         {   name => 'Switch --QUIET',
885             args => {
886                 argv => [qw( one two three )],
887             },
888             switches => [ '--QUIET', $dummy_test ],
889             expect => { really_quiet => 1 },
890             runlog => [
891                 [   '_runtests',
892                     { verbosity => -2
893                     },
894                     'TAP::Harness',
895                     $dummy_test
896                 ]
897             ],
898         },
899
900         {   name => 'Switch -m',
901             args => {
902                 argv => [qw( one two three )],
903             },
904             switches => [ '-m', $dummy_test ],
905             expect => { merge => 1 },
906             runlog => [
907                 [   '_runtests',
908                     {   merge     => 1,
909                         verbosity => 0
910                     },
911                     'TAP::Harness',
912                     $dummy_test
913                 ]
914             ],
915         },
916
917         {   name => 'Switch --merge',
918             args => {
919                 argv => [qw( one two three )],
920             },
921             switches => [ '--merge', $dummy_test ],
922             expect => { merge => 1 },
923             runlog => [
924                 [   '_runtests',
925                     {   merge     => 1,
926                         verbosity => 0
927                     },
928                     'TAP::Harness',
929                     $dummy_test
930                 ]
931             ],
932         },
933
934         {   name => 'Switch --directives',
935             args => {
936                 argv => [qw( one two three )],
937             },
938             switches => [ '--directives', $dummy_test ],
939             expect => { directives => 1 },
940             runlog => [
941                 [   '_runtests',
942                     {   directives => 1,
943                         verbosity  => 0
944                     },
945                     'TAP::Harness',
946                     $dummy_test
947                 ]
948             ],
949         },
950
951         # Executing one word (why would it be a -s though?)
952         {   name => 'Switch --exec -s',
953             args => {
954                 argv => [qw( one two three )],
955             },
956             switches => [ '--exec', '-s', $dummy_test ],
957             expect => { exec => '-s' },
958             runlog => [
959                 [   '_runtests', { exec => ['-s'], verbosity => 0 },
960                     'TAP::Harness',
961                     $dummy_test
962                 ]
963             ],
964         },
965
966         # multi-part exec
967         {   name => 'Switch --exec "/foo/bar/perl -Ilib"',
968             args => {
969                 argv => [qw( one two three )],
970             },
971             switches => [ '--exec', '/foo/bar/perl -Ilib', $dummy_test ],
972             expect => { exec => '/foo/bar/perl -Ilib' },
973             runlog => [
974                 [   '_runtests',
975                     {   exec      => [qw(/foo/bar/perl -Ilib)],
976                         verbosity => 0
977                     },
978                     'TAP::Harness',
979                     $dummy_test
980                 ]
981             ],
982         },
983
984         # null exec (run tests as compiled binaries)
985         {   name     => 'Switch --exec ""',
986             switches => [ '--exec', '', $dummy_test ],
987             expect   => {
988                 exec =>   # ick, must workaround the || default bit with a sub
989                   sub { my $val = shift; defined($val) and !length($val) }
990             },
991             runlog => [
992                 [   '_runtests',
993                     { exec => [], verbosity => 0 },
994                     'TAP::Harness',
995                     $dummy_test
996                 ]
997             ],
998         },
999
1000         # Plugins
1001         {   name     => 'Load plugin',
1002             switches => [ '-P', 'Dummy', $dummy_test ],
1003             args     => {
1004                 argv => [qw( one two three )],
1005             },
1006             expect => {
1007                 plugins => ['Dummy'],
1008             },
1009             extra => sub {
1010                 my @loaded = get_import_log();
1011                 is_deeply \@loaded, [ ['App::Prove::Plugin::Dummy'] ],
1012                   "Plugin loaded OK";
1013             },
1014             plan   => 1,
1015             runlog => [
1016                 [   '_runtests',
1017                     { verbosity => 0 },
1018                     'TAP::Harness',
1019                     $dummy_test
1020                 ]
1021             ],
1022         },
1023
1024         {   name     => 'Load plugin (args)',
1025             switches => [ '-P', 'Dummy=cracking,cheese,gromit', $dummy_test ],
1026             args     => {
1027                 argv => [qw( one two three )],
1028             },
1029             expect => {
1030                 plugins => ['Dummy'],
1031             },
1032             extra => sub {
1033                 my @loaded = get_import_log();
1034                 is_deeply \@loaded,
1035                   [ [   'App::Prove::Plugin::Dummy', 'cracking', 'cheese',
1036                         'gromit'
1037                     ]
1038                   ],
1039                   "Plugin loaded OK";
1040             },
1041             plan   => 1,
1042             runlog => [
1043                 [   '_runtests',
1044                     { verbosity => 0 },
1045                     'TAP::Harness',
1046                     $dummy_test
1047                 ]
1048             ],
1049         },
1050
1051         {   name     => 'Load plugin (explicit path)',
1052             switches => [ '-P', 'App::Prove::Plugin::Dummy', $dummy_test ],
1053             args     => {
1054                 argv => [qw( one two three )],
1055             },
1056             expect => {
1057                 plugins => ['Dummy'],
1058             },
1059             extra => sub {
1060                 my @loaded = get_import_log();
1061                 is_deeply \@loaded, [ ['App::Prove::Plugin::Dummy'] ],
1062                   "Plugin loaded OK";
1063             },
1064             plan   => 1,
1065             runlog => [
1066                 [   '_runtests',
1067                     { verbosity => 0 },
1068                     'TAP::Harness',
1069                     $dummy_test
1070                 ]
1071             ],
1072         },
1073
1074         {   name     => 'Load module',
1075             switches => [ '-M', 'App::Prove::Plugin::Dummy', $dummy_test ],
1076             args     => {
1077                 argv => [qw( one two three )],
1078             },
1079             expect => {
1080                 plugins => ['Dummy'],
1081             },
1082             extra => sub {
1083                 my @loaded = get_import_log();
1084                 is_deeply \@loaded, [ ['App::Prove::Plugin::Dummy'] ],
1085                   "Plugin loaded OK";
1086             },
1087             plan   => 1,
1088             runlog => [
1089                 [   '_runtests',
1090                     { verbosity => 0 },
1091                     'TAP::Harness',
1092                     $dummy_test
1093                 ]
1094             ],
1095         },
1096
1097         # TODO
1098         # Hmm, that doesn't work...
1099         # {   name => 'Switch -h',
1100         #     args => {
1101         #         argv => [qw( one two three )],
1102         #     },
1103         #     switches => [ '-h', $dummy_test ],
1104         #     expect   => {},
1105         #     runlog   => [
1106         #         [   '_runtests',
1107         #             {},
1108         #             'TAP::Harness',
1109         #             $dummy_test
1110         #         ]
1111         #     ],
1112         # },
1113
1114         # {   name => 'Switch --help',
1115         #     args => {
1116         #         argv => [qw( one two three )],
1117         #     },
1118         #     switches => [ '--help', $dummy_test ],
1119         #     expect   => {},
1120         #     runlog   => [
1121         #         [   {},
1122         #             'TAP::Harness',
1123         #             $dummy_test
1124         #         ]
1125         #     ],
1126         # },
1127         # {   name => 'Switch -?',
1128         #     args => {
1129         #         argv => [qw( one two three )],
1130         #     },
1131         #     switches => [ '-?', $dummy_test ],
1132         #     expect   => {},
1133         #     runlog   => [
1134         #         [   {},
1135         #             'TAP::Harness',
1136         #             $dummy_test
1137         #         ]
1138         #     ],
1139         # },
1140         #
1141         # {   name => 'Switch -H',
1142         #     args => {
1143         #         argv => [qw( one two three )],
1144         #     },
1145         #     switches => [ '-H', $dummy_test ],
1146         #     expect   => {},
1147         #     runlog   => [
1148         #         [   {},
1149         #             'TAP::Harness',
1150         #             $dummy_test
1151         #         ]
1152         #     ],
1153         # },
1154         #
1155         # {   name => 'Switch --man',
1156         #     args => {
1157         #         argv => [qw( one two three )],
1158         #     },
1159         #     switches => [ '--man', $dummy_test ],
1160         #     expect   => {},
1161         #     runlog   => [
1162         #         [   {},
1163         #             'TAP::Harness',
1164         #             $dummy_test
1165         #         ]
1166         #     ],
1167         # },
1168         #
1169         # {   name => 'Switch -V',
1170         #     args => {
1171         #         argv => [qw( one two three )],
1172         #     },
1173         #     switches => [ '-V', $dummy_test ],
1174         #     expect   => {},
1175         #     runlog   => [
1176         #         [   {},
1177         #             'TAP::Harness',
1178         #             $dummy_test
1179         #         ]
1180         #     ],
1181         # },
1182         #
1183         # {   name => 'Switch --version',
1184         #     args => {
1185         #         argv => [qw( one two three )],
1186         #     },
1187         #     switches => [ '--version', $dummy_test ],
1188         #     expect   => {},
1189         #     runlog   => [
1190         #         [   {},
1191         #             'TAP::Harness',
1192         #             $dummy_test
1193         #         ]
1194         #     ],
1195         # },
1196         #
1197         # {   name => 'Switch --color!',
1198         #     args => {
1199         #         argv => [qw( one two three )],
1200         #     },
1201         #     switches => [ '--color!', $dummy_test ],
1202         #     expect   => {},
1203         #     runlog   => [
1204         #         [   {},
1205         #             'TAP::Harness',
1206         #             $dummy_test
1207         #         ]
1208         #     ],
1209         # },
1210         #
1211         {   name => 'Switch -I=s@',
1212             args => {
1213                 argv => [qw( one two three )],
1214             },
1215             switches => [ '-Ilib', $dummy_test ],
1216             expect   => {
1217                 includes => sub {
1218                     my ( $val, $attr ) = @_;
1219                     return
1220                          'ARRAY' eq ref $val
1221                       && 1 == @$val
1222                       && $val->[0] =~ /lib$/;
1223                 },
1224             },
1225         },
1226
1227         # {   name => 'Switch -a',
1228         #     args => {
1229         #         argv => [qw( one two three )],
1230         #     },
1231         #     switches => [ '-a', $dummy_test ],
1232         #     expect   => {},
1233         #     runlog   => [
1234         #         [   {},
1235         #             'TAP::Harness',
1236         #             $dummy_test
1237         #         ]
1238         #     ],
1239         # },
1240         #
1241         # {   name => 'Switch --archive=-s',
1242         #     args => {
1243         #         argv => [qw( one two three )],
1244         #     },
1245         #     switches => [ '--archive=-s', $dummy_test ],
1246         #     expect   => {},
1247         #     runlog   => [
1248         #         [   {},
1249         #             'TAP::Harness',
1250         #             $dummy_test
1251         #         ]
1252         #     ],
1253         # },
1254         #
1255         # {   name => 'Switch --formatter=-s',
1256         #     args => {
1257         #         argv => [qw( one two three )],
1258         #     },
1259         #     switches => [ '--formatter=-s', $dummy_test ],
1260         #     expect   => {},
1261         #     runlog   => [
1262         #         [   {},
1263         #             'TAP::Harness',
1264         #             $dummy_test
1265         #         ]
1266         #     ],
1267         # },
1268         #
1269         # {   name => 'Switch -e',
1270         #     args => {
1271         #         argv => [qw( one two three )],
1272         #     },
1273         #     switches => [ '-e', $dummy_test ],
1274         #     expect   => {},
1275         #     runlog   => [
1276         #         [   {},
1277         #             'TAP::Harness',
1278         #             $dummy_test
1279         #         ]
1280         #     ],
1281         # },
1282         #
1283         # {   name => 'Switch --harness=-s',
1284         #     args => {
1285         #         argv => [qw( one two three )],
1286         #     },
1287         #     switches => [ '--harness=-s', $dummy_test ],
1288         #     expect   => {},
1289         #     runlog   => [
1290         #         [   {},
1291         #             'TAP::Harness',
1292         #             $dummy_test
1293         #         ]
1294         #     ],
1295         # },
1296
1297     );
1298
1299     # END SCHEDULE
1300     ########################################################################
1301
1302     my $extra_plan = 0;
1303     for my $test (@SCHEDULE) {
1304         $extra_plan += $test->{plan} || 0;
1305         $extra_plan += 2 if $test->{runlog};
1306         $extra_plan += 1 if $test->{switches};
1307     }
1308
1309     plan tests => @SCHEDULE * ( 3 + @ATTR ) + $extra_plan;
1310 }    # END PLAN
1311
1312 # ACTUAL TEST
1313 for my $test (@SCHEDULE) {
1314     my $name = $test->{name};
1315     my $class = $test->{class} || 'FakeProve';
1316
1317     ok my $app = $class->new( exists $test->{args} ? $test->{args} : () ),
1318       "$name: App::Prove created OK";
1319
1320     isa_ok $app, 'App::Prove';
1321     isa_ok $app, $class;
1322
1323     # Optionally parse command args
1324     if ( my $switches = $test->{switches} ) {
1325         eval { $app->process_args( '--norc', @$switches ) };
1326         if ( my $err_pattern = $test->{parse_error} ) {
1327             like $@, $err_pattern, "$name: expected parse error";
1328         }
1329         else {
1330             ok !$@, "$name: no parse error";
1331         }
1332     }
1333
1334     my $expect = $test->{expect} || {};
1335     for my $attr ( sort @ATTR ) {
1336         my $val       = $app->$attr();
1337         my $assertion = $expect->{$attr} || $DEFAULT_ASSERTION{$attr};
1338         my $is_ok     = undef;
1339
1340         if ( 'CODE' eq ref $assertion ) {
1341             $is_ok = ok $assertion->( $val, $attr ),
1342               "$name: $attr has the expected value";
1343         }
1344         elsif ( 'Regexp' eq ref $assertion ) {
1345             $is_ok = like $val, $assertion, "$name: $attr matches $assertion";
1346         }
1347         else {
1348             $is_ok = is_deeply $val, $assertion,
1349               "$name: $attr has the expected value";
1350         }
1351
1352         unless ($is_ok) {
1353             diag "got $val for $attr";
1354         }
1355     }
1356
1357     if ( my $runlog = $test->{runlog} ) {
1358         eval { $app->run };
1359         if ( my $err_pattern = $test->{run_error} ) {
1360             like $@, $err_pattern, "$name: expected error OK";
1361             pass;
1362             pass for 1 .. $test->{plan};
1363         }
1364         else {
1365             unless ( ok !$@, "$name: no error OK" ) {
1366                 diag "$name: error: $@\n";
1367             }
1368
1369             my $gotlog = [ $app->get_log ];
1370
1371             if ( my $extra = $test->{extra} ) {
1372                 $extra->($gotlog);
1373             }
1374
1375             unless (
1376                 is_deeply $gotlog, $runlog,
1377                 "$name: run results match"
1378               )
1379             {
1380                 use Data::Dumper;
1381                 diag Dumper( { wanted => $runlog, got => $gotlog } );
1382             }
1383         }
1384     }
1385 }