📄 builder.pm
字号:
$self->ok($test, $name); $self->_cmp_diag($got, 'ne', $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<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);=cutmy %numeric_cmps = map { ($_, 1) } ("<", "<=", ">", ">=", "==", "!=", "<=>");sub cmp_ok { my($self, $got, $type, $expect, $name) = @_; # Treat overloaded objects as numbers if we're asked to do a # numeric comparison. my $unoverload = $numeric_cmps{$type} ? '_unoverload_num' : '_unoverload_str'; $self->$unoverload(\$got, \$expect); my $test; { local($@,$!,$SIG{__DIE__}); # isolate eval my $code = $self->_caller_context; # Yes, it has to look like this or 5.4.5 won't see the #line directive. # Don't ask me, man, I just work here. $test = eval "$code" . "\$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}sub _caller_context { my $self = shift; my($pack, $file, $line) = $self->caller(1); my $code = ''; $code .= "#line $line $file\n" if defined $file and defined $line; return $code;}=back=head2 Other Testing MethodsThese are methods which are used in the course of writing a test but are not themselves tests.=over 4=item B<BAIL_OUT> $Test->BAIL_OUT($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 BAIL_OUT { my($self, $reason) = @_; $self->{Bailed_Out} = 1; $self->_print("Bail out! $reason"); exit 255;}=for deprecatedBAIL_OUT() used to be BAILOUT()=cut*BAILOUT = \&BAIL_OUT;=item B<skip> $Test->skip; $Test->skip($why);Skips the current test, reporting $why.=cutsub skip { my($self, $why) = @_; $why ||= ''; $self->_unoverload_str(\$why); $self->_plan_check; lock($self->{Curr_Test}); $self->{Curr_Test}++; $self->{Test_Results}[$self->{Curr_Test}-1] = &share({ 'ok' => 1, actual_ok => 1, name => '', type => 'skip', reason => $why, }); my $out = "ok"; $out .= " $self->{Curr_Test}" if $self->use_numbers; $out .= " # skip"; $out .= " $why" if length $why; $out .= "\n"; $self->_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 ||= ''; $self->_plan_check; lock($self->{Curr_Test}); $self->{Curr_Test}++; $self->{Test_Results}[$self->{Curr_Test}-1] = &share({ 'ok' => 1, actual_ok => 0, name => '', type => 'todo_skip', reason => $why, }); my $out = "not ok"; $out .= " $self->{Curr_Test}" if $self->use_numbers; $out .= " # TODO & SKIP $why\n"; $self->_print($out); return 1;}=begin _unimplemented=item B<skip_rest> $Test->skip_rest; $Test->skip_rest($reason);Like skip(), only it skips all the rest of the tests you plan to runand terminates the test.If you're running under no_plan, it skips once and terminates thetest.=end _unimplemented=back=head2 Test building utility methodsThese methods are useful when writing your own test methods.=over 4=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; return $usable_regex unless defined $regex; my($re, $opts); # Check for qr/foo/ if( ref $regex eq 'Regexp' ) { $usable_regex = $regex; } # Check for '/foo/' or 'm,foo,' elsif( ($re, $opts) = $regex =~ m{^ /(.*)/ (\w*) $ }sx or (undef, $re, $opts) = $regex =~ m,^ m([^\w\s]) (.+) \1 (\w*) $,sx ) { $usable_regex = length $opts ? "(?$opts)$re" : $re; } return $usable_regex;};sub _regex_ok { my($self, $this, $regex, $cmp, $name) = @_; 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; } { my $test; my $code = $self->_caller_context; local($@, $!, $SIG{__DIE__}); # isolate eval # Yes, it has to look like this or 5.4.5 won't see the #line directive. # Don't ask me, man, I just work here. $test = eval "$code" . q{$test = $this =~ /$usable_regex/ ? 1 : 0}; $test = !$test if $cmp eq '!~'; local $Level = $Level + 1; $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;}# I'm not ready to publish this. It doesn't deal with array return# values from the code or context.=begin private=item B<_try> my $return_from_code = $Test->try(sub { code }); my($return_from_code, $error) = $Test->try(sub { code });Works like eval BLOCK except it ensures it has no effect on the rest of the test (ie. $@ is not set) nor is effected by outside interference (ie. $SIG{__DIE__}) and works around some quirks in older Perls.$error is what would normally be in $@.It is suggested you use this in place of eval BLOCK.=cutsub _try { my($self, $code) = @_; local $!; # eval can mess up $! local $@; # don't set $@ in the test local $SIG{__DIE__}; # don't trip an outside DIE handler. my $return = eval { $code->() }; return wantarray ? ($return, $@) : $return;}=end private=item B<is_fh> my $is_fh = $Test->is_fh($thing);Determines if the given $thing can be used as a filehandle.=cutsub is_fh { my $self = shift; my $maybe_fh = shift; return 0 unless defined $maybe_fh; return 1 if ref $maybe_fh eq 'GLOB'; # its a glob ref return 1 if ref \$maybe_fh eq 'GLOB'; # its a glob return eval { $maybe_fh->isa("IO::Handle") } || # 5.5.4's tied() and can() doesn't like getting undef eval { (tied($maybe_fh) || '')->can('TIEHANDLE') };}=back=head2 Test style=over 4=item B<level> $Test->level($how_high);How far up the call stack should $Test look when reporting where thetest failed.Defaults to 1.Setting L<$Test::Builder::Level> overrides. This is typically usefullocalized: sub my_ok { my $test = shift; local $Test::Builder::Level = $Test::Builder::Level + 1; $TB->ok($test); }To be polite to other functions wrapping your own you usually want to increment C<$Level> rather than set it to a constant.=cutsub level { my($self, $level) = @_; if( defined $level ) { $Level = $level; } return $Level;}=item B<use_numbers> $Test->use_numbers($on_or_off);Whether or not the test should output numbers. That is, this if true: ok 1 ok 2 ok 3or this if false ok ok okMost useful when you can't depend on the test output order, such aswhen threads or forking is involved.Defaults to on.=cutsub use_numbers { my($self, $use_nums) = @_; if( defined $use_nums ) { $self->{Use_Nums} = $use_nums; } return $self->{Use_Nums};}=item B<no_diag> $Test->no_diag($no_diag);If set true no diagnostics will be printed. This includes calls todiag().=item B<no_ending> $Test->no_ending($no_ending);Normally, Test::Builder does some extra diagnostics when the testends. It also changes the exit code as described below.If this is true, none of that will be done.=item B<no_header> $Test->no_header($no_header);If set to true, no "1..N" header will be printed.=cutforeach my $attribute (qw(No_Header No_Ending No_Diag)) { my $method = lc $attribute; my $code = sub { my($self, $no) = @_; if( defined $no ) { $self->{$attribute} = $no; } return $self->{$attribute}; }; no strict 'refs'; *{__PACKAGE__.'::'.$method} = $code;}=back=head2 OutputControlling where the test output goes.It's ok for your test to change where STDOUT and STDERR point to,Test::Builder's default output settings will not be affected.=over 4=item B<diag> $Test->diag(@msgs);Prints out the given @msgs. Like C<print>, arguments are simplyappended together.Normally, it uses the failure_output() handle, but if this is for aTODO test, the todo_output() handle is used.Output will be indented and marked with a # so as not to interferewith test output. A newline will be put on the end if there isn't onealready.We encourage using this rather than calling print directly.Returns false. Why? Because diag() is often used in conjunction witha failing test (C<ok() || diag()>) it "passes through" the failure. return ok(...) || diag(...);=for blame transferMark Fowler <mark@twoshortplanks.com>=cutsub diag { my($self, @msgs) = @_; return if $self->no_diag; return unless @msgs; # Prevent printing headers when compiling (i.e. -c) return if $^C; # Smash args together like print does. # Convert undef to 'undef' so its readable. my $msg = join '', map { defined($_) ? $_ : 'undef' } @msgs; # Escape each line with a #. $msg =~ s/^/# /gm; # Stick a newline on the end if it needs it. $msg .= "\n" unless $msg =~ /\n\Z/; local $Level = $Level + 1; $self->_print_diag($msg); return 0;}=begin _private=item B<_print> $Test->_print(@msgs);Prints to the output() filehandle.=end _private=cutsub _print { my($self, @msgs) = @_; # Prevent printing headers when only compiling. Mostly for when # tests are deparsed with B::Deparse return if $^C; my $msg = join '', @msgs;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -