File Coverage

blib/lib/Keystone/Resolver/Test.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             # $Id: Test.pm,v 1.4 2008-04-11 12:03:30 mike Exp $
2              
3             package Keystone::Resolver::Test;
4              
5 1     1   33459 use strict;
  1         3  
  1         34  
6 1     1   6 use warnings;
  1         2  
  1         28  
7 1     1   5 use IO::File;
  1         2  
  1         144  
8 1     1   2271 use CGI;
  1         19172  
  1         7  
9 1     1   624 use Keystone::Resolver;
  0            
  0            
10              
11              
12             =head1 NAME
13              
14             Keystone::Resolver::Test - run tests for the Keystone Resolver library
15              
16             =head1 SYNOPSIS
17              
18             my %opts = ( loglevel => 0x600 );
19             Keystone::Resolver::Test::run_test(\%opts, "path/to/test");
20              
21             =head1 DESCRIPTION
22              
23             This module is not part of the resolver I, but is used to test
24             it. It exists to provide a single function, C, described
25             below.
26              
27             =head1 METHODS
28              
29             =head2 run_test()
30              
31             Keystone::Resolver::Test::run_test(\%opts, "path/to/test");
32             # -- or --
33             $status = Keystone::Resolver::Test::run_test(\%opts, "path/to/test", 1);
34              
35             Runs the indicated test, using a resolver created with the specified
36             options. If the optional third parameter is absent or false, then
37             output is written describing the outcome of the test. If it is
38             provided and true, then no output is generated. In any case, an
39             integer status is returned as follows:
40              
41             =over 4
42              
43             =item 0
44              
45             Success.
46              
47             =item 1
48              
49             The test was run without errors, but the generated XML was different
50             from what the test-file said to expect.
51              
52             =item 2
53              
54             The test could not be run because of a fatal error in the resolver.
55              
56             =item 3
57              
58             The test could not be run because the test-case was malformed.
59              
60             =item 4
61              
62             The test could not be run because of a system error.
63              
64             =back
65              
66             =cut
67              
68             sub run_test { return _do_test(0, @_) }
69              
70             =head2 write_test()
71              
72             $status = Keystone::Resolver::Test::write_test(\%opts, "another/test", 1);
73              
74             Like C, but instead of testing the results of running the
75             test against a known-good regression output, it writes the results to
76             that output for the use of subsequent regression testing.
77              
78             =cut
79              
80             sub write_test { return _do_test(1, @_) }
81              
82             sub _do_test {
83             my($write, $optsref, $filename, $quiet) = @_;
84              
85             my $params;
86             my $fh = new IO::File("<$filename.in")
87             or return fail(4, $quiet, "can't open test input '$filename.in': $!");
88             while (my $line = <$fh>) {
89             chomp($line);
90             $line =~ s/^\s+//;
91             next if $line =~ /^#/;
92             next if $line =~ /^\s*$/;
93             $params = $line;
94             last;
95             }
96             $fh->close();
97             return fail(3, $quiet, $filename, "malformed: no OpenURL params")
98             if !defined $params;
99              
100             my $xml;
101             if (!$write) {
102             $fh = new IO::File("<$filename.out")
103             or return fail(4, $quiet,
104             "can't open test output '$filename.out': $!");
105             $xml = join("", <$fh>);
106             $fh->close();
107             }
108              
109             my $cgi = new CGI($params);
110             my $resolver = new Keystone::Resolver();
111             my $openURL = Keystone::Resolver::OpenURL->newFromCGI($resolver, $cgi, undef,
112             { baseURL => "http://example.com/resolve", %$optsref });
113             my($__UNUSED_type, $result) = $openURL->resolve();
114              
115             if ($result !~ /\n$/s) {
116             # Diff has problems dealing with files that don't end in
117             # newlines, so we always include a newline at the end of the
118             # test-files, and append one to the generated content here if
119             # necessary to make them compare equal.
120             $result .= "\n";
121             }
122              
123             if ($write) {
124             my $res = write_file($quiet, "$filename.out", $result);
125             return $res if $res != 0;
126             } elsif ($result ne $xml) {
127             fail(1, $quiet, $filename, "XML output differs:");
128             if (!$quiet) {
129             print STDERR "---\n";
130             my $expected = "/tmp/resolver-$$.expected";
131             my $res = write_file($quiet, $expected, $xml);
132             return $res if $res != 0;
133             my $got = "/tmp/resolver-$$.got";
134             $res = write_file($quiet, $got, $result);
135             return $res if $res != 0;
136             system("diff $expected $got >&2");
137             unlink($expected);
138             unlink($got);
139             print STDERR "---\n";
140             print "Generated document:\n$result"
141             if $cgi->param("opt_show_xml");
142             }
143             return 1;
144             }
145              
146             print STDERR "test-case '$filename' ok\n"
147             if !$quiet;
148             return 0;
149             }
150              
151              
152             sub write_file {
153             my($quiet, $filename, $content) = @_;
154              
155             my $fh = new IO::File(">$filename")
156             or return fail(4, $quiet, "can't write file '$filename': $!");
157             $fh->print($content);
158             $fh->close();
159             return 0;
160             }
161              
162              
163             sub fail {
164             my($retval, $quiet, $filename, @text) = @_;
165              
166             print STDERR "*** test-case '$filename': ", @text, "\n"
167             if !$quiet;
168              
169             return $retval;
170             }
171              
172              
173             1;