File Coverage

lib/Test/BDD/Cucumber/Harness/TAP.pm
Criterion Covered Total %
statement 54 67 80.6
branch 14 24 58.3
condition 5 13 38.4
subroutine 12 12 100.0
pod 6 6 100.0
total 91 122 74.5


line stmt bran cond sub pod time code
1 3     3   1705 use v5.14;
  3         11  
2 3     3   18 use warnings;
  3         6  
  3         143  
3              
4             package Test::BDD::Cucumber::Harness::TAP 0.86;
5              
6             =head1 NAME
7              
8             Test::BDD::Cucumber::Harness::TAP - Generate results in TAP format
9              
10             =head1 VERSION
11              
12             version 0.86
13              
14             =head1 DESCRIPTION
15              
16             A L subclass whose output
17             is TAP (Test Anything Protocol), such as consumed by C
18             and C.
19              
20             =head1 OPTIONS
21              
22             =head2 fail_skip
23              
24             Boolean - makes tests with no matcher fail
25              
26             =cut
27              
28 3     3   19 use Moo;
  3         8  
  3         19  
29              
30 3     3   1205 use Types::Standard qw( Bool InstanceOf );
  3         9  
  3         47  
31 3     3   2238 use Test2::API qw/context/;
  3         8  
  3         2550  
32              
33              
34             extends 'Test::BDD::Cucumber::Harness';
35             has 'fail_skip' => ( is => 'rw', isa => Bool, default => 0 );
36              
37              
38             sub feature {
39 9     9 1 29 my ( $self, $feature ) = @_;
40              
41 9         43 my $ctx = context();
42             $ctx->note(join(' ', $feature->keyword_original,
43             ($feature->name || '') . "\n",
44 9   50     1349 map { $_->content } @{ $feature->satisfaction }));
  35         157  
  9         433  
45 9         5911 $ctx->release;
46             }
47              
48             sub scenario {
49 73     73 1 258 my ( $self, $scenario, $dataset ) = @_;
50 73         291 my $ctx = context();
51             $ctx->note(join(' ', $scenario->keyword_original,
52             ($scenario->name || '') . "\n",
53 73   50     8468 map { $_->content} @{ $scenario->description }));
  8         95  
  73         3476  
54 73         34331 $ctx->release;
55             }
56       73 1   sub scenario_done { }
57              
58       497 1   sub step { }
59              
60             sub step_done {
61 497     497 1 988 my ( $self, $context, $result ) = @_;
62              
63 497         1081 my $status = $result->result;
64              
65 497         999 my $step = $context->step;
66 497         1067 my $scenario = $context->scenario;
67 497         801 my $step_name;
68 497         1432 my $ctx = context();
69              
70             # when called from a 'before' or 'after' hook, we have context, but no step
71             $ctx->trace->{frame} = [
72             undef,
73 497 100       61448 $step ? $step->line->document->filename : $scenario->line->document->filename,
    100          
74             $step ? $step->line->number : $scenario->line->number,
75             undef ];
76 497 100       43318 if ( $context->is_hook ) {
77             $status ne 'undefined'
78             and $status ne 'pending'
79             and $status ne 'passing'
80 192 50 33     5302 or do { $ctx->release; return; };
  192   33     760  
  192         5286  
81 0         0 $step_name = ucfirst( $context->verb ) . ' Hook';
82             } else {
83 305         12087 $step_name
84             = ucfirst( $step->verb_original ) . ' ' . $context->text;
85             }
86              
87 305 50 33     4501 if ( $status eq 'undefined' || $status eq 'pending' ) {
    50          
88 0 0       0 if ( $self->fail_skip ) {
89 0 0       0 if ( $status eq 'undefined' ) {
90 0         0 $ctx->fail( "Matcher for: $step_name",
91             $self->_note_step_data($step));
92             } else {
93 0         0 $ctx->skip( "Test skipped due to failure in previous step",
94             $self->_note_step_data($step));
95             }
96             } else {
97 0         0 $ctx->send_event( 'Skip', todo => 'pending', todo_diag => 1,
98             reason => 'Step not implemented', pass => 0);
99 0         0 $ctx->note($self->_note_step_data($step));
100             }
101             } elsif ( $status eq 'passing' ) {
102 305         1237 $ctx->pass( $step_name );
103 305         91460 $ctx->note($self->_note_step_data($step));
104             } else {
105 0         0 $ctx->fail( $step_name );
106 0         0 $ctx->note($self->_note_step_data($step));
107 0 0       0 if ( !$context->is_hook ) {
108 0         0 my $step_location
109             = ' in step at '
110             . $step->line->document->filename
111             . ' line '
112             . $step->line->number . '.';
113 0         0 $ctx->diag($step_location);
114             }
115 0         0 $ctx->diag( $result->output );
116             }
117 305         137097 $ctx->release;
118             }
119              
120             sub _note_step_data {
121 305     305   856 my ( $self, $step ) = @_;
122 305 50       885 return unless $step;
123 305         501 my @step_data = @{ $step->data_as_strings };
  305         7686  
124 305 100       3303 return '' unless @step_data;
125              
126 25 100       164 if ( ref( $step->data ) eq 'ARRAY' ) {
127 6         51 return join("\n", @step_data);
128             } else {
129 19         162 return join('', '"""', join("\n", @step_data), '"""');
130             }
131             }
132              
133 1     1 1 3 sub shutdown { my $self = shift; my $ctx = context(); $ctx->done_testing; $ctx->release; }
  1         4  
  1         106  
  1         851  
134              
135             =head1 AUTHOR
136              
137             Peter Sergeant C
138              
139             =head1 LICENSE
140              
141             Copyright 2019-2023, Erik Huelsmann
142             Copyright 2011-2019, Peter Sergeant; Licensed under the same terms as Perl
143              
144             =cut
145              
146             1;