[perl #32717] BeOS specific Updates
[p5sagit/p5-mst-13.2.git] / lib / Tie / File / t / 09_gen_rs.t
1 #!/usr/bin/perl
2
3 my $file = "tf$$.txt";
4
5 print "1..59\n";
6
7 my $N = 1;
8 use Tie::File;
9 print "ok $N\n"; $N++;
10
11 $RECSEP = 'blah';
12 my $o = tie @a, 'Tie::File', $file, 
13     recsep => $RECSEP, autochomp => 0, autodefer => 0;
14 print $o ? "ok $N\n" : "not ok $N\n";
15 $N++;
16
17
18 # 3-4 create
19 $a[0] = 'rec0';
20 check_contents("rec0");
21
22 # 5-8 append
23 $a[1] = 'rec1';
24 check_contents("rec0", "rec1");
25 $a[2] = 'rec2';
26 check_contents("rec0", "rec1", "rec2");
27
28 # 9-14 same-length alterations
29 $a[0] = 'new0';
30 check_contents("new0", "rec1", "rec2");
31 $a[1] = 'new1';
32 check_contents("new0", "new1", "rec2");
33 $a[2] = 'new2';
34 check_contents("new0", "new1", "new2");
35
36 # 15-24 lengthening alterations
37 $a[0] = 'long0';
38 check_contents("long0", "new1", "new2");
39 $a[1] = 'long1';
40 check_contents("long0", "long1", "new2");
41 $a[2] = 'long2';
42 check_contents("long0", "long1", "long2");
43 $a[1] = 'longer1';
44 check_contents("long0", "longer1", "long2");
45 $a[0] = 'longer0';
46 check_contents("longer0", "longer1", "long2");
47
48 # 25-34 shortening alterations, including truncation
49 $a[0] = 'short0';
50 check_contents("short0", "longer1", "long2");
51 $a[1] = 'short1';
52 check_contents("short0", "short1", "long2");
53 $a[2] = 'short2';
54 check_contents("short0", "short1", "short2");
55 $a[1] = 'sh1';
56 check_contents("short0", "sh1", "short2");
57 $a[0] = 'sh0';
58 check_contents("sh0", "sh1", "short2");
59
60 # (35-38) file with holes
61 $a[4] = 'rec4';
62 check_contents("sh0", "sh1", "short2", "", "rec4");
63 $a[3] = 'rec3';
64 check_contents("sh0", "sh1", "short2", "rec3", "rec4");
65
66 # (39-40) zero out file
67 @a = ();
68 check_contents();
69
70 # (41-42) insert into the middle of an empty file
71 $a[3] = "rec3";
72 check_contents("", "", "", "rec3");
73
74 # (43-47) 20020326 You thought there would be a bug in STORE where if
75 # a cached record was false, STORE wouldn't see it at all.  Yup, there is,
76 # and adding the appropriate defined() test fixes the problem.
77 undef $o;  untie @a;  1 while unlink $file;
78 $RECSEP = '0';
79 $o = tie @a, 'Tie::File', $file, 
80     recsep => $RECSEP, autochomp => 0, autodefer => 0;
81 print $o ? "ok $N\n" : "not ok $N\n";
82 $N++;
83 $#a = 2;
84 my $z = $a[1];                  # caches "0"
85 $a[2] = "oops";
86 check_contents("", "", "oops");
87 $a[1] = "bah";
88 check_contents("", "bah", "oops");
89 undef $o; untie @a;
90
91 # (48-56) 20020331 Make sure we correctly handle the case where the final
92 # record of the file is not properly terminated, Through version 0.90,
93 # we would mangle the file.
94 my $badrec = "Malformed";
95 $: = $RECSEP = Tie::File::_default_recsep();
96 # (48-50)
97 if (setup_badly_terminated_file(3)) {
98   $o = tie @a, 'Tie::File', $file,
99     recsep => $RECSEP, autochomp => 0, autodefer => 0
100     or die "Couldn't tie file: $!";
101   my $z = $a[0];
102   print $z eq "$badrec$:" ? "ok $N\n" : 
103                         "not ok $N \# got $z, expected $badrec\n";
104   $N++;
105   push @a, "next";
106   check_contents($badrec, "next");
107 }
108 # (51-52)
109 if (setup_badly_terminated_file(2)) {
110   $o = tie @a, 'Tie::File', $file,
111     recsep => $RECSEP, autochomp => 0, autodefer => 0
112     or die "Couldn't tie file: $!";
113   splice @a, 1, 0, "x", "y";
114   check_contents($badrec, "x", "y");
115 }
116 # (53-56)
117 if (setup_badly_terminated_file(4)) {
118   $o = tie @a, 'Tie::File', $file,
119     recsep => $RECSEP, autochomp => 0, autodefer => 0
120     or die "Couldn't tie file: $!";
121   my @r = splice @a, 0, 1, "x", "y";
122   my $n = @r;
123   print $n == 1 ? "ok $N\n" : "not ok $N \# expected 1 elt, got $n\n";
124   $N++;
125   print $r[0] eq "$badrec$:" ? "ok $N\n"
126     : "not ok $N \# expected <$badrec>, got <$r[0]>\n";
127   $N++;
128   check_contents("x", "y");
129 }
130
131 # (57-58) 20020402 The modification would have failed if $\ were set wrong.
132 # I hate $\.
133 if (setup_badly_terminated_file(2)) {
134   $o = tie @a, 'Tie::File', $file,
135     recsep => $RECSEP, autochomp => 0, autodefer => 0
136     or die "Couldn't tie file: $!";
137   { local $\ = "I hate \$\\.";
138     my $z = $a[0];
139   }
140   check_contents($badrec);
141 }
142
143 # (59) 20030527 Tom Christiansen pointed out that FETCH returns the wrong
144 # data on the final record of an unterminated file if the file is opened
145 # in read-only mode.  Note that the $#a is necessary here.
146 # There's special-case code to fix the final record when it is read normally.
147 # But the $#a forces it to be read from the cache, which skips the
148 # termination.
149 $badrec = "world${RECSEP}hello";
150 if (setup_badly_terminated_file(1)) {
151   tie(@a, "Tie::File", $file, mode => 0, recsep => $RECSEP)
152       or die "Couldn't tie file: $!";
153   my $z = $#a;
154   $z = $a[1];
155   print $z eq "hello" ? "ok $N\n" : 
156       "not ok $N \# got $z, expected hello\n";
157   $N++;
158 }
159
160 sub setup_badly_terminated_file {
161   my $NTESTS = shift;
162   open F, "> $file" or die "Couldn't open $file: $!";
163   binmode F;
164   print F $badrec;
165   close F;
166   unless (-s $file == length $badrec) {
167     for (1 .. $NTESTS) {
168       print "ok $N \# skipped - can't create improperly terminated file\n";
169       $N++;
170     }
171     return;
172   }
173   return 1;
174 }
175
176
177 use POSIX 'SEEK_SET';
178 sub check_contents {
179   my @c = @_;
180   my $x = join $RECSEP, @c, '';
181   local *FH = $o->{fh};
182   seek FH, 0, SEEK_SET;
183   my $a;
184   { local $/; $a = <FH> }
185
186   $a = "" unless defined $a;
187   if ($a eq $x) {
188     print "ok $N\n";
189   } else {
190     my $msg = "# expected <$x>, got <$a>";
191     ctrlfix($msg);
192     print "not ok $N $msg\n";
193   }
194   $N++;
195
196   # now check FETCH:
197   my $good = 1;
198   for (0.. $#c) {
199     unless ($a[$_] eq "$c[$_]$RECSEP") {
200       $msg = "expected $c[$_]$RECSEP, got $a[$_]";
201       ctrlfix($msg);
202       $good = 0;
203     }
204   }
205   print $good ? "ok $N\n" : "not ok $N # fetch $msg\n";
206   $N++;
207 }
208
209
210 sub ctrlfix {
211   for (@_) {
212     s/\n/\\n/g;
213     s/\r/\\r/g;
214   }
215 }
216
217
218 END {
219   undef $o;
220   untie @a;
221   1 while unlink $file;
222 }
223