File Coverage

blib/lib/TAP/Formatter/Diffable.pm
Criterion Covered Total %
statement 24 66 36.3
branch 0 8 0.0
condition 0 6 0.0
subroutine 8 18 44.4
pod 2 2 100.0
total 34 100 34.0


line stmt bran cond sub pod time code
1             package TAP::Formatter::Diffable;
2 1     1   664 use strict;
  1         2  
  1         53  
3 1     1   4 use warnings;
  1         1  
  1         29  
4 1     1   11 use base 'TAP::Base', 'TAP::Formatter::File';
  1         1  
  1         444  
5 1     1   17562 use accessors qw(sessions);
  1         564  
  1         3  
6              
7             =head1 NAME
8              
9             TAP::Formatter::Diffable - Diff friendly (ie sorted) TAP output.
10              
11             =head1 SYNOPSIS
12              
13             prove -j5 --formatter=TAP::Formatter::Diffable t
14              
15             =head1 DESCRIPTION
16              
17             Delays TAP output until the entire test suite has completed.
18              
19             Sorts test output by test filename. This way tests alway display in the same order, even when processing in parallel.
20              
21             Skips over passing tests, unless they are marked as TODO. These are skipped to make the diff easier to matchup when test numbers change slightly.
22              
23             Sorts the final "Test Results"
24              
25              
26              
27             =over
28              
29             =item Example Pass
30              
31             All tests successful.
32             Files=1, Tests=1,
33             Result: PASS
34              
35             =item Example Fail
36              
37             Failed test 'Example failred test'
38             # at t/00-load.t line 6.
39             # Looks like you planned 1 test but ran 2.
40             # Looks like you failed 1 test of 2 run.
41             [t/00-load.t]
42             not ok 2 - Example failred test
43              
44              
45             Test Summary Report
46             -------------------
47             t/00-load.t (Wstat: 256 Tests: 2 Failed: 1)
48             Failed test: 2
49             Non-zero exit status: 1
50             Parse errors: Bad plan. You planned 1 tests but ran 2.
51             Files=1, Tests=2,
52             Result: FAIL
53              
54             =back
55              
56             =cut
57              
58 1     1   63 use vars qw($VERSION);
  1         2  
  1         287  
59             $VERSION = '0.15';
60              
61             sub _initialize {
62 0     0     my ($self, $hash) = @_;
63 0           $self->sessions( [] );
64 0           $self->$_( $hash->{$_} ) for keys %$hash;
65 0           return $self;
66             }
67              
68             sub _output {
69 0     0     my $self = shift;
70 0           print @_;
71             }
72              
73             sub open_test {
74 0     0 1   my ($self, $test, $parser) = @_;
75 0           my $session = TAP::Formatter::Diffable::Session->new({
76             test => $test,
77             parser => $parser,
78             formatter => $self,
79             });
80 0           push @{ $self->sessions }, $session;
  0            
81 0           return $session;
82             }
83              
84             sub summary {
85 0     0 1   my $self = shift;
86              
87 0           my %sessions;
88 0           $sessions{ $_->test } = $_ for @{ $self->sessions };
  0            
89              
90             # Sorting by test, that's what this module is all about.
91             # Sorted output is diffable.
92 0           for (sort keys %sessions) {
93 0 0         $sessions{ $_ }->is_interesting or next;
94 0           $self->_output( $sessions{ $_ }->as_report );
95 0           $self->_output( "\n" );
96             }
97              
98             # Elapsed time makes the output undiffable.
99 1     1   6 no warnings 'redefine';
  1         2  
  1         151  
100 0     0     local *TAP::Parser::Aggregator::timestr = sub { "" };
  0            
101              
102             # Make sure the "Test Summary Report" is sorted
103 0           my @tmp = sort @{$_[0]->{'parse_order'}};
  0            
104 0           $_[0]->{'parse_order'} = \@tmp;
105              
106 0           $self->SUPER::summary(@_);
107             }
108              
109              
110             package TAP::Formatter::Diffable::Session;
111 1     1   7 use base 'TAP::Base';
  1         1  
  1         80  
112 1     1   6 use accessors qw( test formatter parser results );
  1         2  
  1         8  
113              
114             sub _initialize {
115 0     0     my ($self, $hash) = @_;
116 0           $self->results( [] );
117 0           $self->$_( $hash->{$_} ) for keys %$hash;
118 0           return $self;
119             }
120              
121             sub result {
122 0     0     my ($self, $result) = @_;
123              
124 0 0         return unless $result->is_test;
125 0 0 0       return if $result->is_actual_ok and not $result->has_todo;
126 0 0 0       return if $result->has_todo and not $result->is_actual_ok;
127              
128 0           push @{ $self->results }, $result->as_string;
  0            
129             }
130              
131 0     0     sub close_test {
132             }
133              
134             sub is_interesting {
135 0     0     my ($self) = @_;
136 0           return ! ! @{ $self->results };
  0            
137             };
138              
139             sub as_report {
140 0     0     my ($self) = @_;
141 0           return join "", map "$_\n", "[" . $self->test . "]", @{ $self->results };
  0            
142             }
143              
144             1;