More than likely, something like this exists somewhere else.
I just didn't feel like looking for it today. Basically this script
when run in a module directory will generate the barebones test
scripts for any modules found in cwd() . 'lib'; Its just a quick hack
but it does do something kinda cool. If leaves a section for
you to enter in your own module specific tests, and then if for some
reason (you add a new module to your package, add/remove subs from
a current pacakge), it will grab your tests, replace
everything it originally put in there and rewrite it, and append
your custom tests so long as they come after the # ===> <=== #
line.
Lemme know what you think..
-brad..
#!/usr/bin/perl
#
# Generate the base test files for the modules
# in a given base directory
$|++;
use strict;
use Getopt::Std;
use File::Find;
my %OPTS = ();
getopts('vOht:d:', \%OPTS);
&help if $OPTS{h};
my $LIB_DIR = $OPTS{d} || 'lib';
$LIB_DIR =~ s/\/$//;
my $TEST_DIR = $OPTS{t} || 't';
$TEST_DIR =~ s/\/$//;
my $OVERWRITE_OK = $OPTS{O};
my %MODULES = ();
die "Directory: $LIB_DIR isn't a directory!\n" unless -d $LIB_DIR;
#
# populate the %MODULES hash
find(\&build_hash, $LIB_DIR);
my $MODULES = scalar keys %MODULES;
die "No modules found in $LIB_DIR !\n" unless $MODULES > 0;
logthis( "Found $MODULES Modules to write tests for.\n" );
#
# make sure our $TEST_DIR exists, otherwise create it
mkdir($TEST_DIR, 0755) unless -d $TEST_DIR;
my $POS = tell DATA;
#
# process the modules
foreach my $module (keys %MODULES) {
logthis("=> Building $module test scripts ...\n");
process($module);
logthis("\tdone\n");
}
sub build_hash {
/^(.*)\.pm/;
my $pm_file = $1;
return unless $pm_file;
my $file = my $full_file = $File::Find::name;
$file =~ s/^$LIB_DIR\///;
$file =~ s/\.pm$//;
my $test_file = my $module = $file;
$module =~ s/\//\:\:/g;
$test_file =~ s/\//\_/g;
$test_file .= '.t';
$test_file = join '/', $TEST_DIR, $test_file;
$MODULES{$module} = {
file => $full_file,
test_file => $test_file
};
logthis("$module - $test_file\n");
}
sub process {
my $module = shift;
return unless exists $MODULES{$module};
#
# List of variables we _NEED_
my $MODULE = $module;
my $TIME = scalar localtime;
my $METHODS = undef;
my @methods = ();
open(PM, "< $MODULES{$module}->{file}") or die "couldn't read
+$module: $!\n";
while(local $_ = <PM>) {
while( /sub\s+([\w\d_]+)\s*\{/mg ) {
push @methods, $1;
}
}
close PM;
$METHODS = join ' ', @methods;
my $test_file = $MODULES{$module}->{test_file};
my $CUSTOM_DATA = get_custom_data($test_file);
unless( length $CUSTOM_DATA ) {
$CUSTOM_DATA =<<' EOD';
######################################################
+##########################
# This section is for more extensive testing of
+the return values #
# and functionality of the module and should be
+comprehensive #
######################################################
+##########################
# ================> PLEASE CUSTOMIZE THIS SECTION
+ <================ #
#-----------------------------------------------------
+-------------------------#
EOD
$CUSTOM_DATA =~ s/^\t+//mg;
}
open(TEST, "> $test_file") or die "couldn't write $test_file:
+$!\n";
seek DATA, $POS, 0;
while( local $_ = <DATA> ) {
s/\@(\$[\w\d_]+)\@/$1/gee;
print TEST;
}
print TEST $CUSTOM_DATA;
close TEST;
}
sub get_custom_data {
my $file = shift;
return unless -f $file;
return if $OPTS{O};
open( FILE, "< $file") or die "Couldn't open $file for reading
+: $!\n";
while( local $_ = <FILE> ) {
last if /^# ====> !!!! DO NOT ERASE THIS LINE !!!! <==
+== #/;
}
local $/ = undef;
my $data = <FILE>;
return $data;
}
sub logthis {
print @_ if $OPTS{v};
}
sub help {
print "usage: $0 [-hv] [-t testdir] [-d dir_to_search]\n",
"-----------------------------------------------\n",
" This script searches a lib directory and generates
+generic\n",
" test scripts for each module in the lib directory.\
+n\n",
" options:\n",
"\t -h display this menu and exit\n",
"\t -v use verbose mode (prints as is
+ it goes)\n",
"\t -O not recommended. Overwrite al
+l files\n",
"\t -t testdir store test files in testdir\n"
+,
"\t defaults to ./t/\n",
"\t -d dir_to_search lib directory to search for mo
+dules\n",
"\t defaults to ./lib\n";
exit;
}
__DATA__
#!/usr/bin/perl
#
# AUTOGENERATED TEST SCRIPT FOR @$MODULE@
#
# Built: @$TIME@
# by @$0@ written by Brad Lhotsky <brad.lhotsky@epokinc.com>
#
$|++;
use strict;
use Test::More qw(no_plan);
######################################################################
+##########
# This section is basic module testing and should be completed
+ #
######################################################################
+##########
#
# make sure we can safely use the module
BEGIN: { use_ok( '@$MODULE@' ); }
#
# test object creation via new
my $obj;
alarm 5;
eval {
local $SIG{ALRM} = sub { die 'timedout' };
$obj = new @$MODULE@;
isa_ok( $obj, '@$MODULE@' );
};
alarm 0;
if($@) {
fail ( 'new() - create an object' );
diag( $@ );
}
else {
pass ( 'new() - create an object' );
}
#
# list of all public and private methods
#
can_ok($obj, qw/@$METHODS@/);
# ====> !!!! DO NOT ERASE THIS LINE !!!! <==== #