Archive-Lha
view release on metacpan or search on metacpan
t/charset.t view on Meta::CPAN
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
use FindBin qw/$Bin/;
use Archive::Lha::Header;
use Archive::Lha::Header::Base;
use Archive::Lha::Stream::File;
# charset_for_os maps OS byte to encoding name
my %os_map = (
'a' => 'iso-8859-15', # Amiga
'M' => 'cp1252', # MS-DOS / Windows
'w' => 'cp1252', # WinNT / Win95
'U' => 'guess', # Unix (encoding varies)
'H' => 'cp932', # Human68K
'J' => 'cp932', # Java VM
'm' => 'UTF-8', # Macintosh
'?' => 'guess', # unknown -> Encode::Guess
);
subtest 'charset_for_os OS mapping' => sub {
for my $os (sort keys %os_map) {
my $obj = bless { os => [$os] }, 'Archive::Lha::Header::Level2';
is Archive::Lha::Header::Base::charset_for_os($obj),
$os_map{$os},
"OS '$os' -> $os_map{$os}";
}
};
subtest 'charset_for_os with no OS field' => sub {
my $obj = bless {}, 'Archive::Lha::Header::Level0';
is Archive::Lha::Header::Base::charset_for_os($obj), 'guess',
'missing OS field falls back to guess';
};
subtest 'Amiga archive: latin-1 filename decoded to UTF-8' => sub {
my $archive = "$Bin/archive/Amoric_src.lha";
plan skip_all => "Amoric_src.lha not found" unless -f $archive;
my $stream = Archive::Lha::Stream::File->new(file => $archive);
my $found;
while (defined(my $level = $stream->search_header)) {
my $header = Archive::Lha::Header->new(level => $level, stream => $stream);
$stream->seek($header->{next_header});
my $raw = $header->{filename} // $header->{pathname} // '';
if ($raw =~ /\xe7/) {
$found = $header;
last;
}
}
ok $found, 'Found entry with non-ASCII byte (0xe7 = ç in iso-8859-15)';
my $name = $found->pathname;
like $name, qr/fran/, 'Decoded name starts with "fran"';
like $name, qr/ais/, 'Decoded name ends with "ais"';
# \xc3\xa7 is UTF-8 for ç
ok utf8::is_utf8($name) || $name =~ /\xc3\xa7/, 'Name contains UTF-8 ç';
like $name, qr/fran.*ais/, 'Full name matches français pattern';
};
subtest 'Amiga archive: charset auto-detected as iso-8859-15' => sub {
my $archive = "$Bin/archive/Amoric_src.lha";
plan skip_all => "Amoric_src.lha not found" unless -f $archive;
my $stream = Archive::Lha::Stream::File->new(file => $archive);
my $header;
while (defined(my $level = $stream->search_header)) {
$header = Archive::Lha::Header->new(level => $level, stream => $stream);
$stream->seek($header->{next_header});
last if ($header->{os}[0] // '') eq 'a';
}
ok $header, 'Found Amiga entry';
is $header->charset_for_os, 'iso-8859-15', 'Amiga OS auto-detects iso-8859-15';
};
subtest 'pathname explicit charset override' => sub {
my $archive = "$Bin/archive/Amoric_src.lha";
plan skip_all => "Amoric_src.lha not found" unless -f $archive;
my $stream = Archive::Lha::Stream::File->new(file => $archive);
my $found;
while (defined(my $level = $stream->search_header)) {
my $header = Archive::Lha::Header->new(level => $level, stream => $stream);
$stream->seek($header->{next_header});
my $raw = $header->{filename} // $header->{pathname} // '';
if ($raw =~ /\xe7/) {
$found = $header;
last;
}
}
plan skip_all => "No latin-1 entry found" unless $found;
my $name = $found->pathname('iso-8859-15', 'UTF-8');
like $name, qr/fran.*ais/, 'Explicit iso-8859-15->UTF-8 gives français';
};
done_testing;
( run in 0.550 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )