File Coverage

blib/lib/Cucumber/TagExpressions/Node.pm
Criterion Covered Total %
statement 40 55 72.7
branch 1 2 50.0
condition 1 3 33.3
subroutine 15 22 68.1
pod 12 12 100.0
total 69 94 73.4


line stmt bran cond sub pod time code
1              
2             package Cucumber::TagExpressions::Node;
3             $Cucumber::TagExpressions::Node::VERSION = '4.1.0';
4             =head1 NAME
5              
6             Cucumber::TagExpressions::Node - Cucumber Tag expression components
7              
8             =head1 SYNOPSIS
9              
10             use Cucumber::TagExpressions;
11              
12             my $expr = Cucumber::TagExpressions->parse( '@a and @b' );
13             if ( $expr->evaluate( qw/x y z/ ) ) {
14             say "The evaluation returned false";
15             }
16              
17             =head1 DESCRIPTION
18              
19             This module defines the components making up the tag expressions.
20              
21             =head1 METHODS
22              
23             =cut
24              
25 1     1   1283 use Moo;
  1         10821  
  1         18  
26             # 'use Moo' implies 'use strict; use warnings;'
27              
28             =head2 evaluate( @tags )
29              
30             Returns C when the tag set specified in C<$tags> satisfies the
31             condition(s) of the expression, C otherwise.
32              
33             C<@tags> can be a list of tags to be used in the expression. It can
34             also be a reference to a hash with the keys being the tags and the
35             values being considered boolean values indicating whether the tag (key)
36             is considered part of the tagset (true) or not (false).
37              
38             =cut
39              
40             sub evaluate {
41 0     0 1 0 die 'Abstract superclass; override "evaluate" method';
42             }
43              
44              
45             =head2 stringify
46              
47             Returns a string representation of the expression node.
48              
49             =cut
50              
51       0 1   sub stringify { }
52              
53             =head1 NODE CLASSES
54              
55             =cut
56              
57             package Cucumber::TagExpressions::LiteralNode {
58             $Cucumber::TagExpressions::LiteralNode::VERSION = '4.1.0';
59             =head2 Cucumber::TagExpressions::LiteralNode
60              
61             =head3 DESCRIPTION
62              
63             This node class returns C if the literal tag is specified as part of
64             the tag-list in the expression evaluation.
65              
66             =head3 ATTRIBUTES
67              
68             =head4 tag
69              
70             The tag to test presence for.
71              
72             =cut
73              
74 1     1   1413 use Moo;
  1         3  
  1         4  
75             # 'use Moo' implies 'use strict; use warnings;'
76             extends 'Cucumber::TagExpressions::Node';
77              
78             has tag => ( is => 'ro', required => 1 );
79              
80             sub evaluate {
81 85     85 1 121 my ( $self, $tags ) = @_;
82              
83 85         493 return $tags->{ $self->tag };
84             }
85              
86             sub stringify {
87 0     0 1 0 my ( $self ) = @_;
88              
89 0         0 return $self->tag;
90             }
91             }
92              
93             package Cucumber::TagExpressions::AndNode {
94             $Cucumber::TagExpressions::AndNode::VERSION = '4.1.0';
95             =head2 Cucumber::TagExpressions::AndNode
96              
97             =head3 DESCRIPTION
98              
99             This node class type evaluates one or more sub-expressions ("terms") and
100             returns C if any of the terms does. It returns C if all of
101             the terms return C.
102              
103             =head3 ATTRIBUTES
104              
105             =head4 terms
106              
107             The sub-expressions to evaluate.
108              
109             =cut
110              
111 1     1   365 use Moo;
  1         3  
  1         3  
112             # 'use Moo' implies 'use strict; use warnings;'
113             extends 'Cucumber::TagExpressions::Node';
114              
115 1     1   300 use List::Util qw( all );
  1         1  
  1         221  
116              
117             has terms => ( is => 'ro', required => 1 );
118              
119             sub evaluate {
120 24     24 1 38 my ( $self, $tags ) = @_;
121              
122 24     37   67 return all { $_->evaluate( $tags ) } @{ $self->terms };
  37         75  
  24         65  
123             }
124              
125             sub stringify {
126 0     0 1 0 my ( $self ) = @_;
127              
128             return join('', '(and ',
129 0         0 join(' ', map { $_->stringify } @{ $self->terms } ),
  0         0  
  0         0  
130             ')');
131             }
132             }
133              
134             package Cucumber::TagExpressions::OrNode {
135             $Cucumber::TagExpressions::OrNode::VERSION = '4.1.0';
136             =head2 Cucumber::TagExpressions::OrNode
137              
138             =head3 DESCRIPTION
139              
140             This node class type evaluates one or more sub-expressions ("terms") and
141             returns C if any of the terms does. It returns C if all of
142             the terms return C.
143              
144             =head3 ATTRIBUTES
145              
146             =head4 terms
147              
148             The sub-expressions to evaluate.
149              
150             =cut
151              
152 1     1   6 use Moo;
  1         3  
  1         3  
153             # 'use Moo' implies 'use strict; use warnings;'
154             extends 'Cucumber::TagExpressions::Node';
155              
156 1     1   260 use List::Util qw( any );
  1         1  
  1         197  
157              
158             has terms => ( is => 'ro', required => 1 );
159              
160             sub evaluate {
161 34     34 1 57 my ( $self, $tags ) = @_;
162              
163 34     55   97 return any { $_->evaluate( $tags ) } @{ $self->terms };
  55         111  
  34         99  
164             }
165              
166             sub stringify {
167 0     0 1 0 my ( $self ) = @_;
168              
169             return join('', '(or ',
170 0         0 join(' ', map {$_->stringify} @{ $self->terms } ),
  0         0  
  0         0  
171             ')');
172             }
173             }
174              
175             package Cucumber::TagExpressions::NotNode {
176             $Cucumber::TagExpressions::NotNode::VERSION = '4.1.0';
177             =head2 Cucumber::TagExpressions::NotNode
178              
179             =head3 DESCRIPTION
180              
181             This class wraps one of the other node class types, negating its
182             result on evaluation.
183              
184             =head3 ATTRIBUTES
185              
186             =head4 expression
187              
188             The wrapped node class instance for which to negate the result.
189              
190             =cut
191              
192 1     1   6 use Moo;
  1         1  
  1         21  
193             # 'use Moo' implies 'use strict; use warnings;'
194             extends 'Cucumber::TagExpressions::Node';
195              
196             has expression => ( is => 'ro', required => 1 );
197              
198             sub evaluate {
199 21     21 1 35 my ( $self, $tags ) = @_;
200              
201 21         51 return not $self->expression->evaluate( $tags );
202             }
203              
204             sub stringify {
205 0     0 1 0 my ( $self ) = @_;
206              
207 0         0 return '(not ' . $self->expression->stringify . ')';
208             }
209             }
210              
211             package Cucumber::TagExpressions::ExpressionNode {
212             $Cucumber::TagExpressions::ExpressionNode::VERSION = '4.1.0';
213             =head2 Cucumber::TagExpressions::ExpressionNode
214              
215             =head3 DESCRIPTION
216              
217             This class models the outer-most node in the tag expression; it wraps all
218             other nodes and is the entry-point for tag expression evaluation.
219              
220             =head3 ATTRIBUTES
221              
222             =head4 sub_expression
223              
224             An instance of one of the other node class types.
225              
226             =cut
227              
228 1     1   424 use Moo;
  1         2  
  1         10  
229             # 'use Moo' implies 'use strict; use warnings;'
230             extends 'Cucumber::TagExpressions::Node';
231              
232             has sub_expression => ( is => 'ro', required => 1 );
233              
234             sub evaluate {
235 51     51 1 9667 my ( $self, @tags ) = @_;
236             my $tags = (ref $tags[0] and ref $tags[0] eq 'HASH') ? $tags[0]
237 51 50 33     184 : { map { $_ => 1 } @tags };
  66         199  
238              
239 51         172 return not not $self->sub_expression->evaluate( $tags );
240             }
241              
242             sub stringify {
243 0     0 1   my ( $self ) = @_;
244              
245 0           return $self->sub_expression->stringify;
246             }
247             }
248              
249              
250             1;
251              
252             __END__