work on docs
[pspp] / tests / perl-module.at
index 115f2a8d20e714f8b644f150df9c1c3c9609210c..244b1b9999dc537457a6176f3a8eb7b6271f14d3 100644 (file)
@@ -1,14 +1,49 @@
+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])
 
 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 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.
-m4_define([RUN_PERL_MODULE],
-  [LD_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])
 
 AT_SETUP([Perl create system file])
 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
@@ -34,7 +69,7 @@ AT_DATA([test.pl],
    die "accept legal variable name" if !ref $var0;
    die if $d->get_var_cnt () != 1;
 
    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;
                              (fmt=>PSPP::Fmt::DOLLAR,
                               width=>4, decimals=>2) );
    die "cappet valid format" if !ref $var1;
@@ -47,7 +82,7 @@ AT_DATA([test.pl],
 
    $sysfile->close ();
 ])
 
    $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.
 AT_DATA([dump-dict.sps],
   [GET FILE='testfile.sav'.
 DISPLAY FILE LABEL.
@@ -55,24 +90,17 @@ DISPLAY DOCUMENTS.
 DISPLAY DICTIONARY.
 SHOW WEIGHT.
 ])
 DISPLAY DICTIONARY.
 SHOW WEIGHT.
 ])
-AT_CHECK([pspp -O format=csv dump-dict.sps], [0],
-  [File label:
-
-My Dictionary
-
-Documents in the active file:
+AT_CHECK([pspp -O format=csv dump-dict.sps], [0], [dnl
+Table: File Label
+Label,My Dictionary
 
 
+Table: Documents
 These 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.
 ])
 
 dump-dict.sps:5: note: SHOW: WEIGHT is money.
 ])
@@ -88,16 +116,16 @@ AT_DATA([test.pl],
     my $d = PSPP::Dict->new();
     PSPP::Var->new ($d, "id",
                    (
     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",
                           (
                     decimals=>0
                     )
                    );
 
     PSPP::Var->new ($d, "name",
                           (
-                           fmt=>PSPP::Fmt::A, 
-                           width=>20, 
+                           fmt=>PSPP::Fmt::A,
+                           width=>20,
                            )
                           );
 
                            )
                           );
 
@@ -126,7 +154,7 @@ AT_DATA([test.pl],
 
     # Don't close.  We want to test that the destructor does that.
 ]])
 
     # 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.
 AT_DATA([dump-dicts.sps],
   [GET FILE='testfile.sav'.
 DISPLAY DICTIONARY.
@@ -140,50 +168,36 @@ DISPLAY FILE LABEL.
 DISPLAY DOCUMENTS.
 LIST.
 ])
 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 file:
+Table: File Label
+Label,This is the file label
 
 
+Table: Documents
 This is a document line
 
 Table: Data List
 id,name
 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:
+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
 
 
-This is the file label
-
-Documents in the active file:
+Table: File Label
+Label,This is the file label
 
 
+Table: Documents
 This is a document line
 
 Table: Data List
 id,name
 This is a document line
 
 Table: Data List
 id,name
-21,wheelbarrow         @&t@
+21,wheelbarrow
 ])
 AT_CLEANUP
 
 ])
 AT_CLEANUP
 
@@ -197,7 +211,7 @@ AT_DATA([test.pl],
     my $dict = PSPP::Dict->new();
     die "dictionary creation" if !ref $dict;
 
     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");
                              (width=>8, decimals=>0) );
 
     $int->set_label ("My Integer");
@@ -208,7 +222,7 @@ AT_DATA([test.pl],
     $int->add_value_label (1, "Unity");
     $int->add_value_label (2, "Duality");
 
     $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) );
 
 
                              (fmt=>PSPP::Fmt::A, width=>8) );
 
 
@@ -218,7 +232,7 @@ AT_DATA([test.pl],
 
     $str->set_missing_values ("this", "that");
 
 
     $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) );
 
 
                              (fmt=>PSPP::Fmt::A, width=>9) );
 
 
@@ -232,36 +246,27 @@ AT_DATA([test.pl],
 
     $sysfile->close ();
 ]])
 
     $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_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
 
 ])
 AT_CLEANUP
 
@@ -279,8 +284,8 @@ my $sysfile ;
 
        PSPP::Var->new ($d, "id",
                        (
 
        PSPP::Var->new ($d, "id",
                        (
-                        fmt=>PSPP::Fmt::F, 
-                        width=>2, 
+                        fmt=>PSPP::Fmt::F,
+                        width=>2,
                         decimals=>0
                         )
                        );
                         decimals=>0
                         )
                        );
@@ -291,7 +296,7 @@ my $sysfile ;
     my $res = $sysfile->append_case ([3]);
     print "Dictionary survives sysfile\n" if $res;
 ]])
     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
   [Dictionary survives sysfile
 ])
 AT_CLEANUP
@@ -357,7 +362,7 @@ AT_DATA([test.pl],
        my $vl = $var->get_value_labels ();
 
        print "Value Labels:\n";
        my $vl = $var->get_value_labels ();
 
        print "Value Labels:\n";
-       print "$_ => $vl->{$_}\n" for keys %$vl;
+       print "$_ => $vl->{$_}\n" for sort (keys %$vl);
     }
 
     while (my @c = $sf->get_next_case () )
     }
 
     while (my @c = $sf->get_next_case () )
