spreadsheet-reader: Merge duplicate code with libpspp/str.h.
[pspp.git] / tests / perl-module.at
blobb83e42a073bde2e1424614e6755dcfd57d3048a0
1 dnl PSPP - a program for statistical analysis.
2 dnl Copyright (C) 2017, 2020, 2021 Free Software Foundation, Inc.
3 dnl
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.
8 dnl
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.
13 dnl
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/>.
16 dnl
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 \
24            | grep asan \
25            | awk '{print $3}')
26 if test -e "$asan_lib"; then
27     USING_ASAN=:
28 else
29     USING_ASAN=false
30     asan_lib=
33 dnl This command can be used to run with the PSPP Perl module after it has been
34 dnl built (with "make") but before it has been installed.  The -I options are
35 dnl equivalent to "use ExtUtils::testlib;" inside the Perl program, but it does
36 dnl not need to be run with the perl-module build directory as the current
37 dnl working directory.
38 run_perl_module () {
39     LD_PRELOAD="$asan_lib":"$LD_PRELOAD" \
40     LD_LIBRARY_PATH="$abs_top_builddir/src/.libs" \
41     DYLD_LIBRARY_PATH="$abs_top_builddir/src/.libs" \
42     ASAN_OPTIONS="$ASAN_OPTIONS detect_leaks=false" \
43     $PERL -I"$abs_top_builddir/perl-module/blib/arch" \
44           -I"$abs_top_builddir/perl-module/blib/lib" "$@"
46 m4_divert_pop([PREPARE_TESTS])
48 AT_SETUP([Perl create system file])
49 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
50 AT_DATA([test.pl],
51   [use warnings;
52    use strict;
53    use PSPP;
55    my $d = PSPP::Dict->new();
56    die "dictionary creation" if !ref $d;
57    die if $d->get_var_cnt () != 0;
59    $d->set_label ("My Dictionary");
60    $d->set_documents ("These Documents");
62    # Tests for variable creation
64    my $var0 = PSPP::Var->new ($d, "le");
65    die "trap illegal variable name" if ref $var0;
66    die if $d->get_var_cnt () != 0;
68    $var0 = PSPP::Var->new ($d, "legal");
69    die "accept legal variable name" if !ref $var0;
70    die if $d->get_var_cnt () != 1;
72    my $var1 = PSPP::Var->new ($d, "money",
73                               (fmt=>PSPP::Fmt::DOLLAR,
74                                width=>4, decimals=>2) );
75    die "cappet valid format" if !ref $var1;
76    die if $d->get_var_cnt () != 2;
78    $d->set_weight ($var1);
80    my $sysfile = PSPP::Sysfile->new ('testfile.sav', $d);
81    die "create sysfile object" if !ref $sysfile;
83    $sysfile->close ();
85 AT_CHECK([run_perl_module test.pl])
86 AT_DATA([dump-dict.sps],
87   [GET FILE='testfile.sav'.
88 DISPLAY FILE LABEL.
89 DISPLAY DOCUMENTS.
90 DISPLAY DICTIONARY.
91 SHOW WEIGHT.
93 AT_CHECK([pspp -O format=csv dump-dict.sps], [0], [dnl
94 Table: File Label
95 Label,My Dictionary
97 Table: Documents
98 These Documents
100 Table: Variables
101 Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
102 legal,1,Scale,Input,8,Right,F9.2,F9.2
103 money,2,Scale,Input,8,Right,DOLLAR6.2,DOLLAR6.2
105 Table: Settings
106 WEIGHT,money
108 AT_CLEANUP
110 AT_SETUP([Perl writing cases to system files])
111 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
112 AT_DATA([test.pl],
113   [[use warnings;
114     use strict;
115     use PSPP;
117     my $d = PSPP::Dict->new();
118     PSPP::Var->new ($d, "id",
119                     (
120                      fmt=>PSPP::Fmt::F,
121                      width=>2,
122                      decimals=>0
123                      )
124                     );
126     PSPP::Var->new ($d, "name",
127                            (
128                             fmt=>PSPP::Fmt::A,
129                             width=>20,
130                             )
131                            );
133     $d->set_documents ("This should not appear");
134     $d->clear_documents ();
135     $d->add_document ("This is a document line");
137     $d->set_label ("This is the file label");
139     # Check that we can write cases to system files.
140     my $sysfile = PSPP::Sysfile->new ("testfile.sav", $d);
141     my $res = $sysfile->append_case ( [34, "frederick"]);
142     die "append case" if !$res;
144     $res = $sysfile->append_case ( [34, "frederick", "extra"]);
145     die "append case with too many variables" if $res;
146     $sysfile->close ();
148     # Check that sysfiles are closed properly automaticallly in the destructor.
149     my $sysfile2 = PSPP::Sysfile->new ("testfile2.sav", $d);
150     $res = $sysfile2->append_case ( [21, "wheelbarrow"]);
151     die "append case 2" if !$res;
153     $res = $sysfile->append_case ( [34, "frederick", "extra"]);
154     die "append case with too many variables" if $res;
156     # Don't close.  We want to test that the destructor does that.
158 AT_CHECK([run_perl_module test.pl])
159 AT_DATA([dump-dicts.sps],
160   [GET FILE='testfile.sav'.
161 DISPLAY DICTIONARY.
162 DISPLAY FILE LABEL.
163 DISPLAY DOCUMENTS.
164 LIST.
166 GET FILE='testfile2.sav'.
167 DISPLAY DICTIONARY.
168 DISPLAY FILE LABEL.
169 DISPLAY DOCUMENTS.
170 LIST.
172 AT_CHECK([pspp -O format=csv dump-dicts.sps], [0], [dnl
173 Table: Variables
174 Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
175 id,1,Scale,Input,8,Right,F2.0,F2.0
176 name,2,Nominal,Input,20,Left,A20,A20
178 Table: File Label
179 Label,This is the file label
181 Table: Documents
182 This is a document line
184 Table: Data List
185 id,name
186 34,frederick
188 Table: Variables
189 Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
190 id,1,Scale,Input,8,Right,F2.0,F2.0
191 name,2,Nominal,Input,20,Left,A20,A20
193 Table: File Label
194 Label,This is the file label
196 Table: Documents
197 This is a document line
199 Table: Data List
200 id,name
201 21,wheelbarrow
203 AT_CLEANUP
205 AT_SETUP([Perl write variable parameters])
206 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
207 AT_DATA([test.pl],
208   [[use warnings;
209     use strict;
210     use PSPP;
212     my $dict = PSPP::Dict->new();
213     die "dictionary creation" if !ref $dict;
215     my $int = PSPP::Var->new ($dict, "integer",
216                               (width=>8, decimals=>0) );
218     $int->set_label ("My Integer");
220     $int->add_value_label (99, "Silly");
221     $int->clear_value_labels ();
222     $int->add_value_label (0, "Zero");
223     $int->add_value_label (1, "Unity");
224     $int->add_value_label (2, "Duality");
226     my $str = PSPP::Var->new ($dict, "string",
227                               (fmt=>PSPP::Fmt::A, width=>8) );
230     $str->set_label ("My String");
231     $str->add_value_label ("xx", "foo");
232     $str->add_value_label ("yy", "bar");
234     $str->set_missing_values ("this", "that");
236     my $longstr = PSPP::Var->new ($dict, "longstring",
237                               (fmt=>PSPP::Fmt::A, width=>9) );
240     $longstr->set_label ("My Long String");
241     my $re = $longstr->add_value_label ("xxx", "xfoo");
243     $int->set_missing_values (9, 99);
245     my $sysfile = PSPP::Sysfile->new ("testfile.sav", $dict);
248     $sysfile->close ();
250 AT_CHECK([run_perl_module test.pl], [0], [], [stderr])
251 cat stderr
252 AT_DATA([dump-dict.sps],
253   [GET FILE='testfile.sav'.
254 DISPLAY DICTIONARY.
256 AT_CHECK([pspp -O format=csv dump-dict.sps], [0], [dnl
257 Table: Variables
258 Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
259 integer,1,My Integer,Scale,Input,8,Right,F8.0,F8.0,9; 99
260 string,2,My String,Nominal,Input,8,Left,A8,A8,"""this    ""; ""that    """
261 longstring,3,My Long String,Nominal,Input,9,Left,A9,A9,
263 Table: Value Labels
264 Variable Value,,Label
265 My Integer,0,Zero
266 ,1,Unity
267 ,2,Duality
268 My String,xx,foo
269 ,yy,bar
270 My Long String,xxx,xfoo
272 AT_CLEANUP
274 AT_SETUP([Perl dictionary survives system file])
275 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
276 AT_DATA([test.pl],
277   [[use warnings;
278 use strict;
279 use PSPP;
281 my $sysfile ;
283     {
284         my $d = PSPP::Dict->new();
286         PSPP::Var->new ($d, "id",
287                         (
288                          fmt=>PSPP::Fmt::F,
289                          width=>2,
290                          decimals=>0
291                          )
292                         );
294         $sysfile = PSPP::Sysfile->new ("testfile.sav", $d);
295     }
297     my $res = $sysfile->append_case ([3]);
298     print "Dictionary survives sysfile\n" if $res;
300 AT_CHECK([run_perl_module test.pl], [0],
301   [Dictionary survives sysfile
303 AT_CLEANUP
305 m4_define([PERL_GENERATE_SYSFILE],
306   [AT_DATA([sample.sps],
307     [[data list notable list /string (a8) longstring (a12) numeric (f10) date (date11) dollar (dollar8.2) datetime (datetime17)
308 begin data.
309 1111 One   1 1/1/1 1   1/1/1+01:01
310 2222 Two   2 2/2/2 2   2/2/2+02:02
311 3333 Three 3 3/3/3 3   3/3/3+03:03
312 .    .     . .     .   .
313 5555 Five  5 5/5/5 5   5/5/5+05:05
314 end data.
317 variable labels string 'A Short String Variable'
318   /longstring 'A Long String Variable'
319   /numeric 'A Numeric Variable'
320   /date 'A Date Variable'
321   /dollar 'A Dollar Variable'
322   /datetime 'A Datetime Variable'.
325 missing values numeric (9, 5, 999).
327 missing values string ("3333").
329 add value labels
330   /string '1111' 'ones' '2222' 'twos' '3333' 'threes'
331   /numeric 1 'Unity' 2 'Duality' 3 'Thripality'.
333 variable attribute
334     variables = numeric
335     attribute=colour[1]('blue') colour[2]('pink') colour[3]('violet')
336     attribute=size('large') nationality('foreign').
339 save outfile='sample.sav'.
341    AT_CHECK([pspp -O format=csv sample.sps])])
343 AT_SETUP([Perl read system file])
344 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
345 PERL_GENERATE_SYSFILE
346 AT_DATA([test.pl],
347   [[use warnings;
348     use strict;
349     use PSPP;
351     my $sf = PSPP::Reader->open ("sample.sav");
353     my $dict = $sf->get_dict ();
355     for (my $v = 0 ; $v < $dict->get_var_cnt() ; $v++)
356     {
357        my $var = $dict->get_var ($v);
358        my $name = $var->get_name ();
359        my $label = $var->get_label ();
361        print "Variable $v is \"$name\", label is \"$label\"\n";
363        my $vl = $var->get_value_labels ();
365        print "Value Labels:\n";
366        print "$_ => $vl->{$_}\n" for sort (keys %$vl);
367     }
369     while (my @c = $sf->get_next_case () )
370     {
371        for (my $v = 0; $v < $dict->get_var_cnt(); $v++)
372        {
373            print "val$v: \"$c[$v]\"\n";
374        }
375        print "\n";
376     }
378 AT_CHECK([run_perl_module test.pl], [0],
379   [Variable 0 is "string", label is "A Short String Variable"
380 Value Labels:
381 1111     => ones
382 2222     => twos
383 3333     => threes
384 Variable 1 is "longstring", label is "A Long String Variable"
385 Value Labels:
386 Variable 2 is "numeric", label is "A Numeric Variable"
387 Value Labels:
388 1 => Unity
389 2 => Duality
390 3 => Thripality
391 Variable 3 is "date", label is "A Date Variable"
392 Value Labels:
393 Variable 4 is "dollar", label is "A Dollar Variable"
394 Value Labels:
395 Variable 5 is "datetime", label is "A Datetime Variable"
396 Value Labels:
397 val0: "1111    "
398 val1: "One         "
399 val2: "1"
400 val3: "13197686400"
401 val4: "1"
402 val5: "13197690060"
404 val0: "2222    "
405 val1: "Two         "
406 val2: "2"
407 val3: "13231987200"
408 val4: "2"
409 val5: "13231994520"
411 val0: "3333    "
412 val1: "Three       "
413 val2: "3"
414 val3: "13266028800"
415 val4: "3"
416 val5: "13266039780"
418 val0: ".       "
419 val1: ".           "
420 val2: ""
421 val3: ""
422 val4: ""
423 val5: ""
425 val0: "5555    "
426 val1: "Five        "
427 val2: "5"
428 val3: "13334630400"
429 val4: "5"
430 val5: "13334648700"
433 AT_CLEANUP
435 AT_SETUP([Perl copying system files])
436 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
437 PERL_GENERATE_SYSFILE
438 AT_DATA([test.pl],
439   [[use warnings;
440     use strict;
441     use PSPP;
443     my $input = PSPP::Reader->open ("sample.sav");
445     my $dict = $input->get_dict ();
447     my $output = PSPP::Sysfile->new ("copy.sav", $dict);
449     while (my (@c) = $input->get_next_case () )
450     {
451       $output->append_case (\@c);
452     }
454     $output->close ();
456 AT_CHECK([run_perl_module test.pl])
457 AT_DATA([dump-dicts.sps],
458   [GET FILE='sample.sav'.
459 DISPLAY DICTIONARY.
460 DISPLAY ATTRIBUTES
461 LIST.
463 GET FILE='copy.sav'.
464 DISPLAY DICTIONARY.
465 DISPLAY ATTRIBUTES
466 LIST.
468 AT_CHECK([pspp -O format=csv dump-dicts.sps], [0],
469   [[Table: Variables
470 Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
471 string,1,A Short String Variable,Nominal,Input,8,Left,A8,A8,"""3333    """
472 longstring,2,A Long String Variable,Nominal,Input,12,Left,A12,A12,
473 numeric,3,A Numeric Variable,Nominal,Input,8,Right,F10.0,F10.0,9; 5; 999
474 date,4,A Date Variable,Scale,Input,8,Right,DATE11,DATE11,
475 dollar,5,A Dollar Variable,Scale,Input,8,Right,DOLLAR11.2,DOLLAR11.2,
476 datetime,6,A Datetime Variable,Scale,Input,8,Right,DATETIME17.0,DATETIME17.0,
478 Table: Value Labels
479 Variable Value,,Label
480 A Short String Variable,1111,ones
481 ,2222,twos
482 ,3333[a],threes
483 A Numeric Variable,1,Unity
484 ,2,Duality
485 ,3,Thripality
486 Footnote: a. User-missing value
488 Table: Variable and Dataset Attributes
489 Variable and Name,,Value
490 A Numeric Variable,colour[1],blue
491 ,colour[2],pink
492 ,colour[3],violet
493 ,nationality,foreign
494 ,size,large
496 Table: Data List
497 string,longstring,numeric,date,dollar,datetime
498 1111,One,1,01-JAN-2001,$1.00,01-JAN-2001 01:01
499 2222,Two,2,02-FEB-2002,$2.00,02-FEB-2002 02:02
500 3333,Three,3,03-MAR-2003,$3.00,03-MAR-2003 03:03
501 .,.,.,.,.  ,.
502 5555,Five,5,05-MAY-2005,$5.00,05-MAY-2005 05:05
504 Table: Variables
505 Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
506 string,1,A Short String Variable,Nominal,Input,8,Left,A8,A8,"""3333    """
507 longstring,2,A Long String Variable,Nominal,Input,12,Left,A12,A12,
508 numeric,3,A Numeric Variable,Nominal,Input,8,Right,F10.0,F10.0,9; 5; 999
509 date,4,A Date Variable,Scale,Input,8,Right,DATE11,DATE11,
510 dollar,5,A Dollar Variable,Scale,Input,8,Right,DOLLAR11.2,DOLLAR11.2,
511 datetime,6,A Datetime Variable,Scale,Input,8,Right,DATETIME17.0,DATETIME17.0,
513 Table: Value Labels
514 Variable Value,,Label
515 A Short String Variable,1111,ones
516 ,2222,twos
517 ,3333[a],threes
518 A Numeric Variable,1,Unity
519 ,2,Duality
520 ,3,Thripality
521 Footnote: a. User-missing value
523 Table: Variable and Dataset Attributes
524 Variable and Name,,Value
525 A Numeric Variable,colour[1],blue
526 ,colour[2],pink
527 ,colour[3],violet
528 ,nationality,foreign
529 ,size,large
531 Table: Data List
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
536 .,.,.,.,.  ,.
537 5555,Five,5,05-MAY-2005,$5.00,05-MAY-2005 05:05
539 AT_CLEANUP
541 AT_SETUP([Perl value formatting])
542 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
543 AT_DATA([dd.sps],
544   [DATA LIST LIST /d (DATETIME17).
545 BEGIN DATA.
546 11/9/2001+08:20
547 END DATA.
549 SAVE OUTFILE='dd.sav'.
551 AT_CHECK([pspp -O format=csv dd.sps], [0],
552   [Table: Reading free-form data from INLINE.
553 Variable,Format
554 d,DATETIME17.0
556 AT_DATA([test.pl],
557   [[use warnings;
558     use strict;
559     use PSPP;
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);
568     my $val = $c[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"
578 AT_CLEANUP
580 AT_SETUP([Perl opening nonexistent file])
581 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
582 AT_DATA([test.pl],
583   [[use warnings;
584     use strict;
585     use PSPP;
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.
597 AT_CLEANUP
599 AT_SETUP([Perl missing values])
600 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
601 PERL_GENERATE_SYSFILE
602 AT_DATA([test.pl],
603   [[use warnings;
604     use strict;
605     use PSPP;
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);
615     my $val = $c[0];
617     die "Missing Value Negative String"
618         if PSPP::value_is_missing ($val, $stringvar);
620     $val = $c[2];
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 ();
628     $val = $c[0];
629     die "Missing Value Positive"
630         if !PSPP::value_is_missing ($val, $stringvar);
632     @c = $sf->get_next_case ();
633     $val = $c[2];
634     die "Missing Value Positive SYS"
635         if !PSPP::value_is_missing ($val, $numericvar);
637     @c = $sf->get_next_case ();
638     $val = $c[2];
639     die "Missing Value Positive Num"
640         if !PSPP::value_is_missing ($val, $numericvar);
642 AT_CHECK([run_perl_module test.pl])
643 AT_CLEANUP
645 AT_SETUP([Perl custom attributes])
646 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
647 PERL_GENERATE_SYSFILE
648 AT_DATA([test.pl],
649   [[use warnings;
650     use strict;
651     use PSPP;
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)))
662     {
663         my $ll = $attr->{$k};
664         print "$k =>";
665         print map "$_\n", join ', ', @$ll;
666     }
668 AT_CHECK([run_perl_module test.pl], [0],
669   [[$@Role =>0
670 colour =>blue, pink, violet
671 nationality =>foreign
672 size =>large
674 AT_CLEANUP
676 AT_SETUP([Perl Pspp.t])
677 AT_KEYWORDS([slow])
678 AT_SKIP_IF([test "$WITH_PERL_MODULE" = no])
679 # Skip this test if Perl's Text::Diff module is not installed.
680 AT_CHECK([perl -MText::Diff -e '' || exit 77])
681 # Skip this test if Perl's Test::More module is not installed.
682 AT_CHECK([perl -MTest::More -e '' || exit 77])
683 AT_CHECK([run_perl_module "$abs_top_builddir/perl-module/t/Pspp.t"], [0],
684   [[1..37
685 ok 1 - use PSPP;
686 ok 2 - Dictionary Creation
687 ok 3
688 ok 4 - Trap illegal variable name
689 ok 5
690 ok 6 - Accept legal variable name
691 ok 7
692 ok 8 - Trap duplicate variable name
693 ok 9
694 ok 10 - Accept valid format
695 ok 11
696 ok 12 - Create sysfile object
697 ok 13 - Write system file
698 ok 14 - Append Case
699 ok 15 - Appending Case with too many variables
700 ok 16 - existance
701 ok 17 - Append Case 2
702 ok 18 - existance2
703 ok 19 - Check output
704 ok 20 - Dictionary Creation 2
705 ok 21 - Value label for short string
706 ok 22 - Value label for long string
707 ok 23 - Check output 2
708 ok 24 - Dictionary survives sysfile
709 ok 25 - Basic reader operation
710 ok 26 - Streaming of files
711 Formatted string is "11-SEP-2001 08:20"
712 ok 27 - format_value function
713 ok 28 - Perl representation of time
714 ok 29 - Returns undef on opening failure
715 ok 30 - Error string on open failure
716 ok 31 - Missing Value Negative String
717 ok 32 - Missing Value Negative Num
718 ok 33 - Missing Value Positive
719 ok 34 - Missing Value Positive SYS
720 ok 35 - Missing Value Positive Num
721 ok 36 - Custom Attributes
722 ok 37 - Case count
723 ]],[ignore])
724 AT_CLEANUP