1 dnl PSPP - a program for statistical analysis.
2 dnl Copyright (C) 2017 Free Software Foundation, Inc.
4 dnl This program is free software: you can redistribute it and/or modify
5 dnl it under the terms of the GNU General Public License as published by
6 dnl the Free Software Foundation, either version 3 of the License, or
7 dnl (at your option) any later version.
9 dnl This program is distributed in the hope that it will be useful,
10 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
11 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 dnl GNU General Public License for more details.
14 dnl You should have received a copy of the GNU General Public License
15 dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
17 AT_BANNER([Perl module tests])
19 m4_divert_push([PREPARE_TESTS])
20 # Find the Address Sanitizer library that PSPP is linked against, if any.
21 # If it exists, it needs to be preloaded when we run Perl.
22 asan_lib=$($abs_top_builddir/libtool --mode=execute ldd \
23 $abs_top_builddir/src/ui/terminal/pspp 2>/dev/null \
26 if test ! -e "$asan_lib"; then
30 dnl This command can be used to run with the PSPP Perl module after it has been
31 dnl built (with "make") but before it has been installed. The -I options are
32 dnl equivalent to "use ExtUtils::testlib;" inside the Perl program, but it does
33 dnl not need to be run with the perl-module build directory as the current
34 dnl working directory.
36 LD_PRELOAD=$asan_lib:$LD_PRELOAD \
37 LD_LIBRARY_PATH=$abs_top_builddir/src/.libs \
38 DYLD_LIBRARY_PATH=$abs_top_builddir/src/.libs \
39 ASAN_OPTIONS="$ASAN_OPTIONS detect_leaks=false" \
40 $PERL -I$abs_top_builddir/perl-module/blib/arch \
41 -I$abs_top_builddir/perl-module/blib/lib "$@"
43 m4_divert_pop([PREPARE_TESTS])
45 AT_SETUP([Perl create system file])
46 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
52 my $d = PSPP::Dict->new();
53 die "dictionary creation" if !ref $d;
54 die if $d->get_var_cnt () != 0;
56 $d->set_label ("My Dictionary");
57 $d->set_documents ("These Documents");
59 # Tests for variable creation
61 my $var0 = PSPP::Var->new ($d, "le");
62 die "trap illegal variable name" if ref $var0;
63 die if $d->get_var_cnt () != 0;
65 $var0 = PSPP::Var->new ($d, "legal");
66 die "accept legal variable name" if !ref $var0;
67 die if $d->get_var_cnt () != 1;
69 my $var1 = PSPP::Var->new ($d, "money",
70 (fmt=>PSPP::Fmt::DOLLAR,
71 width=>4, decimals=>2) );
72 die "cappet valid format" if !ref $var1;
73 die if $d->get_var_cnt () != 2;
75 $d->set_weight ($var1);
77 my $sysfile = PSPP::Sysfile->new ('testfile.sav', $d);
78 die "create sysfile object" if !ref $sysfile;
82 AT_CHECK([run_perl_module test.pl])
83 AT_DATA([dump-dict.sps],
84 [GET FILE='testfile.sav'.
90 AT_CHECK([pspp -O format=csv dump-dict.sps], [0], [dnl
98 Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
99 legal,1,,Scale,Input,8,Right,F9.2,F9.2,
100 money,2,,Scale,Input,8,Right,DOLLAR6.2,DOLLAR6.2,
102 dump-dict.sps:5: note: SHOW: WEIGHT is money.
106 AT_SETUP([Perl writing cases to system files])
107 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
113 my $d = PSPP::Dict->new();
114 PSPP::Var->new ($d, "id",
122 PSPP::Var->new ($d, "name",
129 $d->set_documents ("This should not appear");
130 $d->clear_documents ();
131 $d->add_document ("This is a document line");
133 $d->set_label ("This is the file label");
135 # Check that we can write cases to system files.
136 my $sysfile = PSPP::Sysfile->new ("testfile.sav", $d);
137 my $res = $sysfile->append_case ( [34, "frederick"]);
138 die "append case" if !$res;
140 $res = $sysfile->append_case ( [34, "frederick", "extra"]);
141 die "append case with too many variables" if $res;
144 # Check that sysfiles are closed properly automaticallly in the destructor.
145 my $sysfile2 = PSPP::Sysfile->new ("testfile2.sav", $d);
146 $res = $sysfile2->append_case ( [21, "wheelbarrow"]);
147 die "append case 2" if !$res;
149 $res = $sysfile->append_case ( [34, "frederick", "extra"]);
150 die "append case with too many variables" if $res;
152 # Don't close. We want to test that the destructor does that.
154 AT_CHECK([run_perl_module test.pl])
155 AT_DATA([dump-dicts.sps],
156 [GET FILE='testfile.sav'.
162 GET FILE='testfile2.sav'.
168 AT_CHECK([pspp -O format=csv dump-dicts.sps], [0], [dnl
170 Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
171 id,1,,Scale,Input,8,Right,F2.0,F2.0,
172 name,2,,Nominal,Input,20,Left,A20,A20,
175 Label,This is the file label
178 This is a document line
185 Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
186 id,1,,Scale,Input,8,Right,F2.0,F2.0,
187 name,2,,Nominal,Input,20,Left,A20,A20,
190 Label,This is the file label
193 This is a document line
201 AT_SETUP([Perl write variable parameters])
202 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
208 my $dict = PSPP::Dict->new();
209 die "dictionary creation" if !ref $dict;
211 my $int = PSPP::Var->new ($dict, "integer",
212 (width=>8, decimals=>0) );
214 $int->set_label ("My Integer");
216 $int->add_value_label (99, "Silly");
217 $int->clear_value_labels ();
218 $int->add_value_label (0, "Zero");
219 $int->add_value_label (1, "Unity");
220 $int->add_value_label (2, "Duality");
222 my $str = PSPP::Var->new ($dict, "string",
223 (fmt=>PSPP::Fmt::A, width=>8) );
226 $str->set_label ("My String");
227 $str->add_value_label ("xx", "foo");
228 $str->add_value_label ("yy", "bar");
230 $str->set_missing_values ("this", "that");
232 my $longstr = PSPP::Var->new ($dict, "longstring",
233 (fmt=>PSPP::Fmt::A, width=>9) );
236 $longstr->set_label ("My Long String");
237 my $re = $longstr->add_value_label ("xxx", "xfoo");
239 $int->set_missing_values (9, 99);
241 my $sysfile = PSPP::Sysfile->new ("testfile.sav", $dict);
246 AT_CHECK([run_perl_module test.pl], [0], [], [stderr])
248 AT_DATA([dump-dict.sps],
249 [GET FILE='testfile.sav'.
252 AT_CHECK([pspp -O format=csv dump-dict.sps], [0], [dnl
254 Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
255 integer,1,My Integer,Scale,Input,8,Right,F8.0,F8.0,9; 99
256 string,2,My String,Nominal,Input,8,Left,A8,A8,"""this ""; ""that """
257 longstring,3,My Long String,Nominal,Input,9,Left,A9,A9,
260 Variable Value,,Label
266 My Long String,xxx,xfoo
270 AT_SETUP([Perl dictionary survives system file])
271 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
280 my $d = PSPP::Dict->new();
282 PSPP::Var->new ($d, "id",
290 $sysfile = PSPP::Sysfile->new ("testfile.sav", $d);
293 my $res = $sysfile->append_case ([3]);
294 print "Dictionary survives sysfile\n" if $res;
296 AT_CHECK([run_perl_module test.pl], [0],
297 [Dictionary survives sysfile
301 m4_define([PERL_GENERATE_SYSFILE],
302 [AT_DATA([sample.sps],
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='sample.sav'.
337 AT_CHECK([pspp -O format=csv sample.sps])])
339 AT_SETUP([Perl read system file])
340 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
341 PERL_GENERATE_SYSFILE
347 my $sf = PSPP::Reader->open ("sample.sav");
349 my $dict = $sf->get_dict ();
351 for (my $v = 0 ; $v < $dict->get_var_cnt() ; $v++)
353 my $var = $dict->get_var ($v);
354 my $name = $var->get_name ();
355 my $label = $var->get_label ();
357 print "Variable $v is \"$name\", label is \"$label\"\n";
359 my $vl = $var->get_value_labels ();
361 print "Value Labels:\n";
362 print "$_ => $vl->{$_}\n" for sort (keys %$vl);
365 while (my @c = $sf->get_next_case () )
367 for (my $v = 0; $v < $dict->get_var_cnt(); $v++)
369 print "val$v: \"$c[$v]\"\n";
374 AT_CHECK([run_perl_module test.pl], [0],
375 [Variable 0 is "string", label is "A Short String Variable"
380 Variable 1 is "longstring", label is "A Long String Variable"
382 Variable 2 is "numeric", label is "A Numeric Variable"
387 Variable 3 is "date", label is "A Date Variable"
389 Variable 4 is "dollar", label is "A Dollar Variable"
391 Variable 5 is "datetime", label is "A Datetime Variable"
431 AT_SETUP([Perl copying system files])
432 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
433 PERL_GENERATE_SYSFILE
439 my $input = PSPP::Reader->open ("sample.sav");
441 my $dict = $input->get_dict ();
443 my $output = PSPP::Sysfile->new ("copy.sav", $dict);
445 while (my (@c) = $input->get_next_case () )
447 $output->append_case (\@c);
452 AT_CHECK([run_perl_module test.pl])
453 AT_DATA([dump-dicts.sps],
454 [GET FILE='sample.sav'.
464 AT_CHECK([pspp -O format=csv dump-dicts.sps], [0],
466 Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
467 string,1,A Short String Variable,Nominal,Input,8,Left,A8,A8,"""3333 """
468 longstring,2,A Long String Variable,Nominal,Input,12,Left,A12,A12,
469 numeric,3,A Numeric Variable,Scale,Input,8,Right,F10.0,F10.0,9; 5; 999
470 date,4,A Date Variable,Scale,Input,8,Right,DATE11,DATE11,
471 dollar,5,A Dollar Variable,Scale,Input,8,Right,DOLLAR11.2,DOLLAR11.2,
472 datetime,6,A Datetime Variable,Scale,Input,8,Right,DATETIME17.0,DATETIME17.0,
475 Variable Value,,Label
476 A Short String Variable,1111,ones
479 A Numeric Variable,1,Unity
486 Table: Variable and Dataset Attributes
487 Variable and Name,,Value
488 A Numeric Variable,colour[1],blue
495 string,longstring,numeric,date,dollar,datetime
496 1111,One,1,01-JAN-2001,$1.00,01-JAN-2001 01:01
497 2222,Two,2,02-FEB-2002,$2.00,02-FEB-2002 02:02
498 3333,Three,3,03-MAR-2003,$3.00,03-MAR-2003 03:03
500 5555,Five,5,05-MAY-2005,$5.00,05-MAY-2005 05:05
503 Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
504 string,1,A Short String Variable,Nominal,Input,8,Left,A8,A8,"""3333 """
505 longstring,2,A Long String Variable,Nominal,Input,12,Left,A12,A12,
506 numeric,3,A Numeric Variable,Scale,Input,8,Right,F10.0,F10.0,9; 5; 999
507 date,4,A Date Variable,Scale,Input,8,Right,DATE11,DATE11,
508 dollar,5,A Dollar Variable,Scale,Input,8,Right,DOLLAR11.2,DOLLAR11.2,
509 datetime,6,A Datetime Variable,Scale,Input,8,Right,DATETIME17.0,DATETIME17.0,
512 Variable Value,,Label
513 A Short String Variable,1111,ones
516 A Numeric Variable,1,Unity
523 Table: Variable and Dataset Attributes
524 Variable and Name,,Value
525 A Numeric Variable,colour[1],blue
532 string,longstring,numeric,date,dollar,datetime
533 1111,One,1,01-JAN-2001,$1.00,01-JAN-2001 01:01
534 2222,Two,2,02-FEB-2002,$2.00,02-FEB-2002 02:02
535 3333,Three,3,03-MAR-2003,$3.00,03-MAR-2003 03:03
537 5555,Five,5,05-MAY-2005,$5.00,05-MAY-2005 05:05
541 AT_SETUP([Perl value formatting])
542 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
544 [DATA LIST LIST /d (DATETIME17).
549 SAVE OUTFILE='dd.sav'.
551 AT_CHECK([pspp -O format=csv dd.sps], [0],
552 [Table: Reading free-form data from INLINE.
561 my $sf = PSPP::Reader->open ("dd.sav");
563 my $dict = $sf->get_dict ();
565 my (@c) = $sf->get_next_case ();
567 my $var = $dict->get_var (0);
569 my $formatted = PSPP::format_value ($val, $var);
570 my $str = gmtime ($val - PSPP::PERL_EPOCH);
571 print "Formatted string is \"$formatted\"\n";
572 print "Perl representation is \"$str\"\n";
574 AT_CHECK([run_perl_module test.pl], [0],
575 [[Formatted string is "11-SEP-2001 08:20"
576 Perl representation is "Tue Sep 11 08:20:00 2001"
580 AT_SETUP([Perl opening nonexistent file])
581 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
587 my $sf = PSPP::Reader->open ("no-such-file.sav");
589 die "Returns undef on opening failure" if ref $sf;
590 print $PSPP::errstr, "\n";
592 AT_CHECK([run_perl_module test.pl], [0],
593 [[An error occurred while opening `no-such-file.sav': No such file or directory.
595 [[Name "PSPP::errstr" used only once: possible typo at test.pl line 8.
599 AT_SETUP([Perl missing values])
600 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
601 PERL_GENERATE_SYSFILE
607 my $sf = PSPP::Reader->open ("sample.sav");
609 my $dict = $sf->get_dict ();
611 my (@c) = $sf->get_next_case ();
613 my $stringvar = $dict->get_var (0);
614 my $numericvar = $dict->get_var (2);
617 die "Missing Value Negative String"
618 if PSPP::value_is_missing ($val, $stringvar);
622 die "Missing Value Negative Num"
623 if PSPP::value_is_missing ($val, $numericvar);
625 @c = $sf->get_next_case ();
626 @c = $sf->get_next_case ();
629 die "Missing Value Positive"
630 if !PSPP::value_is_missing ($val, $stringvar);
632 @c = $sf->get_next_case ();
634 die "Missing Value Positive SYS"
635 if !PSPP::value_is_missing ($val, $numericvar);
637 @c = $sf->get_next_case ();
639 die "Missing Value Positive Num"
640 if !PSPP::value_is_missing ($val, $numericvar);
642 AT_CHECK([run_perl_module test.pl])
645 AT_SETUP([Perl custom attributes])
646 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
647 PERL_GENERATE_SYSFILE
653 my $sf = PSPP::Reader->open ("sample.sav");
655 my $dict = $sf->get_dict ();
657 my $var = $dict->get_var_by_name ("numeric");
659 my $attr = $var->get_attributes ();
661 foreach my $k (sort (keys (%$attr)))
663 my $ll = $attr->{$k};
665 print map "$_\n", join ', ', @$ll;
668 AT_CHECK([run_perl_module test.pl], [0],
670 colour =>blue, pink, violet
671 nationality =>foreign
676 AT_SETUP([Perl Pspp.t])
677 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
678 # Skip this test if Perl's Text::Diff module is not installed.
679 AT_CHECK([perl -MText::Diff -e '' || exit 77])
680 AT_CHECK([run_perl_module $abs_top_builddir/perl-module/t/Pspp.t], [0],
683 ok 2 - Dictionary Creation
685 ok 4 - Trap illegal variable name
687 ok 6 - Accept legal variable name
689 ok 8 - Trap duplicate variable name
691 ok 10 - Accept valid format
693 ok 12 - Create sysfile object
694 ok 13 - Write system file
696 ok 15 - Appending Case with too many variables
698 ok 17 - Append Case 2
701 ok 20 - Dictionary Creation 2
702 ok 21 - Value label for short string
703 ok 22 - Value label for long string
704 ok 23 - Check output 2
705 ok 24 - Dictionary survives sysfile
706 ok 25 - Basic reader operation
707 ok 26 - Streaming of files
708 Formatted string is "11-SEP-2001 08:20"
709 ok 27 - format_value function
710 ok 28 - Perl representation of time
711 ok 29 - Returns undef on opening failure
712 ok 30 - Error string on open failure
713 ok 31 - Missing Value Negative String
714 ok 32 - Missing Value Negative Num
715 ok 33 - Missing Value Positive
716 ok 34 - Missing Value Positive SYS
717 ok 35 - Missing Value Positive Num
718 ok 36 - Custom Attributes