File Coverage

blib/lib/Gherkin/ParserBase.pm
Criterion Covered Total %
statement 39 51 76.4
branch 3 14 21.4
condition 2 6 33.3
subroutine 13 14 92.8
pod 0 3 0.0
total 57 88 64.7


line stmt bran cond sub pod time code
1             package Gherkin::ParserBase;
2             $Gherkin::ParserBase::VERSION = '39.0.0';
3 1     1   8 use strict;
  1         1  
  1         50  
4 1     1   20 use warnings;
  1         3  
  1         56  
5              
6 1         7 use Class::XSAccessor accessors =>
7 1     1   552 [ qw/ast_builder token_matcher stop_at_first_error max_errors/, ];
  1         2953  
8              
9 1     1   892 use Gherkin::ParserContext;
  1         5  
  1         49  
10 1     1   850 use Gherkin::Exceptions;
  1         5  
  1         41  
11 1     1   742 use Gherkin::AstBuilder;
  1         7  
  1         64  
12              
13 1     1   900 use Gherkin::TokenMatcher;
  1         4  
  1         54  
14 1     1   575 use Gherkin::TokenScanner;
  1         4  
  1         278  
15              
16             sub new {
17 3     3 0 9225 my ( $class, $ast_builder, $token_matcher ) = @_;
18 3   33     39 bless {
      33        
19             ast_builder => $ast_builder || Gherkin::AstBuilder->new(),
20             token_matcher => $token_matcher || Gherkin::TokenMatcher->new(),
21             stop_at_first_error => 0,
22             max_errors => 10,
23             },
24             $class;
25             }
26              
27 3     3 0 51 sub get_result { return $_[0]->ast_builder->get_result }
28              
29             sub add_error {
30 0     0 0 0 my ( $self, $context, $error ) = @_;
31              
32 0 0       0 die $error if not ref $error; # rethrow if unstructured; not ours
33 0 0       0 die $error if $self->stop_at_first_error;
34 0 0       0 if ( ref $error eq 'Gherkin::Exceptions::CompositeParser' ) {
35 0         0 $context->add_errors( @{ $error->errors } );
  0         0  
36             } else {
37 0         0 $context->add_errors( $error );
38             }
39              
40 0         0 my @errors = $context->errors;
41 0 0       0 Gherkin::Exceptions::CompositeParser->throw(@errors)
42             if @errors > $self->max_errors;
43             }
44              
45             ## no critic (Subroutines::ProhibitUnusedPrivateSubroutines)
46             # Private subs (subs prefixed with an underscore) are used as "friend methods" here,
47             # to be used by the actual parser class which is based on this one.
48              
49             sub _start_rule {
50 33     33   78 my ( $self, $context, $ruleType ) = @_;
51              
52 33 50       62 if (not eval { $self->ast_builder->start_rule( $ruleType ); 1 }) {
  33         150  
  33         113  
53 0         0 $self->add_error( $context, $@ );
54             }
55             }
56              
57             sub _end_rule {
58 33     33   81 my ( $self, $context, $ruleType ) = @_;
59 33 50       59 if (not eval { $self->ast_builder->end_rule( $ruleType ); 1 }) {
  33         154  
  33         151  
60 0         0 $self->add_error( $context, $@ );
61             }
62             }
63              
64             sub _build {
65 36     36   102 my ( $self, $context, $token ) = @_;
66 36 50       68 if (not eval { $self->ast_builder->build( $token ); 1 }) {
  36         183  
  36         122  
67 0           $self->add_error( $context, $@ );
68             }
69             }
70              
71             1;