@@ -369,19 +374,19 @@ AT_DATA([test.pl],
        print "\n";
     }
 ]])
        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:
   [Variable 0 is "string", label is "A Short String Variable"
 Value Labels:
-3333     => threes
 1111     => ones
 2222     => twos
 1111     => ones
 2222     => twos
+3333     => threes
 Variable 1 is "longstring", label is "A Long String Variable"
 Value Labels:
 Variable 2 is "numeric", label is "A Numeric Variable"
 Value Labels:
 1 => Unity
 Variable 1 is "longstring", label is "A Long String Variable"
 Value Labels:
 Variable 2 is "numeric", label is "A Numeric Variable"
 Value Labels:
 1 => Unity
-3 => Thripality
 2 => Duality
 2 => Duality
+3 => Thripality
 Variable 3 is "date", label is "A Date Variable"
 Value Labels:
 Variable 4 is "dollar", label is "A Dollar Variable"
 Variable 3 is "date", label is "A Date Variable"
 Value Labels:
 Variable 4 is "dollar", label is "A Dollar Variable"
@@ -447,124 +452,88 @@ AT_DATA([test.pl],
 
     $output->close ();
 ]])
 
     $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.
 AT_DATA([dump-dicts.sps],
   [GET FILE='sample.sav'.
 DISPLAY DICTIONARY.
+DISPLAY ATTRIBUTES
 LIST.
 
 GET FILE='copy.sav'.
 DISPLAY DICTIONARY.
 LIST.
 
 GET FILE='copy.sav'.
 DISPLAY DICTIONARY.
+DISPLAY ATTRIBUTES
 LIST.
 ])
 AT_CHECK([pspp -O format=csv dump-dicts.sps], [0],
 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:,,
-,size,large,
-,nationality,foreign,
-,colour[1],blue,
-,colour[2],pink,
-,colour[3],violet,
-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
 
 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:,,
-,size,large,
-,nationality,foreign,
-,colour[1],blue,
-,colour[2],pink,
-,colour[3],violet,
-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
 
 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
 
 ]])
 AT_CLEANUP
 
@@ -601,7 +570,7 @@ AT_DATA([test.pl],
     print "Formatted string is \"$formatted\"\n";
     print "Perl representation is \"$str\"\n";
 ]])
     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"
 ]])
   [[Formatted string is "11-SEP-2001 08:20"
 Perl representation is "Tue Sep 11 08:20:00 2001"
 ]])
@@ -619,8 +588,8 @@ AT_DATA([test.pl],
     die "Returns undef on opening failure" if ref $sf;
     print $PSPP::errstr, "\n";
 ]])
     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.
 ]])
 ]],
   [[Name "PSPP::errstr" used only once: possible typo at test.pl line 8.
 ]])
@@ -652,24 +621,24 @@ AT_DATA([test.pl],
     die "Missing Value Negative Num"
         if PSPP::value_is_missing ($val, $numericvar);
 
     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);
 
 
     $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);
 
     $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);
 ]])
     $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])
 AT_CLEANUP
 
 AT_SETUP([Perl custom attributes])
@@ -688,24 +657,33 @@ AT_DATA([test.pl],
 
     my $attr = $var->get_attributes ();
 
 
     my $attr = $var->get_attributes ();
 
-    foreach my $k (keys %$attr)
+    foreach my $k (sort (keys (%$attr)))
     {
        my $ll = $attr->{$k};
        print "$k =>";
        print map "$_\n", join ', ', @$ll;
     }
 ]])
     {
        my $ll = $attr->{$k};
        print "$k =>";
        print map "$_\n", join ', ', @$ll;
     }
 ]])
-AT_CHECK([RUN_PERL_MODULE test.pl], [0],
-  [[colour =>blue, pink, violet
+AT_CHECK([run_perl_module test.pl], [0],
+  [[$@Role =>0
+colour =>blue, pink, violet
 nationality =>foreign
 size =>large
 ]])
 AT_CLEANUP
 
 AT_SETUP([Perl Pspp.t])
 nationality =>foreign
 size =>large
 ]])
 AT_CLEANUP
 
 AT_SETUP([Perl Pspp.t])
+AT_KEYWORDS([slow])
 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
-AT_CHECK([RUN_PERL_MODULE $abs_top_builddir/perl-module/t/Pspp.t], [0],
-  [[1..36
+# Skip this test if Perl's Text::Diff module is not installed.
+AT_CHECK([perl -MText::Diff -e '' || exit 77])
+# 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 1 - use PSPP;
 ok 2 - Dictionary Creation
 ok 3
@@ -743,15 +721,7 @@ ok 33 - Missing Value Positive
 ok 34 - Missing Value Positive SYS
 ok 35 - Missing Value Positive Num
 ok 36 - Custom Attributes
 ok 34 - Missing Value Positive SYS
 ok 35 - Missing Value Positive Num
 ok 36 - Custom Attributes
-]],
-  [[# @&t@
-# @@ -0,0 +1 @@
-# +
-# @@ -0,0 +1 @@
-# +
-# @@ -0,0 +1 @@
-# +
-# @@ -0,0 +1 @@
-# +
-]])
+ok 37 - Case count
+ok 38 - Memory management of append_case
+]],[ignore])
 AT_CLEANUP
 AT_CLEANUP