Config-Abstraction

 view release on metacpan or  search on metacpan

t/mutant_killers.t  view on Meta::CPAN

	ok(defined($cfg), 'object created from multi-section INI');
	is($cfg->get('database.user'),  'alice',          'INI section 1 key 1 loaded');
	is($cfg->get('database.port'),  5432,             'INI section 1 key 2 loaded');
	is($cfg->get('logging.level'), 'info',            'INI section 2 key 1 loaded');
};

subtest '_load_config() - INI with logger routes error to logger (COND_INV_531_6)' => sub {
	# A malformed INI with a logger present must log the error, not carp.
	# If the condition were inverted, the logger branch would be skipped.
	my @log;
	my $dir = tempdir(CLEANUP => 1);
	# Write something that Config::IniFiles will reject
	_write_file($dir, 'base.ini', "not an ini file at all\x00\x01\x02\n");

	lives_ok {
		_silenced(sub {
			my $cfg = Config::Abstraction->new(
				data        => { fallback => 'yes' },
				config_dirs => [$dir],
				logger      => \@log,
			);
		});
	}, 'malformed INI with logger does not crash';
};

# ===========================================================================
# COND_INV_545_3
# _load_config() - script_name exclusion from current dir
# Kills: inversion of the guard that prevents loading the script as config
# ===========================================================================
subtest '_load_config() - script not loaded as its own config (COND_INV_545_3)' => sub {
	# The script itself must never be loaded as a config file.
	# If the condition were inverted, the script would be loaded.
	my $cfg = Config::Abstraction->new(
		data        => { key => 'value' },
		config_dirs => [File::Spec->curdir()],
	);
	# If the script were loaded as config it might fail or produce garbage;
	# the key assertion confirms data is from the data arg, not the script
	ok(defined($cfg),             'script not loaded as own config');
	is($cfg->get('key'), 'value', 'data intact: script not treated as config');
};

# ===========================================================================
# NUM_BOUNDARY_557_61_!=
# _load_config() - script_name caching: set once, not reset on each dir
# Kills: flip of == to != in the script_name guard
# ===========================================================================
subtest '_load_config() - script_name set once and reused (NUM_BOUNDARY_557_61_!=)' => sub {
	# script_name must be derived once and cached.
	# If == were flipped to !=, script_name would be re-derived every iteration.
	my $dir1 = tempdir(CLEANUP => 1);
	my $dir2 = tempdir(CLEANUP => 1);
	_write_file($dir1, 'base.yaml', "dir1key: dir1val\n");
	_write_file($dir2, 'base.yaml', "dir2key: dir2val\n");

	my $cfg = Config::Abstraction->new(
		config_dirs => [$dir1, $dir2],
	);
	ok(defined($cfg),                  'object created with multiple dirs');
	# Both dirs loaded; script_name consistent across both iterations
	is($cfg->get('dir1key'), 'dir1val', 'dir1 loaded correctly');
	is($cfg->get('dir2key'), 'dir2val', 'dir2 loaded correctly');
	ok(defined($cfg->{script_name}),   'script_name was set');
};

# ===========================================================================
# COND_INV_570_8
# _load_config() - path construction: catfile vs bare filename
# Kills: inversion of the length($dir) ternary condition
# ===========================================================================
subtest '_load_config() - non-empty dir: path uses catfile (COND_INV_570_8)' => sub {
	# When dir is non-empty, File::Spec->catfile(dir, file) must be used.
	# If the condition were inverted, the bare filename would be used instead.
	my $dir = tempdir(CLEANUP => 1);
	_write_file($dir, 'base.yaml', "dirkey: dirval\n");

	my $cfg = Config::Abstraction->new(config_dirs => [$dir]);
	is($cfg->get('dirkey'), 'dirval', 'non-empty dir: catfile path used correctly');
};

subtest '_load_config() - empty dir string: bare filename used (COND_INV_570_8)' => sub {
	# When dir is empty string, the bare config_file name is used directly.
	my $orig_dir = File::Spec->curdir();
	my $dir = tempdir(CLEANUP => 1);

	# Write to current working directory temporarily
	my $old_cwd = File::Spec->curdir();
	chdir($dir);
	_write_file($dir, 'myapp.cfg', "barekey: bareval\n");

	my $cfg;
	_silenced(sub {
		$cfg = Config::Abstraction->new(
			config_file => 'myapp.cfg',
			config_dirs => [''],
		);
	});
	chdir($old_cwd);
	# May or may not load depending on parser; verify no crash
	ok(!$@, 'empty dir with bare filename does not crash');
};

# ===========================================================================
# COND_INV_597_7
# _load_config() - JSON detection in generic file parser
# Kills: inversion of the JSON pattern match condition
# ===========================================================================
subtest '_load_config() - JSON-like content detected and parsed (COND_INV_597_7)' => sub {
	# The JSON detection regex must match JSON-like content.
	# If inverted, JSON config_files would not be parsed.
	my $dir = tempdir(CLEANUP => 1);
	_write_file($dir, 'myapp.json', '{"jsonfile":"jsonfileval","port":8080}');

	my $cfg = Config::Abstraction->new(
		config_file => 'myapp.json',
		config_dirs => [$dir],
	);
	ok(defined($cfg),                    'JSON config_file parsed');
	is($cfg->get('jsonfile'), 'jsonfileval', 'JSON config_file string value loaded');
	is($cfg->get('port'),     8080,          'JSON config_file integer value loaded');



( run in 0.868 second using v1.01-cache-2.11-cpan-71847e10f99 )