This is an automated email from the git hooks/post-receive script. intrigeri pushed a commit to annotated tag 0.25 in repository libtest-bdd-cucumber-perl.
commit 963e24908a5531a8f12d92880d2cee8d48b968f2 Author: Peter Sergeant <[email protected]> Date: Sun Jun 8 09:32:18 2014 +0100 Highlight parameters correctly using @- and @+ --- CHANGES | 3 ++ dist.ini | 3 +- lib/Test/BDD/Cucumber/Errors.pm | 3 +- lib/Test/BDD/Cucumber/Executor.pm | 66 +++++++++++++++++++++-- lib/Test/BDD/Cucumber/Harness.pm | 5 +- lib/Test/BDD/Cucumber/Harness/Data.pm | 3 +- lib/Test/BDD/Cucumber/Harness/TermColor.pm | 22 ++++---- t/260_match_matcher.t | 84 ++++++++++++++++++++++++++++++ 8 files changed, 171 insertions(+), 18 deletions(-) diff --git a/CHANGES b/CHANGES index c74fe71..1f2c909 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,7 @@ ----- +0.25: 08 Jun 2014 + - Highlight parameters properly in TermColor output using @+ and @- + https://github.com/sheriff/test-bdd-cucumber-perl/issues/24 0.24: 07 Jun 2014 - Replacing string `eval` with block `eval` for requiring test harnesses - thanks Paul Cochrane diff --git a/dist.ini b/dist.ini index de0d179..6d06616 100644 --- a/dist.ini +++ b/dist.ini @@ -1,5 +1,5 @@ name = Test-BDD-Cucumber -version = 0.24 +version = 0.25 abstract = Feature-complete Cucumber-style testing in Perl main_module = lib/Test/BDD/Cucumber.pm author = ['Peter Sergeant <[email protected]>','Ben Rogers <[email protected]>'] @@ -29,6 +29,7 @@ Getopt::Long = 0 JSON::MaybeXS = 0 Module::Runtime = 0 Moose = 0 +Number::Range = 0 Path::Class = 0 Storable = 0 Term::ANSIColor = 3.00 diff --git a/lib/Test/BDD/Cucumber/Errors.pm b/lib/Test/BDD/Cucumber/Errors.pm index 33128ed..2c97fc3 100644 --- a/lib/Test/BDD/Cucumber/Errors.pm +++ b/lib/Test/BDD/Cucumber/Errors.pm @@ -68,7 +68,7 @@ sub parse_error_from_line { _get_context_range( $line->document, $feature_line ); my $formatted_lines; - for ( 0 .. 4 ) { + for ( 0 .. $#lines ) { my $actual_line = $start_line + $_; my $mark = ($feature_line == $actual_line) ? '*' : '|'; $formatted_lines .= @@ -112,6 +112,7 @@ sub _get_context_range { # Then cut it off @range = grep { $_ >= $min_range } @range; + @range = grep { $_ <= $max_range } @range; return( $range[0], map { $document->lines->[$_ - 1]->raw_content } @range ); } diff --git a/lib/Test/BDD/Cucumber/Executor.pm b/lib/Test/BDD/Cucumber/Executor.pm index 38c61ec..f940ca9 100644 --- a/lib/Test/BDD/Cucumber/Executor.pm +++ b/lib/Test/BDD/Cucumber/Executor.pm @@ -15,7 +15,9 @@ use Moose; use FindBin::libs; use Storable qw(dclone); use List::Util qw/first/; +use List::MoreUtils qw/pairwise/; use Test::Builder; +use Number::Range; use Test::BDD::Cucumber::StepContext; use Test::BDD::Cucumber::Util; @@ -362,6 +364,9 @@ sub dispatch { # Say we're about to start it up $context->harness->step( $context ); + # Store the string position of matches for highlighting + my @match_locations; + # New scope for the localization my $result; { @@ -371,6 +376,8 @@ sub dispatch { # Execute! eval { no warnings 'redefine'; + + # Set S and C to be step-specific values before executing the step local *Test::BDD::Cucumber::StepFile::S = sub { return $context->stash->{'scenario'} }; @@ -378,8 +385,17 @@ sub dispatch { return $context }; - # Rematch the regex, setting $1, $2, and friends correctly - $context->matches([ $context->text =~ $regular_expression ]); + # Take a copy of this. Turns out actually matching against it + # directly causes all sorts of weird-ass eisenbugs which mst has + # promised to investigate. + my $text = $context->text; + + # Save the matches + $context->matches([ $text =~ $regular_expression ]); + + # Save the location of matched subgroups for highlighting hijinks + my @starts = @-; my @ends = @+; + @match_locations = pairwise {[$a, $b]} @starts, @ends; # OK, actually execute $coderef->( $context ) @@ -401,14 +417,58 @@ sub dispatch { }); } + + my @clean_matches = $self->_extract_match_strings( + $context->text, \@match_locations + ); + @clean_matches = [ 0, $context->text ] unless @clean_matches; + # Say the step is done, and return the result. Happens outside # the above block so that we don't have the localized harness # anymore... $context->harness->add_result( $result ); - $context->harness->step_done( $context, $result ); + $context->harness->step_done( $context, $result, \@clean_matches ); return $result; } +sub _extract_match_strings { + my ($self, $text, $locations) = @_; + + # Clean up the match locations + my @match_locations = grep { + ( $_->[0] != $_->[1] ) && # No zero-length matches + # And nothing that matched the full string + (! (( $_->[0] == 0 ) && (( $_->[1] == length $text ) ))) + } grep { defined $_ && ref $_ && defined $_->[0] && defined $_->[1] } + @$locations; + + return unless @match_locations; + + # Consolidate overlaps + my $range = Number::Range->new(); + + { + # Don't want a complain about numbers already in range, as that's + # expected for nested matches + no warnings; + $range->addrange($_->[0] . '..' . ($_->[1]-1) ) for @match_locations; + } + + # Walk the string, splitting + my @parts = ([0,'']); + for ( 0 .. ((length $text) - 1) ) { + my $to_highlight = $range->inrange( $_ ); + my $character = substr( $text, $_, 1 ); + + if ( $parts[-1]->[0] != $to_highlight ) { + push( @parts, [$to_highlight, ''] ); + } + + $parts[-1]->[1] .= $character; + } + + return @parts; +} sub _test_status { my $self = shift; diff --git a/lib/Test/BDD/Cucumber/Harness.pm b/lib/Test/BDD/Cucumber/Harness.pm index 32ad781..0219606 100644 --- a/lib/Test/BDD/Cucumber/Harness.pm +++ b/lib/Test/BDD/Cucumber/Harness.pm @@ -68,7 +68,10 @@ sub scenario_done { my ( $self, $scenario, $dataset ) = @_; } Called at the start and end of step execution respectively. Both methods accept a L<Test::BDD::Cucmber::StepContext> object. C<step_done> also accepts -a L<Test::BDD::Cucumber::Model::Result> object. +a L<Test::BDD::Cucumber::Model::Result> object and an arrayref of arrayrefs with +locations of consolidated matches, for highlighting. + + [ [2,5], [7,9] ] =cut diff --git a/lib/Test/BDD/Cucumber/Harness/Data.pm b/lib/Test/BDD/Cucumber/Harness/Data.pm index c5ff28a..f29f2c2 100644 --- a/lib/Test/BDD/Cucumber/Harness/Data.pm +++ b/lib/Test/BDD/Cucumber/Harness/Data.pm @@ -124,9 +124,10 @@ sub step { } sub step_done { - my ($self, $context, $result) = @_; + my ($self, $context, $result, $highlights) = @_; $self->current_step->{'result'} = $result; + $self->current_step->{'highlights'} = $highlights; push( @{ $self->current_scenario->{'steps'} }, $self->current_step ); $self->current_step({}); } diff --git a/lib/Test/BDD/Cucumber/Harness/TermColor.pm b/lib/Test/BDD/Cucumber/Harness/TermColor.pm index b4b055e..e7b0164 100644 --- a/lib/Test/BDD/Cucumber/Harness/TermColor.pm +++ b/lib/Test/BDD/Cucumber/Harness/TermColor.pm @@ -37,7 +37,6 @@ BEGIN { } use Term::ANSIColor; -use Test::BDD::Cucumber::Util; use Test::BDD::Cucumber::Model::Result; extends 'Test::BDD::Cucumber::Harness'; @@ -82,7 +81,7 @@ sub scenario_done { print "\n"; } sub step {} sub step_done { - my ($self, $context, $result ) = @_; + my ($self, $context, $result, $highlights ) = @_; my $color; my $follow_up = []; @@ -109,20 +108,20 @@ sub step_done { my $text; - if ( $context->is_hook ) - { + if ( $context->is_hook ) { $color eq 'red' or return; $text = 'In ' . ucfirst( $context->verb ) . ' Hook'; - } - else - { + undef $highlights; + } else { $text = $context->step->verb_original . ' ' . $context->text; + $highlights = [[ 0, $context->step->verb_original . ' ' ], @$highlights]; } $self->_display({ indent => 4, color => $color, text => $text, + highlights => $highlights, highlight => 'bright_cyan', trailing => 0, follow_up => $follow_up, @@ -174,14 +173,15 @@ sub _display { # Highlight as appropriate my $color = color $options->{'color'}; - if ( $options->{'highlight'} ) { + if ( $options->{'highlight'} && $options->{'highlights'} ) { my $reset = color 'reset'; my $base = color $options->{'color'}; my $hl = color $options->{'highlight'}; - my $text = $base . Test::BDD::Cucumber::Util::bs_quote( $options->{'text'} ); - $text =~ s/("(.+?)"|[ ^](\d[-?\d\.]*))/$reset$hl$1$reset$base/g; - print Test::BDD::Cucumber::Util::bs_unquote( $text ); + for ( @{$options->{'highlights'}} ) { + my ($flag, $text) = @$_; + print $reset . ( $flag ? $hl : $base ) . $text . $reset; + } # Normal output } else { diff --git a/t/260_match_matcher.t b/t/260_match_matcher.t new file mode 100644 index 0000000..2983b85 --- /dev/null +++ b/t/260_match_matcher.t @@ -0,0 +1,84 @@ +#!perl + +use strict; +use warnings; + +use Test::More; +use Test::Differences; +use Test::BDD::Cucumber::Parser; +use Test::BDD::Cucumber::Executor; +use Test::BDD::Cucumber::Harness::Data; + +# Check that when we execute steps we get a nicely split string back for +# highlighting +for ( + [ + "Simple example", + "the quick brown fox", + qr/the (quick) brown (fox)/, + [ + [ 0 => 'the ' ], + [ 1 => 'quick' ], + [ 0 => ' brown ' ], + [ 1 => 'fox' ], + ] + ], + [ + "Non-capture", + "the quick brown fox", + qr/the (?:quick) brown (fox)/, + [ + [ 0 => 'the quick brown ' ], + [ 1 => 'fox' ], + ] + ], + [ + "Nested-capture", + "the quick brown fox", + qr/the (q(uic)k) brown (fox)/, + [ + [ 0 => 'the ' ], + [ 1 => 'quick' ], + [ 0 => ' brown ' ], + [ 1 => 'fox' ], + ] + ], + [ + "Multi-group", + "the quick brown fox", + qr/the (.)+ brown (fox)/, + [ + [ 0 => 'the quic' ], + [ 1 => 'k' ], + [ 0 => ' brown ' ], + [ 1 => 'fox' ], + ] + ], +) { + my ( $test_name, $step_text, $step_re, $expected ) = @$_; + + # Set up a feature + my $feature = Test::BDD::Cucumber::Parser->parse_string( + "Feature: Foo\n\tScenario:\n\t\tGiven $step_text\n" + ); + + # Set up step definitions + my $executor = Test::BDD::Cucumber::Executor->new(); + $executor->add_steps( + [ Given => $step_re, sub { 1; } ], + ); + + # Instantiate the harness, and run it + my $harness = Test::BDD::Cucumber::Harness::Data->new(); + $executor->execute( $feature, $harness ); + + # Get the step result + my $step = $harness->features->[0]->{'scenarios'}->[0]->{'steps'}->[0]; + my $highlights = $step->{'highlights'}; + + is_deeply( $highlights, $expected, $test_name ) || eq_or_diff( + $highlights, $expected + ); +} + +done_testing(); \ No newline at end of file -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libtest-bdd-cucumber-perl.git _______________________________________________ Pkg-perl-cvs-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-perl-cvs-commits
