[tapx-dev] [patch] t/030-grammar.t to 100% coverage

Leif Eriksen leif_eriksen at hotmail.com
Sun Aug 5 13:30:11 BST 2007


Below is a patch to bring TAP::Parser::Grammar to 100% coverage.

Reasons for changes I made to modules are (these might form the basis 
for a commit if this patch is accepted) :-

1. lib/TAP/Parser/Grammar.pm
- removed a line of code checking the defined'ness of what comes back from
TAP::Parser::Grammar::_make_unknown_token(). As that method
simply returns a hash, its always defined and there is no way to write a
coverage test to counter that - therefore the defined'ness test is 
redundent and
I removed it.

- in TAP::Parser::Grammar::_make_plann_token(), removed a block that
attempts to force $skip to 'SKIP' if there are no tests planned and
$skip is unset. But as there is only one method that calls 
_make_plan_token,
and it has already set $skip to 'SKIP' when there are zero tests, it is not
possible to write a coverage test (via the API) to counter that, so I 
removed the
block.

2. lib/TAP/PArser/YAMLish/Reader.pm

- when writing a coverage test for the processing of potentially mal-formed
YAML, a warning is thrown about a regex on an undefined value - added a
defined'ness test to suppress that.

Relevant part of './Build test

t/030-grammar...................ok
...
All tests successful.
Files=26, Tests=4697, 11 wallclock secs ( 3.32 cusr +  2.77 csys =  6.09 
CPU)

Relevant part of coverage testing is

---------------------------- ------ ------ ------ ------ ------ ------ 
------
File                           stmt   bran   cond    sub    pod   time  
total
---------------------------- ------ ------ ------ ------ ------ ------ 
------
...
...lib/TAP/Parser/Grammar.pm  100.0  100.0  100.0  100.0  100.0    7.4  
100.0
...

Let me know if and where I've gone wrong...

Leif

-------------------------------------
Index: t/030-grammar.t
===================================================================
--- t/030-grammar.t    (revision 207)
+++ t/030-grammar.t    (working copy)
@@ -6,7 +6,7 @@
 use TAP::Parser::Grammar;
 use TAP::Parser::Iterator::Array;
 
-use Test::More tests => 69;
+use Test::More tests => 76;
 
 my $GRAMMAR = 'TAP::Parser::Grammar';
 
@@ -258,3 +258,121 @@
 };
 is_deeply $token, $expected,
   '... and the token should contain the correct data';
+
+# coverage tests
+
+# set_version
+
+{
+  my @die;
+
+  eval {
+    local $SIG{__DIE__} = sub {push @die, @_};
+
+    $grammar->set_version( 'no_such_version' );
+  };
+
+  is @die, 1,
+    'set_version with bad version';
+
+  like pop @die, qr/^Unsupported syntax version: no_such_version at /,
+       '... and got expected message';
+}
+
+# tokenize
+{
+  my $stream = SS->new;
+
+  my $grammar = $GRAMMAR->new( $stream );
+
+  my $plan = '';
+
+  $stream->put($plan);
+
+  my $result = $grammar->tokenize();
+
+  isa_ok $result, 'TAP::Parser::Result::Unknown';
+}
+
+# _make_plan_token
+
+{
+  my $grammar = $GRAMMAR->new;
+
+  my $plan = '1..1 # SKIP with explanation'; # trigger warning in 
_make_plan_token
+
+  my $method = $handler_for{'plan'};
+
+  $plan =~ $syntax_for{'plan'}; # perform regex to populate $1, $2
+
+  my @warn;
+
+  eval {
+    local $SIG{__WARN__} = sub {push @warn, @_};
+
+    $grammar->$method( $plan );
+  };
+
+  is @warn, 1,
+    'catch warning on inconsistent plan';
+
+  like pop @warn, qr/^Specified SKIP directive in plan but more than 0 
tests [(]1\.\.1 # SKIP with explanation[)]/,
+    '... and its what we expect';
+}
+
+# _make_yaml_token
+
+{
+  my $stream = SS->new;
+
+  my $grammar = $GRAMMAR->new( $stream);
+
+  $grammar->set_version( 13 );
+
+  # now this is badly formed YAML that is missing the
+  # leader padding - this is done for coverage testing
+  # the $reader code sub in _make_yaml_token, that is
+  # passed as the yaml consumer to T::P::YAMLish::Reader.
+
+  # because it isnt valid yaml, the yaml document is
+  # not done, and the _peek in the YAMLish::Reader
+  # code doesnt find the terminating '...' pattern.
+  # but we dont care as this is coverage testing, so
+  # if thats what we have to do to exercise that code,
+  # so be it.
+  my $yaml = [
+          '  ...  ',
+          '- 2',
+          '  ---  ',
+         ];
+
+  sub iter {
+    my $ar = shift;
+    return sub {
+      return shift @$ar;
+    };
+  }
+
+  my $iter = iter($yaml);
+
+  while (my $line = $iter->()) {
+    $stream->put($line);
+  }
+
+  # pad == '   ', marker == '--- '
+  # length $pad == 3
+  # strip == pad
+
+  my @die;
+
+  eval {
+    local $SIG{__DIE__} = sub {push @die, @_};
+    $grammar->tokenize;
+  };
+
+  is @die, 1,
+    'checking badly formed yaml for coverage testing';
+
+  like pop @die, qr/^Missing '[.][.][.]' at end of YAMLish/,
+    '...and it died like we expect';
+}
Index: lib/TAP/Parser/Grammar.pm
===================================================================
--- lib/TAP/Parser/Grammar.pm    (revision 207)
+++ lib/TAP/Parser/Grammar.pm    (working copy)
@@ -190,8 +190,10 @@
             last;
         }
     }
-    $token ||= $self->_make_unknown_token( $line );
-    return defined $token ? TAP::Parser::Result->new( $token ) : ();
+
+    $token = $self->_make_unknown_token( $line ) unless $token;
+
+    return TAP::Parser::Result->new( $token );
 }
 
 ##############################################################################
@@ -269,9 +271,7 @@
 
 sub _make_plan_token {
     my ( $self, $line, $tests_planned, $skip, $explanation ) = @_;
-    if ( 0 == $tests_planned ) {
-        $skip ||= 'SKIP';
-    }
+
     if ( $skip && 0 != $tests_planned ) {
         warn "Specified SKIP directive in plan but more than 0 tests 
($line)\n";
     }
Index: lib/TAP/Parser/YAMLish/Reader.pm
===================================================================
--- lib/TAP/Parser/YAMLish/Reader.pm    (revision 207)
+++ lib/TAP/Parser/YAMLish/Reader.pm    (working copy)
@@ -50,7 +50,7 @@
     # Which might not be a bad idea.
     my $dots = $self->_peek;
     die "Missing '...' at end of YAMLish"
-      unless $dots =~ $IS_END_YAML;
+      unless defined $dots and $dots =~ $IS_END_YAML;
 
     delete $self->{reader};
     delete $self->{next};



More information about the tapx-dev mailing list