#!/usr/local/bin/perl -w

# run tests on valid input
# usage:
#   tests.pl [<test number> [<test number> ...]]
#            [<script name> [<script name> ...]]

use strict;

use IPC::Open3;

use Test::More qw/ no_plan /;

my $num = 0;
my @tests;
{
  local $/ = '--- ';
  <DATA>;
  while (<DATA>) {
    chomp;
    my($label, $data) = split /\n/, $_, 2;
    $data or next;
    $num++;
    my($in, @out) = split /^--\n/m, $data;
    my $re = join '|', map quotemeta($_), @out;
    push @tests, [$num, $label, $in, qr/^(?:$re)\z/];
  }
}

my @test_nums;
while (@ARGV and $ARGV[0] =~ /^\d+\z/) {
  my $num = shift(@ARGV) - 1;
  next if $num < 0 or $num > $#tests;
  push @test_nums, $num;
}

if (@test_nums) {
  @tests = @tests[@test_nums];
}

my @scripts;
if (@ARGV) {
  @scripts = @ARGV;
} else {
  @scripts = qw/ rjk roel xavier christian mjd2
                 rod adrian jurgen jean zsban /;
}

foreach my $script (@scripts) {
  if ($script !~ /\./) {
    if (-e "$script.pl") {
      $script .= '.pl';
    } elsif (-e "$script.ry") {
      $script .= '.ry';
    }
  }

  -e $script or do { warn "$script not found.\n"; next };

  my $cmd = 'perl';
  $cmd = 'ruby' if $script =~ /\.ry\z/;

  diag("** $script");

  local $/;

  foreach my $test (@tests) {
    my($num, $label, $in, $re) = @$test;

    open3(\*WTR, \*RDR, \*ERR, "$cmd $script");

    print WTR $in;
    close WTR;

    my $results = <RDR>;
    my $errors  = <ERR>;

    ok(!$errors, "$num $label STDERR");

    like($results, $re, "$num $label");
  }
}

__DATA__
--- Simple 1
A 1
B 3 A
C 2 A
D 1 B C
FINAL 0 D
--
A
B
D
FINAL

--- Simple 2
A 1
B 2 A
C 3 A
D 1 B C
FINAL 0 D
--
A
C
D
FINAL

--- Multiple Critical Paths
A 1
B 3 A
C 3 A
D 1 B C
FINAL 0 D
--
A
B
D
FINAL

A
C
D
FINAL

--
A
C
D
FINAL

A
B
D
FINAL

--
A
B
C
D
FINAL

--
A
C
B
D
FINAL

--
A
B
D
FINAL

--
A
C
D
FINAL

--- Complicated
G 24
A 14
I 14
J 9
H 21 G
D 10 A
B 5 I
C 5 J
E 31 B C D
F 7 E
K 21 F
FINAL 0 H K
--
A
D
E
F
K
FINAL

--- FINAL depends on everything
A 4
B 5 A
C 6 B
D 3
E 4 D
F 5 E
FINAL 0 A B C D E F
--
A
B
C
FINAL

--- Extra dependencies
A 4
B 1 A
C 6 B
D 5 B C
E 2 A B C
FINAL 0 D E
--
A
B
C
D
FINAL

--- Extra tasks
A 1
B 2 A
FINAL 0 B     
C 1
D 2 C
QUININE 0 D
--
A
B
FINAL

--- No dependency for FINAL
A 1
B 2 A
FINAL 0
--
FINAL

--- Out of order
FINAL 0 B
B 1 A
A 1
--
A
B
FINAL

--- Blank lines
A 1

B 2 A

FINAL 0 B
--
A
B
FINAL

--- END
