File Coverage

blib/lib/PerlX/Assert.pm
Criterion Covered Total %
statement 42 49 85.7
branch 13 24 54.1
condition 6 15 40.0
subroutine 11 13 84.6
pod n/a
total 72 101 71.2


line stmt bran cond sub pod time code
1 4     4   100504 use 5.008001;
  4         13  
2 4     4   19 use strict;
  4         7  
  4         69  
3 4     4   20 use warnings;
  4         7  
  4         127  
4 4     4   19 no warnings qw( uninitialized void once );
  4         6  
  4         133  
5              
6 4     4   1307 use Devel::StrictMode ();
  4         1134  
  4         66  
7 4     4   23 use Exporter::Tiny ();
  4         6  
  4         1925  
8              
9             package PerlX::Assert;
10              
11             our $AUTHORITY = 'cpan:TOBYINK';
12             our $VERSION = '0.905';
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   750 my $me = shift;
25             my $symbols = grep {
26 9         19 ref($_) ? 0 : # refs are not symbols
27 5 100 66     45 /\A[:-](\w+)\z/ && $HINTS{$1} ? 0 : # hints are not symbols
    100          
28             1; # everything else is
29             } @_;
30            
31 9 100       37 push @_, @EXPORT if $symbols == 0;
32            
33 9 50       31 my $globals = ref($_[0]) eq 'HASH' ? shift() : {};
34 9         22 unshift @_, $me, $globals;
35 9         43 goto \&Exporter::Tiny::import;
36             }
37              
38             sub _exporter_validate_opts
39             {
40 9     9   821 my $me = shift;
41 9         19 my ($globals) = @_;
42            
43 9 50 0     29 $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     29 || do {
      66        
50             require PerlX::Assert::DD;
51             'PerlX::Assert::DD';
52             };
53            
54 9         27 ++$globals->{check} if Devel::StrictMode::STRICT;
55             }
56              
57             sub _exporter_install_sub
58             {
59 9     9   60 my $me = shift;
60 9         21 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     53 if ($name eq 'assert' and not ref $globals->{into})
66             {
67             my $tmp = exists($globals->{installer})
68 9 50       26 ? [ delete($globals->{installer}) ]
69             : undef;
70             $globals->{installer} = sub {
71 9     9   347 $IMPLEMENTATION->_install_assert(
72             $_[1][0],
73             $globals,
74             );
75 9         42 };
76 9         51 $me->SUPER::_exporter_install_sub(@_);
77             $tmp
78             ? ($globals->{installer} = $tmp->[0])
79 9 50       327 : delete($globals->{installer});
80 9         28 return;
81             }
82            
83 0         0 $me->SUPER::_exporter_install_sub(@_);
84             }
85              
86             sub _generate_assert
87             {
88 13     13   339 my $me = shift;
89 13         33 my ($name, $args, $globals) = @_;
90            
91 0     0   0 return sub ($$) { 0 }
92 13 100       89 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         24 };
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.