From: Ben Pfaff <blp@cs.stanford.edu>
Date: Tue, 13 Apr 2010 04:30:16 +0000 (-0700)
Subject: AGGREGATE: Convert tests to use Autotest.
X-Git-Tag: sav-api~304
X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5dda55a193943200dbb77705657da238bd7ab837;p=pspp

AGGREGATE: Convert tests to use Autotest.
---

diff --git a/tests/automake.mk b/tests/automake.mk
index 7fb106c6af..f23e3b131e 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -10,7 +10,6 @@ TESTS_ENVIRONMENT += LC_ALL=C
 
 dist_TESTS = \
 	tests/command/add-files.sh \
-	tests/command/aggregate.sh \
 	tests/command/attributes.sh \
 	tests/command/beg-data.sh \
 	tests/command/bignum.sh \
@@ -99,8 +98,6 @@ dist_TESTS = \
 	tests/formats/wkday-in.sh \
 	tests/formats/wkday-out.sh \
 	tests/formats/360.sh \
-	tests/bugs/agg_crash.sh \
-	tests/bugs/agg-crash-2.sh \
 	tests/bugs/big-input.sh \
 	tests/bugs/big-input-2.sh \
 	tests/bugs/case-map.sh \
@@ -407,6 +404,7 @@ EXTRA_DIST += \
 	$(TESTSUITE)
 TESTSUITE_AT = \
 	tests/testsuite.at \
+	tests/language/stats/aggregate.at \
 	tests/language/stats/autorecode.at \
 	tests/language/stats/crosstabs.at \
 	tests/language/stats/descriptives.at \
diff --git a/tests/bugs/agg-crash-2.sh b/tests/bugs/agg-crash-2.sh
deleted file mode 100755
index 98bd8dcfe3..0000000000
--- a/tests/bugs/agg-crash-2.sh
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/bin/sh
-
-# This program tests for a bug which caused AGGREGATE to crash when
-# the MAX function was used.
-
-TEMPDIR=/tmp/pspp-tst-$$
-TESTFILE=$TEMPDIR/`basename $0`.sps
-
-# ensure that top_builddir  are absolute
-if [ -z "$top_builddir" ] ; then top_builddir=. ; fi
-if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi
-top_builddir=`cd $top_builddir; pwd`
-PSPP=$top_builddir/src/ui/terminal/pspp
-
-# ensure that top_srcdir is absolute
-top_srcdir=`cd $top_srcdir; pwd`
-
-STAT_CONFIG_PATH=$top_srcdir/config
-export STAT_CONFIG_PATH
-
-
-cleanup()
-{
-     if [ x"$PSPP_TEST_NO_CLEANUP" != x ] ; then 
-	echo "NOT cleaning $TEMPDIR" 
-	return ; 
-     fi
-     cd /
-     rm -rf $TEMPDIR
-}
-
-
-fail()
-{
-    echo $activity
-    echo FAILED
-    cleanup;
-    exit 1;
-}
-
-
-no_result()
-{
-    echo $activity
-    echo NO RESULT;
-    cleanup;
-    exit 2;
-}
-
-pass()
-{
-    cleanup;
-    exit 0;
-}
-
-mkdir -p $TEMPDIR
-
-cd $TEMPDIR
-
-activity="create program"
-cat > $TESTFILE <<EOF
-DATA LIST LIST /X (F8.2) Y (a25).
-
-BEGIN DATA.
-87.50 foo
-87.34 bar
-1 bar
-END DATA.
-
-
-
-AGGREGATE OUTFILE=* /BREAK=y /X=MAX(x).
-LIST /x y.
-EOF
-if [ $? -ne 0 ] ; then no_result ; fi
-
-$SUPERVISOR $PSPP -o pspp.csv $TESTFILE
-if [ $? -ne 0 ] ; then no_result ; fi
-
-activity="compare output"
-diff $TEMPDIR/pspp.csv - << EOF | cat -E
-Table: Reading free-form data from INLINE.
-Variable,Format
-X,F8.2
-Y,A25
-
-Table: Data List
-X,Y
-87.34,bar                      
-87.50,foo                      
-EOF
-if [ $? -ne 0 ] ; then fail ; fi
-
-pass;
diff --git a/tests/bugs/agg_crash.sh b/tests/bugs/agg_crash.sh
deleted file mode 100755
index 449e90e949..0000000000
--- a/tests/bugs/agg_crash.sh
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/bin/sh
-
-# This program tests for a bug which crashed pspp when doing a aggregate 
-# procedure
-
-TEMPDIR=/tmp/pspp-tst-$$
-TESTFILE=$TEMPDIR/`basename $0`.sps
-
-# ensure that top_builddir  are absolute
-if [ -z "$top_builddir" ] ; then top_builddir=. ; fi
-if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi
-top_builddir=`cd $top_builddir; pwd`
-PSPP=$top_builddir/src/ui/terminal/pspp
-
-# ensure that top_srcdir is absolute
-top_srcdir=`cd $top_srcdir; pwd`
-
-STAT_CONFIG_PATH=$top_srcdir/config
-export STAT_CONFIG_PATH
-
-
-cleanup()
-{
-     if [ x"$PSPP_TEST_NO_CLEANUP" != x ] ; then 
-	echo "NOT cleaning $TEMPDIR" 
-	return ; 
-     fi
-     cd /
-     rm -rf $TEMPDIR
-}
-
-
-fail()
-{
-    echo $activity
-    echo FAILED
-    cleanup;
-    exit 1;
-}
-
-
-no_result()
-{
-    echo $activity
-    echo NO RESULT;
-    cleanup;
-    exit 2;
-}
-
-pass()
-{
-    cleanup;
-    exit 0;
-}
-
-mkdir -p $TEMPDIR
-
-cd $TEMPDIR
-
-activity="create program"
-cat > $TESTFILE <<EOF
-INPUT PROGRAM.
-LOOP c=1 TO 20.
-  COMPUTE x=UNIFORM(10)
-  END CASE.
-END LOOP.
-END FILE.
-END INPUT PROGRAM.
-
-AGGREGATE /BREAK=x .
-EOF
-if [ $? -ne 0 ] ; then no_result ; fi
-
-
-# The above input is invalid.
-# So this will have a non zero error status.
-# But it shouldn't crash!
-activity="run_program"
-$SUPERVISOR $PSPP -o pspp.csv -e /dev/null $TESTFILE 
-if [ $? -ne 1 ] ; then fail ; fi
-
-
-pass;
diff --git a/tests/command/aggregate.sh b/tests/command/aggregate.sh
deleted file mode 100755
index ba51161c6a..0000000000
--- a/tests/command/aggregate.sh
+++ /dev/null
@@ -1,242 +0,0 @@
-#!/bin/sh
-
-# This program tests the aggregate procedure
-
-TEMPDIR=/tmp/pspp-tst-$$
-TESTFILE=$TEMPDIR/aggregate.pspp
-
-
-# ensure that top_srcdir and top_builddir  are absolute
-if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi
-if [ -z "$top_builddir" ] ; then top_builddir=. ; fi
-top_srcdir=`cd $top_srcdir; pwd`
-top_builddir=`cd $top_builddir; pwd`
-PSPP=$top_builddir/src/ui/terminal/pspp
-
-
-STAT_CONFIG_PATH=$top_srcdir/config
-export STAT_CONFIG_PATH
-
-cleanup()
-{
-     if [ x"$PSPP_TEST_NO_CLEANUP" != x ] ; then 
-	echo "NOT cleaning $TEMPDIR" 
-	return ; 
-     fi
-     cd /
-     rm -rf $TEMPDIR
-}
-
-
-fail()
-{
-    echo $activity
-    echo FAILED
-    cleanup;
-    exit 1;
-}
-
-
-no_result()
-{
-    echo $activity
-    echo NO RESULT;
-    cleanup;
-    exit 2;
-}
-
-pass()
-{
-    cleanup;
-    exit 0;
-}
-
-mkdir -p $TEMPDIR
-
-cd $TEMPDIR
-
-activity="data create"
-cat > aggregate.data <<EOF
-2 42
-1001
-4 41
-3112
-1112
-2661
-1221
-2771
-1331
-1441
-2881
-1551
-EOF
-if [ $? -ne 0 ] ; then no_result ; fi
-
-activity="command skeleton create"
-cat > agg-skel.pspp <<EOF
-	/document
-	/break=g
-	/N = n
-	/NI = n./
-	NU = nu
-	/NUI = nu./
-	NFGT2 = fgt(n, 2)
-	/NFGT2I = fgt.(n, 2)
-	/SFGT2 = fgt(s, '2')
-	/SFGT2I = fgt.(s, '2')
-	/NFIN23 = fin(n, 2, 3)
-	/NFIN23I = fin.(n, 2, 3)
-	/SFIN23 = fin(s, '2', '3')
-	/SFIN23I = fin.(s, '2', '3')
-	/NFLT2 = flt(n, 2)
-	/NFLT2I = flt.(n, 2)
-	/SFLT2 = flt(s, '2')
-	/SFLT2I = flt.(s, '2')
-	/NFIRST = first(n)
-	/NFIRSTI = first.(n)
-	/SFIRST = first(s)
-	/SFIRSTI = first.(s)
-	/NFOUT23 = fout(n, 3, 2)
-	/NFOUT23I = fout.(n, 3, 2)
-	/SFOUT23 = fout(s, '3', '2')
-	/SFOUT23I = fout.(s, '3', '2')
-	/NLAST = last(n)
-	/NLASTI = last.(n)
-	/SLAST = last(s)
-	/SLASTI = last.(s)
-	/NMAX = max(n)
-	/NMAXI = max.(n)
-	/SMAX = max(s)
-	/SMAXI = max.(s)
-	/NMEAN = mean(n)
-	/NMEANI = mean.(n)
-	/NMIN = min(n)
-	/NMINI = min.(n)
-	/SMIN = min(s)
-	/SMINI = min.(s)
-	/NN = n(n)
-	/NNI = n.(n)
-	/SN = n(s)
-	/SNI = n.(s)
-	/NNMISS = nmiss(n)
-	/NNMISSI = nmiss.(n)
-	/SNMISS = nmiss(s)
-	/SNMISSI = nmiss.(s)
-	/NNU = nu(n)
-	/NNUI = nu.(n)
-	/SNU = nu(s)
-	/SNUI = nu.(s)
-	/NNUMISS = numiss(n)
-	/NNUMISSI = numiss.(n)
-	/SNUMISS = numiss(s)
-	/SNUMISSI = numiss.(s)
-	/NPGT2 = pgt(n, 2)
-	/NPGT2I = pgt.(n, 2)
-	/SPGT2 = pgt(s, '2')
-	/SPGT2I = pgt.(s, '2')
-	/NPIN23 = pin(n, 2, 3)
-	/NPIN23I = pin.(n, 2, 3)
-	/SPIN23 = pin(s, '2', '3')
-	/SPIN23I = pin.(s, '2', '3')
-	/NPLT2 = plt(n, 2)
-	/NPLT2I = plt.(n, 2)
-	/SPLT2 = plt(s, '2')
-	/SPLT2I = plt.(s, '2')
-	/NPOUT23 = pout(n, 2, 3)
-	/NPOUT23I = pout.(n, 2, 3)
-	/SPOUT23 = pout(s, '2', '3')
-	/SPOUT23I = pout.(s, '2', '3')
-	/NMEDIAN = median(n)
-	/NMEDIANI = median.(n)
-	/NSD = sd(n)
-	/NSDI = sd.(n)
-	/NSUM = sum(n)
-	/NSUMI = sum.(n).
-EOF
-
-activity="expected output (itemwise missing) create"
-cat > agg-itemwise.csv <<EOF
-warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
-
-warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
-
-warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
-
-warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
-
-Table: Data List
-G,N,NI,NU,NUI,NFGT2,NFGT2I,SFGT2,SFGT2I,NFIN23,NFIN23I,SFIN23,SFIN23I,NFLT2,NFLT2I,SFLT2,SFLT2I,NFIRST,NFIRSTI,SFIRST,SFIRSTI,NFOUT23,NFOUT23I,SFOUT23,SFOUT23I,NLAST,NLASTI,SLAST,SLASTI,NMAX,NMAXI,SMAX,SMAXI,NMEAN,NMEANI,NMIN,NMINI,SMIN,SMINI,NN,NNI,SN,SNI,NNMISS,NNMISSI,SNMISS,SNMISSI,NNU,NNUI,SNU,SNUI,NNUMISS,NNUMISSI,SNUMISS,SNUMISSI,NPGT2,NPGT2I,SPGT2,SPGT2I,NPIN23,NPIN23I,SPIN23,SPIN23I,NPLT2,NPLT2I,SPLT2,SPLT2I,NPOUT23,NPOUT23I,SPOUT23,SPOUT23I,NMEDIAN,NMEDIANI,NSD,NSDI,NSUM,NSUMI
-1,7.00,7.00,6,6,.333,.429,.333,.429,.333,.286,.333,.286,.500,.429,.500,.429,0,0,0,0,.667,.714,.667,.714,5,5,5,5,5,5,5,5,2.00,2.29,0,0,0,0,6.00,7.00,6.00,7.00,1.00,.00,1.00,.00,5,6,5,6,1,0,1,0,33.3,42.9,33.3,42.9,33.3,28.6,33.3,28.6,50.0,42.9,50.0,42.9,66.7,71.4,66.7,71.4,1.50,2.00,1.79,1.80,12.00,16.00
-2,5.00,5.00,4,4,1.000,1.000,1.000,1.000,.000,.000,.000,.000,.000,.000,.000,.000,6,6,6,4,1.000,1.000,1.000,1.000,8,8,8,8,8,8,8,8,7.00,7.00,6,6,6,4,3.00,3.00,3.00,5.00,2.00,2.00,2.00,.00,3,3,3,4,1,1,1,0,100.0,100.0,100.0,100.0,.0,.0,.0,.0,.0,.0,.0,.0,100.0,100.0,100.0,100.0,7.00,7.00,1.00,1.00,21.00,21.00
-3,2.00,2.00,1,1,.000,.000,.000,.000,.000,.000,.000,.000,1.000,1.000,1.000,1.000,1,1,1,1,1.000,1.000,1.000,1.000,1,1,1,1,1,1,1,1,1.00,1.00,1,1,1,1,2.00,2.00,2.00,2.00,.00,.00,.00,.00,1,1,1,1,0,0,0,0,.0,.0,.0,.0,.0,.0,.0,.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,1.00,1.00,.00,.00,2.00,2.00
-4,1.00,1.00,1,1,.   ,.   ,.   ,1.000,.   ,.   ,.   ,.000,.   ,.   ,.   ,.000,.,.,,4,.   ,.   ,.   ,1.000,.,.,,4,.,.,,4,.  ,.  ,.,.,,4,.00,.00,.00,1.00,1.00,1.00,1.00,.00,0,0,0,1,1,1,1,0,. ,. ,. ,100.0,. ,. ,. ,.0,. ,. ,. ,.0,. ,. ,. ,100.0,NaN,NaN,.  ,.  ,.  ,.  
-EOF
-
-activity="expected output (columnwise missing) create"
-cat > agg-columnwise.csv <<EOF
-warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
-
-warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
-
-warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
-
-warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
-
-Table: Data List
-G,N,NI,NU,NUI,NFGT2,NFGT2I,SFGT2,SFGT2I,NFIN23,NFIN23I,SFIN23,SFIN23I,NFLT2,NFLT2I,SFLT2,SFLT2I,NFIRST,NFIRSTI,SFIRST,SFIRSTI,NFOUT23,NFOUT23I,SFOUT23,SFOUT23I,NLAST,NLASTI,SLAST,SLASTI,NMAX,NMAXI,SMAX,SMAXI,NMEAN,NMEANI,NMIN,NMINI,SMIN,SMINI,NN,NNI,SN,SNI,NNMISS,NNMISSI,SNMISS,SNMISSI,NNU,NNUI,SNU,SNUI,NNUMISS,NNUMISSI,SNUMISS,SNUMISSI,NPGT2,NPGT2I,SPGT2,SPGT2I,NPIN23,NPIN23I,SPIN23,SPIN23I,NPLT2,NPLT2I,SPLT2,SPLT2I,NPOUT23,NPOUT23I,SPOUT23,SPOUT23I,NMEDIAN,NMEDIANI,NSD,NSDI,NSUM,NSUMI
-1,7.00,7.00,6,6,.   ,.429,.   ,.429,.   ,.286,.   ,.286,.   ,.429,.   ,.429,.,0,,0,.   ,.714,.   ,.714,.,5,,5,.,5,,5,.  ,2.29,.,0,,0,6.00,7.00,6.00,7.00,1.00,.00,1.00,.00,5,6,5,6,1,0,1,0,. ,42.9,. ,42.9,. ,28.6,. ,28.6,. ,42.9,. ,42.9,. ,71.4,. ,71.4,.  ,2.00,.  ,1.80,.  ,16.00
-2,5.00,5.00,4,4,.   ,.   ,.   ,1.000,.   ,.   ,.   ,.000,.   ,.   ,.   ,.000,.,.,,4,.   ,.   ,.   ,1.000,.,.,,8,.,.,,8,.  ,.  ,.,.,,4,3.00,3.00,3.00,5.00,2.00,2.00,2.00,.00,3,3,3,4,1,1,1,0,. ,. ,. ,100.0,. ,. ,. ,.0,. ,. ,. ,.0,. ,. ,. ,100.0,.  ,.  ,.  ,.  ,.  ,.  
-3,2.00,2.00,1,1,.000,.000,.000,.000,.000,.000,.000,.000,1.000,1.000,1.000,1.000,1,1,1,1,1.000,1.000,1.000,1.000,1,1,1,1,1,1,1,1,1.00,1.00,1,1,1,1,2.00,2.00,2.00,2.00,.00,.00,.00,.00,1,1,1,1,0,0,0,0,.0,.0,.0,.0,.0,.0,.0,.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,1.00,1.00,.00,.00,2.00,2.00
-4,1.00,1.00,1,1,.   ,.   ,.   ,1.000,.   ,.   ,.   ,.000,.   ,.   ,.   ,.000,.,.,,4,.   ,.   ,.   ,1.000,.,.,,4,.,.,,4,.  ,.  ,.,.,,4,.00,.00,.00,1.00,1.00,1.00,1.00,.00,0,0,0,1,1,1,1,0,. ,. ,. ,100.0,. ,. ,. ,.0,. ,. ,. ,.0,. ,. ,. ,100.0,.  ,.  ,.  ,.  ,.  ,.  
-EOF
-
-for outfile in scratch active external; do
-    for sort in presorted unsorted; do
-	for missing in itemwise columnwise; do
-	    name=$outfile-$sort-$missing
-
-	    activity="create $name.pspp"
-	    {
-		echo "data list notable file='aggregate.data' /G N 1-2 S 3(a) W 4."
-		echo "weight by w."
-		echo "missing values n(4) s('4')."
-		if [ "$sort" = "presorted" ]; then
-		    echo "sort cases by g."
-		fi
-		echo "aggregate"
-		if [ "$outfile" = "active" ]; then
-		    echo "	outfile=*"
-		elif [ "$outfile" = "external" ]; then
-		    echo "	outfile='aggregate.sys'"
-		else
-		    echo "	outfile=#AGGREGATE"
-		fi
-		if [ "$sort" = "presorted" ]; then
-		    echo "	/presorted"
-		fi
-		if [ "$missing" = "columnwise" ]; then
-		    echo "	/missing=columnwise"
-		fi
-		cat agg-skel.pspp
-		if [ "$outfile" = "external" ]; then
-		    echo "get file='aggregate.sys'."
-		elif [ "$outfile" = "scratch" ]; then
-		    echo "get file=#AGGREGATE."
-		fi
-		echo "list."
-	    } > $name.pspp
-	    if [ $? -ne 0 ] ; then no_result ; fi
-	    
-	    activity="run $name.pspp"
-	    $SUPERVISOR $PSPP -o pspp.csv -e /dev/null $name.pspp 
-	    if [ $? -ne 0 ] ; then no_result ; fi
-
-	    activity="check $name output"
-	    perl -pi -e 's/^.*:\d+: //;' pspp.csv
-	    diff -c pspp.csv agg-$missing.csv
-	    if [ $? -ne 0 ] ; then fail ; fi
-	done
-    done
-done
-
-pass;
diff --git a/tests/language/stats/aggregate.at b/tests/language/stats/aggregate.at
new file mode 100644
index 0000000000..5e00965e2d
--- /dev/null
+++ b/tests/language/stats/aggregate.at
@@ -0,0 +1,212 @@
+AT_BANNER([AGGREGATE procedure])
+
+dnl CHECK_AGGREGATE(OUTFILE, SORT, MISSING)
+dnl
+dnl Checks the AGGREGATE procedure with the specified combination of:
+dnl
+dnl - OUTFILE: One of "scratch", "active", or "external" according to
+dnl   where AGGREGATE's output should be directed.
+dnl 
+dnl - SORT: Either "presorted" or "unsorted" according to whether
+dnl   AGGREGATE should received presorted input.
+dnl
+dnl - MISSING: Either "itemwise" or "columnwise" according to the basis
+dnl   on which missing values should be eliminated.
+dnl
+m4_define([CHECK_AGGREGATE], [
+  AT_SETUP([AGGREGATE $2 data to $1 file, $3 missing])
+  AT_DATA([aggregate.data],
+  [2 42
+1001
+4 41
+3112
+1112
+2661
+1221
+2771
+1331
+1441
+2881
+1551
+])
+  AT_DATA([aggregate.sps],
+    [DATA LIST NOTABLE FILE='aggregate.data' /G N 1-2 S 3(a) W 4.
+WEIGHT BY w.
+MISSING VALUES n(4) s('4').
+m4_if([$2], [presorted], [SORT CASES BY g.])
+AGGREGATE dnl
+m4_if([$1], [active], [OUTFILE=*],
+      [$1], [external], [OUTFILE='aggregate.sys'],
+      [outfile=@%:@AGGREGATE]) dnl
+m4_if([$2], [presorted], [/PRESORTED]) dnl
+m4_if([$3], [columnwise], [/MISSING=COLUMNWISE])
+	/DOCUMENT
+	/BREAK=g
+	/N = n
+	/NI = n./
+	NU = nu
+	/NUI = nu./
+	NFGT2 = fgt(n, 2)
+	/NFGT2I = fgt.(n, 2)
+	/SFGT2 = fgt(s, '2')
+	/SFGT2I = fgt.(s, '2')
+	/NFIN23 = fin(n, 2, 3)
+	/NFIN23I = fin.(n, 2, 3)
+	/SFIN23 = fin(s, '2', '3')
+	/SFIN23I = fin.(s, '2', '3')
+	/NFLT2 = flt(n, 2)
+	/NFLT2I = flt.(n, 2)
+	/SFLT2 = flt(s, '2')
+	/SFLT2I = flt.(s, '2')
+	/NFIRST = first(n)
+	/NFIRSTI = first.(n)
+	/SFIRST = first(s)
+	/SFIRSTI = first.(s)
+	/NFOUT23 = fout(n, 3, 2)
+	/NFOUT23I = fout.(n, 3, 2)
+	/SFOUT23 = fout(s, '3', '2')
+	/SFOUT23I = fout.(s, '3', '2')
+	/NLAST = last(n)
+	/NLASTI = last.(n)
+	/SLAST = last(s)
+	/SLASTI = last.(s)
+	/NMAX = max(n)
+	/NMAXI = max.(n)
+	/SMAX = max(s)
+	/SMAXI = max.(s)
+	/NMEAN = mean(n)
+	/NMEANI = mean.(n)
+	/NMIN = min(n)
+	/NMINI = min.(n)
+	/SMIN = min(s)
+	/SMINI = min.(s)
+	/NN = n(n)
+	/NNI = n.(n)
+	/SN = n(s)
+	/SNI = n.(s)
+	/NNMISS = nmiss(n)
+	/NNMISSI = nmiss.(n)
+	/SNMISS = nmiss(s)
+	/SNMISSI = nmiss.(s)
+	/NNU = nu(n)
+	/NNUI = nu.(n)
+	/SNU = nu(s)
+	/SNUI = nu.(s)
+	/NNUMISS = numiss(n)
+	/NNUMISSI = numiss.(n)
+	/SNUMISS = numiss(s)
+	/SNUMISSI = numiss.(s)
+	/NPGT2 = pgt(n, 2)
+	/NPGT2I = pgt.(n, 2)
+	/SPGT2 = pgt(s, '2')
+	/SPGT2I = pgt.(s, '2')
+	/NPIN23 = pin(n, 2, 3)
+	/NPIN23I = pin.(n, 2, 3)
+	/SPIN23 = pin(s, '2', '3')
+	/SPIN23I = pin.(s, '2', '3')
+	/NPLT2 = plt(n, 2)
+	/NPLT2I = plt.(n, 2)
+	/SPLT2 = plt(s, '2')
+	/SPLT2I = plt.(s, '2')
+	/NPOUT23 = pout(n, 2, 3)
+	/NPOUT23I = pout.(n, 2, 3)
+	/SPOUT23 = pout(s, '2', '3')
+	/SPOUT23I = pout.(s, '2', '3')
+	/NMEDIAN = median(n)
+	/NMEDIANI = median.(n)
+	/NSD = sd(n)
+	/NSDI = sd.(n)
+	/NSUM = sum(n)
+	/NSUMI = sum.(n).
+m4_if([$1], [external], [GET FILE='aggregate.sys'.],
+      [$1], [scratch], [GET FILE=@%:@AGGREGATE.])
+LIST.
+])
+  AT_CHECK([pspp -O format=csv aggregate.sps], [0], [stdout])
+  AT_CHECK([[sed 's/^[^:]*:[0-9]*: //' < stdout]], [0],
+    [m4_if([$3], [itemwise],
+      [warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
+
+warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
+
+warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
+
+warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
+
+Table: Data List
+G,N,NI,NU,NUI,NFGT2,NFGT2I,SFGT2,SFGT2I,NFIN23,NFIN23I,SFIN23,SFIN23I,NFLT2,NFLT2I,SFLT2,SFLT2I,NFIRST,NFIRSTI,SFIRST,SFIRSTI,NFOUT23,NFOUT23I,SFOUT23,SFOUT23I,NLAST,NLASTI,SLAST,SLASTI,NMAX,NMAXI,SMAX,SMAXI,NMEAN,NMEANI,NMIN,NMINI,SMIN,SMINI,NN,NNI,SN,SNI,NNMISS,NNMISSI,SNMISS,SNMISSI,NNU,NNUI,SNU,SNUI,NNUMISS,NNUMISSI,SNUMISS,SNUMISSI,NPGT2,NPGT2I,SPGT2,SPGT2I,NPIN23,NPIN23I,SPIN23,SPIN23I,NPLT2,NPLT2I,SPLT2,SPLT2I,NPOUT23,NPOUT23I,SPOUT23,SPOUT23I,NMEDIAN,NMEDIANI,NSD,NSDI,NSUM,NSUMI
+1,7.00,7.00,6,6,.333,.429,.333,.429,.333,.286,.333,.286,.500,.429,.500,.429,0,0,0,0,.667,.714,.667,.714,5,5,5,5,5,5,5,5,2.00,2.29,0,0,0,0,6.00,7.00,6.00,7.00,1.00,.00,1.00,.00,5,6,5,6,1,0,1,0,33.3,42.9,33.3,42.9,33.3,28.6,33.3,28.6,50.0,42.9,50.0,42.9,66.7,71.4,66.7,71.4,1.50,2.00,1.79,1.80,12.00,16.00
+2,5.00,5.00,4,4,1.000,1.000,1.000,1.000,.000,.000,.000,.000,.000,.000,.000,.000,6,6,6,4,1.000,1.000,1.000,1.000,8,8,8,8,8,8,8,8,7.00,7.00,6,6,6,4,3.00,3.00,3.00,5.00,2.00,2.00,2.00,.00,3,3,3,4,1,1,1,0,100.0,100.0,100.0,100.0,.0,.0,.0,.0,.0,.0,.0,.0,100.0,100.0,100.0,100.0,7.00,7.00,1.00,1.00,21.00,21.00
+3,2.00,2.00,1,1,.000,.000,.000,.000,.000,.000,.000,.000,1.000,1.000,1.000,1.000,1,1,1,1,1.000,1.000,1.000,1.000,1,1,1,1,1,1,1,1,1.00,1.00,1,1,1,1,2.00,2.00,2.00,2.00,.00,.00,.00,.00,1,1,1,1,0,0,0,0,.0,.0,.0,.0,.0,.0,.0,.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,1.00,1.00,.00,.00,2.00,2.00
+4,1.00,1.00,1,1,.   ,.   ,.   ,1.000,.   ,.   ,.   ,.000,.   ,.   ,.   ,.000,.,.,,4,.   ,.   ,.   ,1.000,.,.,,4,.,.,,4,.  ,.  ,.,.,,4,.00,.00,.00,1.00,1.00,1.00,1.00,.00,0,0,0,1,1,1,1,0,. ,. ,. ,100.0,. ,. ,. ,.0,. ,. ,. ,.0,. ,. ,. ,100.0,NaN,NaN,.  ,.  ,.  ,.  @&t@
+],
+      [warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
+
+warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
+
+warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
+
+warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
+
+Table: Data List
+G,N,NI,NU,NUI,NFGT2,NFGT2I,SFGT2,SFGT2I,NFIN23,NFIN23I,SFIN23,SFIN23I,NFLT2,NFLT2I,SFLT2,SFLT2I,NFIRST,NFIRSTI,SFIRST,SFIRSTI,NFOUT23,NFOUT23I,SFOUT23,SFOUT23I,NLAST,NLASTI,SLAST,SLASTI,NMAX,NMAXI,SMAX,SMAXI,NMEAN,NMEANI,NMIN,NMINI,SMIN,SMINI,NN,NNI,SN,SNI,NNMISS,NNMISSI,SNMISS,SNMISSI,NNU,NNUI,SNU,SNUI,NNUMISS,NNUMISSI,SNUMISS,SNUMISSI,NPGT2,NPGT2I,SPGT2,SPGT2I,NPIN23,NPIN23I,SPIN23,SPIN23I,NPLT2,NPLT2I,SPLT2,SPLT2I,NPOUT23,NPOUT23I,SPOUT23,SPOUT23I,NMEDIAN,NMEDIANI,NSD,NSDI,NSUM,NSUMI
+1,7.00,7.00,6,6,.   ,.429,.   ,.429,.   ,.286,.   ,.286,.   ,.429,.   ,.429,.,0,,0,.   ,.714,.   ,.714,.,5,,5,.,5,,5,.  ,2.29,.,0,,0,6.00,7.00,6.00,7.00,1.00,.00,1.00,.00,5,6,5,6,1,0,1,0,. ,42.9,. ,42.9,. ,28.6,. ,28.6,. ,42.9,. ,42.9,. ,71.4,. ,71.4,.  ,2.00,.  ,1.80,.  ,16.00
+2,5.00,5.00,4,4,.   ,.   ,.   ,1.000,.   ,.   ,.   ,.000,.   ,.   ,.   ,.000,.,.,,4,.   ,.   ,.   ,1.000,.,.,,8,.,.,,8,.  ,.  ,.,.,,4,3.00,3.00,3.00,5.00,2.00,2.00,2.00,.00,3,3,3,4,1,1,1,0,. ,. ,. ,100.0,. ,. ,. ,.0,. ,. ,. ,.0,. ,. ,. ,100.0,.  ,.  ,.  ,.  ,.  ,.  @&t@
+3,2.00,2.00,1,1,.000,.000,.000,.000,.000,.000,.000,.000,1.000,1.000,1.000,1.000,1,1,1,1,1.000,1.000,1.000,1.000,1,1,1,1,1,1,1,1,1.00,1.00,1,1,1,1,2.00,2.00,2.00,2.00,.00,.00,.00,.00,1,1,1,1,0,0,0,0,.0,.0,.0,.0,.0,.0,.0,.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,1.00,1.00,.00,.00,2.00,2.00
+4,1.00,1.00,1,1,.   ,.   ,.   ,1.000,.   ,.   ,.   ,.000,.   ,.   ,.   ,.000,.,.,,4,.   ,.   ,.   ,1.000,.,.,,4,.,.,,4,.  ,.  ,.,.,,4,.00,.00,.00,1.00,1.00,1.00,1.00,.00,0,0,0,1,1,1,1,0,. ,. ,. ,100.0,. ,. ,. ,.0,. ,. ,. ,.0,. ,. ,. ,100.0,.  ,.  ,.  ,.  ,.  ,.  @&t@
+])])
+  AT_CLEANUP])
+
+CHECK_AGGREGATE([scratch], [presorted], [itemwise])
+CHECK_AGGREGATE([scratch], [presorted], [columnwise])
+CHECK_AGGREGATE([scratch], [unsorted], [itemwise])
+CHECK_AGGREGATE([scratch], [unsorted], [columnwise])
+CHECK_AGGREGATE([active], [presorted], [itemwise])
+CHECK_AGGREGATE([active], [presorted], [columnwise])
+CHECK_AGGREGATE([active], [unsorted], [itemwise])
+CHECK_AGGREGATE([active], [unsorted], [columnwise])
+CHECK_AGGREGATE([external], [presorted], [itemwise])
+CHECK_AGGREGATE([external], [presorted], [columnwise])
+CHECK_AGGREGATE([external], [unsorted], [itemwise])
+CHECK_AGGREGATE([external], [unsorted], [columnwise])
+
+AT_SETUP([AGGREGATE crash with MAX function])
+AT_DATA([aggregate.sps], 
+  [DATA LIST LIST /X (F8.2) Y (a25).
+
+BEGIN DATA.
+87.50 foo
+87.34 bar
+1 bar
+END DATA.
+
+AGGREGATE OUTFILE=* /BREAK=y /X=MAX(x).
+LIST /x y.
+])
+AT_CHECK([pspp -O format=csv aggregate.sps], [0],
+  [Table: Reading free-form data from INLINE.
+Variable,Format
+X,F8.2
+Y,A25
+
+Table: Data List
+X,Y
+87.34,bar                      @&t@
+87.50,foo                      @&t@
+])
+AT_CLEANUP
+
+AT_SETUP([AGGREGATE crash with invalid syntax])
+AT_DATA([aggregate.sps],
+  [INPUT PROGRAM.
+LOOP c=1 TO 20.
+  COMPUTE x=UNIFORM(10)
+  END CASE.
+END LOOP.
+END FILE.
+END INPUT PROGRAM.
+
+AGGREGATE /BREAK=x .
+])
+AT_CHECK([pspp -O format=csv aggregate.sps], [1], [ignore], [])
+AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 06cb6f9fac..ce26a57507 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -1,5 +1,6 @@
 AT_INIT
 
+m4_include([tests/language/stats/aggregate.at])
 m4_include([tests/language/stats/autorecode.at])
 m4_include([tests/language/stats/crosstabs.at])
 m4_include([tests/language/stats/descriptives.at])