+++: tests
[perl/list-index.git] / t / 10-ranges.t
1 #!/usr/bin/env perl
2 use strict;
3 use warnings;
4
5 use Test::More tests => 7;
6 use Test::NoWarnings;
7 use Data::Dump 'pp';
8
9 BEGIN { use_ok('List::Index'); }
10 ok(eval { List::Index->VERSION(1) }, 'version 1.00 compatibility');
11
12 subtest 'single-char alphabet' => sub {
13         plan tests => 4;
14         my @uniform = 'a'..'z';
15         my $index = List::Index->new(\@uniform) or return;
16         is_deeply(\@uniform, ['a'..'z'], 'original data unaltered');
17         is_deeply($index->ranges, ['-'], 'single page');
18         is_deeply($index->ranges({pages => 3}), [qw(-i j-q r-)], 'given pages');
19         is_deeply($index->ranges({pagesize => @uniform / 2.1}), [qw(
20                 -i j-q r-
21         )], 'equivalent pagesize');
22 };
23
24 subtest 'uniform alphanumeric' => sub {
25         plan tests => 2;
26         my $index = List::Index->new(['aa'..'zz', 1..202]) or return;
27         is_deeply($index->ranges, [qw(
28                 -.
29                 .-bp bq-dm dn-fi fj-hf hg-i j-k l-m n-os ot-qp qq-sm sn-uj uk-wf wg-x y-
30
31         )], 'default ranges');
32         is_deeply($index->ranges({pagesize => 300}), [qw(-c d-n o-)], 'large pagesize');
33 };
34
35 subtest 'context' => sub {
36         plan tests => 9;
37         my $index = List::Index->new([qw(
38                 kkeg kl km kmlu knsy    koxb kpeo kuaa kuab kuac
39                 kuapa kuq kur kux kzb   lc lg lgu lgua lguc
40                 lguq lgur lgus lgx lka  lkq lks lln llq llx
41         )]) or return;
42         is_deeply(
43                 $index->ranges({ pagesize=>10, context=>0, length=>5 }),
44                 # ranges should match offsets exactly
45                 [qw(-kuap. kuapa-lgup lguq-)],
46                 'no context'
47         );
48         is_deeply(
49                 $index->ranges({ pagesize=>10, context=>0 }),
50                 # default length limits to 4 chars
51                 [qw(-kuao kuap-lgup lguq-)],
52                 'default length'
53         );
54         is_deeply(
55                 $index->ranges({ pagesize=>10, context=>1 }),
56                 # lookbehinds aren't shorter (kuac<kuap, lguc<lguq)
57                 # 'kuap' can advance to 'kuq'
58                 [qw(-kup kuq-lgup lguq-)],
59                 'lookahead'
60         );
61 TODO: {
62         local $TODO = 'backtrack';
63         is_deeply(
64                 $index->ranges({ pagesize=>10, context=>2 }),
65                 # allowed to advance to 'kur', but provides no benefits over 'kuq'
66                 [qw(-kup kuq-lgup lguq-)],
67                 'minimal lookahead'
68         );
69 }
70         is_deeply(
71                 $index->ranges({ pagesize=>10, context=>3 }),
72                 # shorten 'kuap' to 'ku' because lookbehind is 'kp...'
73                 # 'lguq' matches 'lg', but may only backtrack to 'lgu'
74                 [qw(-kt ku-lgt lgu-)],
75                 'lookbehind'
76         );
77         is_deeply(
78                 $index->ranges({ pagesize=>10, context=>4 }),
79                 [qw(-kt ku-lf lg-)],
80                 'maximal lookahead'
81         );
82         is_deeply(
83                 $index->ranges({ pagesize=>10, context=>5 }),
84                 # after forwarding 'kuap' to 'lc'
85                 # disallow backtracking of 'lguq' to 'lc' to prevent qw[-k l-]
86                 # so only lookahead (to 'lkq') remains
87                 [qw(-k l-lj lk-)],
88                 'no lookbehind after full lookahead'
89         );
90         is_deeply(
91                 $index->ranges({ pagesize=>10, context=>9 }),
92                 # allow a single (10-9) entry (l-lf = lc) to remain
93                 [qw(-k l-lf lg-)],
94                 'lookbehind after full lookahead'
95         );
96         is_deeply(
97                 $index->ranges({ pagesize=>10, context=>10 }),
98                 # allow the last page to go back upto 'lc', replacing the 2nd page
99                 [qw(-k l-)],
100                 'full overlap'
101         );
102 };
103
104 subtest 'context' => sub {
105         plan tests => 4;
106         my $index = List::Index->new([qw(
107                 baa1 baa2  baa3 baaa  bbc cbc  daaa ea  eaaa zed
108         )]) or return;
109         is_deeply($index->ranges({pagesize => 2, context => 0}), [
110                 qw(-baa. baa.-bbb bbc-daa. daaa-eaa. eaaa-)
111         ], 'no context');
112         is_deeply($index->ranges({pagesize => 2}), [
113                 qw(-a b c d e-)
114         ], 'default context');  # context should be 1
115         is_deeply($index->ranges({pagesize => 2, context => 2}), [
116                 qw(-a b-c d e-)
117         ], 'overlap');  # first item equals second due to large context
118         is_deeply($index->ranges({pagesize => 2, context => 0, length => 1}), [
119                 qw(-a b-c d e-)
120         ], 'single char');
121
122         #pp($index->ranges({pagesize => 2, context => 2, length => 1}));
123 };
124