Config-Abstraction
view release on metacpan or search on metacpan
t/integration.t view on Meta::CPAN
# Keys not in file retain data defaults
is($cfg->get('retries'), $EXPECTED_RETRIES, 'data default retained for key absent from YAML');
# config_path records the file
my $all = $cfg->all();
my @paths = @{$all->{config_path}};
ok(grep { /\Q$YAML_BASE\E/ } @paths, 'config_path includes YAML file');
};
# ===========================================================================
# File loading end-to-end: local overrides base
# ===========================================================================
subtest 'end-to-end: local.yaml overrides base.yaml' => sub {
my $dir = tempdir(CLEANUP => 1);
_write_file($dir, $YAML_BASE, "level: base\ntimeout: $EXPECTED_TIMEOUT\n");
_write_file($dir, $YAML_LOCAL, "level: local\n");
my $cfg = new_ok($MODULE => [config_dirs => [$dir]]);
is($cfg->get('level'), 'local', 'local.yaml overrides base.yaml');
is($cfg->get('timeout'), $EXPECTED_TIMEOUT, 'base.yaml value retained when not in local');
};
# ===========================================================================
# File loading end-to-end: JSON
# ===========================================================================
subtest 'end-to-end: JSON file loaded and accessible' => sub {
my $dir = tempdir(CLEANUP => 1);
_write_file($dir, $JSON_BASE,
qq({"database":{"user":"$OVERRIDE_USER","port":$OVERRIDE_PORT},"retries":$EXPECTED_RETRIES}));
my $cfg = new_ok($MODULE => [config_dirs => [$dir]]);
is($cfg->get('database.user'), $OVERRIDE_USER, 'JSON database.user loaded');
is($cfg->get('database.port'), $OVERRIDE_PORT, 'JSON database.port loaded');
is($cfg->get('retries'), $EXPECTED_RETRIES, 'JSON retries loaded');
};
# ===========================================================================
# File loading end-to-end: INI
# ===========================================================================
subtest 'end-to-end: INI file loaded and accessible' => sub {
my $dir = tempdir(CLEANUP => 1);
_write_file($dir, $INI_BASE, <<END);
[database]
user=$OVERRIDE_USER
port=$OVERRIDE_PORT
END
my $cfg = new_ok($MODULE => [config_dirs => [$dir]]);
is($cfg->get('database.user'), $OVERRIDE_USER, 'INI database.user loaded');
is($cfg->get('database.port'), $OVERRIDE_PORT, 'INI database.port loaded');
};
# ===========================================================================
# Full merge precedence stack: data < file < ENV < CLI
# ===========================================================================
subtest 'end-to-end: full merge precedence stack' => sub {
local %ENV = %ENV;
local @ARGV = ("--${ENV_PREFIX}DATABASE__USER=cli_user");
$ENV{"${ENV_PREFIX}DATABASE__PORT"} = $OVERRIDE_PORT;
my $dir = tempdir(CLEANUP => 1);
_write_file($dir, $YAML_BASE,
"database:\n user: file_user\n port: $EXPECTED_PORT\n host: $EXPECTED_HOST\n");
my $cfg = new_ok($MODULE => [
data => _fresh_data(),
config_dirs => [$dir],
env_prefix => $ENV_PREFIX,
]);
# CLI beats everything
is($cfg->get('database.user'), 'cli_user', 'CLI wins over ENV/file/data');
# ENV beats file and data
is($cfg->get('database.port'), $OVERRIDE_PORT, 'ENV wins over file/data');
# File beats data
is($cfg->get('database.host'), $EXPECTED_HOST, 'file value present');
# Data provides fallback
is($cfg->get('retries'), $EXPECTED_RETRIES, 'data fallback intact');
};
# ===========================================================================
# merge_defaults() integration with caller package workflow
# POD: merge_defaults is designed for use in other modules' new() methods
# ===========================================================================
subtest 'end-to-end: merge_defaults() workflow as documented in POD' => sub {
my $cfg = new_ok($MODULE => [
data => _fresh_data(),
config_dirs => [],
]);
# Simulate the documented pattern: caller passes its own $params hash
my $caller_params = {
timeout => 99,
retries => 99,
extra => 'caller_value',
};
my $merged = $cfg->merge_defaults(
defaults => $caller_params,
merge => 1,
);
# Config overrides caller defaults on conflict
is($merged->{retries}, $EXPECTED_RETRIES, 'config wins over caller default');
is($merged->{timeout}, $EXPECTED_TIMEOUT, 'config wins over caller timeout');
# Caller-only keys preserved
is($merged->{extra}, 'caller_value', 'caller-only key preserved');
};
subtest 'end-to-end: merge_defaults() with global section' => sub {
my $cfg = new_ok($MODULE => [
data => {
global => { timeout => $GLOBAL_TIMEOUT, loglevel => $EXPECTED_LEVEL },
retries => $EXPECTED_RETRIES,
},
config_dirs => [],
]);
( run in 0.540 second using v1.01-cache-2.11-cpan-9169edd2b0e )