xref: /openbsd-src/gnu/usr.bin/perl/dist/Tie-File/t/41_heap.t (revision de8cc8edbc71bd3e3bc7fbffa27ba0e564c37d8b)
1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6#
7# Unit tests for heap implementation
8#
9# Test the following methods:
10# new
11# is_empty
12# empty
13# insert
14# remove
15# popheap
16# promote
17# lookup
18# set_val
19# rekey
20# expire_order
21
22
23# Finish these later.
24
25# They're nonurgent because the important heap stuff is extensively
26# tested by tests 19, 20, 24, 30, 32, 33, and 40, as well as by pretty
27# much everything else.
28print "1..1\n";
29
30
31my ($N, @R, $Q, $ar) = (1);
32
33use Tie::File;
34print "ok $N\n";
35$N++;
36exit;
37
38__END__
39
40my @HEAP_MOVE;
41sub Fake::Cache::_heap_move { push @HEAP_MOVE, @_ }
42
43my $h = Tie::File::Heap->new(bless [] => 'Fake::Cache');
44print "ok $N\n";
45$N++;
46
47# (3) Are all the methods there?
48{
49  my $good = 1;
50  for my $meth (qw(new is_empty empty lookup insert remove popheap
51                   promote set_val rekey expire_order)) {
52    unless ($h->can($meth)) {
53      print STDERR "# Method '$meth' is missing.\n";
54      $good = 0;
55    }
56  }
57  print $good ? "ok $N\n" : "not ok $N\n";
58  $N++;
59}
60
61# (4) Straight insert and removal FIFO test
62$ar = 'a0';
63for (1..10) {
64  $h->insert($_, $ar++);
65}
66for (1..10) {
67  push @R, $h->popheap;
68}
69$iota = iota('a',9);
70print "@R" eq $iota
71  ? "ok $N\n" : "not ok $N \# expected ($iota), got (@R)\n";
72$N++;
73
74# (5) Remove from empty heap
75$n = $h->popheap;
76print ! defined $n ? "ok $N\n" : "not ok $N \# expected UNDEF, got $n";
77$N++;
78
79# (6) Interleaved insert and removal
80$Q = 0;
81@R = ();
82for my $i (1..4) {
83  for my $j (1..$i) {
84    $h->insert($Q, "b$Q");
85    $Q++;
86  }
87  for my $j (1..$i) {
88    push @R, $h->popheap;
89  }
90}
91$iota = iota('b', 9);
92print "@R" eq $iota ? "ok $N\n" : "not ok $N \# expected ($iota), got (@R)\n";
93$N++;
94
95# (7) It should be empty now
96print $h->is_empty ? "ok $N\n" : "not ok $N\n";
97$N++;
98
99# (8) Insert and delete
100$Q = 1;
101for (1..10) {
102  $h->insert($_, "c$Q");
103  $Q++;
104}
105for (2, 4, 6, 8, 10) {
106  $h->remove($_);
107}
108@R = ();
109push @R, $n while defined ($n = $h->popheap);
110print "@R" eq "c1 c3 c5 c7 c9" ?
111  "ok $N\n" : "not ok $N \# expected (c1 c3 c5 c7 c9), got (@R)\n";
112$N++;
113
114# (9) Interleaved insert and delete
115$Q = 1; my $QQ = 1;
116@R = ();
117for my $i (1..4) {
118  for my $j (1..$i) {
119    $h->insert($Q, "d$Q");
120    $Q++;
121  }
122  for my $j (1..$i) {
123    $h->remove($QQ) if $QQ % 2 == 0;
124    $QQ++;
125  }
126}
127push @R, $n while defined ($n = $h->popheap);
128print "@R" eq "d1 d3 d5 d7 d9" ?
129  "ok $N\n" : "not ok $N \# expected (d1 d3 d5 d7 d9), got (@R)\n";
130$N++;
131
132# (10) Promote
133$Q = 1;
134for (1..10) {
135  $h->insert($_, "e$Q");
136  $Q++;
137}
138for (2, 4, 6, 8, 10) {
139  $h->promote($_);
140}
141@R = ();
142push @R, $n while defined ($n = $h->popheap);
143print "@R" eq "e1 e3 e5 e7 e9 e2 e4 e6 e8 e10" ?
144  "ok $N\n" :
145  "not ok $N \# expected (e1 e3 e5 e7 e9 e2 e4 e6 e8 e10), got (@R)\n";
146$N++;
147
148# (11-15) Lookup
149$Q = 1;
150for (1..10) {
151  $h->insert($_, "f$Q");
152  $Q++;
153}
154for (2, 4, 6, 4, 8) {
155  my $r = $h->lookup($_);
156  print $r eq "f$_" ? "ok $N\n" : "not ok $N \# expected f$_, got $r\n";
157  $N++;
158}
159
160# (16) It shouldn't be empty
161print ! $h->is_empty ? "ok $N\n" : "not ok $N\n";
162$N++;
163
164# (17) Lookup should have promoted the looked-up records
165@R = ();
166push @R, $n while defined ($n = $h->popheap);
167print "@R" eq "f1 f3 f5 f7 f9 f10 f2 f6 f4 f8" ?
168  "ok $N\n" :
169  "not ok $N \# expected (f1 f3 f5 f7 f9 f10 f2 f6 f4 f8), got (@R)\n";
170$N++;
171
172# (18-19) Typical 'rekey' operation
173$Q = 1;
174for (1..10) {
175  $h->insert($_, "g$Q");
176  $Q++;
177}
178
179$h->rekey([6,7,8,9,10], [8,9,10,11,12]);
180my %x = qw(1 g1 2 g2  3 g3  4 g4  5 g5
181           8 g6 9 g7 10 g8 11 g9 12 g10);
182{
183  my $good = 1;
184  for my $k (keys %x) {
185    my $v = $h->lookup($k);
186    $v = "UNDEF" unless defined $v;
187    unless ($v eq $x{$k}) {
188      print "# looked up $k, got $v, expected $x{$k}\n";
189      $good = 0;
190    }
191  }
192  print $good ? "ok $N\n" : "not ok $N\n";
193  $N++;
194}
195{
196  my $good = 1;
197  for my $k (6, 7) {
198    my $v = $h->lookup($k);
199    if (defined $v) {
200      print "# looked up $k, got $v, should have been undef\n";
201      $good = 0;
202    }
203  }
204  print $good ? "ok $N\n" : "not ok $N\n";
205  $N++;
206}
207
208# (20) keys
209@R = sort { $a <=> $b } $h->keys;
210print "@R" eq "1 2 3 4 5 8 9 10 11 12" ?
211  "ok $N\n" :
212  "not ok $N \# expected (1 2 3 4 5 8 9 10 11 12) got (@R)\n";
213$N++;
214
215# (21) update
216for (1..5, 8..12) {
217  $h->update($_, "h$_");
218}
219@R = ();
220for (sort { $a <=> $b } $h->keys) {
221  push @R, $h->lookup($_);
222}
223print "@R" eq "h1 h2 h3 h4 h5 h8 h9 h10 h11 h12" ?
224  "ok $N\n" :
225  "not ok $N \# expected (h1 h2 h3 h4 h5 h8 h9 h10 h11 h12) got (@R)\n";
226$N++;
227
228# (22-23) bytes
229my $B;
230$B = $h->bytes;
231print $B == 23 ? "ok $N\n" : "not ok $N \# expected 23, got $B\n";
232$N++;
233$h->update('12', "yobgorgle");
234$B = $h->bytes;
235print $B == 29 ? "ok $N\n" : "not ok $N \# expected 29, got $B\n";
236$N++;
237
238# (24-25) empty
239$h->empty;
240print $h->is_empty ? "ok $N\n" : "not ok $N\n";
241$N++;
242$n = $h->popheap;
243print ! defined $n ? "ok $N\n" : "not ok $N \# expected UNDEF, got $n";
244$N++;
245
246# (26) very weak testing of DESTROY
247undef $h;
248# are we still alive?
249print "ok $N\n";
250$N++;
251
252
253sub iota {
254  my ($p, $n) = @_;
255  my $r;
256  my $i = 0;
257  while ($i <= $n) {
258    $r .= "$p$i ";
259    $i++;
260  }
261  chop $r;
262  $r;
263}
264