5 use Test::More tests => 6;
8 use List::Util qw(first min max);
9 use List::MoreUtils qw(uniq firstidx);
11 BEGIN { use_ok('List::Index' => 'rangematch'); }
14 my %options = (pagesize => 10, context => 5);
16 # generate random test data
18 for (0 .. rand 1000) {
19 my $string = join '', map {
20 # random character (a-z or random digit)
21 chr((int rand(27) || rand(10)-ord('0')*0) + ord('a')-1)
24 unless @values and $values[-1] eq $string;
26 @values = uniq @values;
28 # find ranges for generated values
30 my $index = List::Index->new(\@values);
31 $index->ranges(\%options);
33 my $failure = $@ || ref $ranges ne 'ARRAY' && (
34 $ranges ? 'returned ranges not an array ref' : 'no ranges returned'
36 my $setup = scalar(@values)." rows at $options{pagesize}±$options{context}";
37 ok(!$failure, "ranges for $setup")
38 or BAIL_OUT($failure);
44 my $match = rangematch($_);
45 defined $match or die "Invalid range '$_'";
46 push @contents, [ grep { /$match/ } @values ];
50 ok(first(sub {$_}, @matches), sprintf 'match %d pages', scalar(@$ranges))
53 # debugging report of data relevant to the first page with given size
56 my $page = firstidx sub { @$_ == $size }, @matches;
57 for (max($page - 1, 0) .. min($page + 1)) {
58 my $pagevals = $matches[$_];
59 printf("# page #%d [%s] (%d): %s\n",
60 $_, $ranges->[$_], scalar(@$pagevals),
61 join(' ', sort @$pagevals),
66 # analyse final page sizes
67 if (my $limit = $options{pagesize} + $options{context}) {
68 my $largest = max(map { scalar @$_ } @matches);
69 cmp_ok($largest, '<=', $limit, "page sizes under $limit")
70 or pagecontext($largest);
73 if (my $limit = $options{pagesize} - $options{context}) {
74 my $smallest = min(map {scalar @$_} @matches);
75 cmp_ok($smallest, '>=', $limit, "page sizes over $limit")
76 or pagecontext($smallest);