Outputting failed test information

Ovid on 2007-01-04T21:49:56

Part of my current work with TAPx::Parser is to get the TAPx::Harness output as similar to Test::Harness output as I can. This turns out to be annoyingly tricky.

Failed Test         Stat Wstat Total Fail  List of Failed
-------------------------------------------------------------------------------
runtests_example.pl    5  1280    13    5  3 5 10-12
 (1 subtest UNEXPECTEDLY SUCCEEDED).
Failed 1/1 test scripts. 5/13 subtests failed.
Files=1, Tests=13,  0 wallclock secs ( 0.06 cusr +  0.02 csys =  0.08 CPU)
Failed 1/1 test programs. 5/13 subtests failed.

Test::Harness uses formats to get this right. While my code doesn't use formats, I have worked on getting the "List of Failed" ranges right with code similar to the following:

#!/usr/bin/perl

use strict;
use warnings;
use Test::More qw/no_plan/;

is join( ', ', range(qw( 33 34 35 37 99 100 101 )) ), '33-35, 37, 99-101';
is join( ', ', range(qw( 1 2 3 4)) ),                 '1-4';
is join( ', ', range(qw(1 2 5 6 7 9)) ),              '1-2, 5-7, 9';
is join( ', ', range(qw(17 19 33)) ),                 '17, 19, 33';
is join( ', ', range(qw(17 19)) ),                    '17, 19';

diag balanced_range( 15,
    range(qw(  1 2 3 5 7 9 20 33 34 35 37 99 100 101 )) );

sub balanced_range {
    my ( $limit, @range ) = @_;
    my $lines = "\t";
    my $curr  = 0;
    while (@range) {
        if ( $curr < $limit ) {
            my $range = ( shift @range ) . ", ";
            $lines .= $range;
            $curr += length $range;
        }
        elsif (@range) {
            $lines .= "\n\t";
            $curr = 0;
        }
    }
    $lines =~ s/, $//;
    return $lines;
}

sub range {
    my @numbers = @_;
    my ( $min, @range );

    foreach my $i ( 0 .. $#numbers ) {
        my $num  = $numbers[$i];
        my $next = $numbers[ $i + 1 ];
        if ( defined $next && $next == $num + 1 ) {
            if ( !defined $min ) {
                $min = $num;
            }
        }
        elsif ( defined $min ) {
            push @range => "$min-$num";
            undef $min;
        }
        else {
            push @range => $num;
        }
    }
    return @range;
}

As a first pass, it's awful, but I'm working on it!


golf it

rafl on 2007-01-04T23:56:35

/\b(\d+)( ((??{$++1})))+/$1-$+/g;s/ /, /g

Please don't

petdance on 2007-01-05T02:48:25

Please don't try to make it match Test::Harness. The old Test::Harness format is clunky and yucky. I've been meaning to redo it for some time.

Maybe you can come up with something beautiful that I can steal instead!

Re:Please don't

Ovid on 2007-01-05T07:29:33

Well, I've had a lot of trouble coming up with an exact match (and in any event, it can't match exactly because I have different information I present). However, so far I'm quite satisfied I've come up with something even clunkier and yuckier than Test::Harness. However, it works :)

My thought is fix a couple of minor nits, get --exec nailed down, and release. If I do that, maybe my output will be so ugly I can get suggestions or even patches!