use strict;
use warnings;
-my %exports = (
- load_or_skip => \&load_or_skip,
- skip_all => \&skip_all,
-);
+use Config ();
-sub import {
- my $pkg = caller;
+sub export_to_pkg {
+ my ($subs, $pkg) = @_;
- while (my ($name, $code) = each %exports) {
+ while (my ($name, $code) = each %$subs) {
no strict 'refs';
*{$pkg.'::'.$name} = $code;
}
+
+ return 1;
+}
+
+my %default_exports = (
+ load_or_skip => \&load_or_skip,
+ load_or_skip_all => \&load_or_skip_all,
+ run_perl => \&run_perl,
+ skip_all => \&skip_all,
+);
+
+my %features = ();
+
+sub import {
+ shift;
+ my @opts = @_;
+
+ my %exports = %default_exports;
+
+ for (my $i = 0; $i <= $#opts; ++$i) {
+ my $feature = $opts[$i];
+ next unless defined $feature;
+
+ my $args;
+ if ($i < $#opts and defined $opts[$i+1] and ref $opts[$i+1] eq 'ARRAY') {
+ ++$i;
+ $args = $opts[$i];
+ } else {
+ $args = [ ];
+ }
+
+ my $handler = $features{$feature};
+ die "Unknown feature '$feature'" unless defined $handler;
+
+ my %syms = $handler->(@$args);
+
+ $exports{$_} = $syms{$_} for sort keys %syms;
+ }
+
+ export_to_pkg \%exports => scalar caller;
}
my $test_sub = sub {
return $glob ? *$glob{CODE} : undef;
};
+sub skip { $test_sub->('skip')->(@_) }
+
sub skip_all { $test_sub->('plan')->(skip_all => $_[0]) }
sub diag {
our $TODO;
local $TODO;
-sub load_or_skip {
- my ($pkg, $ver, $imports, $desc) = @_;
+sub load {
+ my ($pkg, $ver, $imports) = @_;
+
my $spec = $ver && $ver !~ /^[0._]*$/ ? "$pkg $ver" : $pkg;
+ my $err;
+
local $@;
if (eval "use $spec (); 1") {
$ver = do { no strict 'refs'; ${"${pkg}::VERSION"} };
if ($imports) {
my @imports = @$imports;
- my $caller = (caller 0)[0];
+ my $caller = (caller 1)[0];
local $@;
my $res = eval <<"IMPORTER";
package
BEGIN { \$pkg->import(\@imports) }
1;
IMPORTER
- skip_all "Could not import '@imports' from $pkg $ver: $@" unless $res;
+ $err = "Could not import '@imports' from $pkg $ver: $@" unless $res;
}
- diag "Using $pkg $ver";
} else {
(my $file = "$pkg.pm") =~ s{::}{/}g;
delete $INC{$file};
- skip_all "$spec $desc";
+ $err = "Could not load $spec";
+ }
+
+ if ($err) {
+ return wantarray ? (0, $err) : 0;
+ } else {
+ diag "Using $pkg $ver";
+ return 1;
}
}
+sub load_or_skip {
+ my ($pkg, $ver, $imports, $tests) = @_;
+
+ die 'You must specify how many tests to skip' unless defined $tests;
+
+ my ($loaded, $err) = load($pkg, $ver, $imports);
+ skip $err => $tests unless $loaded;
+
+ return $loaded;
+}
+
+sub load_or_skip_all {
+ my ($pkg, $ver, $imports) = @_;
+
+ my ($loaded, $err) = load($pkg, $ver, $imports);
+ skip_all $err unless $loaded;
+
+ return $loaded;
+}
+
+sub run_perl {
+ my $code = shift;
+
+ my ($SystemRoot, $PATH) = @ENV{qw<SystemRoot PATH>};
+ my $ld_name = $Config::Config{ldlibpthname};
+ my $ldlibpth = $ENV{$ld_name};
+
+ local %ENV;
+ $ENV{$ld_name} = $ldlibpth if defined $ldlibpth;
+ $ENV{SystemRoot} = $SystemRoot if $^O eq 'MSWin32' and defined $SystemRoot;
+ $ENV{PATH} = $PATH if $^O eq 'cygwin' and defined $PATH;
+
+ system { $^X } $^X, '-T', map("-I$_", @INC), '-e', $code;
+}
+
package VPIT::TestHelpers::Guard;
sub new {