2 # Before `make install' is performed this script should be runnable with
3 # `make test'. After `make install' it should work as `perl PSPP.t'
5 #########################
7 # change 'tests => 1' to 'tests => last_test_to_print';
9 use Test::More tests => 37;
11 use File::Temp qw/ tempfile tempdir /;
12 BEGIN { use_ok('PSPP') };
14 #########################
20 return ! diff ("$file", \$pattern);
23 my $pspp_cmd = $ENV{PSPP_TEST_CMD};
35 my $syntaxfile = "$tempdir/foo.sps";
37 open (FH, ">$syntaxfile");
41 system ("cd $tempdir; $pspp_cmd -o raw-ascii $syntaxfile");
44 sub run_pspp_syntax_cmp
51 run_pspp_syntax ($tempdir, $syntax);
53 my $diff = diff ("$tempdir/pspp.list", \$result);
64 # Insert your test code below, the Test::More module is used here so read
65 # its man page ( perldoc Test::More ) for help writing this test script.
68 my $d = PSPP::Dict->new();
69 ok (ref $d, "Dictionary Creation");
70 ok ($d->get_var_cnt () == 0);
72 $d->set_label ("My Dictionary");
73 $d->set_documents ("These Documents");
75 # Tests for variable creation
77 my $var0 = PSPP::Var->new ($d, "le");
78 ok (!ref $var0, "Trap illegal variable name");
79 ok ($d->get_var_cnt () == 0);
81 $var0 = PSPP::Var->new ($d, "legal");
82 ok (ref $var0, "Accept legal variable name");
83 ok ($d->get_var_cnt () == 1);
85 my $var1 = PSPP::Var->new ($d, "legal");
86 ok (!ref $var1, "Trap duplicate variable name");
87 ok ($d->get_var_cnt () == 1);
89 $var1 = PSPP::Var->new ($d, "money",
90 (fmt=>PSPP::Fmt::DOLLAR,
91 width=>4, decimals=>2) );
92 ok (ref $var1, "Accept valid format");
93 ok ($d->get_var_cnt () == 2);
95 $d->set_weight ($var1);
98 # Tests for system file creation
99 # Make sure a system file can be created
101 my $tempdir = tempdir( CLEANUP => 1 );
102 my $tempfile = "$tempdir/testfile.sav";
103 my $syntaxfile = "$tempdir/syntax.sps";
104 my $sysfile = PSPP::Sysfile->new ("$tempfile", $d);
105 ok (ref $sysfile, "Create sysfile object");
108 ok (-s "$tempfile", "Write system file");
113 # Make sure we can write cases to a file
115 my $d = PSPP::Dict->new();
116 PSPP::Var->new ($d, "id",
124 PSPP::Var->new ($d, "name",
131 $d->set_documents ("This should not appear");
132 $d->clear_documents ();
133 $d->add_document ("This is a document line");
135 $d->set_label ("This is the file label");
137 # Check that we can write system files
139 my $tempdir = tempdir( CLEANUP => 1 );
140 my $tempfile = "$tempdir/testfile.sav";
141 my $sysfile = PSPP::Sysfile->new ("$tempfile", $d);
143 my $res = $sysfile->append_case ( [34, "frederick"]);
144 ok ($res, "Append Case");
146 $res = $sysfile->append_case ( [34, "frederick", "extra"]);
147 ok (!$res, "Appending Case with too many variables");
150 ok (-s "$tempfile", "existance");
153 # Check that sysfiles are closed properly
155 my $tempdir = tempdir( CLEANUP => 1 );
156 my $tempfile = "$tempdir/testfile.sav";
158 my $sysfile = PSPP::Sysfile->new ("$tempfile", $d);
160 my $res = $sysfile->append_case ( [21, "wheelbarrow"]);
161 ok ($res, "Append Case 2");
163 # Don't close. We want to test that the destructor does that
166 ok (-s "$tempfile", "existance2");
168 ok (run_pspp_syntax_cmp ($tempdir, <<SYNTAX, <<RESULT), "Check output");
170 GET FILE='$tempfile'.
177 +--------+-------------------------------------------+--------+
178 |Variable|Description |Position|
179 #========#===========================================#========#
180 |id |Format: F2.0 | 1|
181 | |Measure: Scale | |
182 | |Display Alignment: Right | |
183 | |Display Width: 8 | |
184 +--------+-------------------------------------------+--------+
185 |name |Format: A20 | 2|
186 | |Measure: Nominal | |
187 | |Display Alignment: Left | |
188 | |Display Width: 20 | |
189 +--------+-------------------------------------------+--------+
192 This is the file label
194 Documents in the active file:
196 This is a document line
199 -- --------------------
207 # Now do some tests to make sure all the variable parameters
208 # can be written properly.
211 my $tempdir = tempdir( CLEANUP => 1 );
212 my $tempfile = "$tempdir/testfile.sav";
213 my $dict = PSPP::Dict->new();
214 ok (ref $dict, "Dictionary Creation 2");
216 my $int = PSPP::Var->new ($dict, "integer",
217 (width=>8, decimals=>0) );
219 $int->set_label ("My Integer");
221 $int->add_value_label (99, "Silly");
222 $int->clear_value_labels ();
223 $int->add_value_label (0, "Zero");
224 $int->add_value_label (1, "Unity");
225 $int->add_value_label (2, "Duality");
227 my $str = PSPP::Var->new ($dict, "string",
228 (fmt=>PSPP::Fmt::A, width=>8) );
231 $str->set_label ("My String");
232 ok ($str->add_value_label ("xx", "foo"), "Value label for short string");
233 diag ($PSPP::errstr);
234 $str->add_value_label ("yy", "bar");
236 $str->set_missing_values ("this", "that");
238 my $longstr = PSPP::Var->new ($dict, "longstring",
239 (fmt=>PSPP::Fmt::A, width=>9) );
242 $longstr->set_label ("My Long String");
243 my $re = $longstr->add_value_label ("xxx", "xfoo");
244 ok (($re == 0), "Long strings cant have labels");
246 ok ($PSPP::errstr eq "Cannot add label to a long string variable", "Error msg");
248 $int->set_missing_values (9, 99);
250 my $sysfile = PSPP::Sysfile->new ("$tempfile", $dict);
255 ok (run_pspp_syntax_cmp ($tempdir, <<SYNTAX, <<RESULT), "Check output 2");
256 GET FILE='$tempfile'.
260 +----------+-----------------------------------------+--------+
261 |Variable |Description |Position|
262 #==========#=========================================#========#
263 |integer |My Integer | 1|
265 | |Measure: Scale | |
266 | |Display Alignment: Right | |
267 | |Display Width: 8 | |
268 | |Missing Values: 9; 99 | |
269 | +-----+-----------------------------------+ |
273 +----------+-----+-----------------------------------+--------+
274 |string |My String | 2|
276 | |Measure: Nominal | |
277 | |Display Alignment: Left | |
278 | |Display Width: 8 | |
279 | |Missing Values: "this "; "that " | |
280 | +-----+-----------------------------------+ |
283 +----------+-----+-----------------------------------+--------+
284 |longstring|My Long String | 3|
286 | |Measure: Nominal | |
287 | |Display Alignment: Left | |
288 | |Display Width: 9 | |
289 +----------+-----------------------------------------+--------+
297 sub generate_sav_file
299 my $filename = shift;
302 run_pspp_syntax_cmp ($tempdir, <<SYNTAX, <<RESULT);
303 data list notable list /string (a8) longstring (a12) numeric (f10) date (date11) dollar (dollar8.2) datetime (datetime17)
305 1111 One 1 1/1/1 1 1/1/1+01:01
306 2222 Two 2 2/2/2 2 2/2/2+02:02
307 3333 Three 3 3/3/3 3 3/3/3+03:03
309 5555 Five 5 5/5/5 5 5/5/5+05:05
313 variable labels string 'A Short String Variable'
314 /longstring 'A Long String Variable'
315 /numeric 'A Numeric Variable'
316 /date 'A Date Variable'
317 /dollar 'A Dollar Variable'
318 /datetime 'A Datetime Variable'.
321 missing values numeric (9, 5, 999).
323 missing values string ("3333").
326 /string '1111' 'ones' '2222' 'twos' '3333' 'threes'
327 /numeric 1 'Unity' 2 'Duality' 3 'Thripality'.
331 attribute=colour[1]('blue') colour[2]('pink') colour[3]('violet')
332 attribute=size('large') nationality('foreign').
335 save outfile='$filename'.
343 # Test to make sure that the dictionary survives the sysfile.
344 # Thanks to Rob Messer for reporting this problem
346 my $tempdir = tempdir( CLEANUP => 1 );
347 my $tempfile = "$tempdir/testfile.sav";
351 my $d = PSPP::Dict->new();
353 PSPP::Var->new ($d, "id",
361 $sysfile = PSPP::Sysfile->new ("$tempfile", $d);
364 my $res = $sysfile->append_case ([3]);
366 ok ($res, "Dictionary survives sysfile");
372 my $tempdir = tempdir( CLEANUP => 1 );
374 generate_sav_file ("$tempdir/in.sav", "$tempdir");
376 my $sf = PSPP::Reader->open ("$tempdir/in.sav");
378 my $dict = $sf->get_dict ();
380 open (MYFILE, ">$tempdir/out.txt");
381 for ($v = 0 ; $v < $dict->get_var_cnt() ; $v++)
383 my $var = $dict->get_var ($v);
384 my $name = $var->get_name ();
385 my $label = $var->get_label ();
387 print MYFILE "Variable $v is \"$name\", label is \"$label\"\n";
389 my $vl = $var->get_value_labels ();
391 print MYFILE "Value Labels:\n";
392 print MYFILE "$_ => $vl->{$_}\n" for keys %$vl;
395 while (my @c = $sf->get_next_case () )
397 for ($v = 0; $v < $dict->get_var_cnt(); $v++)
399 print MYFILE "val$v: \"$c[$v]\"\n";
406 ok (compare ("$tempdir/out.txt", <<EOF), "Basic reader operation");
407 Variable 0 is "string", label is "A Short String Variable"
412 Variable 1 is "longstring", label is "A Long String Variable"
414 Variable 2 is "numeric", label is "A Numeric Variable"
419 Variable 3 is "date", label is "A Date Variable"
421 Variable 4 is "dollar", label is "A Dollar Variable"
423 Variable 5 is "datetime", label is "A Datetime Variable"
465 # Check that we can stream one file into another
467 my $tempdir = tempdir( CLEANUP => 1 );
469 generate_sav_file ("$tempdir/in.sav", "$tempdir");
471 my $input = PSPP::Reader->open ("$tempdir/in.sav");
473 my $dict = $input->get_dict ();
475 my $output = PSPP::Sysfile->new ("$tempdir/out.sav", $dict);
477 while (my (@c) = $input->get_next_case () )
479 $output->append_case (\@c);
485 #Check the two files are the same (except for metadata)
487 run_pspp_syntax ($tempdir, <<SYNTAX);
488 get file='$tempdir/in.sav'.
494 system ("cp $tempdir/pspp.list $tempdir/in.txt");
496 run_pspp_syntax ($tempdir, <<SYNTAX);
497 get file='$tempdir/out.sav'.
503 ok (! diff ("$tempdir/pspp.list", "$tempdir/in.txt"), "Streaming of files");
508 # Check that the format_value function works properly
510 my $tempdir = tempdir( CLEANUP => 1 );
512 run_pspp_syntax ($tempdir, <<SYNTAX);
514 data list list /d (datetime17).
519 save outfile='$tempdir/dd.sav'.
523 my $sf = PSPP::Reader->open ("$tempdir/dd.sav");
525 my $dict = $sf->get_dict ();
527 my (@c) = $sf->get_next_case ();
529 my $var = $dict->get_var (0);
531 my $formatted = PSPP::format_value ($val, $var);
532 my $str = gmtime ($val - PSPP::PERL_EPOCH);
533 print "Formatted string is \"$formatted\"\n";
534 ok ( $formatted eq "11-SEP-2001 08:20", "format_value function");
535 ok ( $str eq "Tue Sep 11 08:20:00 2001", "Perl representation of time");
539 # Check that attempting to open a non-existent file results in an error
541 my $tempdir = tempdir( CLEANUP => 1 );
543 unlink ("$tempdir/no-such-file.sav");
545 my $sf = PSPP::Reader->open ("$tempdir/no-such-file.sav");
547 ok ( !ref $sf, "Returns undef on opening failure");
549 ok ("$PSPP::errstr" eq "Error opening \"$tempdir/no-such-file.sav\" for reading as a system file: No such file or directory.",
550 "Error string on open failure");
554 # Missing value tests.
556 my $tempdir = tempdir( CLEANUP => 1 );
558 generate_sav_file ("$tempdir/in.sav", "$tempdir");
560 my $sf = PSPP::Reader->open ("$tempdir/in.sav");
562 my $dict = $sf->get_dict ();
565 my (@c) = $sf->get_next_case ();
567 my $stringvar = $dict->get_var (0);
568 my $numericvar = $dict->get_var (2);
571 ok ( !PSPP::value_is_missing ($val, $stringvar), "Missing Value Negative String");
575 ok ( !PSPP::value_is_missing ($val, $numericvar), "Missing Value Negative Num");
577 @c = $sf->get_next_case ();
578 @c = $sf->get_next_case ();
581 ok ( PSPP::value_is_missing ($val, $stringvar), "Missing Value Positive");
583 @c = $sf->get_next_case ();
585 ok ( PSPP::value_is_missing ($val, $numericvar), "Missing Value Positive SYS");
587 @c = $sf->get_next_case ();
589 ok ( PSPP::value_is_missing ($val, $numericvar), "Missing Value Positive Num");
593 #Test reading of custom attributes
595 my $tempdir = tempdir( CLEANUP => 1 );
597 generate_sav_file ("$tempdir/in.sav", "$tempdir");
599 my $sf = PSPP::Reader->open ("$tempdir/in.sav");
601 my $dict = $sf->get_dict ();
603 my $var = $dict->get_var_by_name ("numeric");
605 my $attr = $var->get_attributes ();
607 open (MYFILE, ">$tempdir/out.txt");
609 foreach $k (keys %$attr)
611 my $ll = $attr->{$k};
612 print MYFILE "$k =>";
613 print MYFILE map "$_\n", join ', ', @$ll;
618 ok (compare ("$tempdir/out.txt", <<EOF), "Custom Attributes");
619 colour =>blue, pink, violet
620 nationality =>foreign