⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 builder.pm

📁 SinFP是一种新的识别对方计算机操作系统类型的工具
💻 PM
📖 第 1 页 / 共 2 页
字号:
package Test::Builder;use 5.004;# $^C was only introduced in 5.005-ish.  We do this to prevent# use of uninitialized value warnings in older perls.$^C ||= 0;use strict;use vars qw($VERSION $CLASS);$VERSION = '0.17';$CLASS = __PACKAGE__;my $IsVMS = $^O eq 'VMS';# Make Test::Builder thread-safe for ithreads.BEGIN {    use Config;    if( $] >= 5.008 && $Config{useithreads} ) {        require threads;        require threads::shared;        threads::shared->import;    }    else {        *share = sub { 0 };        *lock  = sub { 0 };    }}use vars qw($Level);my($Test_Died) = 0;my($Have_Plan) = 0;my $Original_Pid = $$;my $Curr_Test = 0;      share($Curr_Test);my @Test_Results = ();  share(@Test_Results);my @Test_Details = ();  share(@Test_Details);=head1 NAMETest::Builder - Backend for building test libraries=head1 SYNOPSIS  package My::Test::Module;  use Test::Builder;  require Exporter;  @ISA = qw(Exporter);  @EXPORT = qw(ok);  my $Test = Test::Builder->new;  $Test->output('my_logfile');  sub import {      my($self) = shift;      my $pack = caller;      $Test->exported_to($pack);      $Test->plan(@_);      $self->export_to_level(1, $self, 'ok');  }  sub ok {      my($test, $name) = @_;      $Test->ok($test, $name);  }=head1 DESCRIPTIONTest::Simple and Test::More have proven to be popular testing modules,but they're not always flexible enough.  Test::Builder provides the abuilding block upon which to write your own test libraries I<which canwork together>.=head2 Construction=over 4=item B<new>  my $Test = Test::Builder->new;Returns a Test::Builder object representing the current state of thetest.Since you only run one test per program, there is B<one and only one>Test::Builder object.  No matter how many times you call new(), you'regetting the same object.  (This is called a singleton).=cutmy $Test;sub new {    my($class) = shift;    $Test ||= bless ['Move along, nothing to see here'], $class;    return $Test;}=back=head2 Setting up testsThese methods are for setting up tests and declaring how many thereare.  You usually only want to call one of these methods.=over 4=item B<exported_to>  my $pack = $Test->exported_to;  $Test->exported_to($pack);Tells Test::Builder what package you exported your functions to.This is important for getting TODO tests right.=cutmy $Exported_To;sub exported_to {    my($self, $pack) = @_;    if( defined $pack ) {        $Exported_To = $pack;    }    return $Exported_To;}=item B<plan>  $Test->plan('no_plan');  $Test->plan( skip_all => $reason );  $Test->plan( tests => $num_tests );A convenient way to set up your tests.  Call this and Test::Builderwill print the appropriate headers and take the appropriate actions.If you call plan(), don't call any of the other methods below.=cutsub plan {    my($self, $cmd, $arg) = @_;    return unless $cmd;    if( $Have_Plan ) {        die sprintf "You tried to plan twice!  Second plan at %s line %d\n",          ($self->caller)[1,2];    }    if( $cmd eq 'no_plan' ) {        $self->no_plan;    }    elsif( $cmd eq 'skip_all' ) {        return $self->skip_all($arg);    }    elsif( $cmd eq 'tests' ) {        if( $arg ) {            return $self->expected_tests($arg);        }        elsif( !defined $arg ) {            die "Got an undefined number of tests.  Looks like you tried to ".                "say how many tests you plan to run but made a mistake.\n";        }        elsif( !$arg ) {            die "You said to run 0 tests!  You've got to run something.\n";        }    }    else {        require Carp;        my @args = grep { defined } ($cmd, $arg);        Carp::croak("plan() doesn't understand @args");    }    return 1;}=item B<expected_tests>    my $max = $Test->expected_tests;    $Test->expected_tests($max);Gets/sets the # of tests we expect this test to run and prints outthe appropriate headers.=cutmy $Expected_Tests = 0;sub expected_tests {    my($self, $max) = @_;    if( defined $max ) {        $Expected_Tests = $max;        $Have_Plan      = 1;        $self->_print("1..$max\n") unless $self->no_header;    }    return $Expected_Tests;}=item B<no_plan>  $Test->no_plan;Declares that this test will run an indeterminate # of tests.=cutmy($No_Plan) = 0;sub no_plan {    $No_Plan    = 1;    $Have_Plan  = 1;}=item B<has_plan>  $plan = $Test->has_plan  Find out whether a plan has been defined. $plan is either C<undef> (no plan has been set), C<no_plan> (indeterminate # of tests) or an integer (the number of expected tests).=cutsub has_plan {	return($Expected_Tests) if $Expected_Tests;	return('no_plan') if $No_Plan;	return(undef);};=item B<skip_all>  $Test->skip_all;  $Test->skip_all($reason);Skips all the tests, using the given $reason.  Exits immediately with 0.=cutmy $Skip_All = 0;sub skip_all {    my($self, $reason) = @_;    my $out = "1..0";    $out .= " # Skip $reason" if $reason;    $out .= "\n";    $Skip_All = 1;    $self->_print($out) unless $self->no_header;    exit(0);}=back=head2 Running testsThese actually run the tests, analogous to the functions inTest::More.$name is always optional.=over 4=item B<ok>  $Test->ok($test, $name);Your basic test.  Pass if $test is true, fail if $test is false.  Justlike Test::Simple's ok().=cutsub ok {    my($self, $test, $name) = @_;    # $test might contain an object which we don't want to accidentally    # store, so we turn it into a boolean.    $test = $test ? 1 : 0;    unless( $Have_Plan ) {        require Carp;        Carp::croak("You tried to run a test without a plan!  Gotta have a plan.");    }    lock $Curr_Test;    $Curr_Test++;    $self->diag(<<ERR) if defined $name and $name =~ /^[\d\s]+$/;    You named your test '$name'.  You shouldn't use numbers for your test names.    Very confusing.ERR    my($pack, $file, $line) = $self->caller;    my $todo = $self->todo($pack);    my $out;    my $result = {};    share($result);    unless( $test ) {        $out .= "not ";        @$result{ 'ok', 'actual_ok' } = ( ( $todo ? 1 : 0 ), 0 );    }    else {        @$result{ 'ok', 'actual_ok' } = ( 1, $test );    }    $out .= "ok";    $out .= " $Curr_Test" if $self->use_numbers;    if( defined $name ) {        $name =~ s|#|\\#|g;     # # in a name can confuse Test::Harness.        $out   .= " - $name";        $result->{name} = $name;    }    else {        $result->{name} = '';    }    if( $todo ) {        my $what_todo = $todo;        $out   .= " # TODO $what_todo";        $result->{reason} = $what_todo;        $result->{type}   = 'todo';    }    else {        $result->{reason} = '';        $result->{type}   = '';    }    $Test_Results[$Curr_Test-1] = $result;    $out .= "\n";    $self->_print($out);    unless( $test ) {        my $msg = $todo ? "Failed (TODO)" : "Failed";        $self->diag("    $msg test ($file at line $line)\n");    }     return $test ? 1 : 0;}=item B<is_eq>  $Test->is_eq($got, $expected, $name);Like Test::More's is().  Checks if $got eq $expected.  This is thestring version.=item B<is_num>  $Test->is_num($got, $expected, $name);Like Test::More's is().  Checks if $got == $expected.  This is thenumeric version.=cutsub is_eq {    my($self, $got, $expect, $name) = @_;    local $Level = $Level + 1;    if( !defined $got || !defined $expect ) {        # undef only matches undef and nothing else        my $test = !defined $got && !defined $expect;        $self->ok($test, $name);        $self->_is_diag($got, 'eq', $expect) unless $test;        return $test;    }    return $self->cmp_ok($got, 'eq', $expect, $name);}sub is_num {    my($self, $got, $expect, $name) = @_;    local $Level = $Level + 1;    if( !defined $got || !defined $expect ) {        # undef only matches undef and nothing else        my $test = !defined $got && !defined $expect;        $self->ok($test, $name);        $self->_is_diag($got, '==', $expect) unless $test;        return $test;    }    return $self->cmp_ok($got, '==', $expect, $name);}sub _is_diag {    my($self, $got, $type, $expect) = @_;    foreach my $val (\$got, \$expect) {        if( defined $$val ) {            if( $type eq 'eq' ) {                # quote and force string context                $$val = "'$$val'"            }            else {                # force numeric context                $$val = $$val+0;            }        }        else {            $$val = 'undef';        }    }    return $self->diag(sprintf <<DIAGNOSTIC, $got, $expect);         got: %s    expected: %sDIAGNOSTIC}    =item B<isnt_eq>  $Test->isnt_eq($got, $dont_expect, $name);Like Test::More's isnt().  Checks if $got ne $dont_expect.  This isthe string version.=item B<isnt_num>  $Test->is_num($got, $dont_expect, $name);Like Test::More's isnt().  Checks if $got ne $dont_expect.  This isthe numeric version.=cutsub isnt_eq {    my($self, $got, $dont_expect, $name) = @_;    local $Level = $Level + 1;    if( !defined $got || !defined $dont_expect ) {        # undef only matches undef and nothing else        my $test = defined $got || defined $dont_expect;        $self->ok($test, $name);        $self->_cmp_diag('ne', $got, $dont_expect) unless $test;        return $test;    }    return $self->cmp_ok($got, 'ne', $dont_expect, $name);}sub isnt_num {    my($self, $got, $dont_expect, $name) = @_;    local $Level = $Level + 1;    if( !defined $got || !defined $dont_expect ) {        # undef only matches undef and nothing else        my $test = defined $got || defined $dont_expect;        $self->ok($test, $name);        $self->_cmp_diag('!=', $got, $dont_expect) unless $test;        return $test;    }    return $self->cmp_ok($got, '!=', $dont_expect, $name);}=item B<like>  $Test->like($this, qr/$regex/, $name);  $Test->like($this, '/$regex/', $name);Like Test::More's like().  Checks if $this matches the given $regex.You'll want to avoid qr// if you want your tests to work before 5.005.=item B<unlike>  $Test->unlike($this, qr/$regex/, $name);  $Test->unlike($this, '/$regex/', $name);Like Test::More's unlike().  Checks if $this B<does not match> thegiven $regex.=cutsub like {    my($self, $this, $regex, $name) = @_;    local $Level = $Level + 1;    $self->_regex_ok($this, $regex, '=~', $name);}sub unlike {    my($self, $this, $regex, $name) = @_;    local $Level = $Level + 1;    $self->_regex_ok($this, $regex, '!~', $name);}=item B<maybe_regex>  $Test->maybe_regex(qr/$regex/);  $Test->maybe_regex('/$regex/');Convenience method for building testing functions that take regularexpressions as arguments, but need to work before perl 5.005.Takes a quoted regular expression produced by qr//, or a stringrepresenting a regular expression.Returns a Perl value which may be used instead of the correspondingregular expression, or undef if it's argument is not recognised.For example, a version of like(), sans the useful diagnostic messages,could be written as:  sub laconic_like {      my ($self, $this, $regex, $name) = @_;      my $usable_regex = $self->maybe_regex($regex);      die "expecting regex, found '$regex'\n"          unless $usable_regex;      $self->ok($this =~ m/$usable_regex/, $name);  }=cutsub maybe_regex {	my ($self, $regex) = @_;    my $usable_regex = undef;    if( ref $regex eq 'Regexp' ) {        $usable_regex = $regex;    }    # Check if it looks like '/foo/'    elsif( my($re, $opts) = $regex =~ m{^ /(.*)/ (\w*) $ }sx ) {        $usable_regex = length $opts ? "(?$opts)$re" : $re;    };    return($usable_regex)};sub _regex_ok {    my($self, $this, $regex, $cmp, $name) = @_;    local $Level = $Level + 1;    my $ok = 0;    my $usable_regex = $self->maybe_regex($regex);    unless (defined $usable_regex) {        $ok = $self->ok( 0, $name );        $self->diag("    '$regex' doesn't look much like a regex to me.");        return $ok;    }    {        local $^W = 0;        my $test = $this =~ /$usable_regex/ ? 1 : 0;        $test = !$test if $cmp eq '!~';        $ok = $self->ok( $test, $name );    }    unless( $ok ) {        $this = defined $this ? "'$this'" : 'undef';        my $match = $cmp eq '=~' ? "doesn't match" : "matches";        $self->diag(sprintf <<DIAGNOSTIC, $this, $match, $regex);                  %s    %13s '%s'DIAGNOSTIC    }    return $ok;}=item B<cmp_ok>  $Test->cmp_ok($this, $type, $that, $name);Works just like Test::More's cmp_ok().    $Test->cmp_ok($big_num, '!=', $other_big_num);=cutsub cmp_ok {    my($self, $got, $type, $expect, $name) = @_;    my $test;    {        local $^W = 0;        local($@,$!);   # don't interfere with $@                        # eval() sometimes resets $!        $test = eval "\$got $type \$expect";    }    local $Level = $Level + 1;    my $ok = $self->ok($test, $name);    unless( $ok ) {        if( $type =~ /^(eq|==)$/ ) {            $self->_is_diag($got, $type, $expect);        }        else {            $self->_cmp_diag($got, $type, $expect);        }    }    return $ok;}sub _cmp_diag {    my($self, $got, $type, $expect) = @_;        $got    = defined $got    ? "'$got'"    : 'undef';    $expect = defined $expect ? "'$expect'" : 'undef';    return $self->diag(sprintf <<DIAGNOSTIC, $got, $type, $expect);    %s        %s    %sDIAGNOSTIC}=item B<BAILOUT>    $Test->BAILOUT($reason);Indicates to the Test::Harness that things are going so badly alltesting should terminate.  This includes running any additional testscripts.It will exit with 255.=cutsub BAILOUT {    my($self, $reason) = @_;    $self->_print("Bail out!  $reason");    exit 255;}=item B<skip>    $Test->skip;    $Test->skip($why);Skips the current test, reporting $why.=cutsub skip {    my($self, $why) = @_;    $why ||= '';    unless( $Have_Plan ) {        require Carp;        Carp::croak("You tried to run tests without a plan!  Gotta have a plan.");    }    lock($Curr_Test);    $Curr_Test++;    my %result;    share(%result);    %result = (        'ok'      => 1,        actual_ok => 1,        name      => '',        type      => 'skip',        reason    => $why,    );    $Test_Results[$Curr_Test-1] = \%result;    my $out = "ok";    $out   .= " $Curr_Test" if $self->use_numbers;    $out   .= " # skip $why\n";    $Test->_print($out);    return 1;}=item B<todo_skip>  $Test->todo_skip;  $Test->todo_skip($why);Like skip(), only it will declare the test as failing and TODO.  Similarto    print "not ok $tnum # TODO $why\n";=cutsub todo_skip {    my($self, $why) = @_;    $why ||= '';    unless( $Have_Plan ) {        require Carp;        Carp::croak("You tried to run tests without a plan!  Gotta have a plan.");    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -