lib/TAP/Parser/Result/YAML.pm A parser for Test Anything Protocol
lib/TAP/Parser/Source.pm A parser for Test Anything Protocol
lib/TAP/Parser/Source/Perl.pm A parser for Test Anything Protocol
+lib/TAP/Parser/Utils.pm A parser for Test Anything Protocol
lib/TAP/Parser/YAMLish/Reader.pm A parser for Test Anything Protocol
lib/TAP/Parser/YAMLish/Writer.pm A parser for Test Anything Protocol
lib/Term/ANSIColor/ChangeLog Term::ANSIColor
lib/Test/Harness/t/taint.t Test::Harness test
lib/Test/Harness/t/testargs.t Test::Harness test
lib/Test/Harness/t/unicode.t Test::Harness test
+lib/Test/Harness/t/utils.t Test::Harness test
lib/Test/Harness/t/yamlish-output.t Test::Harness test
lib/Test/Harness/t/yamlish-writer.t Test::Harness test
lib/Test/Harness/t/yamlish.t Test::Harness test
use strict;
use TAP::Harness;
+use TAP::Parser::Utils qw( split_shell );
use File::Spec;
use Getopt::Long;
use App::Prove::State;
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
push @switches, '-w';
}
- if ( defined( my $hps = $ENV{HARNESS_PERL_SWITCHES} ) ) {
- push @switches, $hps;
- }
+ push @switches, split_shell( $ENV{HARNESS_PERL_SWITCHES} );
return @switches ? \@switches : ();
}
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
my $GOT_TIME_HIRES;
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
$ENV{HARNESS_ACTIVE} = 1;
$ENV{HARNESS_VERSION} = $VERSION;
When you supply a separate display name it becomes possible to run a
test more than once; the display name is effectively the alias by which
the test is known inside the harness. The harness doesn't care if it
-runs the same script more than once along as each invocation uses a
+runs the same script more than once when each invocation uses a
different name.
=cut
my @expanded = map { 'ARRAY' eq ref $_ ? $_ : [ $_, $_ ] } @tests;
+ # #12458
+ local $ENV{HARNESS_IS_VERBOSE} = 1
+ if $self->formatter->verbosity > 0;
+
# Formatter gets only names
$self->formatter->prepare( map { $_->[1] } @expanded );
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
my $DEFAULT_TAP_VERSION = 12;
my $MAX_TAP_VERSION = 13;
This is merely a synonym for C<as_string>.
-=head3 C<tests_planned>
-
- my $planned = $result->tests_planned;
-
-Returns the number of tests planned. For example, a plan of C<1..17> will
-cause this method to return '17'.
-
=head3 C<directive>
my $directive = $result->directive;
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 SYNOPSIS
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head2 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
=head1 DESCRIPTION
$_ = qq["$_"] if ( ( /\s/ || IS_VMS ) && !/^".*"$/ );
}
- my %found_switch = map { $_ => 0 } @switches;
-
- # remove duplicate switches
- @switches
- = grep { defined $_ && $_ ne '' && !$found_switch{$_}++ } @switches;
return @switches;
}
--- /dev/null
+package TAP::Parser::Utils;
+
+use strict;
+use Exporter;
+use vars qw($VERSION @ISA @EXPORT_OK);
+
+@ISA = qw( Exporter );
+@EXPORT_OK = qw( split_shell );
+
+=head1 NAME
+
+TAP::Parser::Utils - Internal TAP::Parser utilities
+
+=head1 VERSION
+
+Version 3.09
+
+=cut
+
+$VERSION = '3.09';
+
+=head1 SYNOPSIS
+
+ use TAP::Parser::Utils qw( split_shell )
+ my @switches = split_shell( $arg );
+
+=head1 DESCRIPTION
+
+B<FOR INTERNAL USE ONLY!>
+
+=head2 INTERFACE
+
+=head3 C<split_shell>
+
+Shell style argument parsing. Handles backslash escaping, single and
+double quoted strings but not shell substitutions.
+
+Pass one or more strings containing shell escaped arguments. The return
+value is an array of arguments parsed from the input strings according
+to (approximate) shell parsing rules. It's legal to pass C<undef> in
+which case an empty array will be returned. That makes it possible to
+
+ my @args = split_shell( $ENV{SOME_ENV_VAR} );
+
+without worrying about whether the environment variable exists.
+
+This is used to split HARNESS_PERL_ARGS into individual switches.
+
+=cut
+
+sub split_shell {
+ my @parts = ();
+
+ for my $switch ( grep defined && length, @_ ) {
+ push @parts, $1 while $switch =~ /
+ (
+ (?: [^\\"'\s]+
+ | \\.
+ | " (?: \\. | [^"] )* "
+ | ' (?: \\. | [^'] )* '
+ )+
+ ) /xg;
+ }
+
+ for (@parts) {
+ s/ \\(.) | ['"] /defined $1 ? $1 : ''/exg;
+ }
+
+ return @parts;
+}
+
+1;
use vars qw{$VERSION};
-$VERSION = '3.08';
+$VERSION = '3.09';
# TODO:
# Handle blessed object syntax
=head1 VERSION
-Version 3.08
+Version 3.09
=head1 SYNOPSIS
use vars qw{$VERSION};
-$VERSION = '3.08';
+$VERSION = '3.09';
my $ESCAPE_CHAR = qr{ [ \x00-\x1f \" ] }x;
my $ESCAPE_KEY = qr{ (?: ^\W ) | $ESCAPE_CHAR }x;
=head1 VERSION
-Version 3.08
+Version 3.09
=head1 SYNOPSIS
use TAP::Parser::Aggregator ();
use TAP::Parser::Source::Perl ();
+use TAP::Parser::Utils qw( split_shell );
+
use Config;
use Exporter;
=head1 VERSION
-Version 3.08
+Version 3.09
=cut
-$VERSION = '3.08';
+$VERSION = '3.09';
# Backwards compatibility for exportable variable names.
*verbose = *Verbose;
supported is not reproduced here. Straps is now available as a stand
alone module: L<Test::Harness::Straps>.
-See L<TAP::Parser> for the main documentation for this distribution.
+See L<TAP::Parser>, L<TAP::Harness> for the main documentation for this
+distribution.
=head1 FUNCTIONS
sub _new_harness {
my $sub_args = shift || {};
- if ( defined( my $env_sw = $ENV{HARNESS_PERL_SWITCHES} ) ) {
- $Switches .= ' ' . $env_sw if ( length($env_sw) );
- }
-
- # This is a bit crufty. The switches have all been joined into a
- # single string so we have to try and recover them.
my ( @lib, @switches );
- for my $opt ( split( /\s+(?=-)/, $Switches ) ) {
+ for my $opt (
+ split_shell( $Switches, $ENV{HARNESS_PERL_SWITCHES} ) )
+ {
if ( $opt =~ /^ -I (.*) $ /x ) {
push @lib, $1;
}
=back
+=head1 Taint Mode
+
+Normally when a Perl program is run in taint mode the contents of the
+C<PERL5LIB> environment variable do not appear in C<@INC>.
+
+Because C<PERL5LIB> is often used during testing to add build
+directories to C<@INC> C<Test::Harness> (actually
+L<TAP::Parser::Source::Perl>) passes the names of any directories found
+in C<PERL5LIB> as -I switches. The net effect of this is that
+C<PERL5LIB> is honoured even in taint mode.
+
=head1 SEE ALSO
L<TAP::Harness>
Andy Armstrong C<< <andy@hexten.net> >>
-L<Test::Harness> (on which this module is based) has this attribution:
+L<Test::Harness> 2.64 (maintained by Andy Lester and on which this
+module is based) has this attribution:
Either Tim Bunce or Andreas Koenig, we don't know. What we know for
sure is, that it was inspired by Larry Wall's F<TEST> script that came
$ prove -b --state=hot --state=all,save
+=head2 Taint Mode
+
+Normally when a Perl program is run in taint mode the contents of the
+C<PERL5LIB> environment variable do not appear in C<@INC>.
+
+Because C<PERL5LIB> is often used during testing to add build directories
+to C<@INC> prove (actually L<TAP::Parser::Source::Perl>) passes the
+names of any directories found in C<PERL5LIB> as -I switches. The net
+effect of this is that C<PERL5LIB> is honoured even when prove is run in
+taint mode.
+
=cut
# vim:ts=4:sw=4:et:sta
use strict;
use lib 't/lib';
-use Test::More tests => 58;
+use Test::More tests => 60;
BEGIN {
TAP::Parser::Source
TAP::Parser::YAMLish::Reader
TAP::Parser::YAMLish::Writer
+ TAP::Parser::Utils
Test::Harness
);
--- /dev/null
+#!/usr/bin/perl -w
+
+BEGIN {
+ chdir 't' and @INC = '../lib' if $ENV{PERL_CORE};
+}
+
+use strict;
+use lib 't/lib';
+
+use TAP::Parser::Utils qw( split_shell );
+use Test::More;
+
+my @schedule = (
+ { name => 'Bare words',
+ in => 'bare words are here',
+ out => [ 'bare', 'words', 'are', 'here' ],
+ },
+ { name => 'Single quotes',
+ in => "'bare' 'words' 'are' 'here'",
+ out => [ 'bare', 'words', 'are', 'here' ],
+ },
+ { name => 'Double quotes',
+ in => '"bare" "words" "are" "here"',
+ out => [ 'bare', 'words', 'are', 'here' ],
+ },
+ { name => 'Escapes',
+ in => '\ "ba\"re" \'wo\\\'rds\' \\\\"are" "here"',
+ out => [ ' ', 'ba"re', "wo'rds", '\\are', 'here' ],
+ },
+ { name => 'Flag',
+ in => '-e "system(shift)"',
+ out => [ '-e', 'system(shift)' ],
+ },
+ { name => 'Nada',
+ in => undef,
+ out => [],
+ },
+ { name => 'Nada II',
+ in => '',
+ out => [],
+ },
+ { name => 'Zero',
+ in => 0,
+ out => ['0'],
+ },
+ { name => 'Empty',
+ in => '""',
+ out => [''],
+ },
+ { name => 'Empty II',
+ in => "''",
+ out => [''],
+ },
+);
+
+plan tests => 1 * @schedule;
+
+for my $test (@schedule) {
+ my $name = $test->{name};
+ my @got = split_shell( $test->{in} );
+ unless ( is_deeply \@got, $test->{out}, "$name: parse OK" ) {
+ use Data::Dumper;
+ diag( Dumper( { want => $test->{out}, got => \@got } ) );
+ }
+}