Add tests for s2p/psed, from Wolfgang Laun.
Jarkko Hietaniemi [Tue, 9 Apr 2002 18:32:27 +0000 (18:32 +0000)]
p4raw-id: //depot/perl@15833

MANIFEST
t/TEST
t/x2p/s2p.t [new file with mode: 0755]

index ebb60de..548b4f2 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -2553,6 +2553,7 @@ t/uni/lower.t                     See if Unicode casing works
 t/uni/sprintf.t                        See if Unicode sprintf works
 t/uni/title.t                  See if Unicode casing works
 t/uni/upper.t                  See if Unicode casing works
+t/x2p/s2p.t                    See if s2p/psed work
 taint.c                                Tainting code
 thrdvar.h                      Per-thread variables
 thread.h                       Threading header
diff --git a/t/TEST b/t/TEST
index b788da9..a970b00 100755 (executable)
--- a/t/TEST
+++ b/t/TEST
@@ -93,6 +93,7 @@ unless (@ARGV) {
         warn "$0: cannot open $mani: $!\n";
     }
     _find_tests('pod');
+    _find_tests('x2p');
 }
 
 # Tests known to cause infinite loops for the perlcc tests.
diff --git a/t/x2p/s2p.t b/t/x2p/s2p.t
new file mode 100755 (executable)
index 0000000..15219fc
--- /dev/null
@@ -0,0 +1,861 @@
+#!./perl
+
+=head1 NAME
+
+s2p.t - test suite for s2p/psed
+
+=head1 NOTES
+
+The general idea is to
+
+  (a) run psed with a sed script and input data to obtain some output
+  (b) run s2p with a sed script creating a Perl program and then run the
+      Perl program with the input data, again producing output
+
+Both final outputs should be identical to the expected output.
+
+A $testcase{<name>} contains entries (after the comment ### <name> ###):
+
+  - script: the sed script
+  - input:  the key of the input data, stored in $input{<input>}
+  - expect: the expected output
+  - datfil: an additional file [ <path>, <data> ] (if required)
+
+Temporary files are created in the working directory (embedding $$
+in the name), and removed after the test.
+
+Except for bin2dec (which indeed converts binary to decimal) none of the
+sed scripts is doing something useful.
+
+Author: Wolfgang Laun.
+
+=cut
+
+BEGIN {
+    chdir 't' if -d 't';
+    @INC = ( '../lib' );
+}
+
+### use Test::More;
+use File::Copy;
+use File::Spec;
+require './test.pl';
+
+# BRE extensions
+$ENV{PSEDEXTBRE} = '<>wW';
+
+our %input = (
+   bins => <<'[TheEnd]',
+0
+111
+1000
+10001
+[TheEnd]
+
+   text => <<'[TheEnd]',
+line 1
+line 2
+line 3
+line 4
+line 5
+line 6
+line 7
+line 8
+[TheEnd]
+
+   adr1 => <<'[TheEnd]',
+#no autoprint
+# This script should be run on itself
+/^#__DATA__$/,${
+   /^#A$/p
+   s/^# *[0-9]* *//
+   /^#\*$/p
+   /^#\.$/p
+   /^#\(..\)\(..\)\2\1*$/p
+   /^#[abc]\{1,\}[def]\{1,\}$/p
+}
+#__DATA__
+#A
+#*
+#.
+#abxyxy
+#abxyxyab
+#abxyxyabab
+#ad
+#abcdef
+[TheEnd]
+);
+
+
+our %testcase = (
+
+### bin2dec ###
+'bin2dec' => {
+  script => <<'[TheEnd]',
+# binary -> decimal
+s/^[   ]*\([01]\{1,\}\)[       ]*/\1/
+t go
+i\
+is not a binary number
+d
+
+# expand binary to Xs
+: go
+s/^0*//
+s/^1/X/
+: expand
+s/^\(X\{1,\}\)0/\1\1/
+s/^\(X\{1,\}\)1/\1\1X/
+t expand
+
+# count Xs in decimal
+: count
+s/^X/1/
+s/0X/1/
+s/1X/2/
+s/2X/3/
+s/3X/4/
+s/4X/5/
+s/5X/6/
+s/6X/7/
+s/7X/8/
+s/8X/9/
+s/9X/X0/
+t count
+s/^$/0/
+[TheEnd]
+  input  => 'bins',
+  expect => <<'[TheEnd]',
+0
+7
+8
+17
+[TheEnd]
+},
+
+
+### = ###
+'=' => {
+  script => <<'[TheEnd]',
+1=
+$=
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+1
+line 1
+line 2
+line 3
+line 4
+line 5
+line 6
+line 7
+8
+line 8
+[TheEnd]
+},
+
+### D ###
+'D' => {
+  script => <<'[TheEnd]',
+#no autoprint
+/1/{
+N
+N
+N
+D
+}
+p
+/2/D
+=
+p
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+line 2
+line 3
+line 4
+line 3
+line 4
+4
+line 3
+line 4
+line 5
+5
+line 5
+line 6
+6
+line 6
+line 7
+7
+line 7
+line 8
+8
+line 8
+[TheEnd]
+},
+
+### H ###
+'H' => {
+  script => <<'[TheEnd]',
+#no autoprint
+1,$H
+$g
+$=
+$p
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+8
+
+line 1
+line 2
+line 3
+line 4
+line 5
+line 6
+line 7
+line 8
+[TheEnd]
+},
+
+### N ###
+'N' => {
+  script => <<'[TheEnd]',
+3a\
+added line
+4a\
+added line
+5a\
+added line
+3,5N
+=
+d
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+1
+2
+added line
+4
+added line
+6
+7
+8
+[TheEnd]
+},
+
+### P ###
+'P' => {
+  script => <<'[TheEnd]',
+1N
+2N
+3N
+4=
+4P
+4,$d
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+4
+line 1
+[TheEnd]
+},
+
+### a ###
+'a' => {
+  script => <<'[TheEnd]',
+1a\
+added line 1.1\
+added line 1.2
+
+3a\
+added line 3.1
+3a\
+added line 3.2
+
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+line 1
+added line 1.1
+added line 1.2
+line 2
+line 3
+added line 3.1
+added line 3.2
+line 4
+line 5
+line 6
+line 7
+line 8
+[TheEnd]
+},
+
+### b ###
+'b' => {
+  script => <<'[TheEnd]',
+#no autoprint
+2 b eos
+4 b eos
+p
+: eos
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+line 1
+line 3
+line 5
+line 6
+line 7
+line 8
+[TheEnd]
+},
+
+### block ###
+'block' => {
+  script => "#no autoprint\n1,3{\n=\np\n}",
+  input  => 'text',
+  expect => <<'[TheEnd]',
+1
+line 1
+2
+line 2
+3
+line 3
+[TheEnd]
+},
+
+### c ###
+'c' => {
+  script => <<'[TheEnd]',
+2=
+
+2,4c\
+change 2,4 line 1\
+change 2,4 line 2
+
+2=
+
+3,5c\
+change 3,5 line 1\
+change 3,5 line 2
+
+3=
+
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+line 1
+2
+change 2,4 line 1
+change 2,4 line 2
+line 5
+line 6
+line 7
+line 8
+[TheEnd]
+},
+
+### c1 ###
+'c1' => {
+  script => <<'[TheEnd]',
+1c\
+replaces line 1
+
+2,3c\
+replaces lines 2-3
+
+/5/,/6/c\
+replaces lines 3-4
+
+8,10c\
+replaces lines 6-10
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+replaces line 1
+replaces lines 2-3
+line 4
+replaces lines 3-4
+line 7
+[TheEnd]
+},
+
+### c2 ###
+'c2' => {
+  script => <<'[TheEnd]',
+3!c\
+replace all except line 3
+
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+replace all except line 3
+replace all except line 3
+line 3
+replace all except line 3
+replace all except line 3
+replace all except line 3
+replace all except line 3
+replace all except line 3
+[TheEnd]
+},
+
+### c3 ###
+'c3' => {
+  script => <<'[TheEnd]',
+1,4!c\
+replace all except 1-4
+
+/5/,/8/!c\
+replace all except 5-8
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+replace all except 5-8
+replace all except 5-8
+replace all except 5-8
+replace all except 5-8
+replace all except 1-4
+replace all except 1-4
+replace all except 1-4
+replace all except 1-4
+[TheEnd]
+},
+
+### d ###
+'d' => {
+  script => <<'[TheEnd]',
+# d delete pattern space, start next cycle
+2,4 d
+5 d
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+line 1
+line 6
+line 7
+line 8
+[TheEnd]
+},
+
+### gh ###
+'gh' => {
+  script => <<'[TheEnd]',
+1h
+2g
+3h
+4g
+5q
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+line 1
+line 1
+line 3
+line 3
+line 5
+[TheEnd]
+},
+
+### i ###
+'i' => {
+  script => <<'[TheEnd]',
+1i\
+inserted line 1.1\
+inserted line 1.2
+
+3i\
+inserted line 3.1
+3i\
+inserted line 3.2
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+inserted line 1.1
+inserted line 1.2
+line 1
+line 2
+inserted line 3.1
+inserted line 3.2
+line 3
+line 4
+line 5
+line 6
+line 7
+line 8
+[TheEnd]
+},
+
+### n ###
+'n' => {
+  script => <<'[TheEnd]',
+3a\
+added line
+4a\
+added line
+5a\
+added line
+3,5n
+=
+d
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+1
+2
+line 3
+added line
+4
+line 5
+added line
+6
+7
+8
+[TheEnd]
+},
+
+### o ###
+'o' => {
+  script => <<'[TheEnd]',
+/abc/,/def/ s//XXX/
+// i\
+cheers
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+line 1
+line 2
+line 3
+line 4
+line 5
+line 6
+line 7
+line 8
+[TheEnd]
+},
+
+### q ###
+'q' => {
+  script => <<'[TheEnd]',
+2a\
+append to line 2
+3a\
+append to line 3 - should not appear in output
+3q
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+line 1
+line 2
+append to line 2
+line 3
+[TheEnd]
+},
+
+### r ###
+'r' => {
+  datfil => [ 'r.txt', "r.txt line 1\nr.txt line 2\nr.txt line 3\n" ],
+  script => <<'[TheEnd]',
+2r%r.txt%
+4r %r.txt%
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+line 1
+line 2
+r.txt line 1
+r.txt line 2
+r.txt line 3
+line 3
+line 4
+r.txt line 1
+r.txt line 2
+r.txt line 3
+line 5
+line 6
+line 7
+line 8
+[TheEnd]
+},
+
+### s ###
+'s' => {
+  script => <<'[TheEnd]',
+# enclose any `(a)'.. `(c)' in `-'
+s/([a-z])/-\1-/g
+
+s/\([abc]\)/-\1-/g
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+line 1
+line 2
+line 3
+line 4
+line 5
+line 6
+line 7
+line 8
+[TheEnd]
+},
+
+### s1 ###
+'s1' => {
+  script => <<'[TheEnd]',
+s/\w/@1/
+s/\y/@2/
+
+s/\n/@3/
+
+# this is literal { }
+s/a{3}/@4/
+
+# proper repetition
+s/a\{3\}/a rep 3/
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+@1ine 1
+@1ine 2
+@1ine 3
+@1ine 4
+@1ine 5
+@1ine 6
+@1ine 7
+@1ine 8
+[TheEnd]
+},
+
+### t ###
+'t' => {
+  script => join( "\n",
+   '#no autoprint', 's/./X/p', 's/foo/bar/p', 't bye', '=', 'p', ':bye' ),
+  input  => 'text',
+  expect => <<'[TheEnd]',
+Xine 1
+Xine 2
+Xine 3
+Xine 4
+Xine 5
+Xine 6
+Xine 7
+Xine 8
+[TheEnd]
+},
+
+### w ###
+'w' => {
+  datfil => [ 'w.txt', '' ],
+  script => <<'[TheEnd]',
+w %w.txt%
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+line 1
+line 2
+line 3
+line 4
+line 5
+line 6
+line 7
+line 8
+[TheEnd]
+},
+
+### x ###
+'x' => {
+  script => <<'[TheEnd]',
+1h
+1d
+2x
+2,$G
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+line 1
+line 2
+line 3
+line 2
+line 4
+line 2
+line 5
+line 2
+line 6
+line 2
+line 7
+line 2
+line 8
+line 2
+[TheEnd]
+},
+
+### y ###
+'y' => {
+  script => <<'[TheEnd]',
+y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
+y/|/\
+/ 
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+LINE 1
+LINE 2
+LINE 3
+LINE 4
+LINE 5
+LINE 6
+LINE 7
+LINE 8
+[TheEnd]
+},
+
+### cnt ###
+'cnt' => {
+  script => <<'[TheEnd]',
+#no autoprint
+
+# delete line, append NL to hold space
+s/.*//
+H
+$!b
+
+# last line only: get hold
+g
+s/./X/g
+t count
+: count
+s/^X/1/
+s/0X/1/
+s/1X/2/
+s/2X/3/
+s/3X/4/
+s/4X/5/
+s/5X/6/
+s/6X/7/
+s/7X/8/
+s/8X/9/
+s/9X/X0/
+t count
+p
+[TheEnd]
+  input  => 'text',
+  expect => <<'[TheEnd]',
+8
+[TheEnd]
+},
+
+### adr1 ###
+'adr1' => {
+  script => <<'[TheEnd]',
+#no autoprint
+# This script should be run on itself
+/^#__DATA__$/,${
+   /^#A$/p
+   s/^# *[0-9]* *//
+   /^#\*$/p
+   /^#\.$/p
+   /^#\(..\)\(..\)\2\1*$/p
+   /^#[abc]\{1,\}[def]\{1,\}$/p
+}
+#__DATA__
+#A
+#*
+#.
+#abxyxy
+#abxyxyab
+#abxyxyabab
+#ad
+#abcdef
+[TheEnd]
+  input  => 'adr1',
+  expect => <<'[TheEnd]',
+#A
+[TheEnd]
+},
+
+);
+
+my @aux = ();
+my $ntc = 2 * keys %testcase;
+plan( $ntc );
+
+# temporary file names
+my $script = "s2pt$$.sed";
+my $stdin  = "s2pt$$.in";
+my $plsed  = "s2pt$$.pl";
+
+# various command lines for 
+my $s2p  = File::Spec->catfile( File::Spec->updir(), 'x2p', 's2p' );
+my $psed = File::Spec->catfile( File::Spec->curdir(), 'psed' );
+my $sedcmd = [ $psed, '-f', $script, $stdin ];
+my $s2pcmd = [ $s2p,  '-f', $script ];
+my $plcmd  = [ $plsed, $stdin ];
+
+# psed: we create a local copy as linking may not work on some systems.
+copy( $s2p, $psed );
+push( @aux, $psed );
+
+# process all testcases
+#
+my $indat = '';
+for my $tc ( sort keys %testcase ){
+    my( $psedres, $s2pres );
+
+    # 1st test: run psed
+    # prepare the script 
+    open( SED, ">$script" ) || goto FAIL_BOTH;
+    my $script = $testcase{$tc}{script};
+
+    # additional files for r, w: patch script, inserting temporary names
+    if( exists( $testcase{$tc}{datfil} ) ){
+        my( $datnam, $datdat ) = @{$testcase{$tc}{datfil}};
+        my $datfil = "s2pt$$" . $datnam;
+        push( @aux, $datfil );
+        open( DAT, ">$datfil" ) || goto FAIL_BOTH;
+        print DAT $datdat;
+        close( DAT );
+        $script =~ s/\%$datnam\%/$datfil/eg;
+    }
+    print SED $script;
+    close( SED ) || goto FAIL_BOTH;
+
+    # prepare input
+    #
+    if( $indat ne $testcase{$tc}{input} ){
+        $indat = $testcase{$tc}{input};
+        open( IN, ">$stdin" ) || goto FAIL_BOTH;
+        print IN $input{$indat};
+        close( IN ) || goto FAIL_BOTH;
+    }
+
+    # run and compare
+    #
+    $psedres = runperl( args => $sedcmd );
+    is( $psedres, $testcase{$tc}{expect}, "psed $tc" );
+
+    # 2nd test: run s2p
+    # translate the sed script to a Perl program
+    
+    my $perlprog = runperl( args => $s2pcmd );
+    open( PP, ">$plsed" ) || goto FAIL_S2P;
+    print PP $perlprog;
+    close( PP ) || goto FAIL_S2P;
+
+    # execute generated Perl program, compare
+    $s2pres = runperl( args => $plcmd );
+    is( $s2pres, $testcase{$tc}{expect}, "s2p $tc" );
+    next;
+
+FAIL_BOTH:
+    fail( "psed $tc" );
+FAIL_S2P:
+    fail( "s2p $tc" );
+}
+
+END {
+    for my $f ( $script, $stdin, $plsed, @aux ){
+        1 while unlink( $f ); # hats off to VMS...
+    }
+}