From 05d7f42550e7c0be843bbdb719ac72be9ba18f1b Mon Sep 17 00:00:00 2001 From: Tim Gim Yee Date: Sun, 28 Oct 2018 15:35:24 -0700 Subject: [PATCH 1/5] Process raw TAP output from STDIN --- bin/prove | 10 ++++++++++ lib/App/Prove/State.pm | 12 ++++++++++-- t/prove.t | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/bin/prove b/bin/prove index 3d41db06..20db995a 100755 --- a/bin/prove +++ b/bin/prove @@ -103,6 +103,16 @@ file, you can add them to your tests by using a '-': See the C in the C directory of this distribution. +If you have raw TAP output (matching C) in a file, you +can likewise add them to your tests by using a '-': + + prove - < my_raw_tap_output.txt + +Or from a command: + + ruby test.rb | prove - + + =head2 Default Test Directory If no files or directories are supplied, C looks for all files diff --git a/lib/App/Prove/State.pm b/lib/App/Prove/State.pm index 0b61a824..1d6109cb 100644 --- a/lib/App/Prove/State.pm +++ b/lib/App/Prove/State.pm @@ -388,8 +388,16 @@ sub _get_raw_tests { for my $arg (@argv) { if ( '-' eq $arg ) { - push @argv => ; - chomp(@argv); + local $/; + my $in = ; + if ($in =~ /\d\.\.\d/) { + # Raw TAP output. TAP::Parser::SourceHandler::RawTAP + # would vote this 0.9. + push @tests => [$in, '*STDIN']; + } else { + # List of tests. + push @argv => split /\n/, $in; + } next; } diff --git a/t/prove.t b/t/prove.t index 75718f62..a2df9e79 100644 --- a/t/prove.t +++ b/t/prove.t @@ -1458,6 +1458,39 @@ BEGIN { # START PLAN # ], # }, + + # STDIN + { name => 'STDIN (file names)', + stdin => "uno\ndos\ntres\n", + args => { + argv => ['-'], + }, + expect => { + argv => ['-'], + }, + runlog => [ + [ '_runtests', + { verbosity => 0, show_count => 1 }, + 'uno', 'dos', 'tres' + ] + ], + }, + { name => 'STDIN (raw TAP)', + stdin => "# comment\n1..1\nok\n", + args => { + argv => ['-'], + }, + expect => { + argv => ['-'], + }, + runlog => [ + [ '_runtests', + { verbosity => 0, show_count => 1 }, + ["# comment\n1..1\nok\n", '*STDIN'], + ] + ], + }, + ); # END SCHEDULE @@ -1536,6 +1569,9 @@ for my $test (@SCHEDULE) { } if ( my $runlog = $test->{runlog} ) { + local *STDIN; + open STDIN, '<', \$test->{stdin} or die "No open STDIN: $!" + if $test->{stdin}; eval { $app->run }; if ( my $err_pattern = $test->{run_error} ) { like $@, $err_pattern, "$name: expected error OK"; From 8302f9b22cf99b886510b4764ea98578a7b54955 Mon Sep 17 00:00:00 2001 From: Tim Gim Yee Date: Mon, 29 Oct 2018 00:16:40 -0700 Subject: [PATCH 2/5] Check for `ok` and `not ok` test lines as well as `1..N` plan line --- lib/App/Prove/State.pm | 5 ++--- t/prove.t | 51 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/lib/App/Prove/State.pm b/lib/App/Prove/State.pm index 1d6109cb..c6b1d84a 100644 --- a/lib/App/Prove/State.pm +++ b/lib/App/Prove/State.pm @@ -390,9 +390,8 @@ sub _get_raw_tests { if ( '-' eq $arg ) { local $/; my $in = ; - if ($in =~ /\d\.\.\d/) { - # Raw TAP output. TAP::Parser::SourceHandler::RawTAP - # would vote this 0.9. + if ($in =~ /^(?:1\.\.\d|ok|not ok)\b(?!\S)/m) { + # Raw TAP output. push @tests => [$in, '*STDIN']; } else { # List of tests. diff --git a/t/prove.t b/t/prove.t index a2df9e79..9f07dc8a 100644 --- a/t/prove.t +++ b/t/prove.t @@ -1475,8 +1475,8 @@ BEGIN { # START PLAN ] ], }, - { name => 'STDIN (raw TAP)', - stdin => "# comment\n1..1\nok\n", + { name => 'STDIN (raw TAP - plan)', + stdin => "\n1..4 # Skipped: Win32 not supported\n", args => { argv => ['-'], }, @@ -1486,7 +1486,52 @@ BEGIN { # START PLAN runlog => [ [ '_runtests', { verbosity => 0, show_count => 1 }, - ["# comment\n1..1\nok\n", '*STDIN'], + ["\n1..4 # Skipped: Win32 not supported\n", '*STDIN'], + ] + ], + }, + { name => 'STDIN (raw TAP - ok)', + stdin => "\nok 1\n", + args => { + argv => ['-'], + }, + expect => { + argv => ['-'], + }, + runlog => [ + [ '_runtests', + { verbosity => 0, show_count => 1 }, + ["\nok 1\n", '*STDIN'], + ] + ], + }, + { name => 'STDIN (raw TAP - not ok)', + stdin => "\nnot ok\n", + args => { + argv => ['-'], + }, + expect => { + argv => ['-'], + }, + runlog => [ + [ '_runtests', + { verbosity => 0, show_count => 1 }, + ["\nnot ok\n", '*STDIN'], + ] + ], + }, + { name => 'STDIN (weird file names)', + stdin => "1..2.t\nok.t\nnot ok.t\n", + args => { + argv => ['-'], + }, + expect => { + argv => ['-'], + }, + runlog => [ + [ '_runtests', + { verbosity => 0, show_count => 1 }, + '1..2.t', 'ok.t', 'not ok.t' ] ], }, From 2dd1146ab58cfefd94292ed7392875328bd0bbd9 Mon Sep 17 00:00:00 2001 From: Tim Gim Yee Date: Mon, 29 Oct 2018 16:20:04 -0700 Subject: [PATCH 3/5] Check for TAP version line, comments, and subtests --- lib/App/Prove/State.pm | 19 +++++++++++- t/prove.t | 66 +++++++++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 27 deletions(-) diff --git a/lib/App/Prove/State.pm b/lib/App/Prove/State.pm index c6b1d84a..2a6164ac 100644 --- a/lib/App/Prove/State.pm +++ b/lib/App/Prove/State.pm @@ -390,7 +390,24 @@ sub _get_raw_tests { if ( '-' eq $arg ) { local $/; my $in = ; - if ($in =~ /^(?:1\.\.\d|ok|not ok)\b(?!\S)/m) { + if ($in =~ / + \A # Beginning of first line + TAP\s+version\s+\d+ # TAP version line + | + ^ # Beginning of any line + \s* # Indented subtests + (?: + [#] # A comment + | + (?: + 1\.\.\d | # A plan line + ok | # A test line - pass + not\s+ok # A test line - fail + ) + \b # End of word or number + (?!\S) # Space if anything else on line + ) + /xm) { # Raw TAP output. push @tests => [$in, '*STDIN']; } else { diff --git a/t/prove.t b/t/prove.t index 9f07dc8a..201f8e6a 100644 --- a/t/prove.t +++ b/t/prove.t @@ -1475,8 +1475,9 @@ BEGIN { # START PLAN ] ], }, - { name => 'STDIN (raw TAP - plan)', - stdin => "\n1..4 # Skipped: Win32 not supported\n", + (map +{ + name => "STDIN (file - $_)", + stdin => "$_\ndos\ntres\n", args => { argv => ['-'], }, @@ -1486,27 +1487,23 @@ BEGIN { # START PLAN runlog => [ [ '_runtests', { verbosity => 0, show_count => 1 }, - ["\n1..4 # Skipped: Win32 not supported\n", '*STDIN'], + $_, 'dos', 'tres', ] ], - }, - { name => 'STDIN (raw TAP - ok)', - stdin => "\nok 1\n", - args => { - argv => ['-'], - }, - expect => { - argv => ['-'], - }, - runlog => [ - [ '_runtests', - { verbosity => 0, show_count => 1 }, - ["\nok 1\n", '*STDIN'], - ] - ], - }, - { name => 'STDIN (raw TAP - not ok)', - stdin => "\nnot ok\n", + } => split /\n/, <<'FILES' +1..2.t +1..2a +ok.t +okay +OK +not ok.t +not oklahoma +NOT OK +FILES + ), + (map +{ + name => "STDIN (TAP - $_)", + stdin => "\n$_\n", args => { argv => ['-'], }, @@ -1516,12 +1513,29 @@ BEGIN { # START PLAN runlog => [ [ '_runtests', { verbosity => 0, show_count => 1 }, - ["\nnot ok\n", '*STDIN'], + ["\n$_\n", '*STDIN'], ] ], - }, - { name => 'STDIN (weird file names)', - stdin => "1..2.t\nok.t\nnot ok.t\n", + } => split /\n/, <<'TAP' +1..4 +1..4 # Skipped: Win32 not supported +ok +ok 2 +not ok +not ok 3 +# comment + 1..4 + 1..4 # Skipped: Win32 not supported + ok + ok 2 + not ok + not ok 3 + # comment +TAP + ), + { + name => "STDIN (TAP - TAP version 13)", + stdin => "TAP version 13\n", args => { argv => ['-'], }, @@ -1531,7 +1545,7 @@ BEGIN { # START PLAN runlog => [ [ '_runtests', { verbosity => 0, show_count => 1 }, - '1..2.t', 'ok.t', 'not ok.t' + ["TAP version 13\n", '*STDIN'], ] ], }, From a2047d262901a28bc03e88b140bd9d53b11408db Mon Sep 17 00:00:00 2001 From: Tim Gim Yee Date: Mon, 29 Oct 2018 23:04:50 -0700 Subject: [PATCH 4/5] Match plan line with more than 9 tests --- lib/App/Prove/State.pm | 2 +- t/prove.t | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/App/Prove/State.pm b/lib/App/Prove/State.pm index 2a6164ac..1321b3cb 100644 --- a/lib/App/Prove/State.pm +++ b/lib/App/Prove/State.pm @@ -400,7 +400,7 @@ sub _get_raw_tests { [#] # A comment | (?: - 1\.\.\d | # A plan line + 1\.\.\d+ | # A plan line ok | # A test line - pass not\s+ok # A test line - fail ) diff --git a/t/prove.t b/t/prove.t index 201f8e6a..a7571302 100644 --- a/t/prove.t +++ b/t/prove.t @@ -1517,7 +1517,7 @@ FILES ] ], } => split /\n/, <<'TAP' -1..4 +1..42 1..4 # Skipped: Win32 not supported ok ok 2 From 6c5cef4b1c3149222d5f17e9833e471aac3feb16 Mon Sep 17 00:00:00 2001 From: Tim Gim Yee Date: Tue, 30 Oct 2018 16:09:31 -0700 Subject: [PATCH 5/5] Add --stdin=list|tap to explicitly set STDIN to list of tests or raw TAP output --- bin/prove | 13 ++++++++-- lib/App/Prove.pm | 7 +++-- lib/App/Prove/State.pm | 52 +++++++++++++++++++++---------------- t/prove.t | 58 +++++++++++++++++++++++++++++++++++++----- 4 files changed, 97 insertions(+), 33 deletions(-) diff --git a/bin/prove b/bin/prove index 20db995a..5d292dd7 100755 --- a/bin/prove +++ b/bin/prove @@ -75,6 +75,7 @@ Options that take arguments: --statefile=file Use `file` instead of `.prove` for state --rc=rcfile Process options from rcfile --rules Rules for parallel vs sequential processing. + --stdin=list|tap STDIN is list of tests or raw TAP output. =head1 NOTES @@ -103,8 +104,8 @@ file, you can add them to your tests by using a '-': See the C in the C directory of this distribution. -If you have raw TAP output (matching C) in a file, you -can likewise add them to your tests by using a '-': +If you have raw TAP output in a file, you can likewise add them to +your tests by using a '-': prove - < my_raw_tap_output.txt @@ -112,6 +113,14 @@ Or from a command: ruby test.rb | prove - +Use the C<--stdin> switch to explicitly set C to a list of +tests: + + prove --stdin=list - < my_list_of_things_to_test.txt + +Or raw TAP output: + + ruby test.rb | prove --stdin=tap - =head2 Default Test Directory diff --git a/lib/App/Prove.pm b/lib/App/Prove.pm index 9298726d..74ced8e7 100644 --- a/lib/App/Prove.pm +++ b/lib/App/Prove.pm @@ -55,7 +55,7 @@ BEGIN { @ATTR = qw( archive argv blib show_count color directives exec failures comments formatter harness includes modules plugins jobs lib merge parse quiet - really_quiet recurse backwards shuffle taint_fail taint_warn timer + really_quiet recurse stdin backwards shuffle taint_fail taint_warn timer verbose warnings_fail warnings_warn show_help show_man show_version state_class test_args state dry extensions ignore_exit rules state_manager normalize sources tapversion trap @@ -220,6 +220,7 @@ sub process_args { 'source=s@' => $self->{sources}, 'formatter=s' => \$self->{formatter}, 'r|recurse' => \$self->{recurse}, + 'stdin=s' => \$self->{stdin}, 'reverse' => \$self->{backwards}, 'p|parse' => \$self->{parse}, 'q|quiet' => \$self->{quiet}, @@ -519,7 +520,7 @@ sub _get_tests { $state->apply_switch(@$state_switch); } - my @tests = $state->get_tests( $self->recurse, @{ $self->argv } ); + my @tests = $state->get_tests( $self, @{ $self->argv } ); $self->_shuffle(@tests) if $self->shuffle; @tests = reverse @tests if $self->backwards; @@ -723,6 +724,8 @@ calling C. =item C +=item C + =item C =item C diff --git a/lib/App/Prove/State.pm b/lib/App/Prove/State.pm index 1321b3cb..234055b9 100644 --- a/lib/App/Prove/State.pm +++ b/lib/App/Prove/State.pm @@ -313,11 +313,13 @@ Given a list of args get the names of tests that should run =cut sub get_tests { - my $self = shift; - my $recurse = shift; - my @argv = @_; + my $self = shift; + my $app = shift; + my @argv = @_; my %seen; + my $recurse = ref $app ? $app->recurse : $app; + my @selected = $self->_query; unless ( @argv || @{ $self->{select} } ) { @@ -326,7 +328,7 @@ sub get_tests { unless -d $argv[0]; } - push @selected, $self->_get_raw_tests( $recurse, @argv ) if @argv; + push @selected, $self->_get_raw_tests( $app, @argv ) if @argv; return grep { !$seen{$_}++ } @selected; } @@ -374,11 +376,14 @@ sub _query_clause { } sub _get_raw_tests { - my $self = shift; - my $recurse = shift; - my @argv = @_; + my $self = shift; + my $app = shift; + my @argv = @_; my @tests; + my $recurse = ref $app ? $app->recurse : $app; + my $stdin = ref $app && $app->stdin || ''; + # Do globbing on Win32. if (NEED_GLOB) { eval "use File::Glob::Windows"; # [49732] @@ -390,24 +395,27 @@ sub _get_raw_tests { if ( '-' eq $arg ) { local $/; my $in = ; - if ($in =~ / - \A # Beginning of first line - TAP\s+version\s+\d+ # TAP version line - | - ^ # Beginning of any line - \s* # Indented subtests - (?: - [#] # A comment + if ( + $stdin eq 'tap' + or !$stdin && $in =~ / + \A # Beginning of first line + TAP\s+version\s+\d+ # TAP version line | + ^ # Beginning of any line + \s* # Indented subtests (?: - 1\.\.\d+ | # A plan line - ok | # A test line - pass - not\s+ok # A test line - fail + [#] # A comment + | + (?: + 1\.\.\d+ | # A plan line + ok | # A test line - pass + not\s+ok # A test line - fail + ) + \b # End of word or number + (?!\S) # Space if anything else on line ) - \b # End of word or number - (?!\S) # Space if anything else on line - ) - /xm) { + /xm + ) { # Raw TAP output. push @tests => [$in, '*STDIN']; } else { diff --git a/t/prove.t b/t/prove.t index a7571302..0915cca0 100644 --- a/t/prove.t +++ b/t/prove.t @@ -84,7 +84,7 @@ BEGIN { # START PLAN @ATTR = qw( archive argv blib color directives exec extensions failures formatter harness includes lib merge parse quiet really_quiet - recurse backwards shuffle taint_fail taint_warn verbose + recurse stdin backwards shuffle taint_fail taint_warn verbose warnings_fail warnings_warn ); @@ -116,8 +116,9 @@ BEGIN { # START PLAN }, { name => 'Set all options via constructor', args => { - archive => 1, + archive => 0, argv => [qw(one two three)], + backwards => 1, blib => 2, color => 3, directives => 4, @@ -132,8 +133,8 @@ BEGIN { # START PLAN quiet => 14, really_quiet => 15, recurse => 16, - backwards => 17, - shuffle => 18, + shuffle => 17, + stdin => 18, taint_fail => 19, taint_warn => 20, verbose => 21, @@ -141,8 +142,9 @@ BEGIN { # START PLAN warnings_warn => 23, }, expect => { - archive => 1, + archive => 0, argv => [qw(one two three)], + backwards => 1, blib => 2, color => 3, directives => 4, @@ -157,8 +159,8 @@ BEGIN { # START PLAN quiet => 14, really_quiet => 15, recurse => 16, - backwards => 17, - shuffle => 18, + shuffle => 17, + stdin => 18, taint_fail => 19, taint_warn => 20, verbose => 21, @@ -1549,6 +1551,48 @@ TAP ] ], }, + (map +{ + name => 'Switch --stdin=list', + stdin => $_, + switches => [ '--stdin=list', '-' ], + expect => { + stdin => 'list', + }, + runlog => [ + [ '_runtests', + { verbosity => 0, show_count => 1 }, + split /\n/ + ] + ], + } => <<'NOT_TAP' +TAP version 13 +1..4 +# comment +ok 1 +ok 2 +not ok 3 +not ok 4 +NOT_TAP + ), + (map +{ + name => 'Switch --stdin=tap', + stdin => $_, + switches => [ '--stdin=tap', '-' ], + expect => { + stdin => 'tap', + }, + runlog => [ + [ '_runtests', + { verbosity => 0, show_count => 1 }, + [$_, '*STDIN'], + ] + ], + } => <<'NOT_LIST' +alpha.t +beta.t +charlie.t +NOT_LIST + ), );