#!/usr/bin/perl

eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}'
  if 0;    # not running under some shell

use strict;
use warnings;

sub _print;
use Getopt::Long;

GetOptions(
    'v|verbose' => \my $VERBOSE,
);

use TAPx::Parser;
use TAPx::Parser::Aggregator;
use TAPx::Parser::Source::Perl;

##############################################################################

=head1 NAME

tprove - Simple proof of concept for proving tests

=head1 USAGE

 tprove [ list of test files ]

=head1 DESCRIPTION

C<tprove> is not installed on your system unless you explicitly copy it
somewhere in your path.  The current incarnation B<must> be run in a directory
with both C<t/> and C<lib/> (i.e., the standard "root" level directory in
which CPAN style modules are developed).  This will probably change in the
future.  As noted, this is a proof of concept.

Note that massive amounts of code have been lifted directly from
C<Test::Harness::Straps>.

=head1 CAVEATS

This is alpha code.  You've been warned.

=head1 TODO

I need to aggregate test results to make them more useful.  In other words, we
need a summary report at the end.

Optional colorization of the test output.

Eventually throw on a TK interface just to let folks know what we can do.

=cut

use File::Find;
my @tests;
if (@ARGV) {
    @tests = @ARGV;
}
else {
    find( sub { -f && /\.t$/ && push @tests => $File::Find::name }, 't' );
}

my $aggregate = TAPx::Parser::Aggregator->new;
my $source    = TAPx::Parser::Source::Perl->new;
foreach my $test (@tests) {
    if ( my $stream = $source->filename($test)->get_stream ) {
        my $parser = analyze_test( $test, $stream );
        $aggregate->add( $test, $parser );
    }
    else {
        my $error = $source->error;
        warn "Could not run ($test): $error";
        next;
    }
}

my ( $total, $passed, $failed, $errors ) = (
    $aggregate->total,
    scalar $aggregate->passed,
    scalar $aggregate->failed,
    scalar $aggregate->parse_errors,
);

print <<"END_SUMMARY";
Tests run:  $total
Passed:     $passed
Failed:     $failed
Errors:     $errors
END_SUMMARY

sub analyze_test {
    my ( $test, $stream ) = @_;

    my $parser = TAPx::Parser->new( { stream => $stream } );
    print "$test......";
    while ( my $result = $parser->next ) {
        _print $result->as_string, $/;
    }
    unless ( $parser->failed ) {
        print "ok\n";
    }
    else {
        print "not ok.\nFailed: @{[$parser->failed]}\n";
    }
    return $parser;
}

sub _print {
    return unless $VERBOSE;
    print @_;
}
