File Coverage

blib/lib/PerlX/Assert.pm
Criterion Covered Total %
statement 43 50 86.0
branch 13 24 54.1
condition 6 15 40.0
subroutine 11 13 84.6
pod n/a
total 73 102 71.5


line stmt bran cond sub pod time code
1 4     4   112058 use 5.008001;
  4         10  
  4         136  
2 4     4   15 use strict;
  4         4  
  4         91  
3 4     4   21 use warnings;
  4         5  
  4         103  
4 4     4   13 no warnings qw( uninitialized void once );
  4         4  
  4         131  
5              
6 4     4   1700 use Devel::StrictMode ();
  4         1221  
  4         66  
7 4     4   16 use Exporter::Tiny ();
  4         6  
  4         2111  
8              
9             package PerlX::Assert;
10              
11             our $AUTHORITY = 'cpan:TOBYINK';
12             our $VERSION = '0.904';
13             our @ISA = qw( Exporter::Tiny );
14             our @EXPORT = qw( assert );
15              
16             our $NO_KEYWORD_API;
17             my $IMPLEMENTATION;
18             my %HINTS = (check => 1);
19              
20             # This functionality probably needs to be added to
21             # Exporter::Tiny itself.
22             sub import
23             {
24 9     9   661 my $me = shift;
25 5 100 66     46 my $symbols = grep {
    100          
26 9         14 ref($_) ? 0 : # refs are not symbols
27             /\A[:-](\w+)\z/ && $HINTS{$1} ? 0 : # hints are not symbols
28             1; # everything else is
29             } @_;
30            
31 9 100       29 push @_, @EXPORT if $symbols == 0;
32            
33 9 50       21 my $globals = ref($_[0]) eq 'HASH' ? shift() : {};
34 9         17 unshift @_, $me, $globals;
35 9         35 goto \&Exporter::Tiny::import;
36             }
37              
38             sub _exporter_validate_opts
39             {
40 9     9   600 my $me = shift;
41 9         12 my ($globals) = @_;
42            
43 9 50 0     26 $IMPLEMENTATION ||= $me unless $me eq __PACKAGE__;
44             $IMPLEMENTATION ||= eval {
45             die if $NO_KEYWORD_API;
46             require PerlX::Assert::Keyword;
47             'PerlX::Assert::Keyword';
48             }
49 9   33     22 || do {
      66        
50             require PerlX::Assert::DD;
51             'PerlX::Assert::DD';
52             };
53            
54 9         21 ++$globals->{check} if Devel::StrictMode::STRICT;
55             }
56              
57             sub _exporter_install_sub
58             {
59 9     9   51 my $me = shift;
60 9         13 my ($name, $value, $globals, $sym) = @_;
61            
62             # This is harder than it should be. :-(
63             # A rather roundabout method for overwriting
64             # the installation of the 'assert' function.
65 9 50 33     54 if ($name eq 'assert' and not ref $globals->{into})
66             {
67 9 50       21 my $tmp = exists($globals->{installer})
68             ? [ delete($globals->{installer}) ]
69             : undef;
70             $globals->{installer} = sub {
71 9     9   299 $IMPLEMENTATION->_install_assert(
72             $_[1][0],
73             $globals,
74             );
75 9         43 };
76 9         40 $me->SUPER::_exporter_install_sub(@_);
77 9 50       308 $tmp
78             ? ($globals->{installer} = $tmp->[0])
79             : delete($globals->{installer});
80 9         20 return;
81             }
82            
83 0         0 $me->SUPER::_exporter_install_sub(@_);
84             }
85              
86             sub _generate_assert
87             {
88 13     13   316 my $me = shift;
89 13         33 my ($name, $args, $globals) = @_;
90            
91 0     0   0 return sub ($$) { 0 }
92 13 100       77 unless $globals->{check};
93            
94             return sub ($$) {
95 0 0   0     my ($desc, $value) = @_==1 ? (undef, @_) : @_;
96 0 0         return if $value;
97 0           require Carp;
98 0 0         Carp::croak(sprintf(q[Assertion failed: %s], $desc)) if defined $desc;
99 0           Carp::croak(sprintf(q[Assertion failed]));
100 3         27 };
101             }
102              
103             *assert = __PACKAGE__->_generate_assert(assert => {}, {});
104              
105             __PACKAGE__
106             __END__
107              
108             =pod
109              
110             =encoding utf-8
111              
112             =for stopwords backported
113              
114             =head1 NAME
115              
116             PerlX::Assert - yet another assertion keyword
117              
118             =head1 SYNOPSIS
119              
120             use PerlX::Assert;
121            
122             assert { 1 >= 10 };
123              
124             =head1 DESCRIPTION
125              
126             PerlX::Assert is a framework for embedding assertions in Perl code.
127             Under normal circumstances, assertions are not checked; they are
128             optimized away at compile time.
129              
130             However if, at compile time, any of the following environment variables
131             is true, assertions are checked, and if they fail, throw an exception.
132              
133             =over
134              
135             =item *
136              
137             C<PERL_STRICT>
138              
139             =item *
140              
141             C<AUTHOR_TESTING>
142              
143             =item *
144              
145             C<EXTENDED_TESTING>
146              
147             =item *
148              
149             C<RELEASE_TESTING>
150              
151             =back
152              
153             That is, assertions will only typically be checked when the test suite
154             is being run on the authors' machine, or otherwise opted into.
155              
156             The exact decision logic can be found in L<Devel::StrictMode>.
157              
158             You can also force assertions to be checked using:
159              
160             use PerlX::Assert -check;
161              
162             There are four syntaxes for expressing assertions:
163              
164             assert EXPR;
165             assert { BLOCK };
166             assert "name", EXPR;
167             assert "name" { BLOCK };
168              
169             Assertions can be named, which is probably a good idea because this
170             module (and the rest of Moops) screws up Perl's reporting of line
171             numbers. Names must be a quoted string (single or double quotes, or
172             the C<q> or C<qq> quote-like operators); general expressions are not
173             supported because L<Text::Balanced> is used to parse the assertion
174             name. An assertion is a statement, so must be followed by a semicolon
175             unless it's the last statement in a block.
176              
177             PerlX::Assert was originally distributed as part of L<Moops>, but was
178             fairly independent of the rest of it, and has been spun off as a
179             separate release, and backported to Perl 5.8.1.
180              
181             Assertions that span multiple lines are very likely to cause problems
182             on versions of Perl prior to 5.12. If the C<assert> keyword, the
183             entire name, and the start of the expression or block are all on the
184             same line, this should be sufficient.
185              
186             =head1 BUGS
187              
188             Please report any bugs to
189             L<http://rt.cpan.org/Dist/Display.html?Queue=PerlX-Assert>.
190              
191             =head1 SEE ALSO
192              
193             L<Devel::Assert>, L<Carp::Assert>.
194              
195             =head1 AUTHOR
196              
197             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
198              
199             =head1 COPYRIGHT AND LICENCE
200              
201             This software is copyright (c) 2013-2014 by Toby Inkster.
202              
203             This is free software; you can redistribute it and/or modify it under
204             the same terms as the Perl 5 programming language system itself.
205              
206             =head1 DISCLAIMER OF WARRANTIES
207              
208             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
209             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
210             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.