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