Config-Abstraction
view release on metacpan or search on metacpan
t/mutant_killers.t view on Meta::CPAN
config_file => $path,
config_dirs => [''],
);
});
ok(defined($cfg), 'config_file parsed via Config::Auto fallback chain');
# If COND_INV_1474_9 were inverted, the Config::Abstract/Config::Auto block
# would be entered when $data IS a HASH (wrong), skipping needed data
# If COND_INV_1496_10 were inverted, Config::Auto parse result would be
# treated as no-data even when parse succeeded
ok(scalar(keys %{$cfg->all()}) > 1, 'Config::Auto loaded at least one key');
pass('COND_INV_1474_9 + COND_INV_1496_10: Config::Auto fallback path exercised');
}
};
subtest '_load_config() - Config::Abstract empty result undef-d (NUM_BOUNDARY_1486_37_!=)' => sub {
SKIP: {
skip 'Config::Abstract not installed â boundary test requires it', 1
unless eval { require Config::Abstract; 1 };
# Config::Abstract is not installed in this environment; test is structural only
pass('NUM_BOUNDARY_1486_37_!= covered if Config::Abstract available');
}
# Without Config::Abstract, verify the Config::Auto path still works cleanly
# (the 1486 boundary is internally about empty-Config::Abstract results;
# when Config::Abstract is absent, _load_driver returns false â block skipped)
my $dir = tempdir(CLEANUP => 1);
my $path = _write_file($dir, 'plain.cfg', "env: dev\n");
my $cfg;
_silenced(sub {
$cfg = Config::Abstraction->new(
data => { fallback => 1 },
config_file => $path,
config_dirs => [''],
);
});
ok(defined($cfg), 'object defined when Config::Abstract absent (falls to Config::Auto)');
};
# ===========================================================================
# COND_INV_1505_6, COND_INV_1512_5
# _load_config() - outer eval error branch and data-is-HASH guard
# Kills: inverting if($@) would skip error handling; inverting data+HASH check
# would push non-HASH data into source records
# ===========================================================================
subtest '_load_config() - parse error logged via logger, data cleared (COND_INV_1505_6)' => sub {
my $dir = tempdir(CLEANUP => 1);
# A file that looks like XML (triggers XML parsing path) but is malformed
_write_file($dir, 'base.xml', '<?xml version="1.0"?><root><unclosed>');
my @warns;
my $logger = bless {}, 'MKLogger2';
{
no warnings 'once';
local *MKLogger2::warn = sub { push @warns, $_[1] };
local *MKLogger2::notice = sub { push @warns, $_[1] };
local *MKLogger2::debug = sub { };
local *MKLogger2::trace = sub { };
my $cfg;
_silenced(sub {
$cfg = Config::Abstraction->new(
data => { sentinel => 'alive' },
config_dirs => [$dir],
logger => $logger,
);
});
# Data from data hash should survive even if XML parsing failed
ok(defined($cfg), 'object created despite XML parse failure');
is($cfg->get('sentinel'), 'alive', 'data sentinel survives parse error');
}
};
subtest '_load_config() - only HASH data merged into source records (COND_INV_1512_5)' => sub {
my $dir = tempdir(CLEANUP => 1);
_write_file($dir, 'base.yaml', "db:\n host: localhost\n port: 5432\n");
my $cfg = Config::Abstraction->new(config_dirs => [$dir]);
ok(defined($cfg), 'nested YAML loaded');
is($cfg->get('db.host'), 'localhost', 'nested key merged into config');
is($cfg->get('db.port'), '5432', 'nested integer merged');
# explain_sources verifies that source records were correctly populated
my $sources = $cfg->explain_sources();
ok(exists $sources->{'db.host'}, 'db.host has provenance record (COND_INV_1512_5)');
like($sources->{'db.host'}{sources}[0]{type}, qr/file|data/,
'provenance type is file or data');
};
# ===========================================================================
# COND_INV_1584_2 (additional coverage alongside existing 741_2 tests)
# _load_config() - flatten flag dispatches correctly
# ===========================================================================
subtest '_load_config() - flatten mode: flat keys vs nested (COND_INV_1584_2)' => sub {
my $dir = tempdir(CLEANUP => 1);
_write_file($dir, 'base.yaml', "server:\n host: myhost\n port: 8080\n");
my $flat = Config::Abstraction->new(config_dirs => [$dir], flatten => 1);
my $nested = Config::Abstraction->new(config_dirs => [$dir], flatten => 0);
ok(exists($flat->all()->{'server.host'}),
'flatten=1: dotted key present (COND_INV_1584_2 true branch)');
ok(!exists($flat->all()->{'server'}),
'flatten=1: nested key absent');
my $srv = $nested->get('server');
is(ref($srv), 'HASH',
'flatten=0: server is a nested hashref (COND_INV_1584_2 false branch)');
is($srv->{host}, 'myhost', 'flatten=0: nested value correct');
};
# ===========================================================================
# COND_INV_1665_3, COND_INV_1666_4, COND_INV_1667_5
# BOOL_NEGATE_1707_2, RETURN_UNDEF_1707_2
# get() fixation block and _load_data_reuse() return value
# Kills: inverting any of these conditions changes whether fixation is attempted
# ===========================================================================
subtest 'get() - Data::Reuse fixation path: HASH triggers _load_data_reuse (COND_INV_1665_3)' => sub {
my $cfg = Config::Abstraction->new(
data => { db => { host => 'h1', port => 5432 } },
config_dirs => [],
);
# get() on a nested hash enters the outer if (defined && HASH && !no_fixate)
# then checks _load_data_reuse(). If inverted, the check is skipped.
my $db = $cfg->get('db');
is(ref($db), 'HASH', 'hashref value returned (COND_INV_1665_3: fixation block entered)');
is($db->{host}, 'h1', 'nested hash content correct after fixation path');
};
subtest 'get() - scalar value skips fixation block (COND_INV_1665_3 outer false)' => sub {
my $cfg = Config::Abstraction->new(
data => { count => 42 },
( run in 2.338 seconds using v1.01-cache-2.11-cpan-14f38c9f855 )