677 lines
22 KiB
Perl
677 lines
22 KiB
Perl
|
#!/usr/bin/perl
|
||
|
##############################################################################
|
||
|
|
||
|
=head1 NAME
|
||
|
|
||
|
LJ::Test::Assertions - Assertion-function library
|
||
|
|
||
|
=head1 SYNOPSIS
|
||
|
|
||
|
use LJ::Test::Assertions qw{:all};
|
||
|
|
||
|
=head1 REQUIRES
|
||
|
|
||
|
C<Carp>, C<Danga::Exceptions>, C<Data::Compare>, C<Data::Dumper>,
|
||
|
C<Scalar::Util>
|
||
|
|
||
|
=head1 DESCRIPTION
|
||
|
|
||
|
None yet.
|
||
|
|
||
|
=head1 EXPORTS
|
||
|
|
||
|
Nothing by default.
|
||
|
|
||
|
This module exports several useful assertion functions for the following tags:
|
||
|
|
||
|
=over 4
|
||
|
|
||
|
=item B<:assertions>
|
||
|
|
||
|
A collection of assertion functions for testing. You can define your own
|
||
|
assertion functions by implementing them in terms of L<assert/"Assertion
|
||
|
Functions">.
|
||
|
|
||
|
L<assert|/"Assertion Functions">, L<assert_not|/"Assertion Functions">,
|
||
|
L<assert_defined|/"Assertion Functions">, L<assert_undef|/"Assertion Functions">,
|
||
|
L<assert_no_exception|/"Assertion Functions">, L<assert_exception|/"Assertion
|
||
|
Functions">, L<assert_exception_type|/"Assertion Functions">,
|
||
|
L<assert_exception_matches|/"Assertion Functions">, L<assert_equals|/"Assertion
|
||
|
Functions">, L<assert_matches|/"Assertion Functions">, L<assert_ref|/"Assertion
|
||
|
Functions">, L<assert_not_ref|/"Assertion Functions">,
|
||
|
L<assert_instance_of|/"Assertion Functions">, L<assert_kind_of|/"Assertion
|
||
|
Functions">, L<fail|/"Assertion Functions">
|
||
|
|
||
|
=item B<:skip>
|
||
|
|
||
|
L<skip_one|/"Skip Functions">, L<skip_all|/"Skip Functions">
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head1 TO DO
|
||
|
|
||
|
=over 4
|
||
|
|
||
|
=item Skip Functions
|
||
|
|
||
|
The skip functions are functional, but the backend isn't set up to handle them
|
||
|
yet.
|
||
|
|
||
|
=item Test::Harness Integration
|
||
|
|
||
|
I ripped out the L<Test::Harness> code when I ported over the
|
||
|
L<Test::SimpleUnit> code for the sake of simplicity. I plan to move that over at
|
||
|
some point.
|
||
|
|
||
|
=item Docs
|
||
|
|
||
|
The docs for most of this stuff is still sketchy.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head1 AUTHOR
|
||
|
|
||
|
Michael Granger E<lt>ged@danga.comE<gt>
|
||
|
|
||
|
Copyright (c) 2004 Danga Interactive. All rights reserved.
|
||
|
|
||
|
This module is free software. You may use, modify, and/or redistribute this
|
||
|
software under the terms of the Perl Artistic License. (See
|
||
|
http://language.perl.com/misc/Artistic.html)
|
||
|
|
||
|
THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
|
||
|
INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND
|
||
|
FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
|
||
|
=cut
|
||
|
|
||
|
##############################################################################
|
||
|
package LJ::Test::Assertions;
|
||
|
use strict;
|
||
|
use warnings qw{all};
|
||
|
|
||
|
|
||
|
###############################################################################
|
||
|
### I N I T I A L I Z A T I O N
|
||
|
###############################################################################
|
||
|
BEGIN {
|
||
|
### Versioning stuff and custom includes
|
||
|
use vars qw{$VERSION $RCSID};
|
||
|
$VERSION = do { my @r = (q$Revision: 1.2 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r };
|
||
|
$RCSID = q$Id: Assertions.pm,v 1.2 2004/10/30 02:07:22 deveiant Exp $;
|
||
|
|
||
|
# Export functions
|
||
|
use base qw{Exporter};
|
||
|
use vars qw{@EXPORT @EXPORT_OK %EXPORT_TAGS};
|
||
|
|
||
|
@EXPORT = qw{};
|
||
|
%EXPORT_TAGS = (
|
||
|
assertions => [qw{
|
||
|
&assert
|
||
|
&assert_not
|
||
|
&assert_defined
|
||
|
&assert_undef
|
||
|
&assert_no_exception
|
||
|
&assert_exception
|
||
|
&assert_exception_type
|
||
|
&assert_exception_matches
|
||
|
&assert_equal
|
||
|
&assert_equals
|
||
|
&assert_matches
|
||
|
&assert_ref
|
||
|
&assert_not_ref
|
||
|
&assert_instance_of
|
||
|
&assert_kind_of
|
||
|
|
||
|
&fail
|
||
|
}],
|
||
|
|
||
|
skip => [qw{
|
||
|
&skip_one
|
||
|
&skip_all
|
||
|
}],
|
||
|
);
|
||
|
|
||
|
# Create an 'all' Exporter class which is the union of all the others and
|
||
|
# then add the symbols it contains to @EXPORT_OK
|
||
|
{
|
||
|
my %seen;
|
||
|
push @{$EXPORT_TAGS{all}},
|
||
|
grep {!$seen{$_}++} @{$EXPORT_TAGS{$_}} foreach keys %EXPORT_TAGS;
|
||
|
}
|
||
|
Exporter::export_ok_tags('all');
|
||
|
|
||
|
# Require modules
|
||
|
use Data::Compare qw{Compare};
|
||
|
use Scalar::Util qw{blessed dualvar};
|
||
|
use Data::Dumper qw{};
|
||
|
use Carp qw{croak confess};
|
||
|
|
||
|
# Observer pattern
|
||
|
use vars qw{@Observers};
|
||
|
@Observers = qw{};
|
||
|
}
|
||
|
|
||
|
|
||
|
#####################################################################
|
||
|
### A S S E R T I O N F A I L U R E C L A S S
|
||
|
#####################################################################
|
||
|
{
|
||
|
package LJ::Test::AssertionFailure;
|
||
|
use Danga::Exceptions qw{};
|
||
|
use Carp qw{croak confess};
|
||
|
use base qw{Danga::Exception};
|
||
|
|
||
|
our $ErrorType = "assertion failure";
|
||
|
|
||
|
### Overridden to unwrap frames from the stacktrace.
|
||
|
sub new {
|
||
|
my $proto = shift;
|
||
|
local $Danga::Exception::Depth = $Danga::Exception::Depth + 2;
|
||
|
return $proto->SUPER::new( @_ );
|
||
|
}
|
||
|
|
||
|
### Override the base class's error message to make sense as an exception
|
||
|
### failure.
|
||
|
sub error {
|
||
|
my $self = shift;
|
||
|
|
||
|
my ( $priorframe, $testframe );
|
||
|
my @frames = $self->stacktrace;
|
||
|
|
||
|
for ( my $i = 0; $i <= $#frames; $i++ ) {
|
||
|
next unless $frames[$i]->{package} eq 'LJ::Test::Result';
|
||
|
( $priorframe, $testframe ) = @frames[ $i-1, $i ];
|
||
|
last;
|
||
|
}
|
||
|
|
||
|
unless ( $priorframe ) {
|
||
|
( $priorframe, $testframe ) = @frames[ 0, 1 ];
|
||
|
}
|
||
|
|
||
|
return sprintf( "%s\n\tin %s (%s) line %d\n\t(%s).\n",
|
||
|
$self->message,
|
||
|
$testframe->{subroutine},
|
||
|
$priorframe->{filename},
|
||
|
$priorframe->{line},
|
||
|
scalar localtime($self->timestamp) );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#####################################################################
|
||
|
### F O R W A R D D E C L A R A T I O N S
|
||
|
#####################################################################
|
||
|
|
||
|
sub assert ($;$);
|
||
|
sub assert_not ($;$);
|
||
|
sub assert_defined ($;$);
|
||
|
sub assert_undef ($;$);
|
||
|
sub assert_no_exception (&;$);
|
||
|
sub assert_exception (&;$);
|
||
|
sub assert_exception_type (&$;$);
|
||
|
sub assert_exception_matches (&$;$);
|
||
|
sub assert_equals ($$;$);
|
||
|
sub assert_matches ($$;$);
|
||
|
sub assert_ref ($$;$);
|
||
|
sub assert_not_ref ($;$);
|
||
|
sub assert_instance_of ($$;$);
|
||
|
sub assert_kind_of ($$;$);
|
||
|
|
||
|
sub fail (;$);
|
||
|
|
||
|
sub skip_one (;$);
|
||
|
sub skip_all (;$);
|
||
|
|
||
|
|
||
|
|
||
|
#####################################################################
|
||
|
### O B S E R V E R F U N C T I O N S
|
||
|
#####################################################################
|
||
|
|
||
|
### METHOD: add_observer( $observer )
|
||
|
### Add the given object, package, or coderef (I<observer>) to the list of
|
||
|
### observers. When an assertion is called, a notification will be sent to the
|
||
|
### registrant. If the specified I<observer> is an object or a package, the
|
||
|
### C<update> method will be called on it. If the observer is a coderef, the
|
||
|
### coderef itself will be called.
|
||
|
sub add_observer {
|
||
|
shift if $_[0] eq __PACKAGE__; # Allow this to be called as a method, too.
|
||
|
my $observer = shift or return;
|
||
|
push @Observers, $observer;
|
||
|
}
|
||
|
|
||
|
|
||
|
### METHOD: remove_observer( $observer )
|
||
|
### Remove the given I<observer> from the list of observers.
|
||
|
sub remove_observer {
|
||
|
shift if $_[0] eq __PACKAGE__; # Allow calling as a method
|
||
|
my $observer = shift or return;
|
||
|
@Observers = grep { "$observer" ne "$_" } @Observers;
|
||
|
}
|
||
|
|
||
|
|
||
|
### METHOD: notify_observers( $type )
|
||
|
### Notify any registered observers that an assertion has been made. The
|
||
|
### I<arguments> will be passed to each observer.
|
||
|
sub notify_observers {
|
||
|
shift if $_[0] eq __PACKAGE__; # Allow calling as a method
|
||
|
|
||
|
foreach my $observer ( @Observers ) {
|
||
|
if ( ref $observer eq 'CODE' ) {
|
||
|
$observer->( __PACKAGE__, @_ );
|
||
|
}
|
||
|
|
||
|
else {
|
||
|
$observer->update( __PACKAGE__, @_ );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
### (PRIVATE) FUNCTION: makeMessage( $failureInfo, $format, @args )
|
||
|
### Do sprintf-style formatting on I<format> and I<args> and catenate it with
|
||
|
### the given I<failureInfo> if it's defined and not empty.
|
||
|
sub makeMessage {
|
||
|
my ( $failureInfo, $fmt, @rawargs ) = @_;
|
||
|
local $Data::Dumper::Terse = 1;
|
||
|
my @args = map {
|
||
|
ref $_
|
||
|
? Data::Dumper->Dumpxs([$_], ['_'])
|
||
|
: (defined $_ ? "$_" : "(undef)")
|
||
|
} @rawargs;
|
||
|
my $failureMessage = sprintf( $fmt, @args );
|
||
|
|
||
|
return $failureInfo
|
||
|
? "$failureInfo\n\t$failureMessage"
|
||
|
: $failureMessage;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#####################################################################
|
||
|
### A S S E R T I O N F U N C T I O N S
|
||
|
#####################################################################
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert( $value[, $failureInfo] )
|
||
|
### Die with a failure message if the specified I<value> is not true. If the
|
||
|
### optional I<failureInfo> is given, It will precede the failure message.
|
||
|
sub assert ($;$) {
|
||
|
my ( $assert, $message ) = @_;
|
||
|
|
||
|
__PACKAGE__->notify_observers( 'assert' );
|
||
|
$message ||= "Assertion failed: " . (defined $assert ? "'$assert'" : "(undef)");
|
||
|
throw LJ::Test::AssertionFailure $message unless $assert;
|
||
|
__PACKAGE__->notify_observers( 'success' );
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_not( $value[, $failureInfo] )
|
||
|
### Die with a failure message if the specified I<value> B<is> true. If the
|
||
|
### optional I<failureInfo> is given, it will precede the failure message.
|
||
|
sub assert_not ($;$) {
|
||
|
my ( $assert, $info ) = @_;
|
||
|
my $message = makeMessage( $info, "Expected a false value, got '%s'", $assert );
|
||
|
assert( !$assert, $message );
|
||
|
}
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_defined( $value[, $failureInfo] )
|
||
|
### Die with a failure message if the specified I<value> is undefined. If the
|
||
|
### optional I<failureInfo> is given, it will precede the failure message.
|
||
|
sub assert_defined ($;$) {
|
||
|
my ( $assert, $info ) = @_;
|
||
|
my $message = makeMessage( $info, "Expected a defined value, got: %s", $assert );
|
||
|
assert( defined($assert), $message );
|
||
|
}
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_undef( $value[, $failureInfo] )
|
||
|
### Die with a failure message if the specified I<value> is B<defined>. If the
|
||
|
### optional I<failureInfo> is given, it will precede the failure message.
|
||
|
sub assert_undef ($;$) {
|
||
|
my ( $assert, $info ) = @_;
|
||
|
my $message = makeMessage( $info, "Expected an undefined value, got %s",
|
||
|
$assert );
|
||
|
assert( !defined($assert), $message );
|
||
|
}
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_no_exception( \&coderef[, $failureInfo] )
|
||
|
### Evaluate the specified I<coderef>, and die with a failure message if it
|
||
|
### generates an exception. If the optional I<failureInfo> is given, it will
|
||
|
### precede the failure message.
|
||
|
sub assert_no_exception (&;$) {
|
||
|
my ( $code, $info ) = @_;
|
||
|
|
||
|
eval { $code->() };
|
||
|
( my $errmsg = $@ ) =~ s{ at .* line \d+\.?\s*$}{};
|
||
|
my $message = makeMessage( $info, "Exception raised when none expected:\n\t<$errmsg>" );
|
||
|
|
||
|
assert( ! $@, $message );
|
||
|
}
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_exception( \&coderef[, $failureInfo] )
|
||
|
### Evaluate the specified I<coderef>, and die with a failure message if it does
|
||
|
### not generate an exception. If the optional I<failureInfo> is given, it will
|
||
|
### precede the failure message.
|
||
|
sub assert_exception (&;$) {
|
||
|
my ( $code, $info ) = @_;
|
||
|
|
||
|
eval { $code->() };
|
||
|
assert( $@, makeMessage($info, "No exception raised.") );
|
||
|
}
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_exception_type( \&coderef, $type[, $failureInfo] )
|
||
|
### Evaluate the specified I<coderef>, and die with a failure message if it does
|
||
|
### not generate an exception which is an object blessed into the specified
|
||
|
### I<type> or one of its subclasses (ie., the exception must return true to
|
||
|
### C<$exception->isa($type)>. If the optional I<failureInfo> is given, it will
|
||
|
### precede the failure message.
|
||
|
sub assert_exception_type (&$;$) {
|
||
|
my ( $code, $type, $info ) = @_;
|
||
|
|
||
|
eval { $code->() };
|
||
|
assert $@, makeMessage($info, "Expected an exception of type '$type', but none was raised.");
|
||
|
|
||
|
my $message = makeMessage( $info, "Exception thrown, but was wrong type" );
|
||
|
assert_kind_of( $type, $@, $message );
|
||
|
}
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_exception_matches( \&code, $regex[, $failureInfo] )
|
||
|
### Evaluate the specified I<coderef>, and die with a failure message if it does
|
||
|
### not generate an exception which matches the specified I<regex>. If the
|
||
|
### optional I<failureInfo> is given, it will precede the failure message.
|
||
|
sub assert_exception_matches (&$;$) {
|
||
|
my ( $code, $regex, $info ) = @_;
|
||
|
|
||
|
eval { $code->() };
|
||
|
assert $@, makeMessage($info, "Expected an exception which matched <$regex>, but none was raised.");
|
||
|
my $err = "$@";
|
||
|
|
||
|
my $message = makeMessage( $info, "Exception thrown, but message didn't match" );
|
||
|
assert_matches( $regex, $err, $message );
|
||
|
}
|
||
|
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_equal( $wanted, $tested[, $failureInfo] )
|
||
|
### Die with a failure message if the specified I<wanted> value doesn't equal the
|
||
|
### specified I<tested> value. The comparison is done with L<Data::Compare>, so
|
||
|
### arbitrarily complex data structures may be compared, as long as they contain
|
||
|
### no C<GLOB>, C<CODE>, or C<REF> references. If the optional I<failureInfo> is
|
||
|
### given, it will precede the failure message.
|
||
|
sub assert_equal ($$;$) {
|
||
|
my ( $wanted, $tested, $info ) = @_;
|
||
|
|
||
|
my $message = makeMessage( $info, "Values not equal: wanted '%s', got '%s' instead",
|
||
|
$wanted, $tested );
|
||
|
assert( Compare($wanted, $tested), $message );
|
||
|
}
|
||
|
*assert_equals = *assert_equal;
|
||
|
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_matches( $wantedRegexp, $testedValue[, $failureInfo] )
|
||
|
### Die with a failure message if the specified I<testedValue> doesn't match the
|
||
|
### specified I<wantedRegExp>. If the optional I<failureInfo> is given, it will
|
||
|
### precede the failure message.
|
||
|
sub assert_matches ($$;$) {
|
||
|
my ( $wanted, $tested, $info ) = @_;
|
||
|
|
||
|
if ( ! blessed $wanted || ! $wanted->isa('Regexp') ) {
|
||
|
$wanted = qr{$wanted};
|
||
|
}
|
||
|
|
||
|
my $message = makeMessage( $info, "Tested value '%s' did not match wanted regex '%s'",
|
||
|
$tested, $wanted );
|
||
|
assert( ($tested =~ $wanted), $message );
|
||
|
}
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_ref( $wantedType, $testedValue[, $failureInfo] )
|
||
|
### Die with a failure message if the specified I<testedValue> is not of the
|
||
|
### specified I<wantedType>. The I<wantedType> can either be a ref-type like 'ARRAY'
|
||
|
### or 'GLOB' or a package name for testing object classes. If the optional
|
||
|
### I<failureInfo> is given, it will precede the failure message.
|
||
|
sub assert_ref ($$;$) {
|
||
|
my ( $wantedType, $testValue, $info ) = @_;
|
||
|
|
||
|
my $message = makeMessage( $info, "Expected a %s reference, got <%s>",
|
||
|
$wantedType, $testValue );
|
||
|
|
||
|
assert( ref $testValue &&
|
||
|
(ref $testValue eq $wantedType || UNIVERSAL::isa($wantedType, $testValue)),
|
||
|
$message );
|
||
|
}
|
||
|
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_not_ref( $testedValue[, $failureInfo] )
|
||
|
### Die with a failure message if the specified I<testedValue> is a reference of
|
||
|
### any kind. If the optional I<failureInfo> is given, it will precede the
|
||
|
### failure message.
|
||
|
sub assert_not_ref ($;$) {
|
||
|
my ( $testValue, $info ) = @_;
|
||
|
|
||
|
my $message = makeMessage( $info, "Expected a simple scalar, got <%s>", $testValue );
|
||
|
assert( !ref $testValue, $message );
|
||
|
}
|
||
|
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_instance_of( $wantedClass, $testedValue[, $failureInfo] )
|
||
|
### Die with a failure message if the specified I<testedValue> is not an instance
|
||
|
### of the specified I<wantedClass>. If the optional I<failureInfo> is given, it will
|
||
|
### precede the failure message.
|
||
|
sub assert_instance_of ($$;$) {
|
||
|
my ( $wantedClass, $testValue, $info ) = @_;
|
||
|
|
||
|
my $message = makeMessage( $info, "Expected an instance of '%s', got a non-object <%s>",
|
||
|
$wantedClass, $testValue );
|
||
|
assert( blessed $testValue, $message );
|
||
|
|
||
|
$message = makeMessage( $info, "Expected an instance of '%s'", $wantedClass );
|
||
|
assert_equals( $wantedClass, ref $testValue, $message );
|
||
|
}
|
||
|
|
||
|
|
||
|
### (ASSERTION) FUNCTION: assert_kind_of( $wantedClass, $testedValue[, $failureInfo] )
|
||
|
### Die with a failure message if the specified I<testedValue> is not an instance
|
||
|
### of the specified I<wantedClass> B<or> one of its derivatives. If the optional
|
||
|
### I<failureInfo> is given, it will precede the failure message.
|
||
|
sub assert_kind_of ($$;$) {
|
||
|
my ( $wantedClass, $testValue, $info ) = @_;
|
||
|
|
||
|
my $message = makeMessage( $info, "Expected an instance of '%s' or a subclass, got <%s>",
|
||
|
$wantedClass, $testValue );
|
||
|
assert( blessed $testValue, $message );
|
||
|
assert( $testValue->isa($wantedClass), $message );
|
||
|
}
|
||
|
|
||
|
|
||
|
### (ASSERTION) FUNCTION: fail( [$message] )
|
||
|
### Die with a failure message unconditionally. If the optional I<message> is
|
||
|
### not given, the failure message will be C<Failed (no reason given)>.
|
||
|
sub fail (;$) {
|
||
|
my $message = shift || "Failed (no reason given)";
|
||
|
__PACKAGE__->notify_observers( 'assert' );
|
||
|
throw LJ::Test::AssertionFailure $message;
|
||
|
}
|
||
|
|
||
|
|
||
|
### (SKIP) FUNCTION: skip_one( [$message] )
|
||
|
### Skip the rest of this test, optionally outputting a message as to why the
|
||
|
### rest of the test was skipped.
|
||
|
sub skip_one (;$) {
|
||
|
my $message = shift || '';
|
||
|
die bless \$message, 'SKIPONE';
|
||
|
}
|
||
|
|
||
|
|
||
|
### (SKIP) FUNCTION: skip_all( [$message] )
|
||
|
### Skip all the remaining tests, optionally outputting a message as to why the
|
||
|
### they were skipped.
|
||
|
sub skip_all (;$) {
|
||
|
my $message = shift || '';
|
||
|
die bless \$message, 'SKIPALL';
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
### Destructors
|
||
|
DESTROY {}
|
||
|
END {}
|
||
|
|
||
|
|
||
|
1;
|
||
|
|
||
|
|
||
|
### AUTOGENERATED DOCUMENTATION FOLLOWS
|
||
|
|
||
|
=head1 FUNCTIONS
|
||
|
|
||
|
=head2 Assertion Functions
|
||
|
|
||
|
=over 4
|
||
|
|
||
|
=item I<assert( $value[, $failureInfo] )>
|
||
|
|
||
|
Die with a failure message if the specified I<value> is not true. If the
|
||
|
optional I<failureInfo> is given, It will precede the failure message.
|
||
|
|
||
|
=item I<assert_defined( $value[, $failureInfo] )>
|
||
|
|
||
|
Die with a failure message if the specified I<value> is undefined. If the
|
||
|
optional I<failureInfo> is given, it will precede the failure message.
|
||
|
|
||
|
=item I<assert_equal( $wanted, $tested[, $failureInfo] )>
|
||
|
|
||
|
Die with a failure message if the specified I<wanted> value doesn't equal the
|
||
|
specified I<tested> value. The comparison is done with L<Data::Compare>, so
|
||
|
arbitrarily complex data structures may be compared, as long as they contain
|
||
|
no C<GLOB>, C<CODE>, or C<REF> references. If the optional I<failureInfo> is
|
||
|
given, it will precede the failure message.
|
||
|
|
||
|
=item I<assert_exception( \&coderef[, $failureInfo] )>
|
||
|
|
||
|
Evaluate the specified I<coderef>, and die with a failure message if it does
|
||
|
not generate an exception. If the optional I<failureInfo> is given, it will
|
||
|
precede the failure message.
|
||
|
|
||
|
=item I<assert_exception_matches( \&code, $regex[, $failureInfo] )>
|
||
|
|
||
|
Evaluate the specified I<coderef>, and die with a failure message if it does
|
||
|
not generate an exception which matches the specified I<regex>. If the
|
||
|
optional I<failureInfo> is given, it will precede the failure message.
|
||
|
|
||
|
=item I<assert_exception_type( \&coderef, $type[, $failureInfo] )>
|
||
|
|
||
|
Evaluate the specified I<coderef>, and die with a failure message if it does
|
||
|
not generate an exception which is an object blessed into the specified
|
||
|
I<type> or one of its subclasses (ie., the exception must return true to
|
||
|
C<$exception->isa($type)>. If the optional I<failureInfo> is given, it will
|
||
|
precede the failure message.
|
||
|
|
||
|
=item I<assert_instance_of( $wantedClass, $testedValue[, $failureInfo] )>
|
||
|
|
||
|
Die with a failure message if the specified I<testedValue> is not an instance
|
||
|
of the specified I<wantedClass>. If the optional I<failureInfo> is given, it will
|
||
|
precede the failure message.
|
||
|
|
||
|
=item I<assert_kind_of( $wantedClass, $testedValue[, $failureInfo] )>
|
||
|
|
||
|
Die with a failure message if the specified I<testedValue> is not an instance
|
||
|
of the specified I<wantedClass> B<or> one of its derivatives. If the optional
|
||
|
I<failureInfo> is given, it will precede the failure message.
|
||
|
|
||
|
=item I<assert_matches( $wantedRegexp, $testedValue[, $failureInfo] )>
|
||
|
|
||
|
Die with a failure message if the specified I<testedValue> doesn't match the
|
||
|
specified I<wantedRegExp>. If the optional I<failureInfo> is given, it will
|
||
|
precede the failure message.
|
||
|
|
||
|
=item I<assert_no_exception( \&coderef[, $failureInfo] )>
|
||
|
|
||
|
Evaluate the specified I<coderef>, and die with a failure message if it
|
||
|
generates an exception. If the optional I<failureInfo> is given, it will
|
||
|
precede the failure message.
|
||
|
|
||
|
=item I<assert_not( $value[, $failureInfo] )>
|
||
|
|
||
|
Die with a failure message if the specified I<value> B<is> true. If the
|
||
|
optional I<failureInfo> is given, it will precede the failure message.
|
||
|
|
||
|
=item I<assert_not_ref( $testedValue[, $failureInfo] )>
|
||
|
|
||
|
Die with a failure message if the specified I<testedValue> is a reference of
|
||
|
any kind. If the optional I<failureInfo> is given, it will precede the
|
||
|
failure message.
|
||
|
|
||
|
=item I<assert_ref( $wantedType, $testedValue[, $failureInfo] )>
|
||
|
|
||
|
Die with a failure message if the specified I<testedValue> is not of the
|
||
|
specified I<wantedType>. The I<wantedType> can either be a ref-type like 'ARRAY'
|
||
|
or 'GLOB' or a package name for testing object classes. If the optional
|
||
|
I<failureInfo> is given, it will precede the failure message.
|
||
|
|
||
|
=item I<assert_undef( $value[, $failureInfo] )>
|
||
|
|
||
|
Die with a failure message if the specified I<value> is B<defined>. If the
|
||
|
optional I<failureInfo> is given, it will precede the failure message.
|
||
|
|
||
|
=item I<fail( [$message] )>
|
||
|
|
||
|
Die with a failure message unconditionally. If the optional I<message> is
|
||
|
not given, the failure message will be C<Failed (no reason given)>.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head2 Private Functions
|
||
|
|
||
|
=over 4
|
||
|
|
||
|
=item I<makeMessage( $failureInfo, $format, @args )>
|
||
|
|
||
|
Do sprintf-style formatting on I<format> and I<args> and catenate it with
|
||
|
the given I<failureInfo> if it's defined and not empty.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head2 Skip Functions
|
||
|
|
||
|
=over 4
|
||
|
|
||
|
=item I<skip_all( [$message] )>
|
||
|
|
||
|
Skip all the remaining tests, optionally outputting a message as to why the
|
||
|
they were skipped.
|
||
|
|
||
|
=item I<skip_one( [$message] )>
|
||
|
|
||
|
Skip the rest of this test, optionally outputting a message as to why the
|
||
|
rest of the test was skipped.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head1 METHODS
|
||
|
|
||
|
=over 4
|
||
|
|
||
|
=item I<add_observer( $observer )>
|
||
|
|
||
|
Add the given object, package, or coderef (I<observer>) to the list of
|
||
|
observers. When an assertion is called, a notification will be sent to the
|
||
|
registrant. If the specified I<observer> is an object or a package, the
|
||
|
C<update> method will be called on it. If the observer is a coderef, the
|
||
|
coderef itself will be called.
|
||
|
|
||
|
=item I<notify_observers( $type )>
|
||
|
|
||
|
Notify any registered observers that an assertion has been made. The
|
||
|
I<arguments> will be passed to each observer.
|
||
|
|
||
|
=item I<remove_observer( $observer )>
|
||
|
|
||
|
Remove the given I<observer> from the list of observers.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=cut
|
||
|
|