PennMUSH Community

root/1.8.3/trunk/test/TestHarness.pm

Revision 1117, 3.9 kB (checked in by shawnw, 11 months ago)

Merge with devel

Line 
1 package TestHarness;
2 use strict;
3 use vars qw/%tests $testcount @failures $alltests $allfailures $allexpected/;
4 use vars qw/$testfiles $use_mortal/;
5 use subs qw/test summary/;
6
7 $alltests = 0;
8 $allfailures = 0;
9 $allexpected = 0;
10 $testfiles = 0;
11 $use_mortal = 0;
12
13 sub new {
14     my $class = shift;
15     my $script = shift;
16     my %self = (
17         -expected => 0,
18         -depends => [],
19         -test => undef,
20     );
21 #    print "Looking at $script\n";
22     $script =~ /^test(.*)\.pl$/o;
23     my $name = $1;
24     $self{-name} = $name;
25     warn "Duplicate test $name\n" if exists $tests{$name};
26     my $code = 'sub { my $god = shift; ' . "\n";
27     open IN, "<", $script or die "Couldn't open ${script}: $!\n";
28     while (<IN>) {
29         chomp;
30         next if /^\s*(?:#|$)/o;
31         last if /^run tests:$/o;
32         if (/^depends on (.*)$/o) {
33             push @{$self{-depends}}, $1;
34         }
35         if (/^expect (\d+) failures!$/) {
36             $self{-expected} = $1;
37             print "Expecting $1 failures in $name\n";
38         }
39         if (/^\s*login mortal$/) {
40             $code .= 'my $mortal = shift;' . "\n";
41             $use_mortal = 1;
42         }
43     }
44     while (<IN>) {
45         $code .= $_;
46     }
47     close IN;
48     $code .= "}";
49 #    print "Test function for $name:\n$code\n";
50     $self{-test} = eval $code;
51     my $obj = bless \%self;
52     $tests{$name} = $obj;
53     return $obj;
54 }
55
56 sub run {
57     my $self = shift;
58     my $god = shift;
59     my $mortal = shift;
60     my ($failures, $test) = (0,0);
61
62     foreach my $dep (@{$self->{-depends}}) {
63         my $test = $tests{$dep};
64         if (defined $test) {
65             $test->run($god, $mortal);
66         } else {
67             warn "Unresolved dependency $dep\n";
68         }
69     }
70    
71     local ($testcount, @failures) = (0, ());
72
73     my $name = $self->{-name};
74
75     print "Running tests for ${name}:\n";
76
77     &{$self->{-test}}($god, $mortal);
78
79     $testfiles++;
80     $alltests += $testcount;
81     $allfailures += @failures;
82     $allexpected += $self->{-expected};
83    
84     summary $self->{-name}, $testcount, \@failures, $self->{-expected};
85 }
86
87 END {
88     print "Totals:\n";
89     summary("all tests run", $alltests, $allfailures, $allexpected)
90         if $testfiles > 1;
91 }
92
93 $| = 1;
94
95 sub test {
96   my $name = shift;
97   my $conn = shift;
98   my $command = shift;
99   my $patterns = shift;
100
101   $patterns = [$patterns] if ref($patterns) ne "ARRAY";
102
103   print substr("Running $name".(" "x80), 0, 78)."\r";
104
105   my $result = defined($command) ? $conn->command($command) : $conn->listen();
106   my $verdict = 1;
107
108   foreach my $pattern (@$patterns) {
109     my $matchpattern = $pattern;
110     my $negate = 0;
111     if ($matchpattern =~ s/^!//o) {
112       $negate = 1;
113     } else {
114       $matchpattern =~ s/^=//o;
115     }
116
117     if ($negate) {
118       $verdict = 0 if $result =~ /$matchpattern/;
119     } else {
120       $verdict = 0 unless $result =~ /$matchpattern/;
121     }
122   }
123
124   $testcount++;
125   unless ($verdict) {
126     push(@failures, $name);
127     print "TEST FAILURE: $name\n";
128     if (defined($command)) {
129       print "  command: $command\n";
130     } else {
131       print "  listening\n";
132     }
133     chomp $result;
134     if ($result =~ /\n/o) {
135       print "  result:\n$result\n";
136     } else {
137       print "  result:  $result\n";
138     }
139     foreach my $pattern (@$patterns) {
140       print "  pattern: $pattern\n";
141     }
142     print "\n";
143   }
144 }
145
146 sub summary {
147     my ($name, $testcount, $failures, $expected) = @_;
148     print ":"x70, "\n";
149     print "\n";
150     my $fcount = 0;
151     if (ref $failures) {
152         $fcount = scalar @$failures;
153     } else {
154         $fcount = $failures;
155     }
156     my $scount = $testcount - $fcount;
157     print "$testcount tests, $scount succeeded, $fcount failed ($expected expected failures)\n";
158     if ($fcount != $expected) {
159         print "failed tests:\n";
160         my $str = join(", ", @$failures);
161         while (length($str) > 67) {
162             $str =~ s/^(.{1,67}), //o;
163             print "  $1,\n";
164         }
165         print "  $str\n";
166     }
167     print "\n";
168 }
169
170 1;
Note: See TracBrowser for help on using the browser.