#!/usr/local/bin/perl -w # Sets a couple standard arguments: @Date::Manip::TestArgs=(); @Date::Manip::TestArgs=qw( PersonalCnf=Manip.cnf PathSep=! PersonalCnfPath=./t!. IgnoreGlobalCnf=1 TZ=EST ); # This takes a list of strings of the form: # ARG1 # ... # ARGn # NOTE # EXP # or # ARG1 # ... # ARGn # NOTE # ~ # EXP1 # ... # EXPm # where ARGi are a list of arguments to pass to the appropriate function, # NOTE is an optional note to print if the test fails, and EXP is the # expected result (or list of results). NOTE must begin with the character # ">". All tests must be separated by a blank line from the next test. If # EXP starts with a "~", it is treated as approximate. # # $funcref is the function to pass the arguments to, $tests is the list of # newline separated strings, $runtests is a value passed in if it is called # using the runtests command, @extra are extra arguments which are added # to the function call. # # If $runtests=0, everything is printed. If it equals -N, only test N is # run. If it equals N, start at test N. # # $ntest is the total number of tests. sub test_Func { my($ntest,$funcref,$tests,$runtests,@extra)=@_; my(@tests)=split(/\n/,$tests); my($comment)="#"; my($test,@args,$note,$exp,$ans,$approx,$ans1,$ans2,$t,@exp)=(); $t=0; while (@tests) { # Find the first argument while(@tests) { $test=$tests[0]; $test =~ s/^\s+//; shift(@tests), next if ($test eq "" or $test =~ /^$comment/); last; } $t++; # Read all arguments, note, and expected value @args=(); @exp=(); $exp=-1; while(@tests) { $test=shift(@tests); $test =~ s/^\s+//; last if ($test eq ""); next if ($test =~ /^$comment/); if ($test eq "nil") { push(@args,""); } elsif ($test eq "~") { $exp=$#args; } else { push(@args,$test); } } next if (defined $runtests and $runtests<0 and $t!=-$runtests); next if (defined $runtests and $runtests>0 and $t<$runtests); # Separate out the note and expected value if ($exp == -1) { @exp=(); $exp=pop(@args); $exp=~ s/\s+//g; $exp=~ s/_/ /g; } else { @exp=splice(@args,$exp+1); $exp=join(" ",@exp); } $exp=~s/ +/ /g; $note=""; if ($args[$#args] =~ /^>/) { $note=pop(@args); $note =~ s/^>\s*//; } # An approximate answer is good to within 10 seconds. $approx=0; if ($exp =~ /^~/) { $approx=1; $exp=~ s/^~//; $ans1=DateCalc($exp,"-10"); $ans2=DateCalc($exp,"+10"); } my(@out,@ans,$tmp,%tmp,@tmp); @ans=&$funcref(@args,@extra); while (@ans) { $tmp=shift(@ans); if (ref $tmp) { if (ref $tmp eq "SCALAR") { unshift(@ans,$$tmp); } elsif (ref $tmp eq "ARRAY") { unshift(@ans,"[",@$tmp,"]"); } elsif (ref $tmp eq "HASH") { %tmp=%$tmp; @tmp=(); foreach $tmp (sort keys %tmp) { push(@tmp,$tmp,"=>",$tmp{$tmp}); } unshift(@ans,"{",@tmp,"}"); } else { push @out,ref $tmp; } } else { push @out,$tmp; } } $ans=join(" ",@out); $ans=~s/ +/ /g; # if (@exp) { # $ans=join(" ",&$funcref(@args,@extra)); # } else { # $ans=&$funcref(@args,@extra); # } $bad=1; $bad=0 if ($exp eq $ans or $exp eq "nil" && $ans eq ""); $bad=0 if ($approx and $ans ge $ans1 && $ans le $ans2); if ($bad) { warn "########################\n"; warn "Expected = $exp\n"; warn "Got = $ans\n"; warn "========================\n"; foreach $test (@args) { if (defined $test) { warn "Test = $test\n"; } else { warn "Test = nil\n"; } } foreach $test (@extra) { if (defined $test) { warn "Extra = $test\n"; } else { warn "Extra = nil\n"; } } warn "Note = $note\n" if ($note); warn "########################\n"; print "not ok $t\n"; } else { print "ok $t\n" if (! defined $runtests or $runtests==0); } } print "$t tests\n" if (defined $runtests); print "ntest: $ntest\n" if (defined $runtests && $ntest != $t); } 1;