Test-Unit-Lite
view release on metacpan or search on metacpan
lib/Test/Unit/Lite.pm view on Meta::CPAN
use warnings;
our $VERSION = '0.1202';
use Carp ();
use File::Spec ();
use File::Basename ();
use File::Copy ();
use File::Path ();
use Symbol ();
# Can't use Exporter 'import'. Compatibility with Perl 5.6
use Exporter ();
BEGIN { *import = \&Exporter::import };
our @EXPORT = qw{ bundle all_tests };
# Copy this module to inc subdirectory of the source distribution
sub bundle {
-f 'Makefile.PL' or -f 'Build.PL'
or die "Cannot find Makefile.PL or Build.PL in current directory\n";
my $src = __FILE__;
my $dst = "inc/Test/Unit/Lite.pm";
my @src = split m{/}, $src;
my @dst = split m{/}, $dst;
my $srcfile = File::Spec->catfile(@src);
my $dstfile = File::Spec->catfile(@dst);
die "Cannot bundle to itself: $srcfile\n" if $srcfile eq $dstfile;
print "Copying $srcfile -> $dstfile\n";
my $dstdir = File::Basename::dirname($dstfile);
-d $dstdir or File::Path::mkpath([$dstdir], 0, oct(777) & ~umask);
File::Copy::cp($srcfile, $dstfile) or die "Cannot copy $srcfile to $dstfile: $!\n";
}
sub all_tests {
Test::Unit::TestRunner->new->start('Test::Unit::Lite::AllTests');
}
{
package Test::Unit::TestCase;
use Carp ();
our $VERSION = $Test::Unit::Lite::VERSION;
our %Seen_Refs = ();
our @Data_Stack;
my $DNE = bless [], 'Does::Not::Exist';
sub new {
my ($class) = @_;
$class = ref $class if ref $class;
my $self = {};
return bless $self => $class;
}
sub set_up { }
sub tear_down { }
sub list_tests {
my ($self) = @_;
my $class = ref $self || $self;
my @tests;
my %seen_isa;
my $list_base_tests;
$list_base_tests = sub {
my ($class) = @_;
foreach my $isa (@{ *{ Symbol::qualify_to_ref("${class}::ISA") } }) {
next unless $isa->isa(__PACKAGE__);
$list_base_tests->($isa) unless $seen_isa{$isa};
$seen_isa{$isa} = 1;
push @tests, grep { /^test_/ } keys %{ *{ Symbol::qualify_to_ref("${class}::") } };
};
};
$list_base_tests->($class);
my %uniq_tests = map { $_ => 1 } @tests;
@tests = sort keys %uniq_tests;
return wantarray ? @tests : [ @tests ];
}
sub __croak {
my ($default_message, $custom_message) = @_;
$default_message = '' unless defined $default_message;
$custom_message = '' unless defined $custom_message;
my $n = 1;
my ($file, $line) = (caller($n++))[1,2];
my $caller;
$n++ while (defined( $caller = caller($n) ) and not eval { $caller->isa('Test::Unit::TestSuite') });
my $sub = (caller($n))[3] || '::';
$sub =~ /^(.*)::([^:]*)$/;
my ($test, $unit) = ($1, $2);
my $message = "$file:$line - $test($unit)\n$default_message\n$custom_message";
chomp $message;
no warnings 'once';
local $Carp::Internal{'Test::Unit::TestCase'} = 1;
Carp::confess("$message\n");
}
sub fail {
my ($self, $msg) = @_;
$msg = '' unless defined $msg;
__croak $msg;
}
lib/Test/Unit/Lite.pm view on Meta::CPAN
return $ok;
}
sub _format_stack {
my ($self, @Stack) = @_;
my $var = '$FOO';
my $did_arrow = 0;
foreach my $entry (@Stack) {
my $type = $entry->{type} || '';
my $idx = $entry->{'idx'};
if( $type eq 'HASH' ) {
$var .= "->" unless $did_arrow++;
$var .= "{$idx}";
}
elsif( $type eq 'ARRAY' ) {
$var .= "->" unless $did_arrow++;
$var .= "[$idx]";
}
elsif( $type eq 'REF' ) {
$var = "\${$var}";
}
}
my @vals = @{$Stack[-1]{vals}}[0,1];
my @vars = ();
($vars[0] = $var) =~ s/\$FOO/ \$a/;
($vars[1] = $var) =~ s/\$FOO/ \$b/;
my $out = "Structures begin differing at:\n";
foreach my $idx (0..$#vals) {
my $val = $vals[$idx];
$vals[$idx] = !defined $val ? 'undef' :
$val eq $DNE ? 'Does not exist'
: "'$val'";
}
$out .= "$vars[0] = $vals[0]\n";
$out .= "$vars[1] = $vals[1]";
return $out;
}
BEGIN { $INC{'Test/Unit/TestCase.pm'} = __FILE__; }
}
{
package Test::Unit::Result;
our $VERSION = $Test::Unit::Lite::VERSION;
sub new {
my ($class) = @_;
my $self = {
'messages' => [],
'errors' => 0,
'failures' => 0,
'passes' => 0,
};
return bless $self => $class;
}
sub messages {
my ($self) = @_;
return $self->{messages};
}
sub errors {
my ($self) = @_;
return $self->{errors};
}
sub failures {
my ($self) = @_;
return $self->{failures};
}
sub passes {
my ($self) = @_;
return $self->{passes};
}
sub add_error {
my ($self, $test, $message, $runner) = @_;
$self->{errors}++;
my $result = {test => $test, type => 'ERROR', message => $message};
push @{$self->messages}, $result;
$runner->print_error($result) if defined $runner;
}
sub add_failure {
my ($self, $test, $message, $runner) = @_;
$self->{failures}++;
my $result = {test => $test, type => 'FAILURE', message => $message};
push @{$self->messages}, $result;
$runner->print_failure($result) if defined $runner;
}
sub add_pass {
my ($self, $test, $message, $runner) = @_;
$self->{passes}++;
my $result = {test => $test, type => 'PASS', message => $message};
push @{$self->messages}, $result;
$runner->print_pass($result) if defined $runner;
}
BEGIN { $INC{'Test/Unit/Result.pm'} = __FILE__; }
}
{
package Test::Unit::TestSuite;
our $VERSION = $Test::Unit::Lite::VERSION;
sub empty_new {
my ($class, $name) = @_;
my $self = {
'name' => defined $name ? $name : 'Test suite',
'units' => [],
};
return bless $self => $class;
}
sub new {
my ($class, $test) = @_;
my $self = {
'name' => 'Test suite',
'units' => [],
};
if (defined $test and not ref $test) {
# untaint $test
$test =~ /([A-Za-z0-9:-]*)/;
$test = $1;
eval "use $test;";
die if $@;
}
elsif (not defined $test) {
$test = $class;
}
if (defined $test and $test->isa('Test::Unit::TestSuite')) {
$class = ref $test ? ref $test : $test;
$self->{name} = $test->name if ref $test;
$self->{units} = $test->units if ref $test;
}
elsif (defined $test and $test->isa('Test::Unit::TestCase')) {
$class = ref $test ? ref $test : $test;
$self->{units} = [ $test ];
}
else {
require Carp;
Carp::croak(sprintf("usage: %s->new([CLASSNAME | TEST])\n", __PACKAGE__));
}
return bless $self => $class;
}
sub name {
return $_[0]->{name};
}
sub units {
return $_[0]->{units};
}
sub add_test {
my ($self, $unit) = @_;
if (not ref $unit) {
# untaint $unit
$unit =~ /([A-Za-z0-9:-]*)/;
$unit = $1;
eval "use $unit;";
die if $@;
return unless $unit->isa('Test::Unit::TestCase');
}
return push @{ $self->{units} }, ref $unit ? $unit : $unit->new;
}
sub count_test_cases {
my ($self) = @_;
my $plan = 0;
foreach my $unit (@{ $self->units }) {
$plan += scalar @{ $unit->list_tests };
}
return $plan;
}
sub run {
my ($self, $result, $runner) = @_;
die "Undefined result object" unless defined $result;
foreach my $unit (@{ $self->units }) {
foreach my $test (@{ $unit->list_tests }) {
my $unit_test = (ref $unit ? ref $unit : $unit) . '::' . $test;
my $add_what;
my $e = '';
eval {
$unit->set_up;
};
if ($@) {
$e = "$@";
$add_what = 'add_error';
}
else {
eval {
$unit->$test;
};
if ($@) {
$e = "$@";
$add_what = 'add_failure';
}
else {
$add_what = 'add_pass';
};
};
eval {
$unit->tear_down;
};
if ($@) {
$e .= "$@";
$add_what = 'add_error';
};
$result->$add_what($unit_test, $e, $runner);
}
}
return;
}
BEGIN { $INC{'Test/Unit/TestSuite.pm'} = __FILE__; }
}
{
package Test::Unit::TestRunner;
our $VERSION = $Test::Unit::Lite::VERSION;
sub new {
my ($class, $fh_out, $fh_err) = @_;
$fh_out = \*STDOUT unless defined $fh_out;
$fh_err = \*STDERR unless defined $fh_err;
_autoflush($fh_out);
_autoflush($fh_err);
my $self = {
'suite' => undef,
'fh_out' => $fh_out,
'fh_err' => $fh_err,
};
return bless $self => $class;
}
sub fh_out {
my ($self) = @_;
return $self->{fh_out};
}
sub fh_err {
my ($self) = @_;
return $self->{fh_err};
}
sub result {
my ($self) = @_;
return $self->{result};
}
sub _autoflush {
my ($fh) = @_;
my $old_fh = select $fh;
$| = 1;
select $old_fh;
}
sub suite {
my ($self) = @_;
return $self->{suite};
}
sub print_header {
}
sub print_error {
my ($self, $result) = @_;
print { $self->fh_out } "E";
}
sub print_failure {
my ($self, $result) = @_;
print { $self->fh_out } "F";
}
sub print_pass {
my ($self, $result) = @_;
print { $self->fh_out } ".";
}
sub print_footer {
my ($self, $result) = @_;
printf { $self->fh_out } "\nTests run: %d", $self->suite->count_test_cases;
if ($result->errors) {
printf { $self->fh_out } ", Errors: %d", $result->errors;
}
if ($result->failures) {
printf { $self->fh_out } ", Failures: %d", $result->failures;
}
print { $self->fh_out } "\n";
if ($result->errors) {
print { $self->fh_out } "\nERRORS!!!\n\n";
foreach my $message (@{ $result->messages }) {
( run in 0.318 second using v1.01-cache-2.11-cpan-eab888a1d7d )