/usr/share/perl5/Test/Class/Load.pm is in libtest-class-perl 0.47-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | use strict;
use warnings;
package Test::Class::Load;
use Test::Class;
use File::Find;
use File::Spec;
our $VERSION = '0.47';
# Override to get your own filter
sub is_test_class {
my ( $class, $file, $dir ) = @_;
# By default, we only care about .pm files
if ($file =~ /\.pm$/) {
return 1;
}
return;
}
my %Added_to_INC;
sub _load {
my ( $class, $file, $dir ) = @_;
$file =~ s{\.pm$}{}; # remove .pm extension
$file =~ s{\\}{/}g; # to make win32 happy
$dir =~ s{\\}{/}g; # to make win32 happy
$file =~ s/^$dir//;
my $_package = join '::' => grep $_ => File::Spec->splitdir( $file );
# untaint that puppy!
my ( $package ) = $_package =~ /^([[:word:]]+(?:::[[:word:]]+)*)$/;
# Filter out bad classes (mainly this means things in .svn and similar)
return unless defined $package;
unshift @INC => $dir unless $Added_to_INC{ $dir }++;
eval "require $package"; ## no critic
die $@ if $@;
}
sub import {
my ( $class, @directories ) = @_;
my @test_classes;
foreach my $dir ( @directories ) {
$dir = File::Spec->catdir( split '/', $dir );
find(
{ no_chdir => 1,
wanted => sub {
my @args = ($File::Find::name, $dir);
if ($class->is_test_class(@args)) {
$class->_load(@args);
}
},
},
$dir
);
}
}
1;
__END__
=head1 NAME
Test::Class::Load - Load C<Test::Class> classes automatically.
=head1 VERSION
Version 0.41
=head1 SYNOPSIS
use Test::Class::Load qw(t/tests t/lib);
Test::Class->runtests;
=head1 EXPORT
None.
=head1 DESCRIPTION
C<Test::Class> typically uses a helper script to load the test classes. It often looks something like this:
#!/usr/bin/perl -T
use strict;
use warnings;
use lib 't/tests';
use MyTest::Foo;
use MyTest::Foo::Bar;
use MyTest::Foo::Baz;
Test::Class->runtests;
This causes a problem, though. When you're writing a test class, it's easy to forget to add it to the helper script. Then you run your huge test suite and see that all tests pass, even though you don't notice that it didn't run your new test class. Or you delete a test class and you forget to remove it from the helper script.
C<Test::Class::Load> automatically finds and loads your test classes for you. There is no longer a need to list them individually.
=head1 BASIC USAGE
Using C<Test::Class::Load> is as simple as this:
#!/usr/bin/perl -T
use strict;
use warnings;
use Test::Class::Load 't/tests';
Test::Class->runtests;
That will search through all files in the C<t/tests> directory and automatically load anything which ends in C<.pm>. You should only put test classes in those directories.
If you have test classes in more than one directory, that's OK. Just list all of them in the import list.
use Test::Class::Load qw<
t/customer
t/order
t/inventory
>;
Test::Class->runtests;
=head1 ADVANCED USAGE
Here's some examples of advanced usage of C<Test::Class::Load>.
=head2 FILTER LOADED CLASSES
You can redefine the filtering criteria, that is, decide what classes are picked
up and what others are not. You do this simply by subclassing
C<Test::Class::Load> overriding the C<is_test_class()> method. You might want to
do this to only load modules which inherit from C<Test::Class>, or anything else
for that matter.
=over 4
=item B<is_test_class>
$is_test_class = $class->is_test_class( $file, $directory )
Returns true if C<$file> in C<$directory> should be considered a test class and be loaded by L<Test::Class::Load>. The default filter simply returns true if C<$file> ends with C<.pm>
=back
For example:
use strict;
use warnings;
package My::Loader;
use base qw( Test::Class::Load );
# Overriding this selects what test classes
# are considered by T::C::Load
sub is_test_class {
my ( $class, $file, $dir ) = @_;
# return unless it's a .pm (the default)
return unless $class->SUPER::is_test_class( $file, $dir );
# and only allow .pm files with "Good" in their filename
return $file =~ m{Good};
}
1;
=head2 CUSTOMIZING TEST RUNS
One problem with this style of testing is that you run I<all> of the tests every time you need to test something. If you want to run only one test class, it's problematic. The easy way to do this is to change your helper script by deleting the C<runtests> call:
#!/usr/bin/perl -T
use strict;
use warnings;
use Test::Class::Load 't/tests';
Then, just make sure that all of your test classes inherit from your own base class which runs the tests for you. It might looks something like this:
package My::Test::Class;
use strict;
use warnings;
use base 'Test::Class';
INIT { Test::Class->runtests } # here's the magic!
1;
Then you can run an individual test class by using the C<prove> utility, tell it the directory of the test classes and the name of the test package you wish to run:
prove -lv -It/tests Some::Test::Class
You can even automate this by binding it to a key in C<vim>:
noremap ,t :!prove -lv -It/tests %<CR>
Then you can just type C<,t> ('comma', 'tee') and it will run the tests for your test class or the tests for your test script (if you're using a traditional C<Test::More> style script).
Of course, you can still run your helper script with C<prove>, C<make test> or C<./Build test> to run all of your test classes.
If you do that, you'll have to make sure that the C<-I> switches point to your test class directories.
=head1 SECURITY
C<Test::Class::Load> is taint safe. Because we're reading the class names from the directory structure, they're marked as tainted when running under taint mode. We use the following ultra-paranoid bit of code to untaint them. Please file a bug report if this is too restrictive.
my ($package) = $_package =~ /^([[:word:]]+(?:::[[:word:]]+)*)$/;
=head1 AUTHOR
Curtis "Ovid" Poe, C<< <ovid@cpan.org> >>
=head1 BUGS
Please report any bugs or feature requests to C<bug-test-class-load@rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-Class-Load>. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
=head1 ACKNOWLEDGMENTS
Thanks to David Wheeler for the idea and Adrian Howard for C<Test::Class>.
=head1 COPYRIGHT & LICENSE
Copyright 2006 Curtis "Ovid" Poe, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
|