From: Peter Rabbitson Date: Wed, 28 Jan 2009 09:45:25 +0000 (+0000) Subject: make load_optional_class smarter when confronted with a PAR environment X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=7dd382fbb39720502560f0594d783f9b23cfe898;p=dbsrgits%2FDBIx-Class-Historic.git make load_optional_class smarter when confronted with a PAR environment --- diff --git a/lib/DBIx/Class/Componentised.pm b/lib/DBIx/Class/Componentised.pm index db70c7b..a438c06 100644 --- a/lib/DBIx/Class/Componentised.pm +++ b/lib/DBIx/Class/Componentised.pm @@ -36,11 +36,19 @@ sub inject_base { # successfully, and false if the class is not installed sub load_optional_class { my ($class, $f_class) = @_; - if ($class->ensure_class_found($f_class)) { - $class->ensure_class_loaded($f_class); + eval { $class->ensure_class_loaded($f_class) }; + my $err = $@; # so we don't lose it + if (! $err) { return 1; - } else { - return 0; + } + else { + my $fn = (join ('/', split ('::', $f_class) ) ) . '.pm'; + if ($err =~ /Can't locate ${fn} in \@INC/ ) { + return 0; + } + else { + die $err; + } } } diff --git a/t/90ensure_class_loaded.t b/t/90ensure_class_loaded.t index 3fc828e..1746d4c 100644 --- a/t/90ensure_class_loaded.t +++ b/t/90ensure_class_loaded.t @@ -13,7 +13,7 @@ BEGIN { my $schema = DBICTest->init_schema(); -plan tests => 20; +plan tests => 28; # Test ensure_class_found ok( $schema->ensure_class_found('DBIx::Class::Schema'), @@ -40,6 +40,50 @@ eval { $schema->load_optional_class('DBICTest::ErrorComponent') }; like( $@, qr/did not return a true value/, 'DBICTest::ErrorComponent threw ok' ); +# Simulate a PAR environment +{ + my @code; + local @INC = @INC; + unshift @INC, sub { + if ($_[1] eq 'VIRTUAL/PAR/PACKAGE.pm') { + return (sub { return 0 unless @code; $_ = shift @code; 1; } ); + } + else { + return (); + } + }; + + $retval = eval { $schema->load_optional_class('FAKE::PAR::PACKAGE') }; + ok( !$@, 'load_optional_class on a nonexistent PAR class did not throw' ); + ok( !$retval, 'nonexistent PAR package not loaded' ); + + + # simulate a class which does load but does not return true + @code = ( + q/package VIRTUAL::PAR::PACKAGE;/, + q/0;/, + ); + + $retval = eval { $schema->load_optional_class('VIRTUAL::PAR::PACKAGE') }; + ok( $@, 'load_optional_class of a no-true-returning PAR module did throw' ); + ok( !$retval, 'no-true-returning PAR package not loaded' ); + + # simulate a normal class (no one adjusted %INC so it will be tried again + @code = ( + q/package VIRTUAL::PAR::PACKAGE;/, + q/1;/, + ); + + $retval = eval { $schema->load_optional_class('VIRTUAL::PAR::PACKAGE') }; + ok( !$@, 'load_optional_class of a PAR module did not throw' ); + ok( $retval, 'PAR package "loaded"' ); + + # see if we can still load stuff with the coderef present + $retval = eval { $schema->load_optional_class('DBIx::Class::ResultClass::HashRefInflator') }; + ok( !$@, 'load_optional_class did not throw' ) || diag $@; + ok( $retval, 'DBIx::Class::ResultClass::HashRefInflator loaded' ); +} + # Test ensure_class_loaded ok( Class::Inspector->loaded('TestPackage::A'), 'anonymous package exists' ); eval { $schema->ensure_class_loaded('TestPackage::A'); };