Initial Commit
This commit is contained in:
182
database/perl/lib/Test/Builder/Module.pm
Normal file
182
database/perl/lib/Test/Builder/Module.pm
Normal file
@@ -0,0 +1,182 @@
|
||||
package Test::Builder::Module;
|
||||
|
||||
use strict;
|
||||
|
||||
use Test::Builder;
|
||||
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
|
||||
our $VERSION = '1.302183';
|
||||
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Test::Builder::Module - Base class for test modules
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
# Emulates Test::Simple
|
||||
package Your::Module;
|
||||
|
||||
my $CLASS = __PACKAGE__;
|
||||
|
||||
use parent 'Test::Builder::Module';
|
||||
@EXPORT = qw(ok);
|
||||
|
||||
sub ok ($;$) {
|
||||
my $tb = $CLASS->builder;
|
||||
return $tb->ok(@_);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a superclass for L<Test::Builder>-based modules. It provides a
|
||||
handful of common functionality and a method of getting at the underlying
|
||||
L<Test::Builder> object.
|
||||
|
||||
|
||||
=head2 Importing
|
||||
|
||||
Test::Builder::Module is a subclass of L<Exporter> which means your
|
||||
module is also a subclass of Exporter. @EXPORT, @EXPORT_OK, etc...
|
||||
all act normally.
|
||||
|
||||
A few methods are provided to do the C<< use Your::Module tests => 23 >> part
|
||||
for you.
|
||||
|
||||
=head3 import
|
||||
|
||||
Test::Builder::Module provides an C<import()> method which acts in the
|
||||
same basic way as L<Test::More>'s, setting the plan and controlling
|
||||
exporting of functions and variables. This allows your module to set
|
||||
the plan independent of L<Test::More>.
|
||||
|
||||
All arguments passed to C<import()> are passed onto
|
||||
C<< Your::Module->builder->plan() >> with the exception of
|
||||
C<< import =>[qw(things to import)] >>.
|
||||
|
||||
use Your::Module import => [qw(this that)], tests => 23;
|
||||
|
||||
says to import the functions C<this()> and C<that()> as well as set the plan
|
||||
to be 23 tests.
|
||||
|
||||
C<import()> also sets the C<exported_to()> attribute of your builder to be
|
||||
the caller of the C<import()> function.
|
||||
|
||||
Additional behaviors can be added to your C<import()> method by overriding
|
||||
C<import_extra()>.
|
||||
|
||||
=cut
|
||||
|
||||
sub import {
|
||||
my($class) = shift;
|
||||
|
||||
Test2::API::test2_load() unless Test2::API::test2_in_preload();
|
||||
|
||||
# Don't run all this when loading ourself.
|
||||
return 1 if $class eq 'Test::Builder::Module';
|
||||
|
||||
my $test = $class->builder;
|
||||
|
||||
my $caller = caller;
|
||||
|
||||
$test->exported_to($caller);
|
||||
|
||||
$class->import_extra( \@_ );
|
||||
my(@imports) = $class->_strip_imports( \@_ );
|
||||
|
||||
$test->plan(@_);
|
||||
|
||||
local $Exporter::ExportLevel = $Exporter::ExportLevel + 1;
|
||||
$class->Exporter::import(@imports);
|
||||
}
|
||||
|
||||
sub _strip_imports {
|
||||
my $class = shift;
|
||||
my $list = shift;
|
||||
|
||||
my @imports = ();
|
||||
my @other = ();
|
||||
my $idx = 0;
|
||||
while( $idx <= $#{$list} ) {
|
||||
my $item = $list->[$idx];
|
||||
|
||||
if( defined $item and $item eq 'import' ) {
|
||||
push @imports, @{ $list->[ $idx + 1 ] };
|
||||
$idx++;
|
||||
}
|
||||
else {
|
||||
push @other, $item;
|
||||
}
|
||||
|
||||
$idx++;
|
||||
}
|
||||
|
||||
@$list = @other;
|
||||
|
||||
return @imports;
|
||||
}
|
||||
|
||||
=head3 import_extra
|
||||
|
||||
Your::Module->import_extra(\@import_args);
|
||||
|
||||
C<import_extra()> is called by C<import()>. It provides an opportunity for you
|
||||
to add behaviors to your module based on its import list.
|
||||
|
||||
Any extra arguments which shouldn't be passed on to C<plan()> should be
|
||||
stripped off by this method.
|
||||
|
||||
See L<Test::More> for an example of its use.
|
||||
|
||||
B<NOTE> This mechanism is I<VERY ALPHA AND LIKELY TO CHANGE> as it
|
||||
feels like a bit of an ugly hack in its current form.
|
||||
|
||||
=cut
|
||||
|
||||
sub import_extra { }
|
||||
|
||||
=head2 Builder
|
||||
|
||||
Test::Builder::Module provides some methods of getting at the underlying
|
||||
Test::Builder object.
|
||||
|
||||
=head3 builder
|
||||
|
||||
my $builder = Your::Class->builder;
|
||||
|
||||
This method returns the L<Test::Builder> object associated with Your::Class.
|
||||
It is not a constructor so you can call it as often as you like.
|
||||
|
||||
This is the preferred way to get the L<Test::Builder> object. You should
|
||||
I<not> get it via C<< Test::Builder->new >> as was previously
|
||||
recommended.
|
||||
|
||||
The object returned by C<builder()> may change at runtime so you should
|
||||
call C<builder()> inside each function rather than store it in a global.
|
||||
|
||||
sub ok {
|
||||
my $builder = Your::Class->builder;
|
||||
|
||||
return $builder->ok(@_);
|
||||
}
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
sub builder {
|
||||
return Test::Builder->new;
|
||||
}
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<< Test2::Manual::Tooling::TestBuilder >> describes the improved
|
||||
options for writing testing modules provided by L<< Test2 >>.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
Reference in New Issue
Block a user