+dnl PSPP - a program for statistical analysis.
+dnl Copyright (C) 2017, 2020, 2021 Free Software Foundation, Inc.
+dnl
+dnl This program is free software: you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation, either version 3 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
+dnl
AT_BANNER([Perl module tests])
+m4_divert_push([PREPARE_TESTS])
+# Find the Address Sanitizer library that PSPP is linked against, if any.
+# If it exists, it needs to be preloaded when we run Perl.
+asan_lib=$("$abs_top_builddir/libtool" --mode=execute ldd \
+ "$abs_top_builddir/src/ui/terminal/pspp" 2>/dev/null \
+ | grep asan \
+ | awk '{print $3}')
+if test -e "$asan_lib"; then
+ USING_ASAN=:
+else
+ USING_ASAN=false
+ asan_lib=
+fi
+
dnl This command can be used to run with the PSPP Perl module after it has been
dnl built (with "make") but before it has been installed. The -I options are
dnl equivalent to "use ExtUtils::testlib;" inside the Perl program, but it does
dnl not need to be run with the perl-module build directory as the current
dnl working directory.
-dnl
-dnl XXX "libtool --mode=execute" is probably better than setting
-dnl LD_LIBRARY_PATH.
-m4_define([RUN_PERL_MODULE],
- [LD_LIBRARY_PATH=$abs_top_builddir/src/.libs \
- DYLD_LIBRARY_PATH=$abs_top_builddir/src/.libs \
- $PERL -I$abs_top_builddir/perl-module/blib/arch \
- -I$abs_top_builddir/perl-module/blib/lib])
+run_perl_module () {
+ LD_PRELOAD="$asan_lib":"$LD_PRELOAD" \
+ LD_LIBRARY_PATH="$abs_top_builddir/src/.libs" \
+ DYLD_LIBRARY_PATH="$abs_top_builddir/src/.libs" \
+ ASAN_OPTIONS="$ASAN_OPTIONS detect_leaks=false" \
+ $PERL -I"$abs_top_builddir/perl-module/blib/arch" \
+ -I"$abs_top_builddir/perl-module/blib/lib" "$@"
+}
+m4_divert_pop([PREPARE_TESTS])
AT_SETUP([Perl create system file])
AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
die "accept legal variable name" if !ref $var0;
die if $d->get_var_cnt () != 1;
- my $var1 = PSPP::Var->new ($d, "money",
+ my $var1 = PSPP::Var->new ($d, "money",
(fmt=>PSPP::Fmt::DOLLAR,
width=>4, decimals=>2) );
die "cappet valid format" if !ref $var1;
$sysfile->close ();
])
-AT_CHECK([RUN_PERL_MODULE test.pl])
+AT_CHECK([run_perl_module test.pl])
AT_DATA([dump-dict.sps],
[GET FILE='testfile.sav'.
DISPLAY FILE LABEL.
DISPLAY DICTIONARY.
SHOW WEIGHT.
])
-AT_CHECK([pspp -O format=csv dump-dict.sps], [0],
- [File label: My Dictionary
-
-Documents in the active dataset:
+AT_CHECK([pspp -O format=csv dump-dict.sps], [0], [dnl
+Table: File Label
+Label,My Dictionary
+Table: Documents
These Documents
-Variable,Description,,Position
-legal,Format: F9.2,,1
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-money,Format: DOLLAR6.2,,2
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+legal,1,Scale,Input,8,Right,F9.2,F9.2
+money,2,Scale,Input,8,Right,DOLLAR6.2,DOLLAR6.2
dump-dict.sps:5: note: SHOW: WEIGHT is money.
])
my $d = PSPP::Dict->new();
PSPP::Var->new ($d, "id",
(
- fmt=>PSPP::Fmt::F,
- width=>2,
+ fmt=>PSPP::Fmt::F,
+ width=>2,
decimals=>0
)
);
PSPP::Var->new ($d, "name",
(
- fmt=>PSPP::Fmt::A,
- width=>20,
+ fmt=>PSPP::Fmt::A,
+ width=>20,
)
);
# Don't close. We want to test that the destructor does that.
]])
-AT_CHECK([RUN_PERL_MODULE test.pl])
+AT_CHECK([run_perl_module test.pl])
AT_DATA([dump-dicts.sps],
[GET FILE='testfile.sav'.
DISPLAY DICTIONARY.
DISPLAY DOCUMENTS.
LIST.
])
-AT_CHECK([pspp -O format=csv dump-dicts.sps], [0],
- [Variable,Description,,Position
-id,Format: F2.0,,1
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-name,Format: A20,,2
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 20,,
+AT_CHECK([pspp -O format=csv dump-dicts.sps], [0], [dnl
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+id,1,Scale,Input,8,Right,F2.0,F2.0
+name,2,Nominal,Input,20,Left,A20,A20
-File label: This is the file label
-
-Documents in the active dataset:
+Table: File Label
+Label,This is the file label
+Table: Documents
This is a document line
Table: Data List
id,name
-34,frederick @&t@
-
-Variable,Description,,Position
-id,Format: F2.0,,1
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-name,Format: A20,,2
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 20,,
+34,frederick
-File label: This is the file label
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+id,1,Scale,Input,8,Right,F2.0,F2.0
+name,2,Nominal,Input,20,Left,A20,A20
-Documents in the active dataset:
+Table: File Label
+Label,This is the file label
+Table: Documents
This is a document line
Table: Data List
id,name
-21,wheelbarrow @&t@
+21,wheelbarrow
])
AT_CLEANUP
my $dict = PSPP::Dict->new();
die "dictionary creation" if !ref $dict;
- my $int = PSPP::Var->new ($dict, "integer",
+ my $int = PSPP::Var->new ($dict, "integer",
(width=>8, decimals=>0) );
$int->set_label ("My Integer");
$int->add_value_label (1, "Unity");
$int->add_value_label (2, "Duality");
- my $str = PSPP::Var->new ($dict, "string",
+ my $str = PSPP::Var->new ($dict, "string",
(fmt=>PSPP::Fmt::A, width=>8) );
$str->set_missing_values ("this", "that");
- my $longstr = PSPP::Var->new ($dict, "longstring",
+ my $longstr = PSPP::Var->new ($dict, "longstring",
(fmt=>PSPP::Fmt::A, width=>9) );
$sysfile->close ();
]])
-AT_CHECK([RUN_PERL_MODULE test.pl])
+AT_CHECK([run_perl_module test.pl], [0], [], [stderr])
+cat stderr
AT_DATA([dump-dict.sps],
[GET FILE='testfile.sav'.
DISPLAY DICTIONARY.
])
-AT_CHECK([pspp -O format=csv dump-dict.sps], [0],
- [Variable,Description,,Position
-integer,My Integer,,1
-,Format: F8.0,,
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-,Missing Values: 9; 99,,
-,0,Zero,
-,1,Unity,
-,2,Duality,
-string,My String,,2
-,Format: A8,,
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 8,,
-,"Missing Values: ""this ""; ""that """,,
-,xx ,foo,
-,yy ,bar,
-longstring,My Long String,,3
-,Format: A9,,
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 9,,
-,xxx ,xfoo,
+AT_CHECK([pspp -O format=csv dump-dict.sps], [0], [dnl
+Table: Variables
+Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
+integer,1,My Integer,Scale,Input,8,Right,F8.0,F8.0,9; 99
+string,2,My String,Nominal,Input,8,Left,A8,A8,"""this ""; ""that """
+longstring,3,My Long String,Nominal,Input,9,Left,A9,A9,
+
+Table: Value Labels
+Variable Value,,Label
+My Integer,0,Zero
+,1,Unity
+,2,Duality
+My String,xx,foo
+,yy,bar
+My Long String,xxx,xfoo
])
AT_CLEANUP
PSPP::Var->new ($d, "id",
(
- fmt=>PSPP::Fmt::F,
- width=>2,
+ fmt=>PSPP::Fmt::F,
+ width=>2,
decimals=>0
)
);
my $res = $sysfile->append_case ([3]);
print "Dictionary survives sysfile\n" if $res;
]])
-AT_CHECK([RUN_PERL_MODULE test.pl], [0],
+AT_CHECK([run_perl_module test.pl], [0],
[Dictionary survives sysfile
])
AT_CLEANUP
print "\n";
}
]])
-AT_CHECK([RUN_PERL_MODULE test.pl], [0],
+AT_CHECK([run_perl_module test.pl], [0],
[Variable 0 is "string", label is "A Short String Variable"
Value Labels:
1111 => ones
$output->close ();
]])
-AT_CHECK([RUN_PERL_MODULE test.pl])
+AT_CHECK([run_perl_module test.pl])
AT_DATA([dump-dicts.sps],
[GET FILE='sample.sav'.
DISPLAY DICTIONARY.
+DISPLAY ATTRIBUTES
LIST.
GET FILE='copy.sav'.
DISPLAY DICTIONARY.
+DISPLAY ATTRIBUTES
LIST.
])
AT_CHECK([pspp -O format=csv dump-dicts.sps], [0],
- [[Variable,Description,,Position
-string,A Short String Variable,,1
-,Format: A8,,
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 8,,
-,"Missing Values: ""3333 """,,
-,1111 ,ones,
-,2222 ,twos,
-,3333 ,threes,
-longstring,A Long String Variable,,2
-,Format: A12,,
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 12,,
-numeric,A Numeric Variable,,3
-,Format: F10.0,,
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-,Missing Values: 9; 5; 999,,
-,1,Unity,
-,2,Duality,
-,3,Thripality,
-,Custom attributes:,,
-,colour[1],blue,
-,colour[2],pink,
-,colour[3],violet,
-,nationality,foreign,
-,size,large,
-date,A Date Variable,,4
-,Format: DATE11,,
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-dollar,A Dollar Variable,,5
-,Format: DOLLAR11.2,,
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-datetime,A Datetime Variable,,6
-,Format: DATETIME17.0,,
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
+ [[Table: Variables
+Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
+string,1,A Short String Variable,Nominal,Input,8,Left,A8,A8,"""3333 """
+longstring,2,A Long String Variable,Nominal,Input,12,Left,A12,A12,
+numeric,3,A Numeric Variable,Scale,Input,8,Right,F10.0,F10.0,9; 5; 999
+date,4,A Date Variable,Scale,Input,8,Right,DATE11,DATE11,
+dollar,5,A Dollar Variable,Scale,Input,8,Right,DOLLAR11.2,DOLLAR11.2,
+datetime,6,A Datetime Variable,Scale,Input,8,Right,DATETIME17.0,DATETIME17.0,
+
+Table: Value Labels
+Variable Value,,Label
+A Short String Variable,1111,ones
+,2222,twos
+,3333[a],threes
+A Numeric Variable,1,Unity
+,2,Duality
+,3,Thripality
+Footnote: a. User-missing value
+
+Table: Variable and Dataset Attributes
+Variable and Name,,Value
+A Numeric Variable,colour[1],blue
+,colour[2],pink
+,colour[3],violet
+,nationality,foreign
+,size,large
Table: Data List
string,longstring,numeric,date,dollar,datetime
-1111 ,One ,1,01-JAN-2001,$1.00,01-JAN-2001 01:01
-2222 ,Two ,2,02-FEB-2002,$2.00,02-FEB-2002 02:02
-3333 ,Three ,3,03-MAR-2003,$3.00,03-MAR-2003 03:03
-. ,. ,.,.,. ,.
-5555 ,Five ,5,05-MAY-2005,$5.00,05-MAY-2005 05:05
-
-Variable,Description,,Position
-string,A Short String Variable,,1
-,Format: A8,,
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 8,,
-,"Missing Values: ""3333 """,,
-,1111 ,ones,
-,2222 ,twos,
-,3333 ,threes,
-longstring,A Long String Variable,,2
-,Format: A12,,
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 12,,
-numeric,A Numeric Variable,,3
-,Format: F10.0,,
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-,Missing Values: 9; 5; 999,,
-,1,Unity,
-,2,Duality,
-,3,Thripality,
-,Custom attributes:,,
-,colour[1],blue,
-,colour[2],pink,
-,colour[3],violet,
-,nationality,foreign,
-,size,large,
-date,A Date Variable,,4
-,Format: DATE11,,
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-dollar,A Dollar Variable,,5
-,Format: DOLLAR11.2,,
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-datetime,A Datetime Variable,,6
-,Format: DATETIME17.0,,
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
+1111,One,1,01-JAN-2001,$1.00,01-JAN-2001 01:01
+2222,Two,2,02-FEB-2002,$2.00,02-FEB-2002 02:02
+3333,Three,3,03-MAR-2003,$3.00,03-MAR-2003 03:03
+.,.,.,.,. ,.
+5555,Five,5,05-MAY-2005,$5.00,05-MAY-2005 05:05
+
+Table: Variables
+Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
+string,1,A Short String Variable,Nominal,Input,8,Left,A8,A8,"""3333 """
+longstring,2,A Long String Variable,Nominal,Input,12,Left,A12,A12,
+numeric,3,A Numeric Variable,Scale,Input,8,Right,F10.0,F10.0,9; 5; 999
+date,4,A Date Variable,Scale,Input,8,Right,DATE11,DATE11,
+dollar,5,A Dollar Variable,Scale,Input,8,Right,DOLLAR11.2,DOLLAR11.2,
+datetime,6,A Datetime Variable,Scale,Input,8,Right,DATETIME17.0,DATETIME17.0,
+
+Table: Value Labels
+Variable Value,,Label
+A Short String Variable,1111,ones
+,2222,twos
+,3333[a],threes
+A Numeric Variable,1,Unity
+,2,Duality
+,3,Thripality
+Footnote: a. User-missing value
+
+Table: Variable and Dataset Attributes
+Variable and Name,,Value
+A Numeric Variable,colour[1],blue
+,colour[2],pink
+,colour[3],violet
+,nationality,foreign
+,size,large
Table: Data List
string,longstring,numeric,date,dollar,datetime
-1111 ,One ,1,01-JAN-2001,$1.00,01-JAN-2001 01:01
-2222 ,Two ,2,02-FEB-2002,$2.00,02-FEB-2002 02:02
-3333 ,Three ,3,03-MAR-2003,$3.00,03-MAR-2003 03:03
-. ,. ,.,.,. ,.
-5555 ,Five ,5,05-MAY-2005,$5.00,05-MAY-2005 05:05
+1111,One,1,01-JAN-2001,$1.00,01-JAN-2001 01:01
+2222,Two,2,02-FEB-2002,$2.00,02-FEB-2002 02:02
+3333,Three,3,03-MAR-2003,$3.00,03-MAR-2003 03:03
+.,.,.,.,. ,.
+5555,Five,5,05-MAY-2005,$5.00,05-MAY-2005 05:05
]])
AT_CLEANUP
print "Formatted string is \"$formatted\"\n";
print "Perl representation is \"$str\"\n";
]])
-AT_CHECK([RUN_PERL_MODULE test.pl], [0],
+AT_CHECK([run_perl_module test.pl], [0],
[[Formatted string is "11-SEP-2001 08:20"
Perl representation is "Tue Sep 11 08:20:00 2001"
]])
die "Returns undef on opening failure" if ref $sf;
print $PSPP::errstr, "\n";
]])
-AT_CHECK([RUN_PERL_MODULE test.pl], [0],
- [[Error opening `no-such-file.sav' for reading as a system file: No such file or directory.
+AT_CHECK([run_perl_module test.pl], [0],
+ [[An error occurred while opening `no-such-file.sav': No such file or directory.
]],
[[Name "PSPP::errstr" used only once: possible typo at test.pl line 8.
]])
die "Missing Value Negative Num"
if PSPP::value_is_missing ($val, $numericvar);
- @c = $sf->get_next_case ();
- @c = $sf->get_next_case ();
+ @c = $sf->get_next_case ();
+ @c = $sf->get_next_case ();
$val = $c[0];
die "Missing Value Positive"
if !PSPP::value_is_missing ($val, $stringvar);
- @c = $sf->get_next_case ();
+ @c = $sf->get_next_case ();
$val = $c[2];
die "Missing Value Positive SYS"
if !PSPP::value_is_missing ($val, $numericvar);
- @c = $sf->get_next_case ();
+ @c = $sf->get_next_case ();
$val = $c[2];
die "Missing Value Positive Num"
if !PSPP::value_is_missing ($val, $numericvar);
]])
-AT_CHECK([RUN_PERL_MODULE test.pl])
+AT_CHECK([run_perl_module test.pl])
AT_CLEANUP
AT_SETUP([Perl custom attributes])
print map "$_\n", join ', ', @$ll;
}
]])
-AT_CHECK([RUN_PERL_MODULE test.pl], [0],
+AT_CHECK([run_perl_module test.pl], [0],
[[$@Role =>0
colour =>blue, pink, violet
nationality =>foreign
AT_CLEANUP
AT_SETUP([Perl Pspp.t])
+AT_KEYWORDS([slow])
AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
# Skip this test if Perl's Text::Diff module is not installed.
AT_CHECK([perl -MText::Diff -e '' || exit 77])
-AT_CHECK([RUN_PERL_MODULE $abs_top_builddir/perl-module/t/Pspp.t], [0],
- [[1..37
+# Skip this test if Perl's Memory::Usage module is not installed.
+AT_CHECK([perl -MMemory::Usage -e '' || exit 77])
+# Skip this test if Address Sanitizer is in use because it will
+# screw up memory accounting and look like a leak.
+AT_SKIP_IF([$USING_ASAN])
+AT_CHECK([run_perl_module "$abs_top_builddir/perl-module/t/Pspp.t"], [0],
+ [[1..38
ok 1 - use PSPP;
ok 2 - Dictionary Creation
ok 3
ok 35 - Missing Value Positive Num
ok 36 - Custom Attributes
ok 37 - Case count
+ok 38 - Memory management of append_case
]],[ignore])
AT_CLEANUP