Hi all, I've implemented a (rather rough) hack in our build subclass which allows different testfile extensions to be mapped to test<foo> tags.
In this case, testgui will run any *.gt files found (recursively) in the t/ directory. testfile_types => { 'gui' => 'gt', }, Additionally, the "testall" action will run all of the test types. I would like to not have to explicitly define ACTION_testgui(), but for now I would like some feedback on whether this is a desirable feature and/or thoughts on a cleaner implementation or any glaring issues. The implementation is primarily in transforming ACTION_test() into the generic_test() method, which takes a 'type' argument. sub ACTION_testgui { my $self = shift; $self->generic_test(type => 'gui'); } sub ACTION_testall { my $self = shift; my $p = $self->{properties}; my @test_types = ('t', ($p->{testfile_types} ? keys(%{$p->{testfile_types}}) : ()) ); $self->generic_test(types => [EMAIL PROTECTED]); } I seem to recall a few discussions about "author tests" and such, so it seems like there might be some interest in such a feature. Perhaps "testnetwork", "testserver", "testdisk", etc. might be useful for things that require explicit environment/setup? Below is some code forked out of Module::Build::Base, which is used to enable the above behavior. ATM, I've just written this into our build subclass, but would be happy to make it a patch if there's interest. Thanks, Eric sub ACTION_test { my $self = shift; $self->generic_test(type => 't'); } # stolen from M::B::B::ACTION_test sub generic_test { my $self = shift; (@_ % 2) and croak('Odd number of elements in argument hash'); my %args = @_; my @types = ( (exists($args{type}) ? $args{type} : ()), (exists($args{types}) ? @{$args{types}} : ()), ); @types or croak "need some types of tests to check"; my $p = $self->{properties}; require Test::Harness; $self->depends_on('code'); # Do everything in our power to work with all # versions of Test::Harness my @harness_switches = $p->{debugger} ? qw(-w -d) : (); local $Test::Harness::switches = join ' ', grep defined, $Test::Harness::switches, @harness_switches; local $Test::Harness::Switches = join ' ', grep defined, $Test::Harness::Switches, @harness_switches; local $ENV{HARNESS_PERL_SWITCHES} = join ' ', grep defined, $ENV{HARNESS_PERL_SWITCHES}, @harness_switches; $Test::Harness::switches = undef unless length $Test::Harness::switches; $Test::Harness::Switches = undef unless length $Test::Harness::Switches; delete $ENV{HARNESS_PERL_SWITCHES} unless length $ENV{HARNESS_PERL_SWITCHES}; local ($Test::Harness::verbose, $Test::Harness::Verbose, $ENV{TEST_VERBOSE}, $ENV{HARNESS_VERBOSE}) = ($p->{verbose} || 0) x 4; # Make sure we test the module in blib/ local @INC = (File::Spec->catdir($p->{base_dir}, $self->blib, 'lib'), File::Spec->catdir($p->{base_dir}, $self->blib, 'arch'), @INC); # Filter out nonsensical @INC entries - some versions of # Test::Harness will really explode the number of entries here @INC = grep {ref() || -d} @INC if @INC > 100; my $tests = $self->find_test_files(@types); if (@$tests) { # Work around a Test::Harness bug that loses the particular perl # we're running under. $self->perl is trustworthy, but $^X isn't. local $^X = $self->perl; Test::Harness::runtests(@$tests); } else { $self->log_info("No tests defined.\n"); } # This will get run and the user will see the output. It doesn't # emit Test::Harness-style output. if (-e 'visual.pl') { $self->run_perl_script('visual.pl', '-Mblib='.$self->blib); } } sub expand_test_dir { my $self = shift; my ($dir, @types) = @_; my $p = $self->{properties}; my @tfiles; my @typelist; foreach my $type (@types) { # old-school if($type eq 't') { push(@typelist, 't'); next; } defined($p->{testfile_types}) or Carp::confess( "cannot have typed testfiles without 'testfile_types' data"); defined($p->{testfile_types}{$type}) or croak "no testfile_type '$type' is defined"; push(@typelist, $p->{testfile_types}{$type}); } #warn "expand_test_dir($dir, @types) @typelist"; #do('./util/BREAK_THIS') or die; if($self->recursive_test_files) { push(@tfiles, @{$self->rscan_dir($dir, qr{^[^.].*\.$_$})}) for(@typelist); } else { push(@tfiles, glob(File::Spec->catfile($dir, $_))) for(map({"*.$_"} @typelist)); } $p->{verbose} and warn "found ", scalar(@tfiles), " test files\n"; return(sort(@tfiles)); } sub find_test_files { my $self = shift; my (@types) = @_; my $p = $self->{properties}; if (my $files = $p->{test_files}) { $files = [keys %$files] if UNIVERSAL::isa($files, 'HASH'); $files = [map { -d $_ ? $self->expand_test_dir($_, @types) : $_ } map glob, $self->split_like_shell($files)]; # Always given as a Unix file spec. return [ map $self->localize_file_path($_), @$files ]; } else { # Find all possible tests in t/ or test.pl my @tests; push @tests, 'test.pl' if -e 'test.pl'; push @tests, $self->expand_test_dir('t', @types) if -e 't' and -d _; return [EMAIL PROTECTED]; } } -- Speak softly and carry a big carrot. --------------------------------------------------- http://scratchcomputing.com ---------------------------------------------------