#!/usr/bin/env perl
use warnings;
print "Running tests...\n" unless @ARGV;
undef $/;

my $DATADIR = $0;
$DATADIR=~s|testsuite$||;
$DATADIR//='.';
my $BINDIR = '.';

-x "$DATADIR/unescape" or $DATADIR="$DATADIR/tests";
-x "$DATADIR/unescape" or die "unescape missing from $DATADIR?\n";
-x "$BINDIR/ansi2html" or $BINDIR="$BINDIR/..";
-x "$BINDIR/ansi2html" or die "ansi2html not yet built in $BINDIR?\n";

my $id = $$;

my ($pass,$fail) = (0,0);
sub test($$$$)
{
    my ($name, $cmd, $stdin, $stdout) = @_;

    return if @ARGV && !grep { $name eq $_ } @ARGV;
    printf '* %-20s ', $name unless @ARGV;

    open I, '>', "stdin.$id" or die "Can't write to \"stdin.$id\": $!\n";
    print I $stdin;
    close I;
    open O, '>', "expout.$id" or die "Can't write to \"expout.$id\": $!\n";
    print O $stdout;
    close O;

    my $pid = fork;
    unless ($pid)
    {
        alarm 20;
        open STDIN,  '<', "stdin.$id"  or die "Can't dup stdin: $!\n";
        open STDOUT, '>', "stdout.$id" or die "Can't dup stdout: $!\n";
        open STDERR, '>', "stderr.$id" or die "Can't dup stderr: $!\n";
        exec $cmd;
        die "Couldn't exec: $!\n";
    }

    waitpid $pid, 0;
    my $ret = $?;
    my $bad = system "cmp -s stdout.$id expout.$id" || system "cmp -s stderr.$id /dev/null";

    if ($ret || $bad)
    {
        $fail++;
        print "\e[31mFAIL\e[0m\n" unless @ARGV;
        system "cat stderr.$id";
        system "diff -u expout.$id stdout.$id";
        print "return value: $ret\n" if $ret;
    }
    else
    {
        $pass++;
        print "\e[32mok\e[0m\n" unless @ARGV;
    }

    unlink "$_.$id" for qw(stdin expout stdout stderr);
}

test('ansi2txt', "$DATADIR/unescape|$BINDIR/ansi2txt", <<'IN', <<'OUT');
foo\e[1mbar\e[0m\n
\e[?2004l
\e]0;title1\e\\
\e]4;16;rgb:0/0/0\e\\
\e]0;title2\a
\n
IN
foobar

OUT

test('ansi2html', "$DATADIR/unescape|$BINDIR/ansi2html|$DATADIR/htmlpre2txt", <<'IN', <<"OUT");
foo\e[1mbar\e[0m\n
\e[?2004l
\e]0;title1\e\\
\e]4;16;rgb:0/0/0\e\\
\e]0;title2\a
\n
\f\n
\xff\n
IN
foobar

\f
\xff
OUT

test('pipetty', "$BINDIR/pipetty </dev/null sh stdin.$id", <<'IN', <<'OUT');
test -t 0
printf 'isatty(0): %d\n' $?
test -t 1
printf 'isatty(1): %d\n' $?
test -t 2
printf 'isatty(2): %d\n' $?
IN
isatty(0): 1
isatty(1): 0
isatty(2): 0
OUT

test('ttyrec2ansi', "$DATADIR/unescape|$BINDIR/ttyrec2ansi", <<'IN', <<'OUT');
aaaa10\a\0\b\0\0\0foo bar\n
aaaa10\b\0\b\0\0\0baz qux\n
IN
foo bar
baz qux
OUT

print "Passed: $pass, failed: $fail.\n" unless @ARGV;
exit($fail>0);
