File Coverage

blib/lib/Assert/Refute.pm
Criterion Covered Total %
statement 112 115 97.3
branch 44 54 81.4
condition 13 22 59.0
subroutine 24 24 100.0
pod 12 12 100.0
total 205 227 90.3


line stmt bran cond sub pod time code
1             package Assert::Refute;
2              
3 38     38   1733092 use 5.006;
  38         388  
4 38     38   205 use strict;
  38         106  
  38         1062  
5 38     38   221 use warnings;
  38         105  
  38         2552  
6             our $VERSION = '0.17';
7              
8             =head1 NAME
9              
10             Assert::Refute - Unified testing and assertion tool
11              
12             =head1 DESCRIPTION
13              
14             This module allows injecting L-like code snippets
15             into production code, without turning the whole application
16             into a giant testing script.
17              
18             This can be though of as a lightweight design-by-contract form.
19              
20             =head1 SYNOPSIS
21              
22             The following code will die unless the conditions listed there are fulfilled:
23              
24             use Assert::Refute ":all", { on_fail => 'croak' };
25              
26             # Lots of code here
27             try_refute {
28             cmp_ok $price + $fee, "==", $total, "Money added up correctly";
29             like $description, qr/\w{3}/, "A readable description is present";
30             isa_ok $my_obj, "My::Class";
31             };
32              
33             A code snippet like this can guard important invariants,
34             ensure data correctness, or serve as a safety net while reworking
35             a monolithic application into separate testable modules.
36              
37             Note that the inside of the block can be copied into a unit-test as is,
38             giving one a fine-grained I----E accuracy> control.
39              
40             The same can be done without polluting the main package namespace:
41              
42             use Assert::Refute { on_fail => 'croak' };
43              
44             try_refute {
45             my $report = shift;
46             $report->cmp_ok( $price + $fee, "==", $total, "Money added up correctly" );
47             $report->like( $description, qr/\w{3}/, "A readable description is present" );
48             $report->isa_ok( $my_obj, "My::Class" );
49             };
50              
51             Relying on a global (in fact, per-package) callback is not required:
52              
53             use Assert::Refute {}, ":all";
54              
55             my $report = try_refute {
56             # ... assertions here
57             };
58             if (!$report->is_passing) {
59             $my_logger->error( "Something is not right: ".$report->get_tap );
60             # do whatever error handling is needed
61             };
62              
63             See L for more information about the underlying
64             object-oriented interface.
65              
66             =head1 ASSERTIONS, CONTRACTS, AND SUBCONTRACTS
67              
68             =over
69              
70             =item * We use the term I here to refer to a binary statement
71             that can be proven wrong using a well-defined, finite calculation.
72              
73             We say that assertion Is if such proof is provided,
74             and Ies otherwise.
75              
76             "X equals Y" and "a string contains such and such words"
77             are assertions by this definition.
78             "This code terminates" isn't because it requires solving the halting problem.
79             "All swans are white" isn't either unless there's code that produces
80             a black swan.
81              
82             =item * We use the term I here to refer to a code block
83             containing zero or more assertions.
84             A contract is said to I if any of its assertions fails,
85             and is assumed to I otherwise.
86              
87             This is not to be confused with full-fledged design-by-contract
88             which is much more specific about what contracts are.
89              
90             =item * Note that a contract itself is an assertion by this definition.
91             We use the term I to refer to an assertion that another
92             contract passes given certain arguments.
93              
94             These building blocks allow to create and verify
95             arbitrarily complex specifications.
96             See L below for limitations, though.
97              
98             =back
99              
100             =head1 EXPORT
101              
102             Any number of hash references may be added to the C statement,
103             resulting in an implicit Cconfigure> call.
104             A literal C<{}> will also trigger C.
105              
106             Everything else will be passed on to L.
107              
108             use Assert::Refute;
109              
110             as well as
111              
112             use Assert::Refute qw(:core);
113              
114             would only export C, C, C,
115             C, C, and C functions.
116              
117             Also for convenience some basic assertions mirroring the L suite
118             are exportable via C<:all> and C<:basic> export tag.
119              
120             use Assert::Refute qw(:all);
121              
122             would also export the following assertions:
123              
124             C, C, C, C, C, C,
125             C, C, C, C, C,
126             C, C, C, C, C.
127              
128             See L for more.
129              
130             This distribution also bundles some extra assertions:
131              
132             =over
133              
134             =item * L - inspect list structure;
135              
136             =item * L - verify exceptions and warnings;
137              
138             =item * L - inspect hash keys and values;
139              
140             =item * L - make sure numbers fit certain intervals;
141              
142             =back
143              
144             These need to be Cd explicitly.
145              
146             =cut
147              
148 38     38   258 use Carp;
  38         93  
  38         2506  
149 38     38   237 use Exporter;
  38         101  
  38         1567  
150              
151 38     38   15798 use Assert::Refute::Report;
  38         100  
  38         1363  
152 38     38   297 use Assert::Refute::Build qw(current_contract);
  38         87  
  38         1911  
153 38     38   244 use Assert::Refute::T::Basic;
  38         98  
  38         76461  
154              
155             my @basic = (
156             @Assert::Refute::T::Basic::EXPORT, 'plan'
157             );
158             my @core = qw(
159             contract refute_these try_refute
160             refute subcontract contract_is current_contract
161             );
162             my @extra = qw( assert_refute refute_and_report refute_invariant );
163              
164             our @ISA = qw(Exporter);
165             our @EXPORT = @core;
166             our @EXPORT_OK = (@basic, @extra);
167              
168             our %EXPORT_TAGS = (
169             basic => [@basic],
170             core => [@core, @extra],
171             all => [@EXPORT, @EXPORT_OK],
172             );
173              
174             our $DRIVER; # Used by other modules, declaration JFYI
175             our %CALLER_CONF;
176              
177             our $NDEBUG;
178             $NDEBUG = $ENV{PERL_NDEBUG} unless defined $NDEBUG;
179             $NDEBUG = $ENV{NDEBUG} unless defined $NDEBUG;
180              
181             sub import {
182 47     47   132925 my $class = shift;
183              
184             # NOTE ugly hack - allow for 'use Assert::Refute {}'
185             # this should not be needed with new assert_refute / refute_and_report API
186 47         131 my %conf = ( on_fail => 'skip' );
187 47         103 my (@exp, $need_conf);
188 47         111 foreach (@_) {
189 41 100 33     322 if (ref $_ eq 'HASH') {
    50          
    50          
190 8         39 %conf = (%conf, %$_);
191 8         22 $need_conf++;
192             } elsif (!ref $_ and $_ eq '{}') {
193             # TODO 0.15 remove together with auto-carp
194 0         0 $need_conf++; # allow for -MAssert::Refute={}
195             } elsif (!ref $_) {
196 33         96 push @exp, $_;
197             } else {
198 0         0 croak "Unexpected argument in Assert::Refute->import: ".ref $_;
199             };
200             };
201              
202 47 100       201 $class->configure( \%conf, scalar caller ) if $need_conf;
203 47         48932 $class->export_to_level(1, undef, @exp);
204             };
205              
206             my %known_callback = (
207             skip => '',
208             carp => sub {
209             my $report = shift;
210             warn $report->get_tap . _report_mess( $report );
211             },
212             croak => sub {
213             my $report = shift;
214             die $report->get_tap . _report_mess( $report );
215             },
216             );
217              
218             # TODO maybe public method in Report?
219             sub _report_mess {
220 6     6   15 my $report = shift;
221              
222 6 100       22 my $state = $report->is_passing ? "passed" : "failed";
223 6         24 my $title = $report->get_title;
224 6 100       27 my $str = $title ? "Contract '$title' $state" : "Contract $state";
225 6         1226 return Carp::shortmess($str);
226             };
227              
228             my %default_conf = (
229             on_fail => 'carp',
230             on_pass => 'skip',
231             );
232              
233             =head2 try_refute { ... }
234              
235             Check whether given contract BLOCK containing zero or more assertions passes.
236              
237             Contract will fail if any of the assertions fails,
238             a C is declared and not fulfilled,
239             or an exception is thrown.
240             Otherwise it is assumed to pass.
241              
242             The BLOCK must accept one argument, the contract execution report,
243             likely a L instance.
244              
245             More arguments MAY be added in the future.
246             Return value is ignored.
247              
248             A read-only report instance is returned by C instead.
249              
250             If C/C callbacks were specified during C or
251             using C, they will also be executed if appropriate.
252              
253             If C or C environment variable is set at compile time,
254             this block is replaced with a stub
255             which returns an unconditionally passing report.
256              
257             This is basically what one expects from a module in C namespace.
258              
259             =cut
260              
261             sub try_refute(&;@) { ## no critic # need prototype
262 18     18 1 337 my ( $block, @arg ) = @_;
263              
264             # Should a missing config even happen? Ok, play defensively...
265 18         55 my $conf = $CALLER_CONF{+caller};
266 18 50       50 if( !$conf ) {
267 0         0 $conf = __PACKAGE__->configure( {}, scalar caller );
268             };
269 18 100       49 return $conf->{skip_all} if exists $conf->{skip_all};
270              
271 17         73 my $report = $conf->{driver}->new;
272             eval {
273 17         56 $report->do_run($block);
274 16         53 1;
275 17 100       33 } || do {
276 1   33     13 $report->done_testing(
277             $@ || Carp::shortmess( 'Contract execution interrupted' ) );
278             };
279              
280             # perform whatever action is needed
281 17 100       53 my $callback = $conf->{ $report->is_passing ? "on_pass" : "on_fail" };
282 17 100       110 $callback->($report) if $callback;
283              
284 15         89 return $report;
285             };
286              
287             =head2 assert_refute { ... }
288              
289             Check whether given contract BLOCK containing zero or more assertions passes.
290              
291             Contract will fail if any of the assertions fail
292             or a C is declared and not fulfilled.
293             Otherwise it is assumed to pass.
294              
295             Unlike with try_refute, exceptions are just let through.
296              
297             The BLOCK must accept one argument, the contract execution report,
298             likely a L instance.
299              
300             More arguments MAY be added in the future.
301             Return value is ignored.
302              
303             A read-only report instance is returned by C instead.
304              
305             If C/C callbacks were specified during C or
306             using C, they will also be executed if appropriate.
307              
308             If C or C environment variable is set at compile time,
309             this block is replaced with a stub
310             which returns an unconditionally passing report.
311              
312             This is basically what one expects from a module in C namespace.
313              
314             B<[EXPERIMENTAL]>. Name and behavior MAY change in the future.
315             Should this function prove useful, it will become the successor
316             or C.
317              
318             =cut
319              
320             sub assert_refute(&;@) { ## no critic # need prototype
321 3     3 1 3700 unshift @_, '';
322              
323 3         14 goto &_real_assert;
324             };
325              
326             =head2 refute_invariant "name" => sub { ... }
327              
328             A named runtime assertion.
329              
330             Exactly as above, except that a title is added to the report object
331             which will be appended to the emitted warning/error (if any).
332              
333             Title can be queried via C method in report object.
334              
335             B<[EXPERIMENTAL]>. Name and meaning may change in the future.
336              
337             =cut
338              
339             sub refute_invariant(@) { ## no critic # need prototype
340 3     3 1 118 my ( $name, $block, @arg ) = @_;
341              
342 3 100 100     381 croak q{Usage: refute_invariant "name" => sub { ... }"}
343             unless $name and ref $block eq 'CODE';
344              
345 1         6 goto &_real_assert;
346             };
347              
348             sub _real_assert {
349 4     4   12 my ( $name, $block ) = @_;
350              
351             # Should a missing config even happen? Ok, play defensively...
352 4         16 my $conf = $CALLER_CONF{+caller};
353 4 100       16 if( !$conf ) {
354             # TODO add configure_global & use default configuration
355 2         18 $conf = __PACKAGE__->configure( { on_fail => 'carp' }, scalar caller );
356             };
357 4 50       18 return $conf->{skip_all} if exists $conf->{skip_all};
358              
359 4         29 my $report = $conf->{driver}->new->set_title($name)->do_run($block);
360              
361             # perform whatever action is needed
362 4 100       18 my $callback = $conf->{ $report->is_passing ? "on_pass" : "on_fail" };
363 4 50       21 $callback->($report) if $callback;
364              
365 4         130 return $report;
366             };
367              
368             =head2 refute_and_report { ... }
369              
370             Run a block of code with a fresh L object as argument.
371             Lock the report afterwards and return it.
372              
373             For instance,
374              
375             my $report = refute_and_report {
376             my $c = shift;
377             $c->is( $price * $amount, $total, "Numbers add up" );
378             $c->like( $header, qr/

/, "Header as expected" );

379             $c->can_ok( $duck, "quack" );
380             };
381              
382             Or alternatively one may resort to L-like DSL:
383              
384             use Assert::Refute qw(:all);
385             my $report = refute_and_report {
386             is $price * $amount, $total, "Numbers add up";
387             like $header, qr/

/, "Header as expected";

388             can_ok $duck, "quack";
389             };
390              
391             This method does not adhere C, apply callbacks, or handle expections.
392             It just executes the checks.
393             Not exported by default.
394              
395             B<[EXPERIMENTAL]>. Name and behavior MAY change in the future.
396             Should this function prove useful, it will become the successor
397             or C.
398              
399             =cut
400              
401             sub refute_and_report (&;@) { ## no critic # need prototype
402 27     27 1 1068 my ( $block, @arg ) = @_;
403              
404 27         180 return Assert::Refute::Report->new->do_run($block);
405             };
406              
407             =head2 contract { ... }
408              
409             Save a contract BLOCK for future use:
410              
411             my $contract = contract {
412             my ($foo, $bar) = @_;
413             # conditions here
414             };
415              
416             # much later
417             my $report = $contract->apply( $real_foo, $real_bar );
418             # Returns an Assert::Refute::Report with conditions applied
419              
420             This is similar to how C / C works in L.
421              
422             B<[DEPRECATED]> This function will disappear in v.0.20.
423              
424             Prior to advent of C, this call used to be the main entry point
425             to this module.
426             This is no more the case, and a simple subroutine containing assertions
427             would fit in most places where C is appropriate.
428              
429             Use L instead.
430              
431             =cut
432              
433             sub contract (&@) { ## no critic
434 1     1 1 228 carp "contract{ ... } is DEPRECATED, use Assert::Refute::Contract::contract instead";
435              
436 1         7 require Assert::Refute::Contract;
437 1         9 goto &Assert::Refute::Contract::contract;
438             };
439              
440             =head2 plan tests => $n
441              
442             Plan to run exactly C assertions within a contract block.
443             Plan is optional, contract blocks can run fine without a plan.
444              
445             A contract will fail unconditionally if plan is present and is not fulfilled.
446              
447             C may only be called before executing any assertions.
448             C dies if called outside a contract block.
449              
450             Not exported by default to avoid namespace pollution.
451              
452             =head2 plan skip_all => $reason
453              
454             B<[EXPERIMENTAL]>.
455             Like above, but plan is assumed to be zero and a reason for that is specified.
456              
457             Note that the contract block is not interrupted,
458             it's up to the user to call return.
459             This MAY change in the future.
460              
461             =cut
462              
463             sub plan(@) { ## no critic
464 3     3 1 21 current_contract->plan( @_ );
465             };
466              
467             =head2 refute( $reason, $message )
468              
469             Verify (or, rather, try hard to disprove)
470             an assertion in scope of the current contract.
471              
472             The test passes if the C<$reason> is I, i.e. an empty string, C<0>,
473             or C.
474             Otherwise the C<$reason> is assumed to be a description of what went wrong.
475              
476             You can think of it as C and C from L combined:
477              
478             ok !$reason, $message
479             or diag $reason;
480              
481             As a special case, a literal C<1> is considered to be a boolean value
482             and the assertions just fails, without further explanation.
483              
484             As another special case, an C<\@arrayref> reason
485             will be unfolded into multiple C lines, for instance
486              
487             refute [ $answer, "isn't", 42 ], "life, universe, and everything";
488              
489             will output 3 diag lines.
490              
491             Returns true for a passing assertion and false for a failing one.
492             Dies if no contract is being executed at the time.
493              
494             =cut
495              
496             sub refute ($$) { ## no critic
497 38     38 1 425 current_contract()->refute(@_);
498             };
499              
500             =head2 subcontract( "Message" => $contract, @arguments )
501              
502             "The specified contract passes, given the arguments" assertion.
503             This is similar to C in L.
504              
505             B<[NOTE]> that the message comes first, unlike in C
506             or other assertion types, and is I.
507              
508             A I may be an L object,
509             a plain subroutine with some assertions inside, or
510             an L instance from a previous contract run.
511              
512             A subroutine MUST accept an empty L object.
513              
514             For instance, one could apply a previously defined validation to a
515             structure member:
516              
517             my $valid_email = contract {
518             my $email = shift;
519             # ... define your checks here
520             };
521              
522             my $valid_user = contract {
523             my $user = shift;
524             is ref $user, 'HASH'
525             or die "Bail out - not a hash";
526             like $user->{id}, qr/^\d+$/, "id is a number";
527             subcontract "Check e-mail" => $valid_email, $user->{email};
528             };
529              
530             # much later
531             $valid_user->apply( $form_input );
532              
533             Or pass a definition as I to be applied to specific structure parts
534             (think I, like C or C).
535              
536             my $array_of_foo = contract {
537             my ($is_foo, $ref) = @_;
538              
539             foreach (@$ref) {
540             subcontract "Element check", $is_foo, $_;
541             };
542             };
543              
544             $array_of_foo->apply( $valid_user, \@user_list );
545              
546             =cut
547              
548             sub subcontract($$@) { ## no critic
549 7     7 1 130 current_contract()->subcontract( @_ );
550             };
551              
552             =head2 contract_is
553              
554             contract_is $report, $signature, "Message";
555              
556             Assert that a contract is fulfilled exactly to the specified extent.
557             See L for signature format.
558              
559             This may be useful for verifying assertions and contracts themselves.
560              
561             This is actually a clone of L.
562              
563             =cut
564              
565             =head2 current_contract
566              
567             Returns the L object being worked on.
568              
569             If L has been detected and no contract block
570             is executed explicitly, returns a L instance.
571             This allows to define assertions and run them uniformly under
572             both L and L control.
573              
574             Dies if no contract could be detected.
575              
576             It is actually a clone of L.
577              
578             =head1 STATIC METHODS
579              
580             Use these methods to configure Assert::Refute globally.
581              
582             =head2 configure
583              
584             use Assert::Refute \%options;
585             Assert::Refute->configure( \%options );
586             Assert::Refute->configure( \%options, "My::Package");
587              
588             Set per-caller configuration values for given package.
589             C is called implicitly by C
590             if hash parameter(s) are present.
591              
592             %options may include:
593              
594             =over
595              
596             =item * on_pass - callback to execute if tests pass (default: C)
597              
598             =item * on_fail - callback to execute if tests fail (default: C,
599             but not just C - see below).
600              
601             =item * driver - use that class instead of L
602             as contract report.
603              
604             =item * skip_all - reason for skipping ALL C blocks
605             in the affected package.
606             This defaults to C or C environment variable.
607              
608             B<[EXPERIMENTAL]>. Name and meaning MAY change in the future.
609              
610             =back
611              
612             The callbacks MUST be either
613             a C accepting L object,
614             or one of predefined strings:
615              
616             =over
617              
618             =item * skip - do nothing;
619              
620             =item * carp - warn the stringified report;
621              
622             =item * croak - die with stringified report as error message;
623              
624             =back
625              
626             Returns the resulting config (with default values added,etc).
627              
628             As of current, this method only affects C.
629              
630             =cut
631              
632             my %conf_known;
633             $conf_known{$_}++ for qw( on_pass on_fail driver skip_all );
634              
635             sub configure {
636 15     15 1 3070 my ($class, $given_conf, $caller) = @_;
637              
638 15 100       287 croak "Usage: $class->configure( \\%hash, \$target )"
639             unless ref $given_conf eq 'HASH';
640              
641 14         47 my @extra = grep { !$conf_known{$_} } keys %$given_conf;
  17         59  
642 14 50       46 croak "$class->configure: unknown parameters (@extra)"
643             if @extra;
644              
645             # configure whoever called us by default
646 14   100     55 $caller ||= scalar caller;
647              
648 14         64 my $conf = { %default_conf, %$given_conf };
649 14         62 $conf->{on_fail} = _coerce_cb($conf->{on_fail});
650 14         49 $conf->{on_pass} = _coerce_cb($conf->{on_pass});
651              
652             # Load driver
653 14 100       41 if( $conf->{driver} ) {
654 1         4 my $mod = "$conf->{driver}.pm";
655 1         4 $mod =~ s#::#/#g;
656 1         6 require $mod;
657             croak "$conf->{driver} is not Assert::Refute::Report, cannot use as driver"
658 1 50       145 unless $conf->{driver}->isa('Assert::Refute::Report');
659             } else {
660 13         28 $conf->{driver} = 'Assert::Refute::Report'; # this works for sure
661             };
662              
663 13 100 66     61 if ($NDEBUG and !$conf->{skip_all}) {
664 1         4 $conf->{skip_all} = "Assert::Refute turned off via NDEBUG=$NDEBUG";
665             };
666              
667 13 100       35 if ($conf->{skip_all}) {
668 1         5 my $default_report = $conf->{driver}->new;
669 1         4 $default_report->plan( skip_all => $conf->{skip_all} );
670 1         4 $default_report->done_testing;
671 1         2 $conf->{skip_all} = $default_report;
672             } else {
673 12         24 delete $conf->{skip_all};
674             };
675              
676 13         42 $CALLER_CONF{$caller} = $conf;
677             };
678              
679             =head2 configure_global( \%global_defaults )
680              
681             Set a global configuration to be used as default.
682              
683             This can be used e.g. to set an assertion failure callback throughout
684             a big project.
685              
686             =cut
687              
688             sub configure_global {
689 1     1 1 21 my ($class, $conf) = @_;
690              
691 1 50       5 croak "Usage: $class->configure_global( \\%hash )"
692             unless ref $conf eq 'HASH';
693              
694 1         5 my @extra = grep { !$conf_known{$_} } keys %$conf;
  2         5  
695 1 50       4 croak "$class->configure_global: unknown parameters (@extra)"
696             if @extra;
697              
698             $default_conf{$_} = $conf->{$_}
699 1         7 for keys %$conf;
700              
701 1         3 return $class; # oh really?
702             };
703              
704             =head2 get_config
705              
706             Returns configuration from above, initializing with defaults if needed.
707              
708             =cut
709              
710             sub get_config {
711 2     2 1 1196 my ($class, $caller) = @_;
712              
713 2   50     12 $caller ||= scalar caller;
714 2   66     8 return $CALLER_CONF{$caller} ||= $class->configure({}, $caller);
715             };
716              
717             sub _coerce_cb {
718 28     28   53 my $sub = shift;
719              
720 28 100       100 $sub = defined $known_callback{$sub} ? $known_callback{$sub} : $sub;
721 28 100       92 return unless $sub;
722 15 50 33     142 croak "Bad callback $sub"
723             unless ref $sub and UNIVERSAL::isa( $sub, 'CODE' );
724 15         38 return $sub;
725             };
726              
727             =head2 refute_these
728              
729             B<[DEPRECATED]> This used to be the old name of C.
730             It just dies now and will be removed completely in the future.
731              
732             =cut
733              
734             # TODO v.0.20 remove completely
735             # Keep it prototyped just in case some poor guy/gal forgot to change it
736             # or else they'll get a very confusing error message
737             sub refute_these (&;@) { ## no critic # need prototype
738 1     1 1 219 croak "refute_these { ... } is no more supported, use try_refute{ ... } instead";
739             }
740              
741             =head1 EXTENDING THE SUITE
742              
743             Although building wrappers around C call is easy enough,
744             specialized tool exists for doing that.
745              
746             Use L to define new I as
747             both prototyped exportable functions and their counterpart methods
748             in L.
749             These functions will perform absolutely the same
750             under control of C, C, and L:
751              
752             package My::Prime;
753              
754             use Assert::Refute::Build;
755             use parent qw(Exporter);
756              
757             build_refute is_prime => sub {
758             my $n = shift;
759             return "Not a natural number: $n" unless $n =~ /^\d+$/;
760             return "$n is not prime" if $n <= 1;
761             for (my $i = 2; $i*$i <= $n; $i++) {
762             return "$i divides $n" unless $n % $i;
763             };
764             return '';
765             }, args => 1, export => 1;
766              
767             Much later:
768              
769             use My::Prime;
770              
771             is_prime 101, "101 is prime";
772             is_prime 42, "Life is simple"; # not true
773              
774             Note that the implementation C only cares about its arguments,
775             and doesn't do anything except returning a value.
776             Suddenly it's a L!
777              
778             Yet the exact reason for $n not being a prime will be reflected in test output.
779              
780             One can also subclass L
781             to create new I, for instance,
782             to register failed/passed tests in a unit-testing framework of choice
783             or generate warnings/exceptions when conditions are not met.
784              
785             That's how L integration is done -
786             see L.
787              
788             =head1 PERFORMANCE
789              
790             Set C or C (takes precedence)
791             environment variable to true to replace I C blocks with a stub.
792             L was used as reference.
793              
794             If that's not enough, use L
795             or just define a DEBUG constant and
796             append an C statement to C blocks.
797              
798             That said, refute is reasonably fast.
799             Special care is taken to minimize the CPU usage by I contracts.
800              
801             The C file in this distribution is capable of
802             verifying around 4000 contracts of 100 statements each in just under a second
803             on my 4500 C laptop.
804             Your mileage may vary!
805              
806             =head1 WHY REFUTE
807              
808             Communicating a passing test normally requires 1 bit of information:
809             everything went as planned.
810             For failing test, however, as much information as possible is desired.
811              
812             Thus C stands for an inverted assertion.
813             If $condition is B, it is regarded as a B.
814             If it is B, however, it is considered to be the B
815             for a failing test.
816              
817             This is similar to how Unix programs set their exit code,
818             or to Perl's own C<$@> variable,
819             or to the I concept in science.
820              
821             A C is a result of multiple checks,
822             combined into a single refutation.
823             It will succeed silently, yet spell out details if it doesn't pass.
824              
825             These primitives can serve as building blocks for arbitrarily complex
826             assertions, tests, and validations.
827              
828             =head1 DEPRECATION WARNING
829              
830             The following modules used to be part of this package, but are separate
831             CPAN distributions now:
832              
833             =over
834              
835             =item * L
836              
837             =item * L
838              
839             =item * L
840              
841             =item * L
842              
843             =back
844              
845             =head1 SEE ALSO
846              
847             L, L, L
848              
849             =head1 BUGS
850              
851             This module is still under heavy development.
852             See C file in this distribution for an approximate roadmap.
853              
854             New features are marked as B<[EXPERIMENTAL]>.
855             Features that are to be removed will
856             stay B<[DEPRECATED]> (with a corresponding warning) for at least 5 releases,
857             unless such deprecation is extremely cumbersome.
858              
859             Test coverage is maintained at >90%, but who knows what lurks in the other 10%.
860              
861             See L
862             to browse old bugs or report new ones.
863              
864             =head1 SUPPORT
865              
866             You can find documentation for this module with the C command.
867              
868             perldoc Assert::Refute
869              
870             You can also look for information at:
871              
872             =over
873              
874             =item * First and foremost, use
875             L!
876              
877             =item * C: CPAN's request tracker (report bugs here)
878              
879             L
880              
881             =item * AnnoCPAN: Annotated CPAN documentation
882              
883             L
884              
885             =item * CPAN Ratings
886              
887             L
888              
889             =item * Search CPAN
890              
891             L
892              
893             =back
894              
895             =head1 ACKNOWLEDGEMENTS
896              
897             =over
898              
899             =item * Thanks to L
900             for C function name as well as a lot of feedback.
901              
902             =item * This L
903             by C inspired me to actually start working
904             on the first incarnation of this project.
905              
906             =item * Thanks to C for pass() and fail() calls.
907              
908             =back
909              
910             =head1 LICENSE AND COPYRIGHT
911              
912             Copyright 2017-2018 Konstantin S. Uvarin. C<< >>
913              
914             This program is free software; you can redistribute it and/or modify it
915             under the terms of the the Artistic License (2.0). You may obtain a
916             copy of the full license at:
917              
918             L
919              
920             Any use, modification, and distribution of the Standard or Modified
921             Versions is governed by this Artistic License. By using, modifying or
922             distributing the Package, you accept this license. Do not use, modify,
923             or distribute the Package, if you do not accept this license.
924              
925             If your Modified Version has been derived from a Modified Version made
926             by someone other than you, you are nevertheless required to ensure that
927             your Modified Version complies with the requirements of this license.
928              
929             This license does not grant you the right to use any trademark, service
930             mark, tradename, or logo of the Copyright Holder.
931              
932             This license includes the non-exclusive, worldwide, free-of-charge
933             patent license to make, have made, use, offer to sell, sell, import and
934             otherwise transfer the Package with respect to any patent claims
935             licensable by the Copyright Holder that are necessarily infringed by the
936             Package. If you institute patent litigation (including a cross-claim or
937             counterclaim) against any party alleging that the Package constitutes
938             direct or contributory patent infringement, then this Artistic License
939             to you shall terminate on the date that such litigation is filed.
940              
941             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
942             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
943             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
944             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
945             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
946             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
947             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
948             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
949              
950             =cut
951              
952             1; # End of Assert::Refute