Upgrade to Test-Harness-3.17
[p5sagit/p5-mst-13.2.git] / ext / Test-Harness / lib / TAP / Formatter / Console / ParallelSession.pm
CommitLineData
b965d173 1package TAP::Formatter::Console::ParallelSession;
2
3use strict;
4use File::Spec;
5use File::Path;
6use TAP::Formatter::Console::Session;
7use Carp;
8
9use constant WIDTH => 72; # Because Eric says
10use vars qw($VERSION @ISA);
11
12@ISA = qw(TAP::Formatter::Console::Session);
13
14my %shared;
15
16sub _initialize {
17 my ( $self, $arg_for ) = @_;
18
19 $self->SUPER::_initialize($arg_for);
20 my $formatter = $self->formatter;
21
22 # Horrid bodge. This creates our shared context per harness. Maybe
23 # TAP::Harness should give us this?
24 my $context = $shared{$formatter} ||= $self->_create_shared_context;
25 push @{ $context->{active} }, $self;
26
27 return $self;
28}
29
30sub _create_shared_context {
31 my $self = shift;
32 return {
33 active => [],
34 tests => 0,
35 fails => 0,
36 };
37}
38
b965d173 39=head1 NAME
40
41TAP::Formatter::Console::ParallelSession - Harness output delegate for parallel console output
42
43=head1 VERSION
44
a39e16d8 45Version 3.17
b965d173 46
47=cut
48
a39e16d8 49$VERSION = '3.17';
b965d173 50
51=head1 DESCRIPTION
52
27fc0087 53This provides console orientated output formatting for L<TAP::Harness>
54when run with multiple L<TAP::Harness/jobs>.
b965d173 55
56=head1 SYNOPSIS
57
58=cut
59
60=head1 METHODS
61
62=head2 Class Methods
63
64=head3 C<header>
65
66Output test preamble
67
68=cut
69
70sub header {
b965d173 71}
72
27fc0087 73sub _clear_ruler {
b965d173 74 my $self = shift;
75 $self->formatter->_output( "\r" . ( ' ' x WIDTH ) . "\r" );
76}
77
27fc0087 78my $now = 0;
79my $start;
80
bdaf8c65 81my $trailer = '... )===';
27fc0087 82my $chop_length = WIDTH - length $trailer;
83
b965d173 84sub _output_ruler {
bdaf8c65 85 my ( $self, $refresh ) = @_;
27fc0087 86 my $new_now = time;
87 return if $new_now == $now and !$refresh;
88 $now = $new_now;
89 $start ||= $now;
b965d173 90 my $formatter = $self->formatter;
91 return if $formatter->really_quiet;
92
93 my $context = $shared{$formatter};
94
27fc0087 95 my $ruler = sprintf '===( %7d;%d ', $context->{tests}, $now - $start;
96
bdaf8c65 97 foreach my $active ( @{ $context->{active} } ) {
98 my $parser = $active->parser;
99 my $tests = $parser->tests_run;
100 my $planned = $parser->tests_planned || '?';
27fc0087 101
bdaf8c65 102 $ruler .= sprintf '%' . length($planned) . "d/$planned ", $tests;
27fc0087 103 }
bdaf8c65 104 chop $ruler; # Remove a trailing space
27fc0087 105 $ruler .= ')===';
106
107 if ( length $ruler > WIDTH ) {
bdaf8c65 108 $ruler =~ s/(.{$chop_length}).*/$1$trailer/o;
27fc0087 109 }
110 else {
bdaf8c65 111 $ruler .= '=' x ( WIDTH - length($ruler) );
27fc0087 112 }
bdaf8c65 113 $formatter->_output("\r$ruler");
b965d173 114}
115
116=head3 C<result>
117
118 Called by the harness for each line of TAP it receives .
119
120=cut
121
122sub result {
123 my ( $self, $result ) = @_;
b965d173 124 my $formatter = $self->formatter;
b965d173 125
126 # my $really_quiet = $formatter->really_quiet;
127 # my $show_count = $self->_should_show_count;
b965d173 128
27fc0087 129 if ( $result->is_test ) {
130 my $context = $shared{$formatter};
131 $context->{tests}++;
132
bdaf8c65 133 my $active = $context->{active};
134 if ( @$active == 1 ) {
135
27fc0087 136 # There is only one test, so use the serial output format.
bdaf8c65 137 return $self->SUPER::result($result);
27fc0087 138 }
139
bdaf8c65 140 $self->_output_ruler( $self->parser->tests_run == 1 );
27fc0087 141 }
142 elsif ( $result->is_bailout ) {
b965d173 143 $formatter->_failure_output(
144 "Bailout called. Further testing stopped: "
145 . $result->explanation
146 . "\n" );
147 }
27fc0087 148}
b965d173 149
27fc0087 150=head3 C<clear_for_close>
b965d173 151
27fc0087 152=cut
b965d173 153
27fc0087 154sub clear_for_close {
155 my $self = shift;
156 my $formatter = $self->formatter;
157 return if $formatter->really_quiet;
bdaf8c65 158 my $context = $shared{$formatter};
27fc0087 159 if ( @{ $context->{active} } == 1 ) {
bdaf8c65 160 $self->SUPER::clear_for_close;
27fc0087 161 }
162 else {
bdaf8c65 163 $self->_clear_ruler;
b965d173 164 }
165}
166
167=head3 C<close_test>
168
169=cut
170
171sub close_test {
172 my $self = shift;
173 my $name = $self->name;
174 my $parser = $self->parser;
175 my $formatter = $self->formatter;
176 my $context = $shared{$formatter};
177
27fc0087 178 $self->SUPER::close_test;
b965d173 179
b965d173 180 my $active = $context->{active};
181
182 my @pos = grep { $active->[$_]->name eq $name } 0 .. $#$active;
183
184 die "Can't find myself" unless @pos;
185 splice @$active, $pos[0], 1;
186
bdaf8c65 187 if ( @$active > 1 ) {
188 $self->_output_ruler(1);
27fc0087 189 }
bdaf8c65 190 elsif ( @$active == 1 ) {
191
27fc0087 192 # Print out "test/name.t ...."
193 $active->[0]->SUPER::header;
194 }
195 else {
bdaf8c65 196
b965d173 197 # $self->formatter->_output("\n");
198 delete $shared{$formatter};
199 }
200}
201
2021;