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

# Content
1 #
2 # Test a documented perl class
3 #
4 # Interface
5 # ---------
6 # new($module,testdatadir) : module example - Utilities/urlhandler
7 # dotest(@args) : Start testing - arguments dependent on inheriting class
8 #
9 # cmpstring(expectedstring,returnedstring) : cmp a string and fail if not equal
10 # 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 # verifyexists(file) : Verify the existence of file
14 # datadir([dir]) : return the current data directory (set it to dir if supplied)
15 # testswitch(int,"0 text"," non 0 text") : testpass or fail according to bool
16 # testfail(string) : report that current test has failed
17 # testpass(string) : report that current test has passed
18 # 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 #cleantemp() : delete the temporary area
25 # cmparray(arrayref, @reqvals) : test the arrayref against expected
26 # cmpstring(expectedstring,actualstring) :
27
28 BEGIN
29 {
30 print "Utilities::TestClass:: I AM called!","\n";
31 };
32
33 package Utilities::TestClass;
34 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 my $dir="";
53 # if ( $fullmodule=~/\// ) {
54 # ($dir=$fullmodule)=~s/(.*\/)(.*)/$1/;
55 # }
56 if ( $fullmodule=~/::/ ) {
57 ($dir=$fullmodule)=~s/(.*::)(.*)/$1/;
58 }
59 else { $dir="" }
60 ($testmodule=$fullmodule)=~s/(.*\/)(.*)/$1test::test_$2/;
61 ($testmodule=$fullmodule)=~s/${dir}(.*)/${dir}test::test_$1/;
62 ($module=$testmodule)=~s/.*\///g;
63
64 $self->{class}=$module;
65 $self->{"datadir"}=$datadir;
66 $self->{filenumber}=0;
67 rmtree("/tmp/SCRAMtest++");
68 $self->{temparea}="/tmp/SCRAMtest++";
69 use File::Path;
70 mkpath ($self->{temparea},0, 0777);
71
72 # Now setup a new testobject of the appropriate type
73 eval "require $testmodule";
74 die $@ if $@;
75 $self->{testobj}=$module->_new($self, $fullmodule);
76
77 # make sure the temparea is cleaned
78 use File::Path;
79
80 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 }
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 }
106
107
108 sub cmpstring {
109 my $self=shift;
110 my $s1=shift;
111 my $s2=shift;
112
113 if ( ! defined $s2) {
114 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 }
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
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 $self->_testout("");
142 $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 while ( $f1=<FILE2> ) {
163 $f2=<FILE1>;
164 if ( (!defined $f2 ) || ( ! defined $f1) || ($f2 ne $f1 )) {
165 #print "T:\n$f1\nB:$f2\n";
166 $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 $self->testpass("Directory $name exists - test passed");
182 }
183 else {
184 $self->testfail("Directory $name does not exist");
185 }
186 }
187
188 sub verifyexists {
189 my $self=shift;
190 my $name=shift;
191
192 if ( -e "$name" ) {
193 $self->testpass("$name exists - test passed");
194 }
195 else {
196 $self->testfail("$name does not exist");
197 }
198 }
199
200 sub testswitch {
201 my $self=shift;
202 my $bool=shift;
203 my $string1=shift;
204 my $string2=shift;
205
206 if ( ! $bool ) {
207 $self->testpass($string1);
208 }
209 else {
210 $self->testfail($string2);
211 }
212 }
213
214 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 ($self->{classname}=$module)=~s/::/\//g;
281 ($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 my $expected;
297
298 $self->_checkdoc($subname);
299 $self->{inttest}{$subname}++;
300 $self->_testout(">Trying interface $subname ");
301 my $args=join ', ', @_;
302 $self->_testout( " (".$args.")" );
303 $num=0;
304 if ( exists $self->{expect} ) {
305 print "Testing Expected Values against actual returns ....\n";
306 @mylist=eval { $self->{object}->$subname(@_); };
307 die "Test Failed $@\n" if $@;
308 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 if ( defined @mylist ) {
314 # size check
315 if ( $#mylist != $#{$self->{expect}} ) {
316 $self->testfail("Number of returned values inconsistent");
317 }
318 foreach $myreturn ( @mylist ) {
319 if ( ! defined $myreturn ) {
320 print "Undefined Value Passed Back\n";
321 }
322 elsif ( $myreturn=~/HASH/ ) {
323 print "Hash Ref ".ref($myreturn)." returned\n";
324 }
325 elsif ( $myreturn=~/CODE/ ) {
326 print "Code Ref returned\n";
327 }
328 elsif ( $myreturn=~/ARRAY/ ) {
329 print "Array Ref returned\n";
330 }
331 else {
332 $expected=$self->{expect}[$num++];
333 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 } # end foreach block
342 }
343 return @mylist;
344 }
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 push @{$self->{expect}}, @_;
357 }
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 }
454
455 sub cleantemp {
456 my $self=shift;
457 use File::Path;
458 rmtree($self->temparea());
459 }