home *** CD-ROM | disk | FTP | other *** search
- package Apache::TestMB;
-
- use strict;
- use vars qw(@ISA);
- use Module::Build;
- use Apache::Test ();
- use Apache::TestConfig ();
- @ISA = qw(Module::Build);
-
- sub new {
- my $pkg = shift;
- my($argv, $vars) =
- Apache::TestConfig::filter_args(\@ARGV, \%Apache::TestConfig::Usage);
- @ARGV = @$argv;
- my $self = $pkg->SUPER::new(@_);
- $self->{properties}{apache_test_args} = $vars;
- $self->{properties}{apache_test_script} ||= 't/TEST';
- $self->generate_script;
- return $self;
- }
-
- sub valid_property {
- return 1 if defined $_[1] &&
- ($_[1] eq 'apache_test_args' || $_[1] eq 'apache_test_script');
- shift->SUPER::valid_property(@_);
- }
-
- sub apache_test_args {
- my $self = shift;
- $self->{properties}{apache_test_args} = shift if @_;
- return $self->{properties}{apache_test_args};
- }
-
- sub apache_test_script {
- my $self = shift;
- $self->{properties}{apache_test_script} = shift if @_;
- return $self->{properties}{apache_test_script};
- }
-
- sub ACTION_test_clean {
- my $self = shift;
- # XXX I'd love to do this without t/TEST.
- $self->do_system( $self->perl, $self->_bliblib,
- $self->localize_file_path($self->apache_test_script),
- '-clean');
- }
-
- sub ACTION_clean {
- my $self = shift;
- $self->depends_on('test_clean');
- $self->SUPER::ACTION_clean(@_);
- }
-
- sub ACTION_run_tests {
- my $self = shift;
- $self->depends_on('test_clean');
- # XXX I'd love to do this without t/TEST.
- $self->do_system($self->perl, $self->_bliblib,
- $self->localize_file_path($self->apache_test_script),
- '-bugreport', '-verbose=' . ($self->verbose || 0));
- }
-
- sub _bliblib {
- my $self = shift;
- return (
- '-I', File::Spec->catdir($self->base_dir, $self->blib, 'lib'),
- '-I', File::Spec->catdir($self->base_dir, $self->blib, 'arch'),
- );
- }
-
- sub ACTION_test {
- my $self = shift;
- $self->depends_on('code');
- $self->depends_on('run_tests');
- $self->depends_on('test_clean');
- }
-
- sub _cmodules {
- my ($self, $action) = @_;
- die "The cmodules" . ( $action ne 'all' ? "_$action" : '')
- . " action is not yet implemented";
- # XXX TBD.
- my $start_dir = $self->cwd;
- chdir $self->localize_file_path('c-modules');
- # XXX How do we get Build.PL to be generated instead of Makefile?
- # Subclass Apache::TestConfigC, perhaps?
- $self->do_system('Build.PL', $action);
- chdir $start_dir;
- }
-
- sub ACTION_cmodules { shift->_cmodues('all') }
- sub ACTION_cmodules_clean { shift->_cmodues('clean') }
-
- # XXX I'd love to make this optional.
- sub generate_script {
- my $self = shift;
-
- # If a file name has been passed in, use it. Otherwise, use the
- # one set up when the Apache::TestMB object was created.
- my $script = $self->localize_file_path($_[0]
- ? $self->apache_test_script(shift)
- : $self->apache_test_script
- );
-
- # We need a class to run the tests from t/TEST.
- my $class = pop || 'Apache::TestRunPerl';
-
- # Delete any existing instance of the file.
- unlink $script if -e $script;
-
- # Start the contents of t/TEST.
- my $body = "BEGIN { eval { require blib; } }\n"
- . Apache::TestConfig->modperl_2_inc_fixup;
-
- # Configure the arguments for t/TEST.
- while (my($k, $v) = each %{ $self->apache_test_args }) {
- $v =~ s/\|/\\|/g;
- $body .= "\n\$Apache::TestConfig::Argv{'$k'} = q|$v|;\n";
- }
-
- my $infile = "$script.PL";
- if (-f $infile) {
- # Use the existing t/TEST.PL.
- my $in = Symbol::gensym();
- open $in, "$infile" or die "Couldn't open $infile: $!";
- local $/;
- $body .= <$in>;
- close $in;
- } else {
- # Create t/TEST from scratch.
- $body .= join "\n",
- Apache::TestConfig->perlscript_header,
- "use $class ();",
- "$class->new->run(\@ARGV);";
- }
-
- # Make it so!
- print "Generating test running script $script\n" if $self->verbose;
- Apache::Test::basic_config()->write_perlscript($script, $body);
- $self->add_to_cleanup($self->apache_test_script);
- }
-
-
- 1;
- __END__
-
- =head1 NAME
-
- Apache::TestMB - Subclass of Module::Build to support Apache::Test
-
- =head1 SYNOPSIS
-
- Standard process for building & installing modules:
-
- perl Build.PL
- ./Build
- ./Build test
- ./Build install
-
- Or, if you're on a platform (like DOS or Windows) that doesn't like the "./"
- notation, you can do this:
-
- perl Build.PL
- perl Build
- perl Build test
- perl Build install
-
- =head1 DESCRIPTION
-
- This class subclasses C<Module::Build> to add support for testing
- Apache integration with Apache::Test. It is broadly based on
- C<Apache::TestMM>, and as such adds a number of build actions to a the
- F<Build> script, while simplifying the process of creating F<Build.PL>
- scripts.
-
- Here's how to use C<Apache::TestMB> in a F<Build.PL> script:
-
- use Module::Build;
-
- my $build_pkg = eval { require Apache::TestMB }
- ? 'Apache::TestMB' : 'Module::Build';
-
- my $build = $build_pkg->new(
- module_name => 'My::Module',
- );
- $build->create_build_script;
-
- This is identical to how C<Module::Build> is used. Not all target
- systems may have C<Apache::Test> (and therefore C<Apache::TestMB>
- installed, so we test for it to be installed, first. But otherwise,
- its use can be exactly the same. Consult the
- L<Module::Build|Module::Build> documentation for more information on
- how to use it; L<Module::Build::Cookbook|Module::Build::Cookbook> may
- be especially useful for those looking to migrate from
- C<ExtUtils::MakeMaker>.
-
- =head1 INTERFACE
-
- =head2 Build
-
- With the above script, users can build your module in the usual
- C<Module::Build> way:
-
- perl Build.PL
- ./Build
- ./Build test
- ./Build install
-
- If C<Apache::TestMB> is installed, then Apache will be started before
- tests are run by the C<test> action, and shut down when the tests
- complete. Note that C<Build.PL> can be called C<Apache::Test>-specific
- options in addition to the usual C<Module::Build> options. For
- example:
-
- perl Build.PL -apxs=/usr/local/apache/bin/apxs
-
- Consult the L<Apache::Test|Apache::Test> documentation for a complete
- list of options.
-
- In addition to the actions provided by C<Module::Build> (C<build>,
- C<clean>, C<code>, C<test>, etc.), C<Apache::TestMB> adds a few extra
- actions:
-
- =over 4
-
- =item test_clean
-
- This action cleans out the files generated by the test script,
- F<t/TEST>. It is also executed by the C<clean> action.
-
- =item run_tests
-
- This action actually the tests by executing the test script,
- F<t/TEST>. It is executed by the C<test> action, so most of the time
- it won't be executed directly.
-
- =back
-
- =head2 Constructor
-
- =head3 new
-
- The C<new()> constructor takes all the same arguments as its parent in
- C<Module::Build>, but can optionally accept one other parameter:
-
- =over
-
- =item apache_test_script
-
- The name of the C<Apache::Test> test script. The default value is
- F<t/TEST>, which will work in the vast majority of cases. If you wish
- to specify your own file name, do so with a relative file name using
- Unix-style paths; the file name will automatically be converted for
- the local platform.
-
- =back
-
- When C<new()> is called it does the following:
-
- =over 4
-
- =item *
-
- Processes the C<Apache::Test>-specific options in C<@ARGV>. See the
- L<Apache::Test|Apache::Test> documentation for a complete list of
- options.
-
- =item *
-
- Sets the name of the C<Apache::Test> test script to F<t/TEST>, unless
- it was explicitly specified by the C<apache_test_script> parameter.
-
- =item *
-
- Calls C<generate_script()> to generate C<Apache::Test> test script,
- usually F<t/TEST>.
-
- =back
-
- =head2 Instance Methods
-
- =head3 apache_test_args
-
- Returns a hash reference containing all of the settings specified by
- options passed to F<Build.PL>, or explicitly added to C<@ARGV> in
- F<Build.PL>. Consult the L<Apache::Test|Apache::Test> documentation
- for a complete list of options.
-
- =head3 apache_test_script
-
- Gets or sets the file name of the C<Apache::Test> test script.
-
- =head3 generate_script
-
- $build->generate_script;
- $build->generate_script('t/FOO');
- $build->generate_script(undef, 'Apache::TestRun');
-
- This method is called by C<new()>, so in most cases it can be
- ignored. If you'd like it to use other than the default arguments, you
- can call it explicitly in F<Build.PL> and pass it the arguments you
- desire. It takes two optional arguments:
-
- =over 4
-
- =item *
-
- The name of the C<Apache::Test> test script. Defaults to the value
- returned by C<apache_test_script()>.
-
- =item *
-
- The name of an C<Apache::Test> test running class. Defaults to
- C<Apache::TestRunPerl>.
-
- =back
-
- If there is an existing F<t/TEST.PL> (or a script with the same name
- as specified by the C<apache_test_script> parameter but with F<.PL>
- appended to it), then that script will be used as the template for the
- test script. Otherwise, a simple test script will be written similar
- to what would be written by C<Apache::TestRun::generate_script()>
- (although that function is not aware of the arguments passed to
- F<Build.PL>, so use this one instead!).
-
- =head1 SEE ALSO
-
- =over 4
-
- =item L<Apache::TestRequest|Apache::TestRequest>
-
- Demonstrates how to write tests to send requests to the Apache server
- run by C<./Build test>.
-
- =item L<Module::Build|Module::Build>
-
- The parent class for C<Apache::TestMB>; consult it's documentation for
- more on its interface.
-
- =item L<http://www.perl.com/pub/a/2003/05/22/testing.html>
-
- This article by Geoffrey Young explains how to configure Apache and
- write tests for your module using Apache::Test. Just use
- C<Apache::TestMB> instead of C<Apache::TestMM> to update it for use
- with C<Module::Build>.
-
- =back
-
- =head1 AUTHOR
-
- David Wheeler
-
- Questions can be asked at the test-dev <at> httpd.apache.org list. For
- more information see: I<http://httpd.apache.org/test/> and
- I<http://perl.apache.org/docs/general/testing/testing.html>.
-
- =cut
-
-