Update rss20 test cases.
authorGavin Carr <gonzai@users.sourceforge.net>
Tue, 4 Dec 2007 10:37:05 +0000 (10:37 +0000)
committerGavin Carr <gonzai@users.sourceforge.net>
Tue, 4 Dec 2007 10:37:05 +0000 (10:37 +0000)
t/README [new file with mode: 0644]
t/Setup [new file with mode: 0755]
t/Tests [new file with mode: 0644]
t/driver [new file with mode: 0644]

diff --git a/t/README b/t/README
new file mode 100644 (file)
index 0000000..25a9edb
--- /dev/null
+++ b/t/README
@@ -0,0 +1,83 @@
+Running Tests
+=============
+
+  perl ./Setup
+  prove *.t
+
+
+
+Test Layout
+===========
+
+To add a new test, you want to add two things - a test script (which
+is typically just a symlink to the main 'driver' script), and a test
+directory. If you just want a symlink test script, then add your
+test script name to 'Tests', and rerun Setup. To add a new test 
+directory, you're probably best just to copy one of the existing 
+ones - 'templates' is a good choice:
+
+  cp -rp templates newtest
+
+Test directory layout is as follows, using 'templates' as an example:
+
+  templates
+  |-- config
+  |   `-- blosxom.conf
+  |-- data
+  |   |-- 1.txt
+  |   |-- 1.txt.200607192254
+  |   |-- content_type.html
+  |   |-- date.html
+  |   |-- foot.html
+  |   |-- head.html
+  |   `-- story.html
+  |-- expected
+  |   |-- index.html
+  |   `-- index.rss
+  `-- spec.yaml
+
+The 'config' directory contains the config files for this blosxom
+instance, which is minimally a 'blosxom.conf' file with the $data_dir
+variable pointing to the 'data' directory. Customising this is 
+optional.
+
+The 'data directory' is the set of stories or posts you want to use
+for your test, and any flavour files you want. Stories may optionally be 
+suffixed with a numeric timestamp (format YYYYMMDDHHMI) like the 
+'1.txt.200607192254' entry above, which is used to set the modify time
+of the story explicitly (since CVS does not store mtimes). Providing 
+flavour files is recommended so that your tests don't break if the 
+default flavours change. 
+At the top level of the test directory are a set of one or more
+expected output files, and the spec.yaml files which controls the set
+of tests that are run. For templates, the spec.yaml looks like this:
+
+  tests:
+    - 
+      - ""
+      - expected/index.html
+
+This lists the set of tests to be run (in this case just a single test).
+Each test requires a list of two arguments - the arguments to path to
+blosxom.cgi (in this case none, an empty string), and a file containing
+the expected output. So this test will execute blosxom.cgi with no 
+arguments, and compare the output produced against that contained in
+the 'expected.html' file.
+
+A longer spec.yaml example is:
+
+  tests:
+    - 
+      - ""
+      - expected/index.html
+    -
+      - path=/foo
+      - expected/foo.html
+    -
+      - path=/foo/bar.html
+      - expected/bar.html
+
+This defines three tests, one with no arguments, one with a path of 
+/foo, and a third with a path of /foo/bar.html.
+
diff --git a/t/Setup b/t/Setup
new file mode 100755 (executable)
index 0000000..93f0733
--- /dev/null
+++ b/t/Setup
@@ -0,0 +1,27 @@
+#!/usr/bin/env perl
+#
+# Script to setup test script symlinks, since CVS can't store them
+#
+
+use strict;
+use IO::File;
+
+my $DRIVER = 'driver';
+my $TESTS = 'Tests';
+die "cannot find driver file '$DRIVER'" unless -f $DRIVER;
+die "cannot find tests file '$TESTS'" unless -f $TESTS;
+
+my @tests = ();
+
+my $th = IO::File->new($TESTS, 'r') 
+  or die "cannot open tests file '$TESTS': $!";
+@tests = <$th>;
+close $th;
+
+for my $t (@tests) {
+  chomp $t;
+  unlink $t if -l $t;
+  print "symlink $DRIVER $t\n"; 
+  eval { symlink $DRIVER, $t } or die "symlink $DRIVER, $t failed: $!";
+} 
+
diff --git a/t/Tests b/t/Tests
new file mode 100644 (file)
index 0000000..0170ddf
--- /dev/null
+++ b/t/Tests
@@ -0,0 +1,2 @@
+50_rss20.t
+50_rss20_static.t
diff --git a/t/driver b/t/driver
new file mode 100644 (file)
index 0000000..52fc128
--- /dev/null
+++ b/t/driver
@@ -0,0 +1,143 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More qw( no_plan );
+
+use Cwd;
+use YAML;
+use IO::File;
+use File::Find;
+use File::Copy;
+#use File::Touch;
+use File::Basename;
+use Test::Differences;
+
+my $test = basename($0);
+$test =~ s/^\d+_?//;
+$test =~ s/\.t$//;
+
+my $testdir = $test;
+$testdir = "t/$testdir" if -d "t/$testdir";
+$testdir = cwd . "/$testdir";
+die "cannot find root '$testdir'" unless -d $testdir;
+
+my $blosxom_config_dir = "$testdir/config";
+die "cannot find blosxom config dir '$blosxom_config_dir'" unless -d $blosxom_config_dir;
+$ENV{BLOSXOM_CONFIG_DIR} = $blosxom_config_dir;
+$ENV{TZ} = 'UTC';
+
+my $blosxom_cgi = $ENV{BLOSXOM_CGI};
+unless ($blosxom_cgi && -f $blosxom_cgi) {
+  if (-f "$testdir/../../blosxom.cgi") {
+    $blosxom_cgi = "$testdir/../../blosxom.cgi";
+    warn "ignoring BLOSXOM_CGI setting '$ENV{BLOSXOM_CGI}' - using '$blosxom_cgi' instead"
+      if $ENV{BLOSXOM_CGI};
+  }
+  elsif ($blosxom_cgi) {
+    die "cannot find blosxom.cgi '$blosxom_cgi' - check your BLOSXOM_CGI environment variable";
+  }
+  else {
+    die "cannot find blosxom.cgi - please set the BLOSXOM_CGI environment variable";
+  }
+}
+die "blosxom.cgi '$blosxom_cgi' is not executable" unless -x $blosxom_cgi;
+
+my $spec = YAML::LoadFile ("$testdir/spec.yaml") 
+  or die("$test - could not load spec");
+
+touch_files("$testdir/data");
+
+# Eval blosxom.conf
+my ($static_dir, $static_password, @static_flavours);
+if (my $fh = IO::File->new("$blosxom_config_dir/blosxom.conf", 'r')) {
+  no strict;
+  local $/ = undef;
+  eval <$fh>;
+}
+
+# Static mode
+if ($static_password) {
+  eval {
+    require File::DirCompare;
+    require File::Remove;
+  };
+  SKIP: {
+    skip "Static tests require additional modules: $@", 1 if $@;
+    my $expected = $spec->{expected};
+    skip "Static tests require 'expected' directory", 1 unless $expected;
+    $expected = "$blosxom_config_dir/../$expected" unless $expected =~ m!^/!;
+    skip "Static tests 'expected' directory is missing", 1 unless -d $expected;
+    skip "Static tests 'static_dir' directory is missing", 1 unless -d $static_dir;
+
+    File::Remove::remove(\1, "$static_dir/*");
+
+    my $errors = qx($blosxom_cgi -quiet=1 -password=$static_password);
+    is($errors, '', 'no errors reported from static run');
+    File::DirCompare->compare($static_dir, "$blosxom_config_dir/../" . $spec->{expected}, sub {
+      my ($a, $b) = @_;
+      my ($a_short, $b_short) = ($a, $b);
+      $a_short =~ s!^.*\.\./!! if $a_short;
+      $b_short =~ s!^.*\.\./!! if $b_short;
+      return if $b =~ m! /CVS$ !x;
+      if (! $b) {
+        fail("$a_short has no corresponding file");
+      } elsif (! $a) {
+        fail("$b_short has no corresponding file");
+      } else {
+        my ($got, $expected) = ('', '');
+        my $fh = IO::File->new($a, 'r') 
+          or die "cannot open static output file '$a': $!";
+        {
+          local $/ = undef;
+          $got = <$fh>;
+          $fh->close;
+        }
+        $fh = IO::File->new($b, 'r') 
+          or die "cannot open static output file '$b': $!";
+        {
+          local $/ = undef;
+          $expected = <$fh>;
+          $fh->close;
+        }
+        eq_or_diff($got, $expected, "file $a_short and $b_short match", { style => 'Unified' });
+      }
+    }, { ignore_cmp => 1 });
+
+    # Cleanup static output
+    File::Remove::remove(\1, "$static_dir/*") unless $ENV{BLOSXOM_STATIC_NO_CLEANUP};
+  }
+}
+
+# Dynamic mode
+else {
+  my %expected = ();
+  for (@{$spec->{tests}}) {
+    my ($args, $output) = @$_;
+
+    unless ($expected{$output}) {
+      my $fh = IO::File->new("$testdir/$output", 'r')
+        or die "cannot open expected output file '$output': $!";
+      {
+        local $/ = undef;
+        $expected{$output} = <$fh>;
+      }
+      $fh->close;
+    }
+
+    my $got = qx($blosxom_cgi $args);
+
+    eq_or_diff($got, $expected{$output}, "$test - got expected output for args [$args]", { style => 'Unified' });
+  }
+}
+
+sub touch_files {
+  find( sub {
+    if (/^(.*)\.(\d+)$/) {
+      copy($_, $1);
+      `touch -t $2 $1`;
+    }
+  },
+  shift );
+}