Please review the patch attached, which contributes 5 files for the purpose of testing configuration step inter::yacc. The patch also makes some modifications to config/inter/yacc.pm along the same lines as revisions proposed yesterday for config/inter/lex.pm and for the same purpose: to increase our ability to cover code in the module with our test suite.
Thank you very much. kid51
Index: MANIFEST =================================================================== --- MANIFEST (revision 21127) +++ MANIFEST (working copy) @@ -1,7 +1,7 @@ # ex: set ro: # $Id$ # -# generated by tools/dev/mk_manifest_and_skip.pl Fri Sep 7 23:13:02 2007 UT +# generated by tools/dev/mk_manifest_and_skip.pl Sat Sep 8 01:17:27 2007 UT # # See tools/dev/install_files.pl for documentation on the # format of this file. @@ -2931,6 +2931,11 @@ t/configure/107-inter_progs.02.t [] t/configure/107-inter_progs.03.t [] t/configure/107-inter_progs.04.t [] +t/configure/110-inter_yacc.01.t [] +t/configure/110-inter_yacc.02.t [] +t/configure/110-inter_yacc.03.t [] +t/configure/110-inter_yacc.04.t [] +t/configure/110-inter_yacc.05.t [] t/configure/113-init_optimize.01.t [] t/configure/113-init_optimize.02.t [] t/configure/113-init_optimize.03.t [] Index: t/configure/110-inter_yacc.01.t =================================================================== --- t/configure/110-inter_yacc.01.t (revision 0) +++ t/configure/110-inter_yacc.01.t (revision 0) @@ -0,0 +1,79 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id$ +# 110-inter_yacc.01.t + +use strict; +use warnings; +use Test::More tests => 12; +use Carp; +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +use_ok('config::inter::yacc'); +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( test_step_thru_runstep); + +my $args = process_options( { + argv => [ q{--ask} ], + mode => q{configure}, +} ); + +my $conf = Parrot::Configure->new(); + +test_step_thru_runstep($conf, q{init::defaults}, $args); + +my ($task, $step_name, @step_params, $step, $ret); +my $pkg = q{inter::yacc}; + +$conf->add_steps($pkg); +$conf->options->set(%{$args}); +$task = $conf->steps->[1]; +$step_name = $task->step; [EMAIL PROTECTED] = @{ $task->params }; + +$step = $step_name->new(); +ok(defined $step, "$step_name constructor returned defined value"); +isa_ok($step, $step_name); +ok($step->description(), "$step_name has description"); +$ret = $step->runstep($conf); +ok(defined $ret, "$step_name runstep() returned defined value"); +is($step->result(), q{skipped}, + "Step was skipped as expected; no '--maintainer' option"); + +pass("Completed all tests in $0"); + +################### DOCUMENTATION ################### + +=head1 NAME + +110-inter_yacc.01.t - test config::inter::yacc + +=head1 SYNOPSIS + + % prove t/configure/110-inter_yacc.01.t + +=head1 DESCRIPTION + +The files in this directory test functionality used by F<Configure.pl>. + +The tests in this file test subroutines exported by config::inter::yacc. In +this case, only the C<--ask> option is provided. Because the C<--maintainer> +option is not provided, the step is skipped and no prompt is ever reached. + +=head1 AUTHOR + +James E Keenan + +=head1 SEE ALSO + +config::inter::yacc, F<Configure.pl>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: Property changes on: t/configure/110-inter_yacc.01.t ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Index: t/configure/110-inter_yacc.03.t =================================================================== --- t/configure/110-inter_yacc.03.t (revision 0) +++ t/configure/110-inter_yacc.03.t (revision 0) @@ -0,0 +1,84 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id$ +# 110-inter_yacc.03.t + +use strict; +use warnings; +use Test::More tests => 12; +use Carp; +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +$ENV{TEST_YACC} = 'foobar'; +use_ok('config::inter::yacc'); +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( test_step_thru_runstep); + +my $args = process_options( { + argv => [ q{--ask}, q{--maintainer} ], + mode => q{configure}, +} ); + +my $conf = Parrot::Configure->new(); + +test_step_thru_runstep($conf, q{init::defaults}, $args); + +my ($task, $step_name, @step_params, $step, $ret); +my $pkg = q{inter::yacc}; + +$conf->add_steps($pkg); +$conf->options->set(%{$args}); + +$task = $conf->steps->[1]; +$step_name = $task->step; [EMAIL PROTECTED] = @{ $task->params }; + +$step = $step_name->new(); +ok(defined $step, "$step_name constructor returned defined value"); +isa_ok($step, $step_name); +ok($step->description(), "$step_name has description"); +$ret = $step->runstep($conf); +is($ret, undef, "$step_name runstep() returned undefined value"); +my $result_expected = q{no yacc program was found}; +is($step->result(), $result_expected, + "Result was $result_expected"); + +pass("Completed all tests in $0"); + +################### DOCUMENTATION ################### + +=head1 NAME + +110-inter_yacc.03.t - test config::inter::yacc + +=head1 SYNOPSIS + + % prove t/configure/110-inter_yacc.03.t + +=head1 DESCRIPTION + +The files in this directory test functionality used by F<Configure.pl>. + +The tests in this file test subroutines exported by config::inter::yacc. In +this case, the C<--ask> and C<--maintainer> options are provided but an +environmental variable was provided in order to trick the package into not +finding a real F<yacc>-equivalent program. As a result, no prompt is ever +reached. + +=head1 AUTHOR + +James E Keenan + +=head1 SEE ALSO + +config::inter::yacc, F<Configure.pl>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: Property changes on: t/configure/110-inter_yacc.03.t ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Index: t/configure/110-inter_yacc.05.t =================================================================== --- t/configure/110-inter_yacc.05.t (revision 0) +++ t/configure/110-inter_yacc.05.t (revision 0) @@ -0,0 +1,110 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id$ +# 110-inter_yacc.05.t + +use strict; +use warnings; +use Test::More tests => 14; +use Carp; +use Data::Dumper; +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +use_ok('config::inter::yacc'); +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::IO::Capture::Mini; +use Parrot::Configure::Test qw( test_step_thru_runstep); +use Tie::Filehandle::Preempt::Stdin; + +my $args = process_options( { + argv => [ q{--ask}, q{--maintainer} ], + mode => q{configure}, +} ); + +my $conf = Parrot::Configure->new(); + +test_step_thru_runstep($conf, q{init::defaults}, $args); + +my ($task, $step_name, @step_params, $step, $ret); +my $pkg = q{inter::yacc}; + +$conf->add_steps($pkg); +$conf->options->set(%{$args}); + +$task = $conf->steps->[1]; +$step_name = $task->step; [EMAIL PROTECTED] = @{ $task->params }; + +$step = $step_name->new(); +ok(defined $step, "$step_name constructor returned defined value"); +isa_ok($step, $step_name); +ok($step->description(), "$step_name has description"); + +my (@prompts, $object); [EMAIL PROTECTED] = q{bison}; + +$object = tie *STDIN, 'Tie::Filehandle::Preempt::Stdin', @prompts; +can_ok('Tie::Filehandle::Preempt::Stdin', ('READLINE')); +isa_ok($object, 'Tie::Filehandle::Preempt::Stdin'); + +{ + my $tie_out = tie *STDOUT, "Parrot::IO::Capture::Mini" + or croak "Unable to tie"; + $ret = $step->runstep($conf); + my @more_lines = $tie_out->READLINE; + my $possible_results = qr/^( + no\syacc\sprogram\swas\sfound + | yacc\sprogram\sdoes\snot\sexist\sor\sdoes\snot\sunderstand\s--version + | could\snot\sunderstand\sbison\sversion\srequirement + | found\sbison\sversion.*?but\sat\sleast.*?is\srequired + | bison + )/x; + my @dump_msg = ( Dumper($step->result()) =~ /'(.*?)'/ ); + like($step->result(), $possible_results, + "Response to prompt led to acceptable result: " . $dump_msg[0]); + if ($dump_msg[0] eq q{no yacc program was found}) { + ok(! @more_lines, "No yacc program => no prompts"); + } else { + ok(@more_lines, "prompts were captured"); + } +} + +$object = undef; +untie *STDIN; + +pass("Completed all tests in $0"); + + +################### DOCUMENTATION ################### + +=head1 NAME + +110-inter_yacc.05.t - test config::inter::yacc + +=head1 SYNOPSIS + + % prove t/configure/110-inter_yacc.05.t + +=head1 DESCRIPTION + +The files in this directory test functionality used by F<Configure.pl>. + +The tests in this file test subroutines exported by config::inter::yacc. + +=head1 AUTHOR + +James E Keenan + +=head1 SEE ALSO + +config::inter::yacc, F<Configure.pl>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: Property changes on: t/configure/110-inter_yacc.05.t ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Index: t/configure/110-inter_yacc.02.t =================================================================== --- t/configure/110-inter_yacc.02.t (revision 0) +++ t/configure/110-inter_yacc.02.t (revision 0) @@ -0,0 +1,83 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id$ +# 110-inter_yacc.02.t + +use strict; +use warnings; +use Test::More tests => 12; +use Carp; +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +use_ok('config::inter::yacc'); +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( test_step_thru_runstep); + +$ENV{YACC} = 'foobar'; + +my $args = process_options( { + argv => [ q{--ask}, q{--maintainer} ], + mode => q{configure}, +} ); + +my $conf = Parrot::Configure->new(); + +test_step_thru_runstep($conf, q{init::defaults}, $args); + +my ($task, $step_name, @step_params, $step, $ret); +my $pkg = q{inter::yacc}; + +$conf->add_steps($pkg); +$conf->options->set(%{$args}); + +$task = $conf->steps->[1]; +$step_name = $task->step; [EMAIL PROTECTED] = @{ $task->params }; + +$step = $step_name->new(); +ok(defined $step, "$step_name constructor returned defined value"); +isa_ok($step, $step_name); +ok($step->description(), "$step_name has description"); +$ret = $step->runstep($conf); +ok(defined $ret, "$step_name runstep() returned defined value"); +my $result_expected = q{user defined}; +is($step->result(), $result_expected, + "Result was $result_expected because environmental variable was set"); +pass("Completed all tests in $0"); + +################### DOCUMENTATION ################### + +=head1 NAME + +110-inter_yacc.02.t - test config::inter::yacc + +=head1 SYNOPSIS + + % prove t/configure/110-inter_yacc.02.t + +=head1 DESCRIPTION + +The files in this directory test functionality used by F<Configure.pl>. + +The tests in this file test subroutines exported by config::inter::lex. In +this case, the C<--ask> and C<--maintainer> options are provided but the +F<yacc>-equivalent program is provided by the user via an environmental +variable. As a result, no prompt is ever reached. + +=head1 AUTHOR + +James E Keenan + +=head1 SEE ALSO + +config::inter::yacc, F<Configure.pl>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: Property changes on: t/configure/110-inter_yacc.02.t ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Index: t/configure/110-inter_yacc.04.t =================================================================== --- t/configure/110-inter_yacc.04.t (revision 0) +++ t/configure/110-inter_yacc.04.t (revision 0) @@ -0,0 +1,93 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id$ +# 110-inter_yacc.04.t + +use strict; +use warnings; +use Test::More tests => 14; +use Carp; +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +use_ok('config::inter::yacc'); +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( test_step_thru_runstep); +use Tie::Filehandle::Preempt::Stdin; + +my $args = process_options( { + argv => [ q{--ask}, q{--maintainer}, q{--yacc=bison} ], + mode => q{configure}, +} ); + +my $conf = Parrot::Configure->new(); + +test_step_thru_runstep($conf, q{init::defaults}, $args); + +my ($task, $step_name, @step_params, $step, $ret); +my $pkg = q{inter::yacc}; + +$conf->add_steps($pkg); +$conf->options->set(%{$args}); + +$task = $conf->steps->[1]; +$step_name = $task->step; [EMAIL PROTECTED] = @{ $task->params }; + +$step = $step_name->new(); +ok(defined $step, "$step_name constructor returned defined value"); +isa_ok($step, $step_name); +ok($step->description(), "$step_name has description"); + +my (@prompts, $object); [EMAIL PROTECTED] = map { q{foo_} . $_ } + qw| alpha |; +$object = tie *STDIN, 'Tie::Filehandle::Preempt::Stdin', @prompts; +can_ok('Tie::Filehandle::Preempt::Stdin', ('READLINE')); +isa_ok($object, 'Tie::Filehandle::Preempt::Stdin'); + +$ret = $step->runstep($conf); +ok(defined $ret, "$step_name runstep() returned defined value"); +my $result_expected = q{user defined}; +is($step->result(), $result_expected, + "Result was $result_expected"); + +$object = undef; +untie *STDIN; + +pass("Completed all tests in $0"); + +################### DOCUMENTATION ################### + +=head1 NAME + +110-inter_yacc.04.t - test config::inter::yacc + +=head1 SYNOPSIS + + % prove t/configure/110-inter_yacc.04.t + +=head1 DESCRIPTION + +The files in this directory test functionality used by F<Configure.pl>. + +The tests in this file test subroutines exported by config::inter::yacc. In +this test the C<--ask>, C<--maintainer> and C<--yacc> options are +provided. + +=head1 AUTHOR + +James E Keenan + +=head1 SEE ALSO + +config::inter::yacc, F<Configure.pl>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: Property changes on: t/configure/110-inter_yacc.04.t ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Index: config/inter/yacc.pm =================================================================== --- config/inter/yacc.pm (revision 21127) +++ config/inter/yacc.pm (working copy) @@ -28,6 +28,10 @@ $prompt = "Do you have a parser generator, like bison or yacc?"; @args = qw( yacc ask maintainer ); +my @yacc_defaults = defined($ENV{TEST_YACC}) + ? $ENV{TEST_YACC} + : ('bison -v -y', 'yacc', 'byacc'); + my $default_required = '2.1'; sub runstep { @@ -44,12 +48,12 @@ return $self; } - my $prog; - # precedence of sources for the program: # default -> probe -> environment -> option -> ask - $prog ||= $conf->options->get($util); - $prog ||= $ENV{ uc($util) }; + my $prog = $conf->options->get($util); + unless ($prog) { + $prog = $ENV{ uc($util) }; + } # never override the user. If a non-existent program is specified then # the user is responsible for the consequences. @@ -57,76 +61,72 @@ $conf->data->set( $util => $prog ); $self->set_result('user defined'); return $self; - } - - $prog = check_progs( [ 'bison -v -y', 'yacc', 'byacc' ], $verbose ); - - unless ($prog) { - $self->set_result('no yacc program was found'); - return; - } - - # RT#43170 should --ask be handled like the other user defines or - # checked for version requirements? - if ( $conf->options->get('ask') ) { - $prog = prompt( $prompt, $prog ? $prog : $conf->data->get($util) ); - } - - my ( $stdout, $stderr, $ret ) = capture_output( $prog, '--version' ); - - # don't override the user even if the program they provided appears to be - # broken - if ( $ret == -1 and !$conf->options->get('ask') ) { - - # fall back to default - $self->set_result('yacc program does not exist or does not understand --version'); - return; - } - - # if '--version' returns a string assume that this is bison. - # if this is bison pretending to be yacc '--version' doesn't work - if ( $stdout =~ /Bison .*? (\d+) \. (\d+) (\w)?/x ) { - - # someday we might need to check $3 also. - my ( $prog_major, $prog_minor, $prog_patch ) = ( $1, $2, $3 ); - my $prog_version = "$1.$2"; - $prog_version .= $3 if $3; - - # is there a version requirement? - my $req = $conf->options->get('bison_required'); - unless ( defined $req ) { - $req = $default_required; - } - if ($req) { - my ( $rmajor, $rminor ) = ( $req =~ / ^ (\d+) \. (\d+) (\w)? $ /x ); - unless ( defined $rmajor ) { - $self->set_result("could not understand bison version requirement"); - return; + } else { + # $prog = check_progs( [ 'bison -v -y', 'yacc', 'byacc' ], $verbose ); + $prog = check_progs( [ @yacc_defaults ], $verbose ); + if (! $prog) { + $self->set_result('no yacc program was found'); + return; + } else { + # RT#43170 should --ask be handled like the other user defines or + # checked for version requirements? + if ( $conf->options->get('ask') ) { + $prog = prompt( + $prompt, $prog ? $prog : $conf->data->get($util) ); } - - unless ( - $prog_major >= $rmajor - - or ( $prog_major == $rmajor - and $prog_minor >= $rminor ) - ) - { - $self->set_result( "found bison version $prog_version" - . " but at least $rmajor.$rminor is required" ); + my ( $stdout, $stderr, $ret ) = + capture_output( $prog, '--version' ); + # don't override the user even if the program they provided + # appears to be broken + if ( $ret == -1 and !$conf->options->get('ask') ) { + # fall back to default + $self->set_result('yacc program does not exist or does not understand --version'); return; + } elsif ( $stdout =~ /Bison .*? (\d+) \. (\d+) (\w)?/x ) { + # if '--version' returns a string assume that this is bison. + # if this is bison pretending to be yacc + # '--version' doesn't work + # someday we might need to check $3 also. + my ( $prog_major, $prog_minor, $prog_patch ) = ( $1, $2, $3 ); + my $prog_version = "$1.$2"; + $prog_version .= $3 if $3; + + # is there a version requirement? + my $req = $conf->options->get('bison_required'); + unless ( defined $req ) { + $req = $default_required; + } + if ($req) { + my ( $rmajor, $rminor ) = + ( $req =~ / ^ (\d+) \. (\d+) (\w)? $ /x ); + if (! defined $rmajor ) { + $self->set_result( + "could not understand bison version requirement"); + return; + } elsif ( +# $prog_major >= $rmajor + $prog_major < $rmajor + or ( $prog_major == $rmajor + and $prog_minor < $rminor ) + ) { + $self->set_result( + "found bison version $prog_version" + . " but at least $rmajor.$rminor is required" ); + return; + } else { + 1; # lack an explicit 'else' here + } + } + $conf->data->set( bison_version => $prog_version ); + $self->set_result("bison $prog_version"); + $conf->data->set( $util => $prog ); + return $self; + } else { + $self->set_result('yacc program does not exist or does not understand --version'); + return; } } - - $conf->data->set( bison_version => $prog_version ); - $self->set_result("bison $prog_version"); - $conf->data->set( $util => $prog ); } - else { - $self->set_result('yacc program does not exist or does not understand --version'); - return; - } - - return $self; } 1;