DBIO
view release on metacpan or search on metacpan
t/test/20_async_future_io_unloadable_adapter.t view on Meta::CPAN
# ---------------------------------------------------------------------------
my $tmplib = File::Temp->newdir;
# T::Unl::MissingDep::Storage::Async -- file EXISTS, but its base class dist is
# not installed (mirrors DBIO::MySQL::Storage::Async when DBIO::Async is absent).
my $missing_dir = dir_path("$tmplib", qw(T Unl MissingDep Storage));
mkpath($missing_dir);
write_file(file_path($missing_dir, 'Async.pm'), <<'EOF');
package T::Unl::MissingDep::Storage::Async;
use strict; use warnings;
use base 'DBIO::Async::NotInstalled::Storage'; # not installed -> compile dies
1;
EOF
# T::Unl::Syntax::Storage::Async -- file EXISTS, installs fine on disk, but has a
# genuine syntax error. Must NOT be misreported as a missing dependency.
my $syntax_dir = dir_path("$tmplib", qw(T Unl Syntax Storage));
mkpath($syntax_dir);
write_file(file_path($syntax_dir, 'Async.pm'), <<'EOF');
package T::Unl::Syntax::Storage::Async;
use strict; use warnings;
this is not valid perl $#@!;
1;
EOF
# T::Unl::Layer::Async -- convention sibling of a storage LAYER, present on disk
# but unloadable (missing base class). Exercises the layer-composition call site.
my $layer_dir = dir_path("$tmplib", qw(T Unl Layer));
mkpath($layer_dir);
write_file(file_path($layer_dir, 'Async.pm'), <<'EOF');
package T::Unl::Layer::Async;
use strict; use warnings;
use base 'DBIO::Async::NotInstalled::LayerBase'; # not installed -> compile dies
1;
EOF
unshift @INC, "$tmplib";
# ---------------------------------------------------------------------------
# Driver storage classes (inline; isa DBIO::Test::Storage). The ::Async siblings
# for the first two live on disk in $tmplib; the "absent" one has none anywhere.
# ---------------------------------------------------------------------------
{
package T::Unl::MissingDep::Storage;
use base 'DBIO::Test::Storage';
use mro 'c3';
}
{
package T::Unl::Syntax::Storage;
use base 'DBIO::Test::Storage';
use mro 'c3';
}
{
package T::Unl::Absent::Storage; # no ::Async anywhere in its MRO
use base 'DBIO::Test::Storage';
use mro 'c3';
}
# Build a driver storage of $class in future_io mode bound to a live schema,
# matching t/test/17's helper. Returns ($storage, $schema); keep $schema in
# scope (storage weakens its schema back-reference).
sub driver_storage {
my ($class) = @_;
my $schema = DBIO::Test->init_schema;
my $storage = $class->new($schema);
$storage->_async_mode('future_io');
delete $storage->{_async_storage_obj};
$storage->_connect_info([ { host => 'localhost' } ]);
return ($storage, $schema);
}
# ---------------------------------------------------------------------------
# (a) Genuinely NO adapter anywhere: the existing friendly "no adapter found"
# croak still fires unchanged (regression guard for the untouched path).
# ---------------------------------------------------------------------------
{
my ($storage, $schema) = driver_storage('T::Unl::Absent::Storage');
my $async = eval { $storage->async };
my $err = $@;
ok !defined($async) && $err, 'absent adapter still croaks';
like $err, qr/does not support future_io/,
'absent: existing future_io croak wording preserved';
like $err, qr/no \QT::Unl::Absent::Storage::Async\E adapter found/,
'absent: existing "no <class>::Async adapter found" wording preserved';
unlike $err, qr/is not installed|present but/,
'absent: not mistaken for a present-but-unloadable adapter';
}
# ---------------------------------------------------------------------------
# (b) Adapter file PRESENT but its own dependency is not installed: a clear,
# actionable message naming the adapter AND the missing module -- not a raw
# compile trace, and not the generic "no adapter found" (absent) wording.
# ---------------------------------------------------------------------------
{
my ($storage, $schema) = driver_storage('T::Unl::MissingDep::Storage');
my $async = eval { $storage->async };
my $err = $@;
ok !defined($async) && $err, 'present-but-unloadable adapter croaks';
like $err, qr/\QT::Unl::MissingDep::Storage::Async\E/,
'present-but-unloadable: message names the adapter that could not load';
like $err, qr/\QDBIO::Async::NotInstalled::Storage\E/,
'present-but-unloadable: message names the actual missing module';
like $err, qr/is not installed/,
'present-but-unloadable: message says the dependency is not installed';
like $err, qr/Install the distribution/,
'present-but-unloadable: message gives an actionable install hint';
# It must NOT be misreported as "no adapter found" -- the adapter IS present.
unlike $err, qr/no \S+ adapter found/,
'present-but-unloadable: NOT misreported as a genuinely-absent adapter';
# The underlying cause is surfaced, not swallowed...
like $err, qr/Underlying error:/,
'present-but-unloadable: the underlying cause is surfaced, not swallowed';
# ...but wrapped in our framing, not left as a bare Componentised stack.
like $err, qr/present but cannot be loaded/,
'present-but-unloadable: wrapped in our framing, not a bare compile stack';
}
( run in 0.516 second using v1.01-cache-2.11-cpan-995e09ba956 )