S_del_body is sufficiently small that inlining it is a space win.
[p5sagit/p5-mst-13.2.git] / t / x2p / s2p.t
CommitLineData
939256b9 1#!./perl
2
3=head1 NAME
4
5s2p.t - test suite for s2p/psed
6
7=head1 NOTES
8
9The general idea is to
10
11 (a) run psed with a sed script and input data to obtain some output
12 (b) run s2p with a sed script creating a Perl program and then run the
13 Perl program with the input data, again producing output
14
15Both final outputs should be identical to the expected output.
16
17A $testcase{<name>} contains entries (after the comment ### <name> ###):
18
19 - script: the sed script
20 - input: the key of the input data, stored in $input{<input>}
21 - expect: the expected output
22 - datfil: an additional file [ <path>, <data> ] (if required)
23
24Temporary files are created in the working directory (embedding $$
25in the name), and removed after the test.
26
27Except for bin2dec (which indeed converts binary to decimal) none of the
28sed scripts is doing something useful.
29
30Author: Wolfgang Laun.
31
32=cut
33
34BEGIN {
35 chdir 't' if -d 't';
36 @INC = ( '../lib' );
37}
38
39### use Test::More;
40use File::Copy;
41use File::Spec;
42require './test.pl';
43
44# BRE extensions
45$ENV{PSEDEXTBRE} = '<>wW';
46
47our %input = (
48 bins => <<'[TheEnd]',
490
50111
511000
5210001
53[TheEnd]
54
55 text => <<'[TheEnd]',
56line 1
57line 2
58line 3
59line 4
60line 5
61line 6
62line 7
63line 8
64[TheEnd]
65
66 adr1 => <<'[TheEnd]',
67#no autoprint
68# This script should be run on itself
69/^#__DATA__$/,${
70 /^#A$/p
71 s/^# *[0-9]* *//
72 /^#\*$/p
73 /^#\.$/p
74 /^#\(..\)\(..\)\2\1*$/p
75 /^#[abc]\{1,\}[def]\{1,\}$/p
76}
77#__DATA__
78#A
79#*
80#.
81#abxyxy
82#abxyxyab
83#abxyxyabab
84#ad
85#abcdef
86[TheEnd]
87);
88
89
90our %testcase = (
91
92### bin2dec ###
93'bin2dec' => {
94 script => <<'[TheEnd]',
95# binary -> decimal
96s/^[ ]*\([01]\{1,\}\)[ ]*/\1/
97t go
98i\
99is not a binary number
100d
101
102# expand binary to Xs
103: go
104s/^0*//
105s/^1/X/
106: expand
107s/^\(X\{1,\}\)0/\1\1/
108s/^\(X\{1,\}\)1/\1\1X/
109t expand
110
111# count Xs in decimal
112: count
113s/^X/1/
114s/0X/1/
115s/1X/2/
116s/2X/3/
117s/3X/4/
118s/4X/5/
119s/5X/6/
120s/6X/7/
121s/7X/8/
122s/8X/9/
123s/9X/X0/
124t count
125s/^$/0/
126[TheEnd]
127 input => 'bins',
128 expect => <<'[TheEnd]',
1290
1307
1318
13217
133[TheEnd]
134},
135
136
137### = ###
138'=' => {
139 script => <<'[TheEnd]',
1401=
141$=
142[TheEnd]
143 input => 'text',
144 expect => <<'[TheEnd]',
1451
146line 1
147line 2
148line 3
149line 4
150line 5
151line 6
152line 7
1538
154line 8
155[TheEnd]
156},
157
158### D ###
159'D' => {
160 script => <<'[TheEnd]',
161#no autoprint
162/1/{
163N
164N
165N
166D
167}
168p
169/2/D
170=
171p
172[TheEnd]
173 input => 'text',
174 expect => <<'[TheEnd]',
175line 2
176line 3
177line 4
178line 3
179line 4
1804
181line 3
182line 4
183line 5
1845
185line 5
186line 6
1876
188line 6
189line 7
1907
191line 7
192line 8
1938
194line 8
195[TheEnd]
196},
197
198### H ###
199'H' => {
200 script => <<'[TheEnd]',
201#no autoprint
2021,$H
203$g
204$=
205$p
206[TheEnd]
207 input => 'text',
208 expect => <<'[TheEnd]',
2098
210
211line 1
212line 2
213line 3
214line 4
215line 5
216line 6
217line 7
218line 8
219[TheEnd]
220},
221
222### N ###
223'N' => {
224 script => <<'[TheEnd]',
2253a\
226added line
2274a\
228added line
2295a\
230added line
2313,5N
232=
233d
234[TheEnd]
235 input => 'text',
236 expect => <<'[TheEnd]',
2371
2382
239added line
2404
241added line
2426
2437
2448
245[TheEnd]
246},
247
248### P ###
249'P' => {
250 script => <<'[TheEnd]',
2511N
2522N
2533N
2544=
2554P
2564,$d
257[TheEnd]
258 input => 'text',
259 expect => <<'[TheEnd]',
2604
261line 1
262[TheEnd]
263},
264
265### a ###
266'a' => {
267 script => <<'[TheEnd]',
2681a\
269added line 1.1\
270added line 1.2
271
2723a\
273added line 3.1
2743a\
275added line 3.2
276
277[TheEnd]
278 input => 'text',
279 expect => <<'[TheEnd]',
280line 1
281added line 1.1
282added line 1.2
283line 2
284line 3
285added line 3.1
286added line 3.2
287line 4
288line 5
289line 6
290line 7
291line 8
292[TheEnd]
293},
294
295### b ###
296'b' => {
297 script => <<'[TheEnd]',
298#no autoprint
2992 b eos
3004 b eos
301p
302: eos
303[TheEnd]
304 input => 'text',
305 expect => <<'[TheEnd]',
306line 1
307line 3
308line 5
309line 6
310line 7
311line 8
312[TheEnd]
313},
314
315### block ###
316'block' => {
317 script => "#no autoprint\n1,3{\n=\np\n}",
318 input => 'text',
319 expect => <<'[TheEnd]',
3201
321line 1
3222
323line 2
3243
325line 3
326[TheEnd]
327},
328
329### c ###
330'c' => {
331 script => <<'[TheEnd]',
3322=
333
3342,4c\
335change 2,4 line 1\
336change 2,4 line 2
337
3382=
339
3403,5c\
341change 3,5 line 1\
342change 3,5 line 2
343
3443=
345
346[TheEnd]
347 input => 'text',
348 expect => <<'[TheEnd]',
349line 1
3502
351change 2,4 line 1
352change 2,4 line 2
353line 5
354line 6
355line 7
356line 8
357[TheEnd]
358},
359
360### c1 ###
361'c1' => {
362 script => <<'[TheEnd]',
3631c\
364replaces line 1
365
3662,3c\
367replaces lines 2-3
368
369/5/,/6/c\
370replaces lines 3-4
371
3728,10c\
373replaces lines 6-10
374[TheEnd]
375 input => 'text',
376 expect => <<'[TheEnd]',
377replaces line 1
378replaces lines 2-3
379line 4
380replaces lines 3-4
381line 7
382[TheEnd]
383},
384
385### c2 ###
386'c2' => {
387 script => <<'[TheEnd]',
3883!c\
389replace all except line 3
390
391[TheEnd]
392 input => 'text',
393 expect => <<'[TheEnd]',
394replace all except line 3
395replace all except line 3
396line 3
397replace all except line 3
398replace all except line 3
399replace all except line 3
400replace all except line 3
401replace all except line 3
402[TheEnd]
403},
404
405### c3 ###
406'c3' => {
407 script => <<'[TheEnd]',
4081,4!c\
409replace all except 1-4
410
411/5/,/8/!c\
412replace all except 5-8
413[TheEnd]
414 input => 'text',
415 expect => <<'[TheEnd]',
416replace all except 5-8
417replace all except 5-8
418replace all except 5-8
419replace all except 5-8
420replace all except 1-4
421replace all except 1-4
422replace all except 1-4
423replace all except 1-4
424[TheEnd]
425},
426
427### d ###
428'd' => {
429 script => <<'[TheEnd]',
430# d delete pattern space, start next cycle
4312,4 d
4325 d
433[TheEnd]
434 input => 'text',
435 expect => <<'[TheEnd]',
436line 1
437line 6
438line 7
439line 8
440[TheEnd]
441},
442
443### gh ###
444'gh' => {
445 script => <<'[TheEnd]',
4461h
4472g
4483h
4494g
4505q
451[TheEnd]
452 input => 'text',
453 expect => <<'[TheEnd]',
454line 1
455line 1
456line 3
457line 3
458line 5
459[TheEnd]
460},
461
462### i ###
463'i' => {
464 script => <<'[TheEnd]',
4651i\
466inserted line 1.1\
467inserted line 1.2
468
4693i\
470inserted line 3.1
4713i\
472inserted line 3.2
473[TheEnd]
474 input => 'text',
475 expect => <<'[TheEnd]',
476inserted line 1.1
477inserted line 1.2
478line 1
479line 2
480inserted line 3.1
481inserted line 3.2
482line 3
483line 4
484line 5
485line 6
486line 7
487line 8
488[TheEnd]
489},
490
491### n ###
492'n' => {
493 script => <<'[TheEnd]',
4943a\
495added line
4964a\
497added line
4985a\
499added line
5003,5n
501=
502d
503[TheEnd]
504 input => 'text',
505 expect => <<'[TheEnd]',
5061
5072
508line 3
509added line
5104
511line 5
512added line
5136
5147
5158
516[TheEnd]
517},
518
519### o ###
520'o' => {
521 script => <<'[TheEnd]',
522/abc/,/def/ s//XXX/
523// i\
524cheers
525[TheEnd]
526 input => 'text',
527 expect => <<'[TheEnd]',
528line 1
529line 2
530line 3
531line 4
532line 5
533line 6
534line 7
535line 8
536[TheEnd]
537},
538
539### q ###
540'q' => {
541 script => <<'[TheEnd]',
5422a\
543append to line 2
5443a\
545append to line 3 - should not appear in output
5463q
547[TheEnd]
548 input => 'text',
549 expect => <<'[TheEnd]',
550line 1
551line 2
552append to line 2
553line 3
554[TheEnd]
555},
556
557### r ###
558'r' => {
559 datfil => [ 'r.txt', "r.txt line 1\nr.txt line 2\nr.txt line 3\n" ],
560 script => <<'[TheEnd]',
5612r%r.txt%
5624r %r.txt%
563[TheEnd]
564 input => 'text',
565 expect => <<'[TheEnd]',
566line 1
567line 2
568r.txt line 1
569r.txt line 2
570r.txt line 3
571line 3
572line 4
573r.txt line 1
574r.txt line 2
575r.txt line 3
576line 5
577line 6
578line 7
579line 8
580[TheEnd]
581},
582
583### s ###
584's' => {
585 script => <<'[TheEnd]',
586# enclose any `(a)'.. `(c)' in `-'
587s/([a-z])/-\1-/g
588
589s/\([abc]\)/-\1-/g
590[TheEnd]
591 input => 'text',
592 expect => <<'[TheEnd]',
593line 1
594line 2
595line 3
596line 4
597line 5
598line 6
599line 7
600line 8
601[TheEnd]
602},
603
604### s1 ###
605's1' => {
606 script => <<'[TheEnd]',
607s/\w/@1/
608s/\y/@2/
609
610s/\n/@3/
611
612# this is literal { }
613s/a{3}/@4/
614
615# proper repetition
616s/a\{3\}/a rep 3/
617[TheEnd]
618 input => 'text',
619 expect => <<'[TheEnd]',
620@1ine 1
621@1ine 2
622@1ine 3
623@1ine 4
624@1ine 5
625@1ine 6
626@1ine 7
627@1ine 8
628[TheEnd]
629},
630
631### t ###
632't' => {
633 script => join( "\n",
634 '#no autoprint', 's/./X/p', 's/foo/bar/p', 't bye', '=', 'p', ':bye' ),
635 input => 'text',
636 expect => <<'[TheEnd]',
637Xine 1
638Xine 2
639Xine 3
640Xine 4
641Xine 5
642Xine 6
643Xine 7
644Xine 8
645[TheEnd]
646},
647
648### w ###
649'w' => {
650 datfil => [ 'w.txt', '' ],
651 script => <<'[TheEnd]',
652w %w.txt%
653[TheEnd]
654 input => 'text',
655 expect => <<'[TheEnd]',
656line 1
657line 2
658line 3
659line 4
660line 5
661line 6
662line 7
663line 8
664[TheEnd]
665},
666
667### x ###
668'x' => {
669 script => <<'[TheEnd]',
6701h
6711d
6722x
6732,$G
674[TheEnd]
675 input => 'text',
676 expect => <<'[TheEnd]',
677line 1
678line 2
679line 3
680line 2
681line 4
682line 2
683line 5
684line 2
685line 6
686line 2
687line 7
688line 2
689line 8
690line 2
691[TheEnd]
692},
693
694### y ###
695'y' => {
696 script => <<'[TheEnd]',
697y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
698y/|/\
699/
700[TheEnd]
701 input => 'text',
702 expect => <<'[TheEnd]',
703LINE 1
704LINE 2
705LINE 3
706LINE 4
707LINE 5
708LINE 6
709LINE 7
710LINE 8
711[TheEnd]
712},
713
714### cnt ###
715'cnt' => {
716 script => <<'[TheEnd]',
717#no autoprint
718
719# delete line, append NL to hold space
720s/.*//
721H
722$!b
723
724# last line only: get hold
725g
726s/./X/g
727t count
728: count
729s/^X/1/
730s/0X/1/
731s/1X/2/
732s/2X/3/
733s/3X/4/
734s/4X/5/
735s/5X/6/
736s/6X/7/
737s/7X/8/
738s/8X/9/
739s/9X/X0/
740t count
741p
742[TheEnd]
743 input => 'text',
744 expect => <<'[TheEnd]',
7458
746[TheEnd]
747},
748
749### adr1 ###
750'adr1' => {
751 script => <<'[TheEnd]',
752#no autoprint
753# This script should be run on itself
754/^#__DATA__$/,${
755 /^#A$/p
756 s/^# *[0-9]* *//
757 /^#\*$/p
758 /^#\.$/p
759 /^#\(..\)\(..\)\2\1*$/p
760 /^#[abc]\{1,\}[def]\{1,\}$/p
761}
762#__DATA__
763#A
764#*
765#.
766#abxyxy
767#abxyxyab
768#abxyxyabab
769#ad
770#abcdef
771[TheEnd]
772 input => 'adr1',
773 expect => <<'[TheEnd]',
774#A
775[TheEnd]
776},
777
778);
779
780my @aux = ();
781my $ntc = 2 * keys %testcase;
782plan( $ntc );
783
784# temporary file names
785my $script = "s2pt$$.sed";
786my $stdin = "s2pt$$.in";
787my $plsed = "s2pt$$.pl";
788
789# various command lines for
790my $s2p = File::Spec->catfile( File::Spec->updir(), 'x2p', 's2p' );
791my $psed = File::Spec->catfile( File::Spec->curdir(), 'psed' );
9ae2b9a0 792if ($^O eq 'VMS') {
793 # default in the .com extenson if it's not already there
794 $s2p = VMS::Filespec::rmsexpand($s2p, '.com');
795 $psed = VMS::Filespec::rmsexpand($psed, '.com');
796}
939256b9 797my $sedcmd = [ $psed, '-f', $script, $stdin ];
798my $s2pcmd = [ $s2p, '-f', $script ];
799my $plcmd = [ $plsed, $stdin ];
800
e69a2255 801my $switches = '';
802$switches = ['-x'] if $^O eq 'MacOS';
803
939256b9 804# psed: we create a local copy as linking may not work on some systems.
805copy( $s2p, $psed );
806push( @aux, $psed );
807
808# process all testcases
809#
810my $indat = '';
811for my $tc ( sort keys %testcase ){
812 my( $psedres, $s2pres );
813
814 # 1st test: run psed
815 # prepare the script
816 open( SED, ">$script" ) || goto FAIL_BOTH;
817 my $script = $testcase{$tc}{script};
818
819 # additional files for r, w: patch script, inserting temporary names
820 if( exists( $testcase{$tc}{datfil} ) ){
821 my( $datnam, $datdat ) = @{$testcase{$tc}{datfil}};
822 my $datfil = "s2pt$$" . $datnam;
823 push( @aux, $datfil );
824 open( DAT, ">$datfil" ) || goto FAIL_BOTH;
825 print DAT $datdat;
826 close( DAT );
827 $script =~ s/\%$datnam\%/$datfil/eg;
828 }
829 print SED $script;
830 close( SED ) || goto FAIL_BOTH;
831
832 # prepare input
833 #
834 if( $indat ne $testcase{$tc}{input} ){
835 $indat = $testcase{$tc}{input};
836 open( IN, ">$stdin" ) || goto FAIL_BOTH;
837 print IN $input{$indat};
838 close( IN ) || goto FAIL_BOTH;
839 }
840
9ae2b9a0 841 # on VMS, runperl eats blank lines to work around
842 # spurious newlines in pipes
843 $testcase{$tc}{expect} =~ s/\n\n/\n/ if $^O eq 'VMS';
844
939256b9 845 # run and compare
846 #
e69a2255 847 $psedres = runperl( args => $sedcmd, switches => $switches );
939256b9 848 is( $psedres, $testcase{$tc}{expect}, "psed $tc" );
849
850 # 2nd test: run s2p
851 # translate the sed script to a Perl program
e69a2255 852
853 my $perlprog = runperl( args => $s2pcmd, switches => $switches );
939256b9 854 open( PP, ">$plsed" ) || goto FAIL_S2P;
855 print PP $perlprog;
856 close( PP ) || goto FAIL_S2P;
857
858 # execute generated Perl program, compare
e69a2255 859 $s2pres = runperl( args => $plcmd, switches => $switches );
939256b9 860 is( $s2pres, $testcase{$tc}{expect}, "s2p $tc" );
861 next;
862
863FAIL_BOTH:
864 fail( "psed $tc" );
865FAIL_S2P:
866 fail( "s2p $tc" );
867}
868
869END {
870 for my $f ( $script, $stdin, $plsed, @aux ){
871 1 while unlink( $f ); # hats off to VMS...
872 }
873}