File Coverage

blib/lib/Test/Proto/Formatter/TestBuilder.pm
Criterion Covered Total %
statement 53 54 98.1
branch 26 32 81.2
condition n/a
subroutine 8 8 100.0
pod 2 2 100.0
total 89 96 92.7


line stmt bran cond sub pod time code
1             package Test::Proto::Formatter::TestBuilder;
2 13     13   387 use 5.008;
  13         555  
  13         526  
3 13     13   74 use strict;
  13         26  
  13         407  
4 13     13   71 use warnings;
  13         23  
  13         391  
5 13     13   235 use Moo;
  13         26  
  13         1303  
6             extends 'Test::Builder::Module';
7             my $CLASS = __PACKAGE__;
8              
9             =pod
10              
11             =head1 NAME
12              
13             Test::Proto::Formatter::TestBuilder - formats RunnerEvents as TestBuilder events.
14              
15             =head1 SYNOPSIS
16              
17             my $formatter = Test::Proto::Formatter->new();
18             $formatter->event($testRunner, 'new');
19             $formatter->event($testRunner, 'done');
20              
21             This formatter is only used by the L class, and will be created when you use a prototype's C.
22              
23              
24             =head1 METHODS
25              
26             =cut
27              
28             =head3 event
29              
30             $formatter->event($testRunner, 'new');
31             $formatter->event($testRunner, 'done');
32              
33             Used in Test::Proto::TestRunner to inform the formatter of progress. Event types 'new' and 'done' are supported.
34              
35             =cut
36              
37             has '_object_id_register',
38             is => 'rw',
39             default => sub { {} };
40              
41             sub _explain_value {
42 66     66   135 my $v = shift;
43 66 50       164 return 'undef' unless defined $v;
44 66 100       233 return $v unless ref $v;
45 33 100       210 return 'Arrayref with ' . ( $#$v + 1 ) . ' values' if ref $v eq 'ARRAY';
46 13 50       48 return 'Hashref with ' . ( scalar keys %$v ) . ' keys' if ref $v eq 'HASH';
47 13         52 return ref $v;
48             }
49              
50             sub _explain_test_case {
51 110     110   152 my $self = shift;
52 110         149 my $test_case = shift;
53 110 100       345 if ( ref $test_case ) {
54 106 100       988 if ( $test_case->isa('Test::Proto::TestCase') ) {
55 66         102 my $report = '';
56 66         1780 $report .= $test_case->name;
57 66 50       1700 $report .= "\nexpected: " . _explain_value( $test_case->data->{expected} ) if defined( $test_case->data->{expected} );
58 66 100       120 if ( scalar keys %{ $test_case->data } > 1 ) {
  66         1734  
59 9         22 $report .= "\nOther data:";
60 9         16 foreach my $key ( grep { 'expected' ne $_ } keys %{ $test_case->data } ) {
  18         60  
  9         233  
61 9         248 $report .= "\n $key: " . $test_case->data->{$key};
62             }
63             }
64 66         2151 return $report;
65             }
66 40         1206 return '[not a TestCase]';
67             }
68             else {
69 4         81 return '[not a TestCase or any other object]';
70             }
71             }
72              
73             sub event {
74 220     220 1 326 my $self = shift;
75 220         249 my $runner = shift;
76 220         257 my $eventType = shift;
77 220 100       605 if ( 'new' eq $eventType ) {
    50          
78 110 100       2789 my $name =
    100          
79             defined( $runner->test_case )
80             ? $runner->test_case->can('name')
81             ? $runner->test_case->name
82             : ref $runner->test_case
83             : undef;
84 110 100       2934 if ( defined $runner->parent ) {
85 107         3149 $self->_object_id_register->{ $runner->object_id } = $self->_object_id_register->{ $runner->parent->object_id }->child($name);
86             }
87             else {
88 3         23 $self->_object_id_register->{ $runner->object_id } = $CLASS->builder->child($name);
89             }
90             }
91             elsif ( 'done' eq $eventType ) {
92 110 50       527 if ( my $tb = $self->_object_id_register->{ $runner->object_id } ) {
93 110 100       1611 $tb->ok( $runner, $runner->status . " - got: " . ( defined $runner->subject ? $runner->subject : '[undefined]' ) . "\n" . $self->_explain_test_case( $runner->test_case ) . ( defined $runner->status_message ? "\n" . $runner->status_message : '' ) );
    50          
94 110         85356 $tb->done_testing;
95 110         22931 $tb->finalize;
96             }
97             else {
98 0         0 die( 'Have not registered object ' . $runner->object_id );
99             }
100             }
101 220         108877 return $self;
102             }
103              
104             =head3 format
105              
106             $formatter->format($runner);
107              
108             Outputs information from a test runner that is already complete but did not expect to be outputting to Test::Builder.
109              
110             =cut
111              
112             sub format {
113 1     1 1 2 my $self = shift;
114 1         1 my $runner = shift;
115 1         4 $self->event( $runner, 'new' );
116 1         3 $self->event( $runner, 'done' );
117 1         2 return $self;
118             }
119              
120             1;
121              
122             =head1 OTHER INFORMATION
123              
124             For author, version, bug reports, support, etc, please see L.
125              
126             =cut
127