compare media example (exiftool, ffprobe)
[barcat.git] / t / examples.t
1 #!/usr/bin/env perl
2 use 5.014;
3 use warnings;
4 use re '/ms';
5 use IPC::Run 'run';
6
7 use Test::More;
8 { # silence fail diagnostics because of single caller
9         no warnings 'redefine';
10         sub Test::Builder::_ok_debug {}
11 }
12
13 my %CMDARGS = (
14         ping => '-c 1',
15         curl => '-sS',
16         'cat \Khttpd/' => '/var/log/apache2/',
17 );
18
19 my $filename = 'barcat';
20 open my $input, '<', $filename
21         or die "Cannot read documentation from $filename script\n";
22
23 local $/ = "\n\n";
24 while (readline $input) {
25         # find scriptlets in the appropriate section
26         /^=head1 EXAMPLES/ ... /^=head1/ or next;
27         /^\h/ or next;  # indented code snippet
28         /\A\h*>/ and next;  # psql prompt
29         chomp;
30
31         # compose an identifier from significant parts
32         do {
33                 s/^\h+//;             # indentation
34                 s/\\\n\s*//g;         # line continuations
35                 s/^[(\h]+//;          # subshell
36                 s/^echo\ .*?\|\s*//;  # preceding input
37                 s/'(\S+)[^']*'/$1/g;  # quoted arguments
38                 s/\|.*//;             # subsequent pipes
39                 s/^cat\ //;           # local file
40                 s/^curl\ // and do {  # remote url
41                         s/\ -.+//g;                 # download options
42                         s{//[^/\s]+/\K\S*(?=/)}{};  # subdirectories
43                         s{^https?://}{};            # http protocol
44                 };
45         } for my $name = $_;
46
47         # prepare shell command to execute
48         my $cmd = $_;
49         while (my ($subcmd, $args) = each %CMDARGS) {
50                 $subcmd .= " \\K", $args .= ' ' unless $subcmd =~ m/\\K/;
51                 $cmd =~ s/\b$subcmd/$args/;
52         }
53         my @cmd = (bash => -c => "set -o pipefail\n$cmd");
54
55         # run and report unexpected results
56         ok(eval {
57                 run(\@cmd, \undef, \my $output, \my $error);
58                 die("error message:\n    $error\n") if $error;
59                 $? == 0 or die "exit status ", $? >> 8, "\n";
60                 length $output or die "empty output\n";
61                 return 1;
62         }, $name) or diag("Failed command\n@cmd\nfrom $filename line $.: $@");
63 }
64
65 done_testing();