Genealogy-Military-Branch
view release on metacpan or search on metacpan
t/extended_tests.t view on Meta::CPAN
#!/usr/bin/env perl
# extended_tests.t - targeted coverage tests for Genealogy::Military::Branch.
#
# Each subtest is chosen to exercise a specific branch, linear code
# sequence, or decision point not reached by unit.t, integration.t, or
# edge_cases.t. Together they aim for >=95% statement coverage and
# maximum LCSAJ/TER3 scores by exercising every reachable path through
# _get_language, _translate, new(), and detect().
#
# External dependencies are mocked where needed to isolate code paths;
# env vars are localised to prevent host-locale interference.
use strict;
use warnings;
use 5.014;
use Test::Most;
use Test::Mockingbird 0.09 qw(mock_scoped);
use_ok('Genealogy::Military::Branch') or BAIL_OUT('Cannot load Genealogy::Military::Branch');
# -----------------------------------------------------------------------
# _get_language - environment variable cascade (all fallback paths)
# Each subtest exercises a distinct branch in the cascade:
# detect() â LANGUAGE â LC_ALL â LC_MESSAGES â LANG â C-locale â undef
# -----------------------------------------------------------------------
subtest '_get_language - LANGUAGE env var used when detect() returns nothing' => sub {
delete local $ENV{LC_ALL};
delete local $ENV{LC_MESSAGES};
delete local $ENV{LANG};
local $ENV{LANGUAGE} = 'de_DE.UTF-8';
# detect() returns nothing so the I18N::LangTags path is skipped;
# _get_language must fall through to the LANGUAGE env var
my $guard = mock_scoped('I18N::LangTags::Detect::detect' => sub { () });
my $obj = Genealogy::Military::Branch->new();
is($obj->detect(text => 'He served in the Navy'),
'Marine', 'LANGUAGE env var drives German language detection');
};
subtest '_get_language - LC_ALL used when LANGUAGE and detect() both absent' => sub {
delete local $ENV{LANGUAGE};
delete local $ENV{LC_MESSAGES};
delete local $ENV{LANG};
local $ENV{LC_ALL} = 'fr_FR.UTF-8';
my $guard = mock_scoped('I18N::LangTags::Detect::detect' => sub { () });
my $obj = Genealogy::Military::Branch->new();
# LC_ALL is the first entry in the foreach fallback list
is($obj->detect(text => 'He served in the Navy'),
'marine', 'LC_ALL env var drives French language detection');
};
subtest '_get_language - LC_MESSAGES used when higher-priority vars absent' => sub {
delete local $ENV{LANGUAGE};
delete local $ENV{LC_ALL};
delete local $ENV{LANG};
local $ENV{LC_MESSAGES} = 'de_DE.UTF-8';
my $guard = mock_scoped('I18N::LangTags::Detect::detect' => sub { () });
my $obj = Genealogy::Military::Branch->new();
# LC_MESSAGES is the second entry in the foreach fallback list
is($obj->detect(text => 'He served in the Navy'),
'Marine', 'LC_MESSAGES env var drives German language detection');
};
subtest '_get_language - C.UTF-8 locale treated as English' => sub {
delete local $ENV{LANGUAGE};
delete local $ENV{LC_ALL};
delete local $ENV{LC_MESSAGES};
local $ENV{LANG} = 'C.UTF-8';
my $guard = mock_scoped('I18N::LangTags::Detect::detect' => sub { () });
# 'C.UTF-8' does not start with two letters so the foreach loop skips it;
# the explicit /^C(\.|$)/ guard then fires and returns 'en'
my $obj = Genealogy::Military::Branch->new();
is($obj->detect(text => 'He served in the Navy'),
'navy', 'C.UTF-8 locale treated as English');
};
subtest '_get_language - detect() returning hyphenated tag extracts prefix' => sub {
delete local $ENV{LANGUAGE};
delete local $ENV{LC_ALL};
delete local $ENV{LC_MESSAGES};
local $ENV{LANG} = 'en_GB.UTF-8';
# 'fr-FR' â /^([a-z]{2})/i captures 'fr'; object behaves as French
my $guard = mock_scoped('I18N::LangTags::Detect::detect' => sub { 'fr-FR' });
my $obj = Genealogy::Military::Branch->new();
is($obj->detect(text => 'He served in the Navy'),
'marine', 'hyphenated detect() tag "fr-FR" extracts "fr"');
};
subtest '_get_language - non-matching detect() tag falls through to env vars' => sub {
delete local $ENV{LANGUAGE};
delete local $ENV{LC_ALL};
delete local $ENV{LC_MESSAGES};
local $ENV{LANG} = 'de_DE.UTF-8';
# '123' does not match /^([a-z]{2})/i so the loop exhausts without returning;
# control falls through to the LANGUAGE/LC_ALL/LC_MESSAGES/LANG cascade
my $guard = mock_scoped('I18N::LangTags::Detect::detect' => sub { '123' });
my $obj = Genealogy::Military::Branch->new();
is($obj->detect(text => 'He served in the Navy'),
'Marine', 'non-matching detect() tag falls through to LANG env var');
};
subtest '_get_language - undef returned when no locale detectable' => sub {
delete local $ENV{LANGUAGE};
delete local $ENV{LC_ALL};
delete local $ENV{LC_MESSAGES};
delete local $ENV{LANG};
# All env vars absent and detect() empty â _get_language returns undef;
# new() must default gracefully via $language // _get_language() // 'en'
my $guard = mock_scoped('I18N::LangTags::Detect::detect' => sub { () });
my $obj = Genealogy::Military::Branch->new();
lives_ok(sub { $obj->detect(text => 'He served in the Navy') },
'undef language defaults to English without crashing');
is($obj->detect(text => 'He served in the Navy'),
'navy', 'undef language treated as English');
};
# -----------------------------------------------------------------------
# _translate - uncovered branches
# -----------------------------------------------------------------------
subtest '_translate - unknown language falls back to English' => sub {
delete local $ENV{LANGUAGE};
delete local $ENV{LC_ALL};
delete local $ENV{LC_MESSAGES};
local $ENV{LANG} = 'en_GB.UTF-8';
my $guard = mock_scoped('I18N::LangTags::Detect::detect' => sub { () });
# 'es' is not a key in %TRANSLATIONS; _translate must fall back to 'en'
my $obj = Genealogy::Military::Branch->new(language => 'es');
is($obj->detect(text => 'He served in the Navy'),
'navy', 'unknown language "es" falls back to English "navy"');
is($obj->detect(text => 'Served with the RAF'),
'RAF', 'unknown language "es" falls back to English "RAF"');
};
subtest '_translate - bare key returned when absent from all translation tables' => sub {
delete local $ENV{LANGUAGE};
delete local $ENV{LC_ALL};
delete local $ENV{LC_MESSAGES};
local $ENV{LANG} = 'en_GB.UTF-8';
my $guard = mock_scoped('I18N::LangTags::Detect::detect' => sub { () });
# Call _translate directly with a key present in neither lang-specific nor
# 'en' tables; the final $key fallback ($TRANSLATIONS{'en'}{$key} // $key)
# must return the key itself
my $obj = Genealogy::Military::Branch->new(language => 'en');
is($obj->_translate('nonexistent_branch_key'),
'nonexistent_branch_key',
'_translate returns bare key when absent from all translation tables');
};
subtest '_translate - undef language field defaults to "en"' => sub {
( run in 2.561 seconds using v1.01-cache-2.11-cpan-5c0b1e786e0 )