📄 straps.pm
字号:
sub _command_line { my $self = shift; my $file = shift; my $command = $self->_command(); my $switches = $self->_switches($file); $file = qq["$file"] if ($file =~ /\s/) && ($file !~ /^".*"$/); my $line = "$command $switches $file"; return $line;}=for private $strap->_command()Returns the command that runs the test. Combine this with C<_switches()>to build a command line.Typically this is C<$^X>, but you can set C<$ENV{HARNESS_PERL}>to use a different Perl than what you're running the harness under.This might be to run a threaded Perl, for example.You can also overload this method if you've built your own strap subclass,such as a PHP interpreter for a PHP-based strap.=cutsub _command { my $self = shift; return $ENV{HARNESS_PERL} if defined $ENV{HARNESS_PERL}; #return qq["$^X"] if $self->{_is_win32} && ($^X =~ /[^\w\.\/\\]/); return qq["$^X"] if $^X =~ /\s/ and $^X !~ /^["']/; return $^X;}=for private $strap->_switches( $file )Formats and returns the switches necessary to run the test.=cutsub _switches { my($self, $file) = @_; my @existing_switches = $self->_cleaned_switches( $Test::Harness::Switches, $ENV{HARNESS_PERL_SWITCHES} ); my @derived_switches; local *TEST; open(TEST, $file) or print "can't open $file. $!\n"; my $shebang = <TEST>; close(TEST) or print "can't close $file. $!\n"; my $taint = ( $shebang =~ /^#!.*\bperl.*\s-\w*([Tt]+)/ ); push( @derived_switches, "-$1" ) if $taint; # When taint mode is on, PERL5LIB is ignored. So we need to put # all that on the command line as -Is. # MacPerl's putenv is broken, so it will not see PERL5LIB, tainted or not. if ( $taint || $self->{_is_macos} ) { my @inc = $self->_filtered_INC; push @derived_switches, map { "-I$_" } @inc; } # Quote the argument if there's any whitespace in it, or if # we're VMS, since VMS requires all parms quoted. Also, don't quote # it if it's already quoted. for ( @derived_switches ) { $_ = qq["$_"] if ((/\s/ || $self->{_is_vms}) && !/^".*"$/ ); } return join( " ", @existing_switches, @derived_switches );}=for private $strap->_cleaned_switches( @switches_from_user )Returns only defined, non-blank, trimmed switches from the parms passed.=cutsub _cleaned_switches { my $self = shift; local $_; my @switches; for ( @_ ) { my $switch = $_; next unless defined $switch; $switch =~ s/^\s+//; $switch =~ s/\s+$//; push( @switches, $switch ) if $switch ne ""; } return @switches;}=for private $strap->_INC2PERL5LIB local $ENV{PERL5LIB} = $self->_INC2PERL5LIB;Takes the current value of C<@INC> and turns it into something suitablefor putting onto C<PERL5LIB>.=cutsub _INC2PERL5LIB { my($self) = shift; $self->{_old5lib} = $ENV{PERL5LIB}; return join $Config{path_sep}, $self->_filtered_INC;}=for private $strap->_filtered_INC() my @filtered_inc = $self->_filtered_INC;Shortens C<@INC> by removing redundant and unnecessary entries.Necessary for OSes with limited command line lengths, like VMS.=cutsub _filtered_INC { my($self, @inc) = @_; @inc = @INC unless @inc; if( $self->{_is_vms} ) { # VMS has a 255-byte limit on the length of %ENV entries, so # toss the ones that involve perl_root, the install location @inc = grep !/perl_root/i, @inc; } elsif ( $self->{_is_win32} ) { # Lose any trailing backslashes in the Win32 paths s/[\\\/+]$// foreach @inc; } my %seen; $seen{$_}++ foreach $self->_default_inc(); @inc = grep !$seen{$_}++, @inc; return @inc;}{ # Without caching, _default_inc() takes a huge amount of time my %cache; sub _default_inc { my $self = shift; my $perl = $self->_command; $cache{$perl} ||= [do { local $ENV{PERL5LIB}; my @inc =`$perl -le "print join qq[\\n], \@INC"`; chomp @inc; }]; return @{$cache{$perl}}; }}=for private $strap->_restore_PERL5LIB() $self->_restore_PERL5LIB;This restores the original value of the C<PERL5LIB> environment variable.Necessary on VMS, otherwise a no-op.=cutsub _restore_PERL5LIB { my($self) = shift; return unless $self->{_is_vms}; if (defined $self->{_old5lib}) { $ENV{PERL5LIB} = $self->{_old5lib}; }}=head1 ParsingMethods for identifying what sort of line you're looking at.=for private _is_diagnostic my $is_diagnostic = $strap->_is_diagnostic($line, \$comment);Checks if the given line is a comment. If so, it will place it intoC<$comment> (sans #).=cutsub _is_diagnostic { my($self, $line, $comment) = @_; if( $line =~ /^\s*\#(.*)/ ) { $$comment = $1; return $YES; } else { return $NO; }}=for private _is_header my $is_header = $strap->_is_header($line);Checks if the given line is a header (1..M) line. If so, it places howmany tests there will be in C<< $strap->{max} >>, a list of which testsare todo in C<< $strap->{todo} >> and if the whole test was skippedC<< $strap->{skip_all} >> contains the reason.=cut# Regex for parsing a header. Will be run with /xmy $Extra_Header_Re = <<'REGEX'; ^ (?: \s+ todo \s+ ([\d \t]+) )? # optional todo set (?: \s* \# \s* ([\w:]+\s?) (.*) )? # optional skip with optional reasonREGEXsub _is_header { my($self, $line) = @_; if( my($max, $extra) = $line =~ /^1\.\.(\d+)(.*)/ ) { $self->{max} = $max; assert( $self->{max} >= 0, 'Max # of tests looks right' ); if( defined $extra ) { my($todo, $skip, $reason) = $extra =~ /$Extra_Header_Re/xo; $self->{todo} = { map { $_ => 1 } split /\s+/, $todo } if $todo; if( $self->{max} == 0 ) { $reason = '' unless defined $skip and $skip =~ /^Skip/i; } $self->{skip_all} = $reason; } return $YES; } else { return $NO; }}=for private _is_bail_out my $is_bail_out = $strap->_is_bail_out($line, \$reason);Checks if the line is a "Bail out!". Places the reason for bailing(if any) in $reason.=cutsub _is_bail_out { my($self, $line, $reason) = @_; if( $line =~ /^Bail out!\s*(.*)/i ) { $$reason = $1 if $1; return $YES; } else { return $NO; }}=for private _reset_file_state $strap->_reset_file_state;Resets things like C<< $strap->{max} >> , C<< $strap->{skip_all} >>,etc. so it's ready to parse the next file.=cutsub _reset_file_state { my($self) = shift; delete @{$self}{qw(max skip_all todo too_many_tests)}; $self->{line} = 0; $self->{saw_header} = 0; $self->{saw_bailout}= 0; $self->{lone_not_line} = 0; $self->{bailout_reason} = ''; $self->{'next'} = 1;}=head1 EXAMPLESSee F<examples/mini_harness.plx> for an example of use.=head1 AUTHORMichael G Schwern C<< <schwern at pobox.com> >>, currently maintained byAndy Lester C<< <andy at petdance.com> >>.=head1 SEE ALSOL<Test::Harness>=cutsub _def_or_blank { return $_[0] if defined $_[0]; return "";}sub set_callback { my $self = shift; $self->{callback} = shift;}sub callback { my $self = shift; return $self->{callback};}1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -