Assert-Conditional
view release on metacpan or search on metacpan
lib/Assert/Conditional.pm view on Meta::CPAN
#!/usr/bin/env perl
# ^^^^^^ !!!!!! ^^^^^^^
# Yes, this module really is supposed to have a #!
# line and be an executable script. See the end of the file
# for why!
package Assert::Conditional;
use v5.12;
use utf8;
use strict;
use warnings;
use version 0.77;
our $VERSION = version->declare("0.010");
use parent "Exporter::ConditionalSubs"; # inherits from Exporter
use namespace::autoclean;
use Attribute::Handlers;
use Assert::Conditional::Utils ":all";
use Carp qw(carp croak cluck confess);
use POSIX ":sys_wait_h";
use Scalar::Util qw{
blessed
looks_like_number
openhandle
refaddr
reftype
};
use Unicode::Normalize qw{
NFC checkNFC
NFD checkNFD
NFKC checkNFKC
NFKD checkNFKD
};
# But these are private internal functions that we
# choose not to expose even if fully qualified,
# and so declaring them here in front of the
# imminent namespace::clean will make sure of that.
sub _coredump_message ( ;$ ) ;
sub _get_invocant_type ( $ ) ;
sub _promote_to_arrayref ( $ ) ;
sub _promote_to_hashref ( $ ) ;
sub _promote_to_typeref ( $$ ) ;
sub _run_code_test ( $$ ) ;
sub _signum_message ( $ ) ;
sub _WIFCORED ( ;$ ) ;
# Need to be able to measure coverage with Devel::Cover
# of stuff we would normally get rid of.
use if !$ENV{HARNESS_ACTIVE}, "namespace::clean";
#######################################################################
# First declare our Exporter vars:
our(@EXPORT, @EXPORT_OK, %EXPORT_TAGS);
# Then thanks to this little guy....
sub Assert;
# Now those have by now all been fully populated *during compilation*,
# so it only remains to re-collate them into pleasant alphabetic order:
@$_ = uca_sort @$_ for \@EXPORT_OK, values %EXPORT_TAGS;
sub assert_ainta ( $@ ) ;
sub assert_alnum ( $ ) ;
sub assert_alphabetic ( $ ) ;
sub assert_anyref ( $ ) ;
sub assert_argc ( ;$ ) ;
sub assert_argc_max ( $ ) ;
sub assert_argc_min ( $ ) ;
sub assert_argc_minmax ( $$ ) ;
sub assert_array_length ( \@ ;$ ) ;
lib/Assert/Conditional.pm view on Meta::CPAN
my($wstat) = @_ ? $_[0] : $?;
my $signo = WTERMSIG($wstat);
my $sigmsg = _signum_message($signo);
_WIFCORED($wstat) || botch "exit value $wstat indicates signal $sigmsg but no core dump";
}
sub assert_no_coredump(;$)
:Assert( qw[process] )
{
my($wstat) = @_ ? $_[0] : $?;
my $cored = $wstat & 128; # not standard; too hard to fish from real sys/wait.h
return unless _WIFCORED($wstat);
return unless $cored;
my $signo = WTERMSIG($wstat);
my $sigmsg = _signum_message($signo);
botch "exit value $wstat shows process died of a $sigmsg and dumped core";
}
sub assert_exited(;$)
:Assert( qw[process] )
{
&assert_legal_exit_status;
my($wstat) = @_ ? $_[0] : $?;
return if WIFEXITED($wstat);
&assert_signalled;
my $signo = WTERMSIG($wstat);
my $sigmsg = _signum_message($signo);
my $cored = _coredump_message($wstat);
botch "exit value $wstat shows process did not exit but rather died of $sigmsg$cored";
}
sub assert_happy_exit(;$)
:Assert( qw[process] )
{
&assert_exited;
my($wstat) = @_ ? $_[0] : $?;
my $exit = WEXITSTATUS($wstat);
$exit == 0 || botch "exit status $exit is not a happy exit";
}
sub assert_sad_exit(;$)
:Assert( qw[process] )
{
&assert_exited;
my($wstat) = @_ ? $_[0] : $?;
my $exit = WEXITSTATUS($wstat);
$exit != 0 || botch "exit status 0 is an unexpectedly happy exit";
}
# If you actually *execute*(!) this module as though it were a perl
# script rather than merely require or compile it, it dumps out its
# export table like the pmexp tool from the pmtools distribution does.
# If moreover the ASSERT_CONDITIONAL_BUILD_POD envariable is true, then
# this actually generates pod you can use directly. This is used by the
# etc/generate-exporter-pod script from the source directory; this
# script is not installed, and is just a helper.
exit !dump_exports(@ARGV) unless his_is_require(-1);
# This can't execute at the "normal" time or else
# namespace::autoclean's call Sub::Identify freaks:
UNITCHECK { close(DATA) if defined fileno(DATA) }
1;
# This has to be __DATA__ not __END__ for the self-executing
# trick to work right.
__DATA__
=encoding utf8
=head1 NAME
Assert::Conditional - conditionally-compiled code assertions
=head1 SYNOPSIS
# use them all unconditionally
use Assert::Conditional qw(:all -if 1);
# Use them based on some external conditional available
# at compile time.
use Assert::Conditional qw(:all)
=> -if => ( $ENV{DEBUG} && ! $ENV{NDEBUG} );
# Use them based on some external conditional available
# at compile time.
use Assert::Conditional qw(:all)
=> -unless => $ENV{RUNTIME} eq "production";
# Method that should be called in list context with two array refs
# as arguments, and which should have both a "cross_product" and
# a "cross_tees" method available to it.
sub some_method {
assert_list_context();
assert_object_method();
assert_argc(3);
my($self, $left, $right) = @_;
assert_arrayref($left);
assert_arrayref($right);
assert_can($self, "cross_product", "cross_tees");
...
assert_happy_code { $i > $j };
...
}
=head1 DESCRIPTION
C programmers have always had F<assert.h> to conditionally compile
assertions into their programs, but options available for Perl programmers
are not so convenient.
Several assertion modules related to assertions exist on CPAN, but none
( run in 1.427 second using v1.01-cache-2.11-cpan-39bf76dae61 )