t: safer calls to opustags

This commit is contained in:
Frédéric Mangano-Tarumi 2018-11-04 14:12:09 -05:00
parent 62ea90e5d5
commit 002b253c06

106
t/cli.t
View File

@ -1,8 +1,10 @@
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Test::More tests => 35;
use Test::More tests => 24;
use Digest::MD5;
use File::Basename;
@ -13,22 +15,39 @@ my $opustags = './opustags';
BAIL_OUT("$opustags does not exist or is not executable") if (! -x $opustags);
my $t = dirname(__FILE__);
BAIL_OUT("'$t' contains unsupported characters") if $t !~ m|^[\w/]*$|;
sub opustags {
my $in = pop @_;
my ($pid, $pin, $pout, $perr);
local $/ = undef;
$perr = gensym;
$pid = open3($pin, $pout, $perr, $opustags, @_);
binmode($pin, ':utf8');
binmode($pout, ':utf8');
binmode($perr, ':utf8');
print $pin $in if defined $in;
close $pin;
my $out = <$pout>;
my $err = <$perr>;
waitpid($pid, 0);
[$out, $err, $?]
}
####################################################################################################
# Tests related to the overall opustags executable, like the help message.
# No Opus file is manipulated here.
chomp(my $version = `$opustags --help | head -n 1`);
like($version, qr/^opustags version \d+\.\d+\.\d+$/, 'get the version string');
my $usage = opustags(undef);
$usage->[0] =~ /^([^\n]*+)/;
my $version = $1;
like($version, qr/^opustags version (\d+\.\d+\.\d+)/, 'get the version string');
is(`$opustags`, <<"EOF", 'no options show the usage');
is_deeply($usage, [<<"EOF", "", 0], 'no options show the usage');
$version
Usage: opustags --help
opustags [OPTIONS] FILE
opustags OPTIONS FILE -o FILE
EOF
is($?, 0, 'no option is not an error'); # should it be?
my $help = <<"EOF";
$version
@ -51,15 +70,12 @@ Options:
See the man page for extensive documentation.
EOF
is(`$opustags --help`, $help, '--help displays the help message');
is($?, 0, '--help returns 0');
is_deeply(opustags('--help', undef), [$help, '', 0], '--help displays the help message');
is_deeply(opustags('-h', undef), [$help, '', 0], '-h displays the help message too');
is(`$opustags --h`, $help, '-h displays the help message too');
is(`$opustags --derp 2>&1`, <<'EOF', 'unrecognized option shows an error');
is_deeply(opustags('--derp', undef), ['', <<'EOF', 256], 'unrecognized option shows an error');
./opustags: unrecognized option '--derp'
EOF
is($?, 256, 'unrecognized option causes return code 256');
####################################################################################################
# Test the main features of opustags on an Ogg Opus sample file.
@ -72,40 +88,32 @@ sub md5 {
$ctx->hexdigest
}
my $fh;
is(md5("$t/gobble.opus"), '111a483596ac32352fbce4d14d16abd2', 'the sample is the one we expect');
is(`./opustags $t/gobble.opus`, <<'EOF', 'read the initial tags');
is_deeply(opustags("$t/gobble.opus", undef), [<<'EOF', '', 0], 'read the initial tags');
encoder=Lavc58.18.100 libopus
EOF
# empty out.opus
open($fh, '>', "$t/out.opus") or die;
close($fh);
is(`./opustags $t/gobble.opus -o $t/out.opus 2>&1 >/dev/null`, <<"EOF", 'refuse to override');
{ my $fh; open($fh, '>', "$t/out.opus") and close($fh) or die }
is_deeply(opustags("$t/gobble.opus", '-o' , "$t/out.opus", undef), ['', <<"EOF", 256], 'refuse to override');
'$t/out.opus' already exists (use -y to overwrite)
EOF
is(md5("$t/out.opus"), 'd41d8cd98f00b204e9800998ecf8427e', 'the output wasn\'t written');
is($?, 256, 'check the error code');
is(`./opustags $t/out.opus -o $t/out.opus 2>&1 >/dev/null`, <<'EOF', 'output and input can\'t be the same');
is_deeply(opustags("$t/out.opus", '-o', "$t/out.opus", undef), ['', <<'EOF', 256], 'output and input can\'t be the same');
error: the input and output files are the same
EOF
is($?, 256, 'check the error code');
unlink("$t/out.opus");
is(`./opustags $t/gobble.opus -o $t/out.opus 2>&1`, '', 'copy the file without changes');
is_deeply(opustags("$t/gobble.opus", '-o', "$t/out.opus", undef), ['', '', 0], 'copy the file without changes');
is(md5("$t/out.opus"), '111a483596ac32352fbce4d14d16abd2', 'the copy is faithful');
is($?, 0, 'check the error code');
is(`./opustags --in-place $t/out.opus -a A=B --add="A=C" --add "TITLE=Foo Bar" --delete A --add TITLE=七面鳥 --set encoder=whatever -s 1=2 -s X=1 -a X=2 -s X=3`, '', 'complex tag editing');
is($?, 0, 'updating the tags went well');
is_deeply(opustags('--in-place', "$t/out.opus", qw(-a A=B --add=A=C --add), "TITLE=Foo Bar",
qw(--delete A --add TITLE=七面鳥 --set encoder=whatever -s 1=2 -s X=1 -a X=2 -s X=3), undef),
['', '', 0], 'complex tag editing');
is(md5("$t/out.opus"), '66780307a6081523dc9040f3c47b0448', 'check the footprint');
$/ = undef;
open($fh, "./opustags $t/out.opus |");
binmode($fh, ':utf8');
is(<$fh>, <<'EOF', 'check the tags written');
is_deeply(opustags("$t/out.opus", undef), [<<'EOF', '', 0], 'check the tags written');
A=B
A=C
TITLE=Foo Bar
@ -116,9 +124,8 @@ X=1
X=2
X=3
EOF
close($fh);
is(`./opustags $t/out.opus -d A -d foo -s X=4 -a TITLE=gobble -d TITLE`, <<'EOF', 'dry editing');
is_deeply(opustags("$t/out.opus", qw(-d A -d foo -s X=4 -a TITLE=gobble -d TITLE), undef), [<<'EOF', '', 0], 'dry editing');
1=2
encoder=whatever
X=4
@ -126,63 +133,46 @@ TITLE=gobble
EOF
is(md5("$t/out.opus"), '66780307a6081523dc9040f3c47b0448', 'the file did not change');
is(`./opustags -i $t/out.opus -a fatal=yes -a FOO -a BAR 2>&1`, <<'EOF', 'bad tag with --add');
is_deeply(opustags('-i', "$t/out.opus", qw(-a fatal=yes -a FOO -a BAR), undef), ['', <<'EOF', 256], 'bad tag with --add');
invalid comment: 'FOO'
EOF
is($?, 256, 'exited with a failure code');
is(md5("$t/out.opus"), '66780307a6081523dc9040f3c47b0448', 'the file did not change');
is(`./opustags -i $t/out.opus -s fatal=yes -s FOO -s BAR 2>&1`, <<'EOF', 'bad tag with --set');
is_deeply(opustags('-i', "$t/out.opus", qw(-s fatal=yes -s FOO -s BAR), undef), ['', <<'EOF', 256], 'bad tag with --set');
invalid comment: 'FOO'
EOF
is($?, 256, 'exited with a failure code');
is(md5("$t/out.opus"), '66780307a6081523dc9040f3c47b0448', 'the file did not change');
is(`./opustags $t/out.opus --delete-all -a OK=yes`, <<'EOF', 'delete all');
is_deeply(opustags("$t/out.opus", qw(--delete-all -a OK=yes), undef), [<<'EOF', '', 0], 'delete all');
OK=yes
EOF
my ($pid, $pin, $pout, $perr);
$perr = gensym;
$pid = open3($pin, $pout, $perr, "./opustags $t/out.opus --set-all -a A=B -s X=Z -d OK");
binmode($pin, ':utf8');
binmode($pout, ':utf8');
print $pin <<'EOF';
is_deeply(opustags("$t/out.opus", qw(--set-all -a A=B -s X=Z -d OK), <<'END_IN'), [<<'END_OUT', '', 0], 'set all');
OK=yes again
ARTIST=七面鳥
A=A
X=Y
EOF
close($pin);
is(<$pout>, <<'EOF', 'set all');
END_IN
OK=yes again
ARTIST=七面鳥
A=A
X=Y
A=B
X=Z
EOF
waitpid($pid, 0);
END_OUT
$pid = open3($pin, $pout, $perr, "./opustags $t/out.opus --set-all");
print $pin <<'EOF';
is_deeply(opustags("$t/out.opus", '-S', <<'END_IN'), [<<'END_OUT', <<'END_ERR', 0], 'set all with bad tags');
whatever
# thing
!
wrong=yes
EOF
close($pin);
is(<$pout>, <<'EOF', 'bad tags are skipped with --set-all');
END_IN
wrong=yes
EOF
is(<$perr>, <<'EOF', 'get warnings for malformed tags');
END_OUT
warning: skipping malformed tag
warning: skipping malformed tag
warning: skipping malformed tag
EOF
waitpid($pid, 0);
is($?, 0, 'non fatal');
END_ERR
unlink("$t/out.opus");