1N/A#!./perl
1N/A
1N/A=head1 NAME
1N/A
1N/As2p.t - test suite for s2p/psed
1N/A
1N/A=head1 NOTES
1N/A
1N/AThe general idea is to
1N/A
1N/A (a) run psed with a sed script and input data to obtain some output
1N/A (b) run s2p with a sed script creating a Perl program and then run the
1N/A Perl program with the input data, again producing output
1N/A
1N/ABoth final outputs should be identical to the expected output.
1N/A
1N/AA $testcase{<name>} contains entries (after the comment ### <name> ###):
1N/A
1N/A - script: the sed script
1N/A - input: the key of the input data, stored in $input{<input>}
1N/A - expect: the expected output
1N/A - datfil: an additional file [ <path>, <data> ] (if required)
1N/A
1N/ATemporary files are created in the working directory (embedding $$
1N/Ain the name), and removed after the test.
1N/A
1N/AExcept for bin2dec (which indeed converts binary to decimal) none of the
1N/Ased scripts is doing something useful.
1N/A
1N/AAuthor: Wolfgang Laun.
1N/A
1N/A=cut
1N/A
1N/ABEGIN {
1N/A chdir 't' if -d 't';
1N/A @INC = ( '../lib' );
1N/A}
1N/A
1N/A### use Test::More;
1N/Ause File::Copy;
1N/Ause File::Spec;
1N/Arequire './test.pl';
1N/A
1N/A# BRE extensions
1N/A$ENV{PSEDEXTBRE} = '<>wW';
1N/A
1N/Aour %input = (
1N/A bins => <<'[TheEnd]',
1N/A0
1N/A111
1N/A1000
1N/A10001
1N/A[TheEnd]
1N/A
1N/A text => <<'[TheEnd]',
1N/Aline 1
1N/Aline 2
1N/Aline 3
1N/Aline 4
1N/Aline 5
1N/Aline 6
1N/Aline 7
1N/Aline 8
1N/A[TheEnd]
1N/A
1N/A adr1 => <<'[TheEnd]',
1N/A#no autoprint
1N/A# This script should be run on itself
1N/A/^#__DATA__$/,${
1N/A /^#A$/p
1N/A s/^# *[0-9]* *//
1N/A /^#\*$/p
1N/A /^#\.$/p
1N/A /^#\(..\)\(..\)\2\1*$/p
1N/A /^#[abc]\{1,\}[def]\{1,\}$/p
1N/A}
1N/A#__DATA__
1N/A#A
1N/A#*
1N/A#.
1N/A#abxyxy
1N/A#abxyxyab
1N/A#abxyxyabab
1N/A#ad
1N/A#abcdef
1N/A[TheEnd]
1N/A);
1N/A
1N/A
1N/Aour %testcase = (
1N/A
1N/A### bin2dec ###
1N/A'bin2dec' => {
1N/A script => <<'[TheEnd]',
1N/A# binary -> decimal
1N/As/^[ ]*\([01]\{1,\}\)[ ]*/\1/
1N/At go
1N/Ai\
1N/Ais not a binary number
1N/Ad
1N/A
1N/A# expand binary to Xs
1N/A: go
1N/As/^0*//
1N/As/^1/X/
1N/A: expand
1N/As/^\(X\{1,\}\)0/\1\1/
1N/As/^\(X\{1,\}\)1/\1\1X/
1N/At expand
1N/A
1N/A# count Xs in decimal
1N/A: count
1N/As/^X/1/
1N/As/0X/1/
1N/As/1X/2/
1N/As/2X/3/
1N/As/3X/4/
1N/As/4X/5/
1N/As/5X/6/
1N/As/6X/7/
1N/As/7X/8/
1N/As/8X/9/
1N/As/9X/X0/
1N/At count
1N/As/^$/0/
1N/A[TheEnd]
1N/A input => 'bins',
1N/A expect => <<'[TheEnd]',
1N/A0
1N/A7
1N/A8
1N/A17
1N/A[TheEnd]
1N/A},
1N/A
1N/A
1N/A### = ###
1N/A'=' => {
1N/A script => <<'[TheEnd]',
1N/A1=
1N/A$=
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/A1
1N/Aline 1
1N/Aline 2
1N/Aline 3
1N/Aline 4
1N/Aline 5
1N/Aline 6
1N/Aline 7
1N/A8
1N/Aline 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### D ###
1N/A'D' => {
1N/A script => <<'[TheEnd]',
1N/A#no autoprint
1N/A/1/{
1N/AN
1N/AN
1N/AN
1N/AD
1N/A}
1N/Ap
1N/A/2/D
1N/A=
1N/Ap
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Aline 2
1N/Aline 3
1N/Aline 4
1N/Aline 3
1N/Aline 4
1N/A4
1N/Aline 3
1N/Aline 4
1N/Aline 5
1N/A5
1N/Aline 5
1N/Aline 6
1N/A6
1N/Aline 6
1N/Aline 7
1N/A7
1N/Aline 7
1N/Aline 8
1N/A8
1N/Aline 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### H ###
1N/A'H' => {
1N/A script => <<'[TheEnd]',
1N/A#no autoprint
1N/A1,$H
1N/A$g
1N/A$=
1N/A$p
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/A8
1N/A
1N/Aline 1
1N/Aline 2
1N/Aline 3
1N/Aline 4
1N/Aline 5
1N/Aline 6
1N/Aline 7
1N/Aline 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### N ###
1N/A'N' => {
1N/A script => <<'[TheEnd]',
1N/A3a\
1N/Aadded line
1N/A4a\
1N/Aadded line
1N/A5a\
1N/Aadded line
1N/A3,5N
1N/A=
1N/Ad
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/A1
1N/A2
1N/Aadded line
1N/A4
1N/Aadded line
1N/A6
1N/A7
1N/A8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### P ###
1N/A'P' => {
1N/A script => <<'[TheEnd]',
1N/A1N
1N/A2N
1N/A3N
1N/A4=
1N/A4P
1N/A4,$d
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/A4
1N/Aline 1
1N/A[TheEnd]
1N/A},
1N/A
1N/A### a ###
1N/A'a' => {
1N/A script => <<'[TheEnd]',
1N/A1a\
1N/Aadded line 1.1\
1N/Aadded line 1.2
1N/A
1N/A3a\
1N/Aadded line 3.1
1N/A3a\
1N/Aadded line 3.2
1N/A
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Aline 1
1N/Aadded line 1.1
1N/Aadded line 1.2
1N/Aline 2
1N/Aline 3
1N/Aadded line 3.1
1N/Aadded line 3.2
1N/Aline 4
1N/Aline 5
1N/Aline 6
1N/Aline 7
1N/Aline 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### b ###
1N/A'b' => {
1N/A script => <<'[TheEnd]',
1N/A#no autoprint
1N/A2 b eos
1N/A4 b eos
1N/Ap
1N/A: eos
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Aline 1
1N/Aline 3
1N/Aline 5
1N/Aline 6
1N/Aline 7
1N/Aline 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### block ###
1N/A'block' => {
1N/A script => "#no autoprint\n1,3{\n=\np\n}",
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/A1
1N/Aline 1
1N/A2
1N/Aline 2
1N/A3
1N/Aline 3
1N/A[TheEnd]
1N/A},
1N/A
1N/A### c ###
1N/A'c' => {
1N/A script => <<'[TheEnd]',
1N/A2=
1N/A
1N/A2,4c\
1N/Achange 2,4 line 1\
1N/Achange 2,4 line 2
1N/A
1N/A2=
1N/A
1N/A3,5c\
1N/Achange 3,5 line 1\
1N/Achange 3,5 line 2
1N/A
1N/A3=
1N/A
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Aline 1
1N/A2
1N/Achange 2,4 line 1
1N/Achange 2,4 line 2
1N/Aline 5
1N/Aline 6
1N/Aline 7
1N/Aline 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### c1 ###
1N/A'c1' => {
1N/A script => <<'[TheEnd]',
1N/A1c\
1N/Areplaces line 1
1N/A
1N/A2,3c\
1N/Areplaces lines 2-3
1N/A
1N/A/5/,/6/c\
1N/Areplaces lines 3-4
1N/A
1N/A8,10c\
1N/Areplaces lines 6-10
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Areplaces line 1
1N/Areplaces lines 2-3
1N/Aline 4
1N/Areplaces lines 3-4
1N/Aline 7
1N/A[TheEnd]
1N/A},
1N/A
1N/A### c2 ###
1N/A'c2' => {
1N/A script => <<'[TheEnd]',
1N/A3!c\
1N/Areplace all except line 3
1N/A
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Areplace all except line 3
1N/Areplace all except line 3
1N/Aline 3
1N/Areplace all except line 3
1N/Areplace all except line 3
1N/Areplace all except line 3
1N/Areplace all except line 3
1N/Areplace all except line 3
1N/A[TheEnd]
1N/A},
1N/A
1N/A### c3 ###
1N/A'c3' => {
1N/A script => <<'[TheEnd]',
1N/A1,4!c\
1N/Areplace all except 1-4
1N/A
1N/A/5/,/8/!c\
1N/Areplace all except 5-8
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Areplace all except 5-8
1N/Areplace all except 5-8
1N/Areplace all except 5-8
1N/Areplace all except 5-8
1N/Areplace all except 1-4
1N/Areplace all except 1-4
1N/Areplace all except 1-4
1N/Areplace all except 1-4
1N/A[TheEnd]
1N/A},
1N/A
1N/A### d ###
1N/A'd' => {
1N/A script => <<'[TheEnd]',
1N/A# d delete pattern space, start next cycle
1N/A2,4 d
1N/A5 d
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Aline 1
1N/Aline 6
1N/Aline 7
1N/Aline 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### gh ###
1N/A'gh' => {
1N/A script => <<'[TheEnd]',
1N/A1h
1N/A2g
1N/A3h
1N/A4g
1N/A5q
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Aline 1
1N/Aline 1
1N/Aline 3
1N/Aline 3
1N/Aline 5
1N/A[TheEnd]
1N/A},
1N/A
1N/A### i ###
1N/A'i' => {
1N/A script => <<'[TheEnd]',
1N/A1i\
1N/Ainserted line 1.1\
1N/Ainserted line 1.2
1N/A
1N/A3i\
1N/Ainserted line 3.1
1N/A3i\
1N/Ainserted line 3.2
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Ainserted line 1.1
1N/Ainserted line 1.2
1N/Aline 1
1N/Aline 2
1N/Ainserted line 3.1
1N/Ainserted line 3.2
1N/Aline 3
1N/Aline 4
1N/Aline 5
1N/Aline 6
1N/Aline 7
1N/Aline 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### n ###
1N/A'n' => {
1N/A script => <<'[TheEnd]',
1N/A3a\
1N/Aadded line
1N/A4a\
1N/Aadded line
1N/A5a\
1N/Aadded line
1N/A3,5n
1N/A=
1N/Ad
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/A1
1N/A2
1N/Aline 3
1N/Aadded line
1N/A4
1N/Aline 5
1N/Aadded line
1N/A6
1N/A7
1N/A8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### o ###
1N/A'o' => {
1N/A script => <<'[TheEnd]',
1N/A/abc/,/def/ s//XXX/
1N/A// i\
1N/Acheers
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Aline 1
1N/Aline 2
1N/Aline 3
1N/Aline 4
1N/Aline 5
1N/Aline 6
1N/Aline 7
1N/Aline 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### q ###
1N/A'q' => {
1N/A script => <<'[TheEnd]',
1N/A2a\
1N/Aappend to line 2
1N/A3a\
1N/Aappend to line 3 - should not appear in output
1N/A3q
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Aline 1
1N/Aline 2
1N/Aappend to line 2
1N/Aline 3
1N/A[TheEnd]
1N/A},
1N/A
1N/A### r ###
1N/A'r' => {
1N/A datfil => [ 'r.txt', "r.txt line 1\nr.txt line 2\nr.txt line 3\n" ],
1N/A script => <<'[TheEnd]',
1N/A2r%r.txt%
1N/A4r %r.txt%
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Aline 1
1N/Aline 2
1N/Ar.txt line 1
1N/Ar.txt line 2
1N/Ar.txt line 3
1N/Aline 3
1N/Aline 4
1N/Ar.txt line 1
1N/Ar.txt line 2
1N/Ar.txt line 3
1N/Aline 5
1N/Aline 6
1N/Aline 7
1N/Aline 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### s ###
1N/A's' => {
1N/A script => <<'[TheEnd]',
1N/A# enclose any `(a)'.. `(c)' in `-'
1N/As/([a-z])/-\1-/g
1N/A
1N/As/\([abc]\)/-\1-/g
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Aline 1
1N/Aline 2
1N/Aline 3
1N/Aline 4
1N/Aline 5
1N/Aline 6
1N/Aline 7
1N/Aline 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### s1 ###
1N/A's1' => {
1N/A script => <<'[TheEnd]',
1N/As/\w/@1/
1N/As/\y/@2/
1N/A
1N/As/\n/@3/
1N/A
1N/A# this is literal { }
1N/As/a{3}/@4/
1N/A
1N/A# proper repetition
1N/As/a\{3\}/a rep 3/
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/A@1ine 1
1N/A@1ine 2
1N/A@1ine 3
1N/A@1ine 4
1N/A@1ine 5
1N/A@1ine 6
1N/A@1ine 7
1N/A@1ine 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### t ###
1N/A't' => {
1N/A script => join( "\n",
1N/A '#no autoprint', 's/./X/p', 's/foo/bar/p', 't bye', '=', 'p', ':bye' ),
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/AXine 1
1N/AXine 2
1N/AXine 3
1N/AXine 4
1N/AXine 5
1N/AXine 6
1N/AXine 7
1N/AXine 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### w ###
1N/A'w' => {
1N/A datfil => [ 'w.txt', '' ],
1N/A script => <<'[TheEnd]',
1N/Aw %w.txt%
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Aline 1
1N/Aline 2
1N/Aline 3
1N/Aline 4
1N/Aline 5
1N/Aline 6
1N/Aline 7
1N/Aline 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### x ###
1N/A'x' => {
1N/A script => <<'[TheEnd]',
1N/A1h
1N/A1d
1N/A2x
1N/A2,$G
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/Aline 1
1N/Aline 2
1N/Aline 3
1N/Aline 2
1N/Aline 4
1N/Aline 2
1N/Aline 5
1N/Aline 2
1N/Aline 6
1N/Aline 2
1N/Aline 7
1N/Aline 2
1N/Aline 8
1N/Aline 2
1N/A[TheEnd]
1N/A},
1N/A
1N/A### y ###
1N/A'y' => {
1N/A script => <<'[TheEnd]',
1N/Ay/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
1N/Ay/|/\
1N/A/
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/ALINE 1
1N/ALINE 2
1N/ALINE 3
1N/ALINE 4
1N/ALINE 5
1N/ALINE 6
1N/ALINE 7
1N/ALINE 8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### cnt ###
1N/A'cnt' => {
1N/A script => <<'[TheEnd]',
1N/A#no autoprint
1N/A
1N/A# delete line, append NL to hold space
1N/As/.*//
1N/AH
1N/A$!b
1N/A
1N/A# last line only: get hold
1N/Ag
1N/As/./X/g
1N/At count
1N/A: count
1N/As/^X/1/
1N/As/0X/1/
1N/As/1X/2/
1N/As/2X/3/
1N/As/3X/4/
1N/As/4X/5/
1N/As/5X/6/
1N/As/6X/7/
1N/As/7X/8/
1N/As/8X/9/
1N/As/9X/X0/
1N/At count
1N/Ap
1N/A[TheEnd]
1N/A input => 'text',
1N/A expect => <<'[TheEnd]',
1N/A8
1N/A[TheEnd]
1N/A},
1N/A
1N/A### adr1 ###
1N/A'adr1' => {
1N/A script => <<'[TheEnd]',
1N/A#no autoprint
1N/A# This script should be run on itself
1N/A/^#__DATA__$/,${
1N/A /^#A$/p
1N/A s/^# *[0-9]* *//
1N/A /^#\*$/p
1N/A /^#\.$/p
1N/A /^#\(..\)\(..\)\2\1*$/p
1N/A /^#[abc]\{1,\}[def]\{1,\}$/p
1N/A}
1N/A#__DATA__
1N/A#A
1N/A#*
1N/A#.
1N/A#abxyxy
1N/A#abxyxyab
1N/A#abxyxyabab
1N/A#ad
1N/A#abcdef
1N/A[TheEnd]
1N/A input => 'adr1',
1N/A expect => <<'[TheEnd]',
1N/A#A
1N/A[TheEnd]
1N/A},
1N/A
1N/A);
1N/A
1N/Amy @aux = ();
1N/Amy $ntc = 2 * keys %testcase;
1N/Aplan( $ntc );
1N/A
1N/A# temporary file names
1N/Amy $script = "s2pt$$.sed";
1N/Amy $stdin = "s2pt$$.in";
1N/Amy $plsed = "s2pt$$.pl";
1N/A
1N/A# various command lines for
1N/Amy $s2p = File::Spec->catfile( File::Spec->updir(), 'x2p', 's2p' );
1N/Amy $psed = File::Spec->catfile( File::Spec->curdir(), 'psed' );
1N/Aif ($^O eq 'VMS') {
1N/A # default in the .com extenson if it's not already there
1N/A $s2p = VMS::Filespec::rmsexpand($s2p, '.com');
1N/A $psed = VMS::Filespec::rmsexpand($psed, '.com');
1N/A}
1N/Amy $sedcmd = [ $psed, '-f', $script, $stdin ];
1N/Amy $s2pcmd = [ $s2p, '-f', $script ];
1N/Amy $plcmd = [ $plsed, $stdin ];
1N/A
1N/Amy $switches = '';
1N/A$switches = ['-x'] if $^O eq 'MacOS';
1N/A
1N/A# psed: we create a local copy as linking may not work on some systems.
1N/Acopy( $s2p, $psed );
1N/Apush( @aux, $psed );
1N/A
1N/A# process all testcases
1N/A#
1N/Amy $indat = '';
1N/Afor my $tc ( sort keys %testcase ){
1N/A my( $psedres, $s2pres );
1N/A
1N/A # 1st test: run psed
1N/A # prepare the script
1N/A open( SED, ">$script" ) || goto FAIL_BOTH;
1N/A my $script = $testcase{$tc}{script};
1N/A
1N/A # additional files for r, w: patch script, inserting temporary names
1N/A if( exists( $testcase{$tc}{datfil} ) ){
1N/A my( $datnam, $datdat ) = @{$testcase{$tc}{datfil}};
1N/A my $datfil = "s2pt$$" . $datnam;
1N/A push( @aux, $datfil );
1N/A open( DAT, ">$datfil" ) || goto FAIL_BOTH;
1N/A print DAT $datdat;
1N/A close( DAT );
1N/A $script =~ s/\%$datnam\%/$datfil/eg;
1N/A }
1N/A print SED $script;
1N/A close( SED ) || goto FAIL_BOTH;
1N/A
1N/A # prepare input
1N/A #
1N/A if( $indat ne $testcase{$tc}{input} ){
1N/A $indat = $testcase{$tc}{input};
1N/A open( IN, ">$stdin" ) || goto FAIL_BOTH;
1N/A print IN $input{$indat};
1N/A close( IN ) || goto FAIL_BOTH;
1N/A }
1N/A
1N/A # on VMS, runperl eats blank lines to work around
1N/A # spurious newlines in pipes
1N/A $testcase{$tc}{expect} =~ s/\n\n/\n/ if $^O eq 'VMS';
1N/A
1N/A # run and compare
1N/A #
1N/A $psedres = runperl( args => $sedcmd, switches => $switches );
1N/A is( $psedres, $testcase{$tc}{expect}, "psed $tc" );
1N/A
1N/A # 2nd test: run s2p
1N/A # translate the sed script to a Perl program
1N/A
1N/A my $perlprog = runperl( args => $s2pcmd, switches => $switches );
1N/A open( PP, ">$plsed" ) || goto FAIL_S2P;
1N/A print PP $perlprog;
1N/A close( PP ) || goto FAIL_S2P;
1N/A
1N/A # execute generated Perl program, compare
1N/A $s2pres = runperl( args => $plcmd, switches => $switches );
1N/A is( $s2pres, $testcase{$tc}{expect}, "s2p $tc" );
1N/A next;
1N/A
1N/AFAIL_BOTH:
1N/A fail( "psed $tc" );
1N/AFAIL_S2P:
1N/A fail( "s2p $tc" );
1N/A}
1N/A
1N/AEND {
1N/A for my $f ( $script, $stdin, $plsed, @aux ){
1N/A 1 while unlink( $f ); # hats off to VMS...
1N/A }
1N/A}