File Coverage

blib/lib/Test/Pcuke/Gherkin/Node/Table.pm
Criterion Covered Total %
statement 91 96 94.7
branch 19 28 67.8
condition 2 3 66.6
subroutine 19 20 95.0
pod 1 11 9.0
total 132 158 83.5


line stmt bran cond sub pod time code
1             package Test::Pcuke::Gherkin::Node::Table;
2              
3 3     3   170760 use warnings;
  3         7  
  3         99  
4 3     3   18 use strict;
  3         6  
  3         91  
5 3     3   19 use Carp;
  3         5  
  3         253  
6 3     3   20 use Scalar::Util qw{blessed};
  3         6  
  3         164  
7              
8 3     3   19 use base 'Test::Pcuke::Gherkin::Node';
  3         5  
  3         859  
9              
10 3     3   2379 use Test::Pcuke::Gherkin::Node::Table::Row;
  3         11  
  3         3385  
11              
12             =head1 NAME
13              
14             Test::Pcuke::Gherkin::Node::Table - table in Gherkin
15              
16             =head1 SYNOPSIS
17              
18             TODO Synopsis
19              
20             use Test::Pcuke::Gherkin::Node::Table;
21              
22             my $table = Test::Pcuke::Gherkin::Node::Table->new();
23              
24              
25             =head1 METHODS
26              
27             =head2 new
28              
29             =cut
30              
31             sub new {
32 4     4 1 2140 my ($self, $args) = @_;
33            
34 4         18 $args->{'_nsteps'} = {pass=>0, undef=>0, fail=>0};
35 4         27 $args->{'_nscenarios'} = {pass=>0, undef=>0, fail=>0};
36            
37 4         38 my $new_instance = $self->SUPER::new(
38             immutables => [qw{executor}],
39             properties => [qw{_nsteps _nscenarios}],
40             args => $args,
41             );
42            
43 4 50       13 if ( $args->{headings} ) {
44 0         0 $new_instance->set_headings( $args->{headings} );
45 0 0       0 if ( $args->{rows} ) {
46 0         0 $new_instance->add_rows( $args->{rows} );
47             }
48             }
49            
50            
51 4         11 return $new_instance;
52             }
53              
54 8 100   8 0 43 sub headings { $_[0]->_get_immutable('headings') || [] }
55              
56             sub set_headings {
57 3     3 0 613 my ($self, $headings) = @_;
58            
59 3 100       11 if ( ref $headings ne 'ARRAY' ) {
60 2         3 local $@;
61 2         3 $headings = eval { [ keys %{$headings->data}] };
  2         2  
  2         7  
62            
63 2 50       108 confess "headings must be either arrayref or Table::Row"
64             if $@;
65             }
66            
67 3         21 $self->_set_immutable('headings', $headings);
68             }
69              
70             sub add_row {
71 9     9 0 2090 my ($self, $row) = @_;
72            
73 9 100 66     54 if ( ref $row eq 'ARRAY' ) {
    100          
74 2         6 $row = $self->_make_row( $row );
75             }
76             elsif ( blessed $row && $row->can('data') ) { # probably isa Table::Row
77 6         240 $self->_set_check_headings($row); # dies if headings differ
78             }
79             else {
80 1         23 confess "add_row takes either arrayref or Table::Row";
81             }
82            
83 7         27 $row->set_executor( $self->_get_immutable('executor') );
84            
85 7         455 $self->_add_property('rows', $row);
86             }
87              
88             sub _set_check_headings {
89 6     6   10 my ($self, $row) = @_;
90            
91 6         7 my @t_heads = sort @{ $self->headings };
  6         12  
92            
93 6 100       15 if ( ! @t_heads ) {
94 2         5 $self->set_headings( $row );
95             }
96             else {
97 4         4 my @r_heads = sort keys %{ $row->data };
  4         12  
98 4 50       205 confess "incorrect number of columns in the row"
99             if @r_heads != @t_heads;
100 4 100       30 confess "headings of a row are different from that of the table!"
101             if join('', @t_heads) ne join('',@r_heads);
102             }
103             }
104              
105             sub _make_row {
106 2     2   4 my ($self, $data) = @_;
107 2         2 my ($hash, $row);
108            
109 2         3 my @headings = @{ $self->_get_immutable('headings') };
  2         10  
110 2 50       6 $self->_no_headings_exception() unless @headings;
111            
112 2 50       6 if ( @headings == @$data ) {
113 2         3 $hash = { map { shift @headings => $_ } @$data };
  6         16  
114 2         10 $row = Test::Pcuke::Gherkin::Node::Table::Row->new();
115 2         424 $row->set_data( $hash );
116             }
117             else {
118 0         0 confess "The number of columns in the row must correspond to the number of headings";
119             }
120            
121 2         228 return $row;
122             }
123              
124             sub add_rows {
125 1     1 0 6 my ($self, $rows) = @_;
126 1         3 foreach (@$rows) {
127 3         6 $self->add_row($_);
128             }
129             }
130              
131 4     4 0 20 sub rows { $_[0]->_get_property('rows') }
132              
133             sub hashes {
134 2     2 0 3254 my ($self) = @_;
135 2         2 my $result;
136            
137 2         4 for my $row ( @{ $self->rows } ) {
  2         5  
138 3         111 push @$result, $row->data;
139             }
140            
141 2         143 return $result;
142             };
143              
144             sub execute {
145 1     1 0 7 my ($self, $steps, $background) = @_;
146            
147 1         2 for my $row ( @{ $self->rows } ) {
  1         4  
148 3         19 $row->execute($steps, $background);
149 3         7952 $self->collect_stats( $row );
150             }
151             }
152              
153             sub collect_stats {
154 3     3 0 9 my ($self, $row) = @_;
155            
156 3         9 my $nsteps = $self->nsteps;
157 3         9 my $nscenarios = $self->nscenarios;
158            
159 3         25 my $r_nsteps = $row->nsteps;
160 3         548 my $r_nscenarios = $row->nscenarios;
161            
162 3         211 for (qw{pass fail undef}) {
163 9         20 $nsteps->{$_} += $r_nsteps->{$_};
164 9         21 $nscenarios->{$_} += $r_nscenarios->{$_};
165             }
166            
167 3         15 $self->_set_property('_nsteps', $nsteps);
168 3         10 $self->_set_property('_nscenarios', $nscenarios);
169             }
170              
171             sub nsteps {
172 4     4 0 11 my ($self, $status) = @_;
173 4         17 my $nsteps = $self->_get_property('_nsteps');
174            
175 4 50       19 return $status ?
176             $nsteps->{$status}
177             : $nsteps;
178             }
179              
180             sub nscenarios {
181 4     4 0 9 my ($self, $status) = @_;
182 4         15 my $nscenarios = $self->_get_property('_nscenarios');
183            
184 4 50       21 return $status ?
185             $nscenarios->{$status}
186             : $nscenarios;
187             }
188              
189              
190 0     0     sub _no_headings_exception { confess "headings must be set before adding the rows" }
191              
192              
193             1; # End of Test::Pcuke::Gherkin::Node::Table
194             __END__