summaryrefslogtreecommitdiff
path: root/lib/Test/Requires.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Test/Requires.pm')
-rw-r--r--lib/Test/Requires.pm147
1 files changed, 147 insertions, 0 deletions
diff --git a/lib/Test/Requires.pm b/lib/Test/Requires.pm
new file mode 100644
index 0000000..3767c24
--- /dev/null
+++ b/lib/Test/Requires.pm
@@ -0,0 +1,147 @@
+package Test::Requires;
+use strict;
+use warnings;
+our $VERSION = '0.08';
+use base 'Test::Builder::Module';
+use 5.006000;
+
+sub import {
+ my $class = shift;
+ my $caller = caller(0);
+
+ # export methods
+ {
+ no strict 'refs';
+ *{"$caller\::test_requires"} = \&test_requires;
+ }
+
+ # test arguments
+ if (@_ == 1 && ref $_[0] && ref $_[0] eq 'HASH') {
+ while (my ($mod, $ver) = each %{$_[0]}) {
+ test_requires($mod, $ver, $caller);
+ }
+ } else {
+ for my $mod (@_) {
+ test_requires($mod, undef, $caller);
+ }
+ }
+}
+
+sub test_requires {
+ my ( $mod, $ver, $caller ) = @_;
+ return if $mod eq __PACKAGE__;
+ if (@_ != 3) {
+ $caller = caller(0);
+ }
+ $ver ||= '';
+
+ eval qq{package $caller; use $mod $ver}; ## no critic.
+ if (my $e = $@) {
+ my $skip_all = sub {
+ my $builder = __PACKAGE__->builder;
+
+ if (not defined $builder->has_plan) {
+ $builder->skip_all(@_);
+ } elsif ($builder->has_plan eq 'no_plan') {
+ $builder->skip(@_);
+ if ( $builder->can('parent') && $builder->parent ) {
+ die bless {} => 'Test::Builder::Exception';
+ }
+ exit 0;
+ } else {
+ for (1..$builder->has_plan) {
+ $builder->skip(@_);
+ }
+ if ( $builder->can('parent') && $builder->parent ) {
+ die bless {} => 'Test::Builder::Exception';
+ }
+ exit 0;
+ }
+ };
+
+ my $msg = "$e";
+ if ( $e =~ /^Can't locate/ ) {
+ $msg = "Test requires module '$mod' but it's not found";
+ }
+
+ if ($ENV{RELEASE_TESTING}) {
+ __PACKAGE__->builder->BAIL_OUT($msg);
+ }
+ else {
+ $skip_all->($msg);
+ }
+ }
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Test::Requires - Checks to see if the module can be loaded
+
+=head1 SYNOPSIS
+
+ # in your Makefile.PL
+ use inc::Module::Install;
+ test_requires 'Test::Requires';
+
+ # in your test
+ use Test::More tests => 10;
+ use Test::Requires {
+ 'HTTP::MobileAttribute' => 0.01, # skip all if HTTP::MobileAttribute doesn't installed
+ };
+ isa_ok HTTP::MobileAttribute->new, 'HTTP::MobileAttribute::NonMobile';
+
+ # or
+ use Test::More tests => 10;
+ use Test::Requires qw(
+ HTTP::MobileAttribute
+ );
+ isa_ok HTTP::MobileAttribute->new, 'HTTP::MobileAttribute::NonMobile';
+
+ # or
+ use Test::More tests => 10;
+ use Test::Requires;
+ test_requires 'Some::Optional::Test::Required::Modules';
+ isa_ok HTTP::MobileAttribute->new, 'HTTP::MobileAttribute::NonMobile';
+
+=head1 DESCRIPTION
+
+Test::Requires checks to see if the module can be loaded.
+
+If this fails rather than failing tests this B<skips all tests>.
+
+Test::Requires can also be used to require a minimum version of Perl:
+
+ use Test::Requires "5.010"; # quoting is necessary!!
+
+ # or
+ use Test::Requires "v5.10";
+
+=head1 AUTHOR
+
+Tokuhiro Matsuno E<lt>tokuhirom @*(#RJKLFHFSDLJF gmail.comE<gt>
+
+=head1 THANKS TO
+
+ kazuho++ # some tricky stuff
+ miyagawa++ # original code from t/TestPlagger.pm
+ tomyhero++ # reported issue related older test::builder
+ tobyink++ # documented that Test::Requires "5.010" works
+
+=head1 ENVIRONMENT
+
+If the C<< RELEASE_TESTING >> environment variable is true, then instead
+of skipping tests, Test::Requires bails out.
+
+=head1 SEE ALSO
+
+L<t/TestPlagger.pm>
+
+=head1 LICENSE
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut