ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/Utilities/TestClass.pm
Revision: 1.14
Committed: Wed Aug 10 17:27:32 2005 UTC (19 years, 9 months ago) by sashby
Content type: text/plain
Branch: MAIN
CVS Tags: V1_0_3-p4, V1_0_3-p3, V1_0_3-p2, before110xmlBRmerge, V1_0_4p1, V1_0_3-p1, V1_0_3, V1_0_2, V1_0_2_p1
Branch point for: v103_with_xml, v103_branch
Changes since 1.13: +5 -0 lines
Log Message:
Starting to add POD documentation.

File Contents

# User Rev Content
1 williamc 1.1 #
2     # Test a documented perl class
3     #
4     # Interface
5     # ---------
6 williamc 1.4 # new($module,testdatadir) : module example - Utilities/urlhandler
7 williamc 1.1 # dotest(@args) : Start testing - arguments dependent on inheriting class
8     #
9 williamc 1.9 # cmpstring(expectedstring,returnedstring) : cmp a string and fail if not equal
10 williamc 1.1 # newtest() : Initiate a testing sequence
11     # verify(actual_result_file, expected_result_file) : compare two files
12     # verifydir(dir) : Check existence of the directory
13 williamc 1.5 # verifyexists(file) : Verify the existence of file
14 williamc 1.1 # datadir([dir]) : return the current data directory (set it to dir if supplied)
15 williamc 1.12 # testswitch(int,"0 text"," non 0 text") : testpass or fail according to bool
16 williamc 1.5 # testfail(string) : report that current test has failed
17     # testpass(string) : report that current test has passed
18 williamc 1.1 # newfilename() : return a new filename that can be opened etc.
19     # temparea() : return a directory for building temporary stuff
20     # newobject(@args) : Set up a new object to be tested
21     # testinterface($name,@args) : perform interface tests for $name with @args
22     # expect(string) : tell the testinterface of any expected return values
23     # clearexpect() : Reset any expect variables.
24 williamc 1.5 #cleantemp() : delete the temporary area
25 williamc 1.10 # cmparray(arrayref, @reqvals) : test the arrayref against expected
26     # cmpstring(expectedstring,actualstring) :
27 williamc 1.1
28 sashby 1.14 BEGIN
29     {
30     print "Utilities::TestClass:: I AM called!","\n";
31     };
32    
33 williamc 1.7 package Utilities::TestClass;
34 williamc 1.1 require 5.004;
35     $bold = "\033[1m";
36     $normal = "\033[0m";
37    
38     # -------------------- Front line Interface methods ---------------------
39     sub new {
40     my $class=shift;
41     my $fullmodule=shift;
42     chomp $fullmodule;
43     my $datadir=shift;
44    
45     # The usual Object blessing
46     $self={};
47     bless $self,$class;
48    
49     #some local working variables
50     my $testmodule;
51     my $module;
52 williamc 1.2 my $dir="";
53 williamc 1.4 # if ( $fullmodule=~/\// ) {
54     # ($dir=$fullmodule)=~s/(.*\/)(.*)/$1/;
55     # }
56     if ( $fullmodule=~/::/ ) {
57     ($dir=$fullmodule)=~s/(.*::)(.*)/$1/;
58     }
59 williamc 1.1 else { $dir="" }
60 williamc 1.4 ($testmodule=$fullmodule)=~s/(.*\/)(.*)/$1test::test_$2/;
61     ($testmodule=$fullmodule)=~s/${dir}(.*)/${dir}test::test_$1/;
62 williamc 1.1 ($module=$testmodule)=~s/.*\///g;
63    
64     $self->{class}=$module;
65     $self->{"datadir"}=$datadir;
66     $self->{filenumber}=0;
67 williamc 1.9 rmtree("/tmp/SCRAMtest++");
68 williamc 1.5 $self->{temparea}="/tmp/SCRAMtest++";
69 williamc 1.2 use File::Path;
70     mkpath ($self->{temparea},0, 0777);
71 williamc 1.1
72     # Now setup a new testobject of the appropriate type
73 williamc 1.4 eval "require $testmodule";
74     die $@ if $@;
75 williamc 1.1 $self->{testobj}=$module->_new($self, $fullmodule);
76    
77 williamc 1.8 # make sure the temparea is cleaned
78     use File::Path;
79    
80 williamc 1.1 return $self;
81     }
82    
83     #
84     # Call the test routine of our inheriting class
85     #
86     sub dotest {
87     $self=shift;
88     $self->{testobj}->test(@_);
89     $self->{testobj}->checktests();
90 williamc 1.10 }
91    
92     sub cmparray {
93     my $self=shift;
94     my $array=shift;
95     my @vals=@_;
96    
97     if ( $#{$array} ne $#vals) { $self->testfail(
98     $#{$array}." items retuned, $#vals expected");
99     }
100     else {
101     for( my $i=0; $i<= $#{$array}; $i++) {
102     $self->cmpstring($vals[$i],$$array[$i]);
103     }
104     }
105 williamc 1.1 }
106    
107    
108 williamc 1.9 sub cmpstring {
109     my $self=shift;
110     my $s1=shift;
111     my $s2=shift;
112    
113     if ( ! defined $s2) {
114 williamc 1.13 if ( ( ! defined $s1 ) || ( $s1==undef )) {
115     $self->testpass("Got undefined as expected");
116     }
117     else {
118     $self->testfail("Return string is undefined expecting $s1"),
119     }
120 williamc 1.9 }
121     elsif ( $s1 ne $s2 ) {
122     $self->testfail("Expecting $s1 got $s2");
123     }
124     else {
125     $self->testpass("Got $s2 as expected");
126     }
127     }
128 williamc 1.1
129     # A virtual method to be overridden
130     sub init {
131     my $self=shift;
132     }
133    
134     #
135     # initiate a new test sequence
136     #
137     sub newtest {
138     my $self=shift;
139     my $string=shift;
140     $self->{testnumber}++;
141 williamc 1.2 $self->_testout("");
142 williamc 1.1 $self->_testout("---------------------------* Test $self->{testnumber}".
143     " *------------------------------");
144     $self->_testout("| $string ");
145     $self->_testout("|");
146     $self->_testout(
147     "---------------------------------------------------------------");
148    
149     }
150    
151     sub verify {
152     my $self=shift;
153     my $file1=shift;
154     my $file2=shift;
155     my $same=1;
156    
157     $self->_testout(">Verifying files : $file1 \n".
158     " $file2");
159     open ( FILE1, "<$file1" ) or die "Cannot Read Test Output $file1 $!\n";
160     open ( FILE2, "<$file2" ) or die "Cannot Read Benchmark file ".
161     "$file2 $!\n";
162 williamc 1.5 while ( $f1=<FILE2> ) {
163     $f2=<FILE1>;
164     if ( (!defined $f2 ) || ( ! defined $f1) || ($f2 ne $f1 )) {
165     #print "T:\n$f1\nB:$f2\n";
166 williamc 1.1 $same=0;
167     }
168     }
169     close FILE1;
170     close FILE2;
171     if ( $same==0 ) {
172     $self->testfail("File $file1 is not the same as $file2");
173     }
174     }
175    
176     sub verifydir {
177     my $self=shift;
178     my $name=shift;
179    
180     if ( -d "$name" ) {
181 williamc 1.5 $self->testpass("Directory $name exists - test passed");
182 williamc 1.1 }
183     else {
184     $self->testfail("Directory $name does not exist");
185     }
186     }
187    
188 williamc 1.5 sub verifyexists {
189     my $self=shift;
190     my $name=shift;
191    
192 williamc 1.6 if ( -e "$name" ) {
193     $self->testpass("$name exists - test passed");
194 williamc 1.5 }
195     else {
196 williamc 1.6 $self->testfail("$name does not exist");
197 williamc 1.11 }
198     }
199    
200     sub testswitch {
201     my $self=shift;
202     my $bool=shift;
203     my $string1=shift;
204     my $string2=shift;
205    
206 williamc 1.12 if ( ! $bool ) {
207 williamc 1.11 $self->testpass($string1);
208     }
209     else {
210     $self->testfail($string2);
211 williamc 1.5 }
212     }
213    
214 williamc 1.1 sub testfail {
215     my $self=shift;
216     my $string=shift;
217    
218     $self->_testout("$bold $string $normal");
219     push @{$self->{failedtests}}, $self->{testnumber};
220     }
221    
222     sub testpass {
223     my $self=shift;
224     my $string=shift;
225    
226     $self->_testout($string);
227     }
228    
229     sub newfilename {
230     my $self=shift;
231     $self->{filenumber}++;
232     return "temptest_$self->{filenumber}";
233     }
234    
235     sub temparea {
236     my $self=shift;
237     return $self->{temparea};
238     }
239    
240     #
241     # return the data directory ( and set if given an argument )
242     #
243     sub datadir {
244     my $self=shift;
245     my $dir=shift;
246     if ( $dir ne "" ) {
247     $self->{datadir}=$dir;
248     }
249     return $self->{datadir};
250     }
251    
252     #
253     # -------------------- Private Methods ----------------------------
254     # (only to be used by the inheriting class)
255    
256     #
257     # A basic new method for inheriting classes
258     #
259    
260     sub _new {
261     my $class=shift;
262     my $testobject=shift;
263     my $module=shift;
264    
265    
266     # Bless this object and all those who inherit from her
267     my $self={};
268     bless $self, $class;
269    
270     # we want the dat members from the initialisation of our class in
271     # here too
272     foreach $key ( keys %$testobject ) {
273     $self->{$key}=$testobject->{$key};
274     }
275    
276     print "Initialising $class\n";
277    
278     # Data Initialisation
279     $self->{testclass}=$class;
280 williamc 1.4 ($self->{classname}=$module)=~s/::/\//g;
281 williamc 1.1 ($self->{class}=$module)=~s/.*\///g;
282     $self->{classfile}=$ENV{SCRAM_HOME}."/src/".$self->{classname}."\.pm";
283     $self->init(@_);
284     $self->analyseInterface();
285     delete $self->{expect};
286     return $self;
287     }
288    
289     #
290     # Test the interface
291     #
292     sub testinterface {
293     my $self=shift;
294     my $subname=shift;
295     my $myreturn;
296 williamc 1.4 my $expected;
297 williamc 1.1
298     $self->_checkdoc($subname);
299     $self->{inttest}{$subname}++;
300     $self->_testout(">Trying interface $subname ");
301     my $args=join ', ', @_;
302     $self->_testout( " (".$args.")" );
303 williamc 1.2 $num=0;
304 williamc 1.1 if ( exists $self->{expect} ) {
305 williamc 1.9 print "Testing Expected Values against actual returns ....\n";
306 williamc 1.2 @mylist=eval { $self->{object}->$subname(@_); };
307     die "Test Failed $@\n" if $@;
308 williamc 1.9 my $nrv=$#mylist+1; my $nrve=$#{$self->{expect}}+1;
309     print $nrv." values returned ".$nrve." expected\n";
310     if ( $nrv != $nrve ) {
311     $self->testfail("Number of returned values != that expected");
312     }
313 williamc 1.4 if ( defined @mylist ) {
314 williamc 1.6 # size check
315 williamc 1.9 if ( $#mylist != $#{$self->{expect}} ) {
316     $self->testfail("Number of returned values inconsistent");
317 williamc 1.6 }
318 williamc 1.4 foreach $myreturn ( @mylist ) {
319     if ( ! defined $myreturn ) {
320     print "Undefined Value Passed Back\n";
321     }
322 williamc 1.5 elsif ( $myreturn=~/HASH/ ) {
323 williamc 1.8 print "Hash Ref ".ref($myreturn)." returned\n";
324 williamc 1.1 }
325 williamc 1.5 elsif ( $myreturn=~/CODE/ ) {
326 williamc 1.2 print "Code Ref returned\n";
327     }
328 williamc 1.5 elsif ( $myreturn=~/ARRAY/ ) {
329 williamc 1.2 print "Array Ref returned\n";
330     }
331     else {
332 williamc 1.4 $expected=$self->{expect}[$num++];
333 williamc 1.2 if ( $myreturn eq $expected ) { #simple return case
334     $self->testpass("OK - returned as expected ($expected)");
335     }
336     else {
337     $self->testfail("Expecting $expected, got ".
338     $myreturn);
339     }
340     }
341 williamc 1.4 } # end foreach block
342     }
343 williamc 1.2 return @mylist;
344 williamc 1.1 }
345     else {
346     return ($self->{object}->$subname(@_));
347     }
348     }
349    
350     #
351     # expect - tell testinterface what returns to expect and fail/pass
352     #
353     sub expect {
354     my $self=shift;
355    
356 williamc 1.6 push @{$self->{expect}}, @_;
357 williamc 1.1 }
358    
359     sub clearexpect {
360     my $self=shift;
361     my $string=shift;
362    
363     delete $self->{expect};
364     }
365    
366     #
367     # checktests
368     #
369     sub checktests {
370     my $self=shift;
371     $self->newtest(">Checking all documented Interfaces have been tested ");
372     foreach $key ( keys %{$self->{interfaceargs}} ) {
373     if ( ! exists $self->{inttest}{$key} ) {
374     $self->testfail ("$key has not been tested");
375     }
376     }
377     # Now see whats failed
378     foreach $fail ( @{$self->{failedtests}} ) {
379     $self->_testout("$bold Failed in $fail $normal");
380     }
381     }
382    
383     #
384     # Create a new object
385     #
386     sub newobject {
387     my $self=shift;
388    
389     $self->_checkdoc("new");
390     $self->_testout(">Creating new Object $self->{class}");
391     $self->{object}=$self->{class}->new(@_);
392     $self->_testout(" ( $self->{object} )");
393     $self->{inttest}{"new"}++;
394     }
395    
396     #
397     # check if interface has been documented
398     #
399     sub _checkdoc {
400     my $self=shift;
401     my $name=shift;
402    
403     if ( exists $self->{interfaceargs}{$name} ) {
404     }
405     else {
406     $self->_testout
407     ("Tester: Interface Method '$name' is not documented\n");
408     }
409     }
410    
411     #
412     # Output messages to screen/logs etc
413     #
414     sub _testout($) {
415     my $self=shift;
416     my $string=shift;
417    
418     print $string;
419     print "\n";
420     }
421     #
422     # Method to read the interface documentation
423     #
424    
425     sub analyseInterface {
426     my $self=shift;
427     my $intregion=0;
428    
429     open ( SRCIN, $self->{"classfile"} )
430     or die "Unable to open $classfile $!\n";
431     while ( <SRCIN> ) {
432     if ( $_=~/#\s*Interface/g ) {
433     $intregion=1;
434     next;
435     }
436     if ( $intregion ) { # if we are in the interface documentation
437     if ( ( $_!~/^#/ ) || ( $_=~/^#\s?-{40}/ ) ) { #moving out of Int doc
438     $intregion=0;
439     next;
440     }
441     if ( $_=~/^#\s*(.*)\((.*)\)?:(.*)/ ) {
442     $interface=$1;
443     $args=$2;
444     $rest=$3;
445     next if ($interface eq "");
446     push @{$self->{'interfaces'}},$interface;
447     $self->{interfaceargs}{$interface}=$args;
448     print " Documented Interface $interface\n";
449     }
450     }
451     }
452     close SRCIN;
453 williamc 1.5 }
454    
455     sub cleantemp {
456     my $self=shift;
457     use File::Path;
458     rmtree($self->temparea());
459 williamc 1.1 }