diff options
Diffstat (limited to 'runtests.pl')
-rw-r--r-- | runtests.pl | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/runtests.pl b/runtests.pl new file mode 100644 index 0000000..5facbe6 --- /dev/null +++ b/runtests.pl @@ -0,0 +1,159 @@ +#!/usr/bin/env perl +use warnings; +use strict; +use Term::ANSIColor; +use IO::Handle; +use IPC::Open2; + +my $usage="runtests.pl PROGRAM SPEC\nSet ANSI_COLORS_DISABLED=1 if you redirect to a file.\nSet PATT='...' to restrict tests to sections matching a regex.\n"; + +my $PROG=$ARGV[0]; +my $SPEC=$ARGV[1]; +my $PATT=$ENV{'PATT'}; + +if (!(defined $PROG && defined $SPEC)) { + print STDERR $usage; + exit 1; +} + +my $passed = 0; +my $failed = 0; +my $skipped = 0; + +# Markdown implementations vary on insignificant whitespace. +# Some leave blanks between block elements, others don't. +# This function tries to normalize the output so it can be +# compared with our test. tidy takes two arguments: the +# string containing the actual output, and a pathname of the +# file to which the tidied output is to be saved. +sub tidy +{ + my $inpre = 0; + my $out = ""; + my $outfh; + open($outfh, '>', \$out); + for (split /^/, $_[0]) { + if (/<pre/) { + $inpre = 1; + } elsif (/<\/pre/) { + $inpre = 0; + } + if ($inpre) { + print $outfh $_; + } else { + # remove leading spaces + s/^ *//; + # remove trailing spaces + s/ *$//; + # collapse consecutive spaces + s/ */ /; + # collapse space before /> in tag + s/ *\/>/\/>/; + # skip blank line + if (/^$/) { + next; + } + print $outfh $_; + } + } + close $outfh; + return $out; +} + +sub dotest +{ + my $markdown = $_[0]; + my $html = $_[1]; + my $testname = $_[2]; + my $actual = ""; + # We use → to indicate tab and ␣ space in the spec + $markdown =~ s/→/\t/g;s/␣/ /g; + $html =~ s/→/\t/g;s/␣/ /g; + open2(my $out, my $in, $PROG); + print $in $markdown; + close $in; + flush $out; + $actual = do { local $/; <$out>; }; + close $out; + $html = &tidy($html); + $actual = &tidy($actual); + $actual =~ s/\'/'/; + if ($actual eq $html) { + print colored("✓", "green"); + return 1; + } else { + print colored("\n✘ $testname", "red"); + print "\n"; + print color "cyan"; + print "=== markdown ===============\n"; + print $markdown; + print "=== expected ===============\n"; + print $html; + print "=== got ====================\n"; + print $actual; + print color "black"; + return 0; + } +} + +my $stage = 0; +my $markdown = ""; +my $html = ""; +my $example = 0; +my $linenum = 0; +my $exampleline = 0; +my @secnums = (); +my $secheading; + +open(SPEC, "< $SPEC"); +while (<SPEC>) { + $linenum++; + if (/^\.$/) { + $stage = ($stage + 1) % 3; + if ($stage == 1) { + $exampleline = $linenum; + } + if ($stage == 0) { + $example++; + if (!$PATT || $secheading =~ /$PATT/) { + if (&dotest($markdown, $html, + "Example $example (line $exampleline)")) { + $passed++; + } else { + $failed++; + } + } else { + $skipped++; + } + $markdown = ""; + $html = ""; + } + } elsif ($stage == 0 && $_ =~ /^<!-- END TESTS -->/) { + last; + } elsif ($stage == 0 && $_ =~ /^(#+) +(.*)/) { + my $seclevel = length($1); + $secheading = $2; + if ($#secnums == $seclevel - 1) { + $secnums[$#secnums]++; + } elsif ($#secnums > $seclevel - 1) { + @secnums = @secnums[0..($seclevel - 1)]; + $secnums[$#secnums]++; + } else { + while ($#secnums < $seclevel - 1) { + push(@secnums, 1); + } + } + if (!$PATT || $secheading =~ /$PATT/) { + print ("\n", join(".", @secnums) . " " . $secheading, " "); + } + } elsif ($stage == 1) { + $markdown .= $_; + } elsif ($stage == 2) { + $html .= $_; + } +} + +print "\n"; +print STDERR colored("$passed tests passed, $failed failed, $skipped skipped.", "bold"); +print STDERR "\n"; +exit $failed; |