Permalink
Browse files

Document uncoverable options.

  • Loading branch information...
1 parent 37b773c commit ac4e370e62d5fac53641f6ad8fb9235d128b25b0 @pjcj committed Feb 9, 2013
View
@@ -5,6 +5,7 @@ Devel::Cover history
- Fix various problems running Devel::Cover under tainting (github 41).
- Add JavaScript to filter results in html_basic (David Cantrell) (github 42).
Use -norestrict option to keep previous behaviour.
+ - Document ability to mark code as uncoverable.
Release 0.99 - 31 December 2012
- Improve documentation (Olaf Alders) (github 34).
View
@@ -824,6 +824,7 @@ static void cover_logop(pTHX)
}
#if PERL_VERSION > 14
+ NDEB(D(L, "Getting next\n"));
next = (PL_op->op_type == OP_XOR)
? PL_op->op_next
: right->op_next;
View
@@ -1549,6 +1549,131 @@ multiple times, but they can also take multiple comma separated arguments. In
any case you should not add a space after the comma, unless you want the
argument to start with that literal space.
+=head1 UNCOVERABLE CRITERIA
+
+Sometimes you have code which is uncoverable for some reason. Perhaps it is
+an else clause that cannot be reached, or a check for an error condition that
+should never happen. You can tell Devel::Cover that certain criteria are
+uncoverable and then they are not counted as errors when they are not
+exercised. In fact, they are counted as error if they are exercised.
+
+This feature should only be used as something of a last resort. Ideally you
+would find some way of exercising all your code. But if you have analysed
+your code and determined that you are not going to be able to exercise it, it
+may be better to record that fact in some formal fashion and stop Devel::Cover
+complaining about it, so that real problems are not lost in the noise.
+
+There are two ways to specify a construct as uncoverable, one invasive and one
+non-invasive.
+
+=head2 Invasive specification
+
+You can use special comments in your code to specify uncoverable criteria.
+Comment are of the form:
+
+ # uncoverable <criterion> [details]
+
+The keyword "uncoverable" must be the first text in the comment. It should be
+followed by the name of the coverage criterion which is uncoverable. There
+may then be further information depending on the nature of the uncoverable
+construct.
+
+=head3 Statements
+
+The "uncoverable" comment should appear on either the same line as the
+statement, of on the line before it:
+
+ $impossible++; # uncoverable statement
+ # uncoverable statement
+ it_has_all_gone_horribly_wrong();
+
+If there are multiple statements on a line you can specify which statement is
+uncoverable by using the "count" attribute, count:n, which indicates that the
+uncoverable statement is the nth statement on the line.
+
+ # uncoverable statement count:1
+ # uncoverable statement count:2
+ cannot_run_this(); or_this();
+
+=head3 Branches
+
+The "uncoverable" comment should specify whether the "true" or "false" branch
+is uncoverable.
+
+ # uncoverable branch true
+ if (pi == 3)
+
+Both branches my be uncoverable:
+
+ # uncoverable branch true
+ # uncoverable branch false
+ if (impossible_thing_happened_one_way()) {
+ handle_it_one_way(); # uncoverable statement
+ } else {
+ handle_it_another_way(); # uncoverable statement
+ }
+
+Both branches could be uncoverable:
+
+=head3 Conditions
+
+Because of the way in which Perl short-circuits boolean operations, there are
+three ways in which such conditionals can be uncoverable. In the case of C<
+$x && $y> for example, the left operator may never be true, the right operator
+may never be true, and the whole operation may never be false. These may be
+modelled thus:
+
+ # uncoverable branch true
+ # uncoverable condition left
+ # uncoverable condition false
+ if ($x && !$y)
+ {
+ $x++; # uncoverable statement
+ }
+
+ # uncoverable branch true
+ # uncoverable condition right
+ # uncoverable condition false
+ if (!$x && $y)
+ {
+ }
+
+Or conditionals are handled in a similar fashion (TODO - provide some
+examples) but xor conditionals are not properly handled yet.
+
+=head3 Subroutines
+
+A subroutine should be marked as uncoverable at the point where the first
+statement is marked as uncoverable. Ideally all statements in the subroutine
+would be marked as uncoverable automatically, but that isn't the case at the
+moment.
+
+ sub z
+ {
+ # uncoverable subroutine
+ $y++; # uncoverable statement
+ }
+
+=head2 Non-invasive specification
+
+If you can't, or don't want to add coverage comments to your code, you can
+specify the uncoverable information in a separate file. My default this file
+is L<.uncoverable> but you can override that.
+
+The interface to managing this file is the L<cover> program, and the options
+are:
+
+ -uncoverable_file
+ -add_uncoverable_point
+ -delete_uncoverable_point
+ -clean_uncoverable_points
+
+Of these, only the first two are implemented at the moment. The parameter for
+-add_uncoverable_point is a string composed of up to seven space separated
+elements: "$file $criterion $line $count $type $class $note".
+
+TODO - more information and examples.
+
=head1 ENVIRONMENT
The -silent option is turned on when Devel::Cover is invoked via
@@ -44,9 +44,9 @@ line err stmt bran cond sub code
23 }
24
25 # uncoverable branch true
-26 # uncoverable condition left
-27 # uncoverable condition right
-28 1 - 50 - 33 if (!$x || !$y)
+26 # uncoverable condition right
+27 # uncoverable condition false
+28 1 - 50 - 33 if (!$x && $y)
29 {
30 # uncoverable statement count:1
31 # uncoverable statement count:2
@@ -70,7 +70,7 @@ Branches
line err % true false branch
----- --- ------ ------ ------ ------
18 - 50 -0 1 if ($x and not $y)
-28 - 50 -0 1 if (not $x or not $y)
+28 - 50 -0 1 if (not $x and $y)
Conditions
@@ -81,12 +81,7 @@ and 3 conditions
line err % !l l&&!r l&&r expr
----- --- ------ ------ ------ ------ ----
18 - 33 -0 1 -0 $x and not $y
-
-or 3 conditions
-
-line err % l !l&&r !l&&!r expr
------ --- ------ ------ ------ ------ ----
-28 - 33 -0 -0 1 not $x or not $y
+28 - 33 1 -0 -0 not $x and $y
Uncovered Subroutines
@@ -1,94 +0,0 @@
-2 unmatched uncoverable comments not found at end of tests/uncoverable
-Reading database from ...
-
-
------------------------------------------- ------ ------ ------ ------ ------
-File stmt bran cond sub total
------------------------------------------- ------ ------ ------ ------ ------
-tests/uncoverable 100.0 100.0 100.0 100.0 100.0
-Total 100.0 100.0 100.0 100.0 100.0
------------------------------------------- ------ ------ ------ ------ ------
-
-
-Run: ...
-Perl version: ...
-OS: ...
-Start: ...
-Finish: ...
-
-tests/uncoverable
-
-line err stmt bran cond sub code
-1 #!/usr/bin/perl
-2
-3 # Copyright 2004-2013, Paul Johnson (paul@pjcj.net)
-4
-5 # This software is free. It is licensed under the same terms as Perl itself.
-6
-7 # The latest version of this software should be available from my homepage:
-8 # http://www.pjcj.net
-9
-10 # __COVER__ uncoverable_file tests/.uncoverable
-11
-12 1 my $x = 1;
-13 1 my $y = 1;
-14
-15 # uncoverable branch true
-16 # uncoverable condition left
-17 # uncoverable condition false
-18 1 - 50 - 33 if ($x && !$y)
-19 {
-20 -0 $x++; # uncoverable statement
-21 # uncoverable statement
-22 -0 z();
-23 }
-24
-25 # uncoverable branch true
-26 # uncoverable condition left
-27 # uncoverable condition right
-28 1 - 50 - 33 if (!$x || !$y)
-29 {
-30 # uncoverable statement count:1
-31 # uncoverable statement count:2
-32 -0 b(); b();
- -0
-33 }
-34
-35 sub z
-36 {
-37 # uncoverable subroutine
-38 -0 -0 $y++; # uncoverable statement
-39 }
-40
-41 # uncoverable statement
-42 # uncoverable subroutine
-
-
-Branches
---------
-
-line err % true false branch
------ --- ------ ------ ------ ------
-18 - 50 -0 1 if ($x and not $y)
-28 - 50 -0 1 unless ($x and $y)
-
-
-Conditions
-----------
-
-and 3 conditions
-
-line err % !l l&&!r l&&r expr
------ --- ------ ------ ------ ------ ----
-18 - 33 -0 1 -0 $x and not $y
-28 - 33 -0 -0 1 $x and $y
-
-
-Uncovered Subroutines
----------------------
-
-Subroutine Count Location
----------- ----- --------------------
-z -0 tests/uncoverable:38
-
-
@@ -1,94 +0,0 @@
-2 unmatched uncoverable comments not found at end of tests/uncoverable
-Reading database from ...
-
-
------------------------------------------- ------ ------ ------ ------ ------
-File stmt bran cond sub total
------------------------------------------- ------ ------ ------ ------ ------
-tests/uncoverable 100.0 100.0 66.7 100.0 90.0
-Total 100.0 100.0 66.7 100.0 90.0
------------------------------------------- ------ ------ ------ ------ ------
-
-
-Run: ...
-Perl version: ...
-OS: ...
-Start: ...
-Finish: ...
-
-tests/uncoverable
-
-line err stmt bran cond sub code
-1 #!/usr/bin/perl
-2
-3 # Copyright 2004-2013, Paul Johnson (paul@pjcj.net)
-4
-5 # This software is free. It is licensed under the same terms as Perl itself.
-6
-7 # The latest version of this software should be available from my homepage:
-8 # http://www.pjcj.net
-9
-10 # __COVER__ uncoverable_file tests/.uncoverable
-11
-12 1 my $x = 1;
-13 1 my $y = 1;
-14
-15 # uncoverable branch true
-16 # uncoverable condition left
-17 # uncoverable condition false
-18 1 - 50 - 33 if ($x && !$y)
-19 {
-20 -0 $x++; # uncoverable statement
-21 # uncoverable statement
-22 -0 z();
-23 }
-24
-25 # uncoverable branch true
-26 # uncoverable condition left
-27 # uncoverable condition right
-28 *** 1 - 50 - 33 if (!$x || !$y)
-29 {
-30 # uncoverable statement count:1
-31 # uncoverable statement count:2
-32 -0 b(); b();
- -0
-33 }
-34
-35 sub z
-36 {
-37 # uncoverable subroutine
-38 -0 -0 $y++; # uncoverable statement
-39 }
-40
-41 # uncoverable statement
-42 # uncoverable subroutine
-
-
-Branches
---------
-
-line err % true false branch
------ --- ------ ------ ------ ------
-18 - 50 -0 1 if ($x and not $y)
-28 - 50 -0 1 unless ($x and $y)
-
-
-Conditions
-----------
-
-and 3 conditions
-
-line err % !l l&&!r l&&r expr
------ --- ------ ------ ------ ------ ----
-18 - 33 -0 1 -0 $x and not $y
-28 *** - 33 -0 -1 0 $x and $y
-
-
-Uncovered Subroutines
----------------------
-
-Subroutine Count Location
----------- ----- --------------------
-z -0 tests/uncoverable:38
-
-
View
@@ -23,9 +23,9 @@ if ($x && !$y)
}
# uncoverable branch true
-# uncoverable condition left
# uncoverable condition right
-if (!$x || !$y)
+# uncoverable condition false
+if (!$x && $y)
{
# uncoverable statement count:1
# uncoverable statement count:2

0 comments on commit ac4e370

Please sign in to comment.