diff options
Diffstat (limited to 'lib/Tie/File')
-rw-r--r-- | lib/Tie/File/01_gen.t | 89 | ||||
-rw-r--r-- | lib/Tie/File/02_fetchsize.t | 47 | ||||
-rw-r--r-- | lib/Tie/File/03_longfetch.t | 38 | ||||
-rw-r--r-- | lib/Tie/File/04_splice.t | 163 | ||||
-rw-r--r-- | lib/Tie/File/05_size.t | 78 | ||||
-rw-r--r-- | lib/Tie/File/06_fixrec.t | 36 | ||||
-rw-r--r-- | lib/Tie/File/07_rv_splice.t | 157 | ||||
-rw-r--r-- | lib/Tie/File/08_ro.t | 41 | ||||
-rw-r--r-- | lib/Tie/File/09_gen_rs.t | 90 | ||||
-rw-r--r-- | lib/Tie/File/10_splice_rs.t | 162 | ||||
-rw-r--r-- | lib/Tie/File/11_rv_splice_rs.t | 157 | ||||
-rw-r--r-- | lib/Tie/File/12_longfetch_rs.t | 38 | ||||
-rw-r--r-- | lib/Tie/File/13_size_rs.t | 78 |
13 files changed, 1174 insertions, 0 deletions
diff --git a/lib/Tie/File/01_gen.t b/lib/Tie/File/01_gen.t new file mode 100644 index 0000000000..58c7a9732c --- /dev/null +++ b/lib/Tie/File/01_gen.t @@ -0,0 +1,89 @@ +#!/usr/bin/perl + +my $file = "tf$$.txt"; + +print "1..38\n"; + +my $N = 1; +use Tie::File; +print "ok $N\n"; $N++; + +my $o = tie @a, 'Tie::File', $file; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; + +# 3-4 create +$a[0] = 'rec0'; +check_contents("rec0"); + +# 5-8 append +$a[1] = 'rec1'; +check_contents("rec0", "rec1"); +$a[2] = 'rec2'; +check_contents("rec0", "rec1", "rec2"); + +# 9-14 same-length alterations +$a[0] = 'new0'; +check_contents("new0", "rec1", "rec2"); +$a[1] = 'new1'; +check_contents("new0", "new1", "rec2"); +$a[2] = 'new2'; +check_contents("new0", "new1", "new2"); + +# 15-24 lengthening alterations +$a[0] = 'long0'; +check_contents("long0", "new1", "new2"); +$a[1] = 'long1'; +check_contents("long0", "long1", "new2"); +$a[2] = 'long2'; +check_contents("long0", "long1", "long2"); +$a[1] = 'longer1'; +check_contents("long0", "longer1", "long2"); +$a[0] = 'longer0'; +check_contents("longer0", "longer1", "long2"); + +# 25-34 shortening alterations, including truncation +$a[0] = 'short0'; +check_contents("short0", "longer1", "long2"); +$a[1] = 'short1'; +check_contents("short0", "short1", "long2"); +$a[2] = 'short2'; +check_contents("short0", "short1", "short2"); +$a[1] = 'sh1'; +check_contents("short0", "sh1", "short2"); +$a[0] = 'sh0'; +check_contents("sh0", "sh1", "short2"); + +# file with holes +$a[4] = 'rec4'; +check_contents("sh0", "sh1", "short2", "", "rec4"); +$a[3] = 'rec3'; +check_contents("sh0", "sh1", "short2", "rec3", "rec4"); + + +# try inserting a record into the middle of an empty file + + +sub check_contents { + my @c = @_; + my $x = join $/, @c, ''; + local *FH; + my $open = open FH, "< $file"; + my $a; + { local $/; $a = <FH> } + print (($open && $a eq $x) ? "ok $N\n" : "not ok $N # file @c\n"); + $N++; + + # now check FETCH: + my $good = 1; + for (0.. $#c) { + $good = 0 unless $a[$_] eq "$c[$_]\n"; + } + print (($open && $good) ? "ok $N\n" : "not ok $N # fetch @c\n"); + $N++; +} + +END { + 1 while unlink $file; +} + diff --git a/lib/Tie/File/02_fetchsize.t b/lib/Tie/File/02_fetchsize.t new file mode 100644 index 0000000000..aaf44f09c7 --- /dev/null +++ b/lib/Tie/File/02_fetchsize.t @@ -0,0 +1,47 @@ +#!/usr/bin/perl + +my $file = "tf$$.txt"; +my $data = "rec1$/rec2$/rec3$/"; + +print "1..6\n"; + +my $N = 1; +use Tie::File; +print "ok $N\n"; $N++; + +open F, "> $file" or die $!; +print F $data; +close F; + + +my $o = tie @a, 'Tie::File', $file; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; + +my $n; + +# 3 test array element count +$n = @a; +print $n == 3 ? "ok $N\n" : "not ok $N # n=$n\n"; +$N++; + +# 4 same thing again +$n = @a; +print $n == 3 ? "ok $N\n" : "not ok $N # n=$n\n"; +$N++; + +# 5 test $#a notation +$n = $#a; +print $n == 2 ? "ok $N\n" : "not ok $N # n=$n\n"; +$N++; + +# 6 test looping over array elements +my $q; +for (@a) { $q .= $_ } +print $q eq $data ? "ok $N\n" : "not ok $N # n=$n\n"; +$N++; + +END { + 1 while unlink $file; +} + diff --git a/lib/Tie/File/03_longfetch.t b/lib/Tie/File/03_longfetch.t new file mode 100644 index 0000000000..7e36962e9b --- /dev/null +++ b/lib/Tie/File/03_longfetch.t @@ -0,0 +1,38 @@ +#!/usr/bin/perl +# +# Make sure we can fetch a record in the middle of the file +# before we've ever looked at any records before it +# +# (tests _fill_offsets_to() ) +# + +my $file = "tf$$.txt"; +my $data = "rec0$/rec1$/rec2$/"; + +print "1..5\n"; + +my $N = 1; +use Tie::File; +print "ok $N\n"; $N++; + +open F, "> $file" or die $!; +print F $data; +close F; + + +my $o = tie @a, 'Tie::File', $file; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; + +my $n; + +# 3-5 +for (2, 1, 0) { + print $a[$_] eq "rec$_$/" ? "ok $N\n" : "not ok $N # rec=$a[$_] ?\n"; + $N++; +} + +END { + 1 while unlink $file; +} + diff --git a/lib/Tie/File/04_splice.t b/lib/Tie/File/04_splice.t new file mode 100644 index 0000000000..c8daf0e9e3 --- /dev/null +++ b/lib/Tie/File/04_splice.t @@ -0,0 +1,163 @@ +#!/usr/bin/perl +# +# Check SPLICE function's effect on the file +# (07_rv_splice.t checks its return value) +# +# Each call to 'check_contents' actually performs two tests. +# First, it calls the tied object's own 'check_integrity' method, +# which makes sure that the contents of the read cache and offset tables +# accurately reflect the contents of the file. +# Then, it checks the actual contents of the file against the expected +# contents. + +use lib '/home/mjd/src/perl/Tie-File2/lib'; +my $file = "tf$$.txt"; +my $data = "rec0$/rec1$/rec2$/"; + +print "1..88\n"; + +my $N = 1; +use Tie::File; +print "ok $N\n"; $N++; # partial credit just for showing up + +my $o = tie @a, 'Tie::File', $file; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; + +my $n; + +# (3-22) splicing at the beginning +init_file($data); + +splice(@a, 0, 0, "rec4"); +check_contents("rec4$/$data"); +splice(@a, 0, 1, "rec5"); # same length +check_contents("rec5$/$data"); +splice(@a, 0, 1, "record5"); # longer +check_contents("record5$/$data"); + +splice(@a, 0, 1, "r5"); # shorter +check_contents("r5$/$data"); +splice(@a, 0, 1); # removal +check_contents("$data"); +splice(@a, 0, 0); # no-op +check_contents("$data"); +splice(@a, 0, 0, 'r7', 'rec8'); # insert more than one +check_contents("r7$/rec8$/$data"); +splice(@a, 0, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_contents("rec7$/record8$/rec9$/$data"); + +splice(@a, 0, 3, 'record9', 'rec10'); # delete more than insert +check_contents("record9$/rec10$/$data"); +splice(@a, 0, 2); # delete more than one +check_contents("$data"); + + +# (23-42) splicing in the middle +splice(@a, 1, 0, "rec4"); +check_contents("rec0$/rec4$/rec1$/rec2$/"); +splice(@a, 1, 1, "rec5"); # same length +check_contents("rec0$/rec5$/rec1$/rec2$/"); +splice(@a, 1, 1, "record5"); # longer +check_contents("rec0$/record5$/rec1$/rec2$/"); + +splice(@a, 1, 1, "r5"); # shorter +check_contents("rec0$/r5$/rec1$/rec2$/"); +splice(@a, 1, 1); # removal +check_contents("$data"); +splice(@a, 1, 0); # no-op +check_contents("$data"); +splice(@a, 1, 0, 'r7', 'rec8'); # insert more than one +check_contents("rec0$/r7$/rec8$/rec1$/rec2$/"); +splice(@a, 1, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_contents("rec0$/rec7$/record8$/rec9$/rec1$/rec2$/"); + +splice(@a, 1, 3, 'record9', 'rec10'); # delete more than insert +check_contents("rec0$/record9$/rec10$/rec1$/rec2$/"); +splice(@a, 1, 2); # delete more than one +check_contents("$data"); + +# (43-62) splicing at the end +splice(@a, 3, 0, "rec4"); +check_contents("$ {data}rec4$/"); +splice(@a, 3, 1, "rec5"); # same length +check_contents("$ {data}rec5$/"); +splice(@a, 3, 1, "record5"); # longer +check_contents("$ {data}record5$/"); + +splice(@a, 3, 1, "r5"); # shorter +check_contents("$ {data}r5$/"); +splice(@a, 3, 1); # removal +check_contents("$data"); +splice(@a, 3, 0); # no-op +check_contents("$data"); +splice(@a, 3, 0, 'r7', 'rec8'); # insert more than one +check_contents("$ {data}r7$/rec8$/"); +splice(@a, 3, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_contents("$ {data}rec7$/record8$/rec9$/"); + +splice(@a, 3, 3, 'record9', 'rec10'); # delete more than insert +check_contents("$ {data}record9$/rec10$/"); +splice(@a, 3, 2); # delete more than one +check_contents("$data"); + +# (63-82) splicing with negative subscript +splice(@a, -1, 0, "rec4"); +check_contents("rec0$/rec1$/rec4$/rec2$/"); +splice(@a, -1, 1, "rec5"); # same length +check_contents("rec0$/rec1$/rec4$/rec5$/"); +splice(@a, -1, 1, "record5"); # longer +check_contents("rec0$/rec1$/rec4$/record5$/"); + +splice(@a, -1, 1, "r5"); # shorter +check_contents("rec0$/rec1$/rec4$/r5$/"); +splice(@a, -1, 1); # removal +check_contents("rec0$/rec1$/rec4$/"); +splice(@a, -1, 0); # no-op +check_contents("rec0$/rec1$/rec4$/"); +splice(@a, -1, 0, 'r7', 'rec8'); # insert more than one +check_contents("rec0$/rec1$/r7$/rec8$/rec4$/"); +splice(@a, -1, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_contents("rec0$/rec1$/r7$/rec8$/rec7$/record8$/rec9$/"); + +splice(@a, -3, 3, 'record9', 'rec10'); # delete more than insert +check_contents("rec0$/rec1$/r7$/rec8$/record9$/rec10$/"); +splice(@a, -4, 3); # delete more than one +check_contents("rec0$/rec1$/rec10$/"); + +# (83-84) scrub it all out +splice(@a, 0, 3); +check_contents(""); + +# (85-86) put some back in +splice(@a, 0, 0, "rec0", "rec1"); +check_contents("rec0$/rec1$/"); + +# (87-88) what if we remove too many records? +splice(@a, 0, 17); +check_contents(""); + +sub init_file { + my $data = shift; + open F, "> $file" or die $!; + print F $data; + close F; +} + +sub check_contents { + my $x = shift; + local *FH; + my $integrity = $o->_check_integrity($file, $ENV{INTEGRITY}); + print $integrity ? "ok $N\n" : "not ok $N\n"; + $N++; + my $open = open FH, "< $file"; + my $a; + { local $/; $a = <FH> } + print (($open && $a eq $x) ? "ok $N\n" : "not ok $N\n"); + $N++; +} + +END { + 1 while unlink $file; +} + diff --git a/lib/Tie/File/05_size.t b/lib/Tie/File/05_size.t new file mode 100644 index 0000000000..4b1085876f --- /dev/null +++ b/lib/Tie/File/05_size.t @@ -0,0 +1,78 @@ +#!/usr/bin/perl +# +# Check FETCHSIZE and SETSIZE functions +# PUSH POP SHIFT UNSHIFT +# + +my $file = "tf$$.txt"; +my $data = "rec0$/rec1$/rec2$/"; +my ($o, $n); + +print "1..10\n"; + +my $N = 1; +use Tie::File; +print "ok $N\n"; $N++; + +# 2-3 FETCHSIZE 0-length file +open F, "> $file" or die $!; +close F; +$o = tie @a, 'Tie::File', $file; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; +$n = @a; +print $n == 0 ? "ok $N\n" : "not ok $N # $n, s/b 0\n"; +$N++; + +# Reset everything +undef $o; +untie @a; + +# 4-5 FETCHSIZE positive-length file +open F, "> $file" or die $!; +print F $data; +close F; +$o = tie @a, 'Tie::File', $file; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; +$n = @a; +print $n == 3 ? "ok $N\n" : "not ok $N # $n, s/b 0\n"; +$N++; + +# STORESIZE +# 6 Make it longer: +$#a = 4; +check_contents("$data$/$/"); + +# 7 Make it longer again: +$#a = 6; +check_contents("$data$/$/$/$/"); + +# 8 Make it shorter: +$#a = 4; +check_contents("$data$/$/"); + +# 9 Make it shorter again: +$#a = 2; +check_contents($data); + +# 10 Get rid of it completely: +$#a = -1; +check_contents(''); + + +sub check_contents { + my $x = shift; + local *FH; + my $open = open FH, "< $file"; + my $a; + { local $/; $a = <FH> } + print (($open && $a eq $x) ? "ok $N\n" : "not ok $N\n"); + $N++; +} + + +END { + 1 while unlink $file; +} + diff --git a/lib/Tie/File/06_fixrec.t b/lib/Tie/File/06_fixrec.t new file mode 100644 index 0000000000..4a8ceb8d55 --- /dev/null +++ b/lib/Tie/File/06_fixrec.t @@ -0,0 +1,36 @@ +#!/usr/bin/perl + +my $file = "tf$$.txt"; + +print "1..5\n"; + +my $N = 1; +use Tie::File; +print "ok $N\n"; $N++; + +my $o = tie @a, 'Tie::File', $file; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; + +$a[0] = 'rec0'; +check_contents("rec0$/"); +$a[1] = "rec1$/"; +check_contents("rec0$/rec1$/"); +$a[2] = "rec2$/$/"; # should we detect this? +check_contents("rec0$/rec1$/rec2$/$/"); + +sub check_contents { + my $x = shift; + local *FH; + my $open = open FH, "< $file"; + my $a; + { local $/; $a = <FH> } + print (($open && $a eq $x) ? "ok $N\n" : "not ok $N\n"); + $N++; +} + + +END { + 1 while unlink $file; +} + diff --git a/lib/Tie/File/07_rv_splice.t b/lib/Tie/File/07_rv_splice.t new file mode 100644 index 0000000000..feaf0096bf --- /dev/null +++ b/lib/Tie/File/07_rv_splice.t @@ -0,0 +1,157 @@ +#!/usr/bin/perl +# +# Check SPLICE function's return value +# (04_splice.t checks its effect on the file) +# + +my $file = "tf$$.txt"; +my $data = "rec0$/rec1$/rec2$/"; + +print "1..45\n"; + +my $N = 1; +use Tie::File; +print "ok $N\n"; $N++; # partial credit just for showing up + +my $o = tie @a, 'Tie::File', $file; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; + +my $n; + +# (3-12) splicing at the beginning +init_file($data); + +@r = splice(@a, 0, 0, "rec4"); +check_result(); +@r = splice(@a, 0, 1, "rec5"); # same length +check_result("rec4"); +@r = splice(@a, 0, 1, "record5"); # longer +check_result("rec5"); + +@r = splice(@a, 0, 1, "r5"); # shorter +check_result("record5"); +@r = splice(@a, 0, 1); # removal +check_result("r5"); +@r = splice(@a, 0, 0); # no-op +check_result(); +@r = splice(@a, 0, 0, 'r7', 'rec8'); # insert more than one +check_result(); +@r = splice(@a, 0, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_result('r7', 'rec8'); + +@r = splice(@a, 0, 3, 'record9', 'rec10'); # delete more than insert +check_result('rec7', 'record8', 'rec9'); +@r = splice(@a, 0, 2); # delete more than one +check_result('record9', 'rec10'); + + +# (13-22) splicing in the middle +@r = splice(@a, 1, 0, "rec4"); +check_result(); +@r = splice(@a, 1, 1, "rec5"); # same length +check_result('rec4'); +@r = splice(@a, 1, 1, "record5"); # longer +check_result('rec5'); + +@r = splice(@a, 1, 1, "r5"); # shorter +check_result("record5"); +@r = splice(@a, 1, 1); # removal +check_result("r5"); +@r = splice(@a, 1, 0); # no-op +check_result(); +@r = splice(@a, 1, 0, 'r7', 'rec8'); # insert more than one +check_result(); +@r = splice(@a, 1, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_result('r7', 'rec8'); + +@r = splice(@a, 1, 3, 'record9', 'rec10'); # delete more than insert +check_result('rec7', 'record8', 'rec9'); +@r = splice(@a, 1, 2); # delete more than one +check_result('record9','rec10'); + +# (23-32) splicing at the end +@r = splice(@a, 3, 0, "rec4"); +check_result(); +@r = splice(@a, 3, 1, "rec5"); # same length +check_result('rec4'); +@r = splice(@a, 3, 1, "record5"); # longer +check_result('rec5'); + +@r = splice(@a, 3, 1, "r5"); # shorter +check_result('record5'); +@r = splice(@a, 3, 1); # removal +check_result('r5'); +@r = splice(@a, 3, 0); # no-op +check_result(); +@r = splice(@a, 3, 0, 'r7', 'rec8'); # insert more than one +check_result(); +@r = splice(@a, 3, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_result('r7', 'rec8'); + +@r = splice(@a, 3, 3, 'record9', 'rec10'); # delete more than insert +check_result('rec7', 'record8', 'rec9'); +@r = splice(@a, 3, 2); # delete more than one +check_result('record9', 'rec10'); + +# (33-42) splicing with negative subscript +@r = splice(@a, -1, 0, "rec4"); +check_result(); +@r = splice(@a, -1, 1, "rec5"); # same length +check_result('rec2'); +@r = splice(@a, -1, 1, "record5"); # longer +check_result("rec5"); + +@r = splice(@a, -1, 1, "r5"); # shorter +check_result("record5"); +@r = splice(@a, -1, 1); # removal +check_result("r5"); +@r = splice(@a, -1, 0); # no-op +check_result(); +@r = splice(@a, -1, 0, 'r7', 'rec8'); # insert more than one +check_result(); +@r = splice(@a, -1, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_result('rec4'); + +@r = splice(@a, -3, 3, 'record9', 'rec10'); # delete more than insert +check_result('rec7', 'record8', 'rec9'); +@r = splice(@a, -4, 3); # delete more than one +check_result('r7', 'rec8', 'record9'); + +# (43) scrub it all out +@r = splice(@a, 0, 3); +check_result('rec0', 'rec1', 'rec10'); + +# (44) put some back in +@r = splice(@a, 0, 0, "rec0", "rec1"); +check_result(); + +# (45) what if we remove too many records? +@r = splice(@a, 0, 17); +check_result('rec0', 'rec1'); + +sub init_file { + my $data = shift; + open F, "> $file" or die $!; + print F $data; + close F; +} + +# actual results are in @r. +# expected results are in @_ +sub check_result { + my @x = @_; + chomp @r; + my $good = 1; + $good = 0 unless @r == @x; + for my $i (0 .. $#r) { + $good = 0 unless $r[$i] eq $x[$i]; + } + print $good ? "ok $N\n" : "not ok $N \# was (@r); should be (@x)\n"; + $N++; +} + +END { + 1 while unlink $file; +} + diff --git a/lib/Tie/File/08_ro.t b/lib/Tie/File/08_ro.t new file mode 100644 index 0000000000..dde7f20f14 --- /dev/null +++ b/lib/Tie/File/08_ro.t @@ -0,0 +1,41 @@ +#!/usr/bin/perl +# +# Make sure it works to open the file in read-only mode +# + +my $file = "tf$$.txt"; + +print "1..9\n"; + +my $N = 1; +use Tie::File; +use Fcntl 'O_RDONLY'; +print "ok $N\n"; $N++; + +my @items = qw(Gold Frankincense Myrrh Ivory Apes Peacocks); +init_file(join $/, @items, ''); + +my $o = tie @a, 'Tie::File', $file, mode => O_RDONLY; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; + +$#a == $#items ? print "ok $N\n" : print "not ok $N\n"; +$N++; + +for my $i (0..$#items) { + ("$items[$i]$/" eq $a[$i]) ? print "ok $N\n" : print "not ok $N\n"; + $N++; +} + +sub init_file { + my $data = shift; + open F, "> $file" or die $!; + print F $data; + close F; +} + + +END { + 1 while unlink $file; +} + diff --git a/lib/Tie/File/09_gen_rs.t b/lib/Tie/File/09_gen_rs.t new file mode 100644 index 0000000000..cf797360e5 --- /dev/null +++ b/lib/Tie/File/09_gen_rs.t @@ -0,0 +1,90 @@ +#!/usr/bin/perl + +my $file = "tf$$.txt"; + +print "1..38\n"; + +my $N = 1; +use Tie::File; +print "ok $N\n"; $N++; + +my $o = tie @a, 'Tie::File', $file, recsep => 'blah'; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; + + +# 3-4 create +$a[0] = 'rec0'; +check_contents("rec0"); + +# 5-8 append +$a[1] = 'rec1'; +check_contents("rec0", "rec1"); +$a[2] = 'rec2'; +check_contents("rec0", "rec1", "rec2"); + +# 9-14 same-length alterations +$a[0] = 'new0'; +check_contents("new0", "rec1", "rec2"); +$a[1] = 'new1'; +check_contents("new0", "new1", "rec2"); +$a[2] = 'new2'; +check_contents("new0", "new1", "new2"); + +# 15-24 lengthening alterations +$a[0] = 'long0'; +check_contents("long0", "new1", "new2"); +$a[1] = 'long1'; +check_contents("long0", "long1", "new2"); +$a[2] = 'long2'; +check_contents("long0", "long1", "long2"); +$a[1] = 'longer1'; +check_contents("long0", "longer1", "long2"); +$a[0] = 'longer0'; +check_contents("longer0", "longer1", "long2"); + +# 25-34 shortening alterations, including truncation +$a[0] = 'short0'; +check_contents("short0", "longer1", "long2"); +$a[1] = 'short1'; +check_contents("short0", "short1", "long2"); +$a[2] = 'short2'; +check_contents("short0", "short1", "short2"); +$a[1] = 'sh1'; +check_contents("short0", "sh1", "short2"); +$a[0] = 'sh0'; +check_contents("sh0", "sh1", "short2"); + +# file with holes +$a[4] = 'rec4'; +check_contents("sh0", "sh1", "short2", "", "rec4"); +$a[3] = 'rec3'; +check_contents("sh0", "sh1", "short2", "rec3", "rec4"); + + +# try inserting a record into the middle of an empty file + + +sub check_contents { + my @c = @_; + my $x = join 'blah', @c, ''; + local *FH; + my $open = open FH, "< $file"; + my $a; + { local $/; $a = <FH> } + print (($open && $a eq $x) ? "ok $N\n" : "not ok $N # file @c\n"); + $N++; + + # now check FETCH: + my $good = 1; + for (0.. $#c) { + $good = 0 unless $a[$_] eq "$c[$_]blah"; + } + print (($open && $good) ? "ok $N\n" : "not ok $N # fetch @c\n"); + $N++; +} + +END { + 1 while unlink $file; +} + diff --git a/lib/Tie/File/10_splice_rs.t b/lib/Tie/File/10_splice_rs.t new file mode 100644 index 0000000000..1e1b545ccd --- /dev/null +++ b/lib/Tie/File/10_splice_rs.t @@ -0,0 +1,162 @@ +#!/usr/bin/perl +# +# Check SPLICE function's effect on the file +# (07_rv_splice.t checks its return value) +# +# Each call to 'check_contents' actually performs two tests. +# First, it calls the tied object's own 'check_integrity' method, +# which makes sure that the contents of the read cache and offset tables +# accurately reflect the contents of the file. +# Then, it checks the actual contents of the file against the expected +# contents. + +my $file = "tf$$.txt"; +my $data = "rec0blahrec1blahrec2blah"; + +print "1..88\n"; + +my $N = 1; +use Tie::File; +print "ok $N\n"; $N++; # partial credit just for showing up + +my $o = tie @a, 'Tie::File', $file, recsep => 'blah'; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; + +my $n; + +# (3-22) splicing at the beginning +init_file($data); + +splice(@a, 0, 0, "rec4"); +check_contents("rec4blah$data"); +splice(@a, 0, 1, "rec5"); # same length +check_contents("rec5blah$data"); +splice(@a, 0, 1, "record5"); # longer +check_contents("record5blah$data"); + +splice(@a, 0, 1, "r5"); # shorter +check_contents("r5blah$data"); +splice(@a, 0, 1); # removal +check_contents("$data"); +splice(@a, 0, 0); # no-op +check_contents("$data"); +splice(@a, 0, 0, 'r7', 'rec8'); # insert more than one +check_contents("r7blahrec8blah$data"); +splice(@a, 0, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_contents("rec7blahrecord8blahrec9blah$data"); + +splice(@a, 0, 3, 'record9', 'rec10'); # delete more than insert +check_contents("record9blahrec10blah$data"); +splice(@a, 0, 2); # delete more than one +check_contents("$data"); + + +# (23-42) splicing in the middle +splice(@a, 1, 0, "rec4"); +check_contents("rec0blahrec4blahrec1blahrec2blah"); +splice(@a, 1, 1, "rec5"); # same length +check_contents("rec0blahrec5blahrec1blahrec2blah"); +splice(@a, 1, 1, "record5"); # longer +check_contents("rec0blahrecord5blahrec1blahrec2blah"); + +splice(@a, 1, 1, "r5"); # shorter +check_contents("rec0blahr5blahrec1blahrec2blah"); +splice(@a, 1, 1); # removal +check_contents("$data"); +splice(@a, 1, 0); # no-op +check_contents("$data"); +splice(@a, 1, 0, 'r7', 'rec8'); # insert more than one +check_contents("rec0blahr7blahrec8blahrec1blahrec2blah"); +splice(@a, 1, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_contents("rec0blahrec7blahrecord8blahrec9blahrec1blahrec2blah"); + +splice(@a, 1, 3, 'record9', 'rec10'); # delete more than insert +check_contents("rec0blahrecord9blahrec10blahrec1blahrec2blah"); +splice(@a, 1, 2); # delete more than one +check_contents("$data"); + +# (43-62) splicing at the end +splice(@a, 3, 0, "rec4"); +check_contents("$ {data}rec4blah"); +splice(@a, 3, 1, "rec5"); # same length +check_contents("$ {data}rec5blah"); +splice(@a, 3, 1, "record5"); # longer +check_contents("$ {data}record5blah"); + +splice(@a, 3, 1, "r5"); # shorter +check_contents("$ {data}r5blah"); +splice(@a, 3, 1); # removal +check_contents("$data"); +splice(@a, 3, 0); # no-op +check_contents("$data"); +splice(@a, 3, 0, 'r7', 'rec8'); # insert more than one +check_contents("$ {data}r7blahrec8blah"); +splice(@a, 3, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_contents("$ {data}rec7blahrecord8blahrec9blah"); + +splice(@a, 3, 3, 'record9', 'rec10'); # delete more than insert +check_contents("$ {data}record9blahrec10blah"); +splice(@a, 3, 2); # delete more than one +check_contents("$data"); + +# (63-82) splicing with negative subscript +splice(@a, -1, 0, "rec4"); +check_contents("rec0blahrec1blahrec4blahrec2blah"); +splice(@a, -1, 1, "rec5"); # same length +check_contents("rec0blahrec1blahrec4blahrec5blah"); +splice(@a, -1, 1, "record5"); # longer +check_contents("rec0blahrec1blahrec4blahrecord5blah"); + +splice(@a, -1, 1, "r5"); # shorter +check_contents("rec0blahrec1blahrec4blahr5blah"); +splice(@a, -1, 1); # removal +check_contents("rec0blahrec1blahrec4blah"); +splice(@a, -1, 0); # no-op +check_contents("rec0blahrec1blahrec4blah"); +splice(@a, -1, 0, 'r7', 'rec8'); # insert more than one +check_contents("rec0blahrec1blahr7blahrec8blahrec4blah"); +splice(@a, -1, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_contents("rec0blahrec1blahr7blahrec8blahrec7blahrecord8blahrec9blah"); + +splice(@a, -3, 3, 'record9', 'rec10'); # delete more than insert +check_contents("rec0blahrec1blahr7blahrec8blahrecord9blahrec10blah"); +splice(@a, -4, 3); # delete more than one +check_contents("rec0blahrec1blahrec10blah"); + +# (83-84) scrub it all out +splice(@a, 0, 3); +check_contents(""); + +# (85-86) put some back in +splice(@a, 0, 0, "rec0", "rec1"); +check_contents("rec0blahrec1blah"); + +# (87-88) what if we remove too many records? +splice(@a, 0, 17); +check_contents(""); + +sub init_file { + my $data = shift; + open F, "> $file" or die $!; + print F $data; + close F; +} + +sub check_contents { + my $x = shift; + local *FH; + my $integrity = $o->_check_integrity($file, $ENV{INTEGRITY}); + print $integrity ? "ok $N\n" : "not ok $N\n"; + $N++; + my $open = open FH, "< $file"; + my $a; + { local $/; $a = <FH> } + print (($open && $a eq $x) ? "ok $N\n" : "not ok $N\n"); + $N++; +} + +END { + 1 while unlink $file; +} + diff --git a/lib/Tie/File/11_rv_splice_rs.t b/lib/Tie/File/11_rv_splice_rs.t new file mode 100644 index 0000000000..f78c25c8d8 --- /dev/null +++ b/lib/Tie/File/11_rv_splice_rs.t @@ -0,0 +1,157 @@ +#!/usr/bin/perl +# +# Check SPLICE function's return value +# (04_splice.t checks its effect on the file) +# + +my $file = "tf$$.txt"; +my $data = "rec0blahrec1blahrec2blah"; + +print "1..45\n"; + +my $N = 1; +use Tie::File; +print "ok $N\n"; $N++; # partial credit just for showing up + +my $o = tie @a, 'Tie::File', $file, recsep => 'blah'; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; + +my $n; + +# (3-12) splicing at the beginning +init_file($data); + +@r = splice(@a, 0, 0, "rec4"); +check_result(); +@r = splice(@a, 0, 1, "rec5"); # same length +check_result("rec4"); +@r = splice(@a, 0, 1, "record5"); # longer +check_result("rec5"); + +@r = splice(@a, 0, 1, "r5"); # shorter +check_result("record5"); +@r = splice(@a, 0, 1); # removal +check_result("r5"); +@r = splice(@a, 0, 0); # no-op +check_result(); +@r = splice(@a, 0, 0, 'r7', 'rec8'); # insert more than one +check_result(); +@r = splice(@a, 0, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_result('r7', 'rec8'); + +@r = splice(@a, 0, 3, 'record9', 'rec10'); # delete more than insert +check_result('rec7', 'record8', 'rec9'); +@r = splice(@a, 0, 2); # delete more than one +check_result('record9', 'rec10'); + + +# (13-22) splicing in the middle +@r = splice(@a, 1, 0, "rec4"); +check_result(); +@r = splice(@a, 1, 1, "rec5"); # same length +check_result('rec4'); +@r = splice(@a, 1, 1, "record5"); # longer +check_result('rec5'); + +@r = splice(@a, 1, 1, "r5"); # shorter +check_result("record5"); +@r = splice(@a, 1, 1); # removal +check_result("r5"); +@r = splice(@a, 1, 0); # no-op +check_result(); +@r = splice(@a, 1, 0, 'r7', 'rec8'); # insert more than one +check_result(); +@r = splice(@a, 1, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_result('r7', 'rec8'); + +@r = splice(@a, 1, 3, 'record9', 'rec10'); # delete more than insert +check_result('rec7', 'record8', 'rec9'); +@r = splice(@a, 1, 2); # delete more than one +check_result('record9','rec10'); + +# (23-32) splicing at the end +@r = splice(@a, 3, 0, "rec4"); +check_result(); +@r = splice(@a, 3, 1, "rec5"); # same length +check_result('rec4'); +@r = splice(@a, 3, 1, "record5"); # longer +check_result('rec5'); + +@r = splice(@a, 3, 1, "r5"); # shorter +check_result('record5'); +@r = splice(@a, 3, 1); # removal +check_result('r5'); +@r = splice(@a, 3, 0); # no-op +check_result(); +@r = splice(@a, 3, 0, 'r7', 'rec8'); # insert more than one +check_result(); +@r = splice(@a, 3, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_result('r7', 'rec8'); + +@r = splice(@a, 3, 3, 'record9', 'rec10'); # delete more than insert +check_result('rec7', 'record8', 'rec9'); +@r = splice(@a, 3, 2); # delete more than one +check_result('record9', 'rec10'); + +# (33-42) splicing with negative subscript +@r = splice(@a, -1, 0, "rec4"); +check_result(); +@r = splice(@a, -1, 1, "rec5"); # same length +check_result('rec2'); +@r = splice(@a, -1, 1, "record5"); # longer +check_result("rec5"); + +@r = splice(@a, -1, 1, "r5"); # shorter +check_result("record5"); +@r = splice(@a, -1, 1); # removal +check_result("r5"); +@r = splice(@a, -1, 0); # no-op +check_result(); +@r = splice(@a, -1, 0, 'r7', 'rec8'); # insert more than one +check_result(); +@r = splice(@a, -1, 2, 'rec7', 'record8', 'rec9'); # insert more than delete +check_result('rec4'); + +@r = splice(@a, -3, 3, 'record9', 'rec10'); # delete more than insert +check_result('rec7', 'record8', 'rec9'); +@r = splice(@a, -4, 3); # delete more than one +check_result('r7', 'rec8', 'record9'); + +# (43) scrub it all out +@r = splice(@a, 0, 3); +check_result('rec0', 'rec1', 'rec10'); + +# (44) put some back in +@r = splice(@a, 0, 0, "rec0", "rec1"); +check_result(); + +# (45) what if we remove too many records? +@r = splice(@a, 0, 17); +check_result('rec0', 'rec1'); + +sub init_file { + my $data = shift; + open F, "> $file" or die $!; + print F $data; + close F; +} + +# actual results are in @r. +# expected results are in @_ +sub check_result { + my @x = @_; + s/blah$// for @r; + my $good = 1; + $good = 0 unless @r == @x; + for my $i (0 .. $#r) { + $good = 0 unless $r[$i] eq $x[$i]; + } + print $good ? "ok $N\n" : "not ok $N \# was (@r); should be (@x)\n"; + $N++; +} + +END { + 1 while unlink $file; +} + diff --git a/lib/Tie/File/12_longfetch_rs.t b/lib/Tie/File/12_longfetch_rs.t new file mode 100644 index 0000000000..60f1fd1a50 --- /dev/null +++ b/lib/Tie/File/12_longfetch_rs.t @@ -0,0 +1,38 @@ +#!/usr/bin/perl +# +# Make sure we can fetch a record in the middle of the file +# before we've ever looked at any records before it +# +# (tests _fill_offsets_to() ) +# + +my $file = "tf$$.txt"; +my $data = "rec0blahrec1blahrec2blah"; + +print "1..5\n"; + +my $N = 1; +use Tie::File; +print "ok $N\n"; $N++; + +open F, "> $file" or die $!; +print F $data; +close F; + + +my $o = tie @a, 'Tie::File', $file, recsep => 'blah'; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; + +my $n; + +# 3-5 +for (2, 1, 0) { + print $a[$_] eq "rec${_}blah" ? "ok $N\n" : "not ok $N # rec=$a[$_] ?\n"; + $N++; +} + +END { + 1 while unlink $file; +} + diff --git a/lib/Tie/File/13_size_rs.t b/lib/Tie/File/13_size_rs.t new file mode 100644 index 0000000000..254f3ab0b0 --- /dev/null +++ b/lib/Tie/File/13_size_rs.t @@ -0,0 +1,78 @@ +#!/usr/bin/perl +# +# Check FETCHSIZE and SETSIZE functions +# PUSH POP SHIFT UNSHIFT +# + +my $file = "tf$$.txt"; +my $data = "rec0blahrec1blahrec2blah"; +my ($o, $n); + +print "1..10\n"; + +my $N = 1; +use Tie::File; +print "ok $N\n"; $N++; + +# 2-3 FETCHSIZE 0-length file +open F, "> $file" or die $!; +close F; +$o = tie @a, 'Tie::File', $file, recsep => 'blah'; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; +$n = @a; +print $n == 0 ? "ok $N\n" : "not ok $N # $n, s/b 0\n"; +$N++; + +# Reset everything +undef $o; +untie @a; + +# 4-5 FETCHSIZE positive-length file +open F, "> $file" or die $!; +print F $data; +close F; +$o = tie @a, 'Tie::File', $file, recsep => 'blah'; +print $o ? "ok $N\n" : "not ok $N\n"; +$N++; +$n = @a; +print $n == 3 ? "ok $N\n" : "not ok $N # $n, s/b 0\n"; +$N++; + +# STORESIZE +# 6 Make it longer: +$#a = 4; +check_contents("${data}blahblah"); + +# 7 Make it longer again: +$#a = 6; +check_contents("${data}blahblahblahblah"); + +# 8 Make it shorter: +$#a = 4; +check_contents("${data}blahblah"); + +# 9 Make it shorter again: +$#a = 2; +check_contents($data); + +# 10 Get rid of it completely: +$#a = -1; +check_contents(''); + + +sub check_contents { + my $x = shift; + local *FH; + my $open = open FH, "< $file"; + my $a; + { local $/; $a = <FH> } + print (($open && $a eq $x) ? "ok $N\n" : "not ok $N\n"); + $N++; +} + + +END { + 1 while unlink $file; +} + |