File Coverage

blib/lib/Gherkin/TokenScanner.pm
Criterion Covered Total %
statement 49 49 100.0
branch 8 10 80.0
condition n/a
subroutine 11 11 100.0
pod 2 3 66.6
total 70 73 95.8


line stmt bran cond sub pod time code
1             package Gherkin::TokenScanner;
2             $Gherkin::TokenScanner::VERSION = '39.0.0';
3 2     2   298600 use strict;
  2         4  
  2         60  
4 2     2   6 use warnings;
  2         4  
  2         108  
5              
6 2     2   402 use Class::XSAccessor accessors => [qw/fh line_number/];
  2         2260  
  2         17  
7              
8 2     2   459 use Carp qw/croak/;
  2         4  
  2         146  
9 2     2   968 use Encode;
  2         32382  
  2         215  
10              
11 2     2   982 use Gherkin::Line;
  2         9  
  2         71  
12 2     2   805 use Gherkin::Token;
  2         6  
  2         642  
13              
14             sub new {
15 5     5 1 485712 my ( $class, $path_or_str ) = @_;
16              
17             # Perl convention is that a string reference is the string itself, but that
18             # a straight string is a path
19             ## no critic (RequireBriefOpen)
20             # the file is opened in this object constructor,
21             # and will be closed in the method next_line at the end
22 5         10 my $fh;
23 5 100       23 if ( ref $path_or_str eq 'SCALAR' ) {
24 3         5 my $bytes = Encode::encode('UTF-8', ${ $path_or_str });
  3         29  
25 2     2   1646 open $fh, '<:encoding(UTF-8)', \$bytes;
  2         33  
  2         11  
  3         238  
26             } else {
27 2 50       120 open( $fh, '<', $path_or_str )
28             || croak "Can't open [$path_or_str] for reading";
29 2         21 $fh->binmode(':utf8');
30             }
31             ## use critic
32              
33 5         2336 return bless { fh => $fh, line_number => 0 }, $class;
34             }
35              
36             sub next_line {
37 42     42 0 65 my $self = shift;
38              
39 42 50       125 return (undef, $self->line_number) if not defined $self->fh;
40              
41 42         455 my $line = $self->fh->getline;
42 42         181 $self->line_number( $self->line_number + 1 );
43              
44 42 100       101 if (not defined $line) {
45 4         58 $self->fh->close;
46 4         131 $self->fh( undef );
47             }
48              
49 42         176 return ($line, $self->line_number);
50             }
51              
52             sub read {
53 42     42 1 91 my $self = shift;
54 42         98 my ($line, $line_number) = $self->next_line;
55              
56 42         120 my $location = { line => $line_number };
57 42         102 my $line_token = undef;
58 42 100       107 if (defined $line) {
59 38         105 $line =~ s/\r$//; # \n as well as \r\n are considered lines separators
60 38         217 $line_token =
61             Gherkin::Line->new(
62             { line_text => $line, line_number => $line_number }
63             );
64             }
65 42         366 return Gherkin::Token->new(line => $line_token, location => $location);
66             }
67              
68             1;
69              
70              
71             __END__