From 870e63be7360b5a0097a27656048e853bc720464 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Mon, 21 Jul 2014 22:29:16 -0700 Subject: Initial commit --- runtests.pl | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 runtests.pl (limited to 'runtests.pl') 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 (/
 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 () {
+  $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 && $_ =~ /^/) {
+      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;
-- 
cgit v1.2.3