cleanup context variables
[perl/list-index.git] / t / 10-ranges.t
index 84f4dbbc7f64dca807831325c08d2a4f29b9aece..a3949453e05ef770b19bdadb884ff6a09feeb283 100644 (file)
@@ -2,7 +2,7 @@
 use strict;
 use warnings;
 
 use strict;
 use warnings;
 
-use Test::More tests => 7;
+use Test::More tests => 9;
 use Test::NoWarnings;
 use Data::Dump 'pp';
 
 use Test::NoWarnings;
 use Data::Dump 'pp';
 
@@ -10,49 +10,71 @@ BEGIN { use_ok('List::Index'); }
 ok(eval { List::Index->VERSION(1) }, 'version 1.00 compatibility');
 
 subtest 'single-char alphabet' => sub {
 ok(eval { List::Index->VERSION(1) }, 'version 1.00 compatibility');
 
 subtest 'single-char alphabet' => sub {
-       plan tests => 4;
-       my @uniform = 'a'..'z';
-       my $index = List::Index->new(\@uniform) or return;
-       is_deeply(\@uniform, ['a'..'z'], 'original data unaltered');
-       is_deeply($index->ranges, ['-'], 'single page');
-       is_deeply($index->ranges({pages => 3}), [qw(-i j-q r-)], 'given pages');
-       is_deeply($index->ranges({pagesize => @uniform / 2.1}), [qw(
-               -i j-q r-
-       )], 'equivalent pagesize');
+       plan tests => 5;
+       my @data = ('a'..'z');
+
+       is_deeply(List::Index->new->ranges(\@data), ['-'], 'single page');
+       is_deeply(\@data, ['a'..'z'], 'original data unaltered');
+       is_deeply(
+               List::Index->new({ pages => 3 })->ranges(\@data),
+               [qw(-i j-q r-)],
+               'given pages'
+       );
+       is_deeply(
+               List::Index->new({ pagesize => @data / 2.1 })->ranges(\@data),
+               [qw(-i j-q r-)],
+               'equivalent pagesize'
+       );
+       is_deeply(
+               List::Index->new({ pages => 500 })->ranges(\@data),
+               ['-a', 'b'..'y', 'z-'],
+               'max pages'
+       );
 };
 
 subtest 'uniform alphanumeric' => sub {
        plan tests => 2;
 };
 
 subtest 'uniform alphanumeric' => sub {
        plan tests => 2;
-       my $index = List::Index->new(['aa'..'zz', 1..202]) or return;
-       is_deeply($index->ranges, [qw(
-               -.
-               .-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-
+       my @data = ('aa'..'zz', 1..202);
+       my $index = List::Index->new or return;
 
 
-       )], 'default ranges');
-       is_deeply($index->ranges({pagesize => 300}), [qw(-c d-n o-)], 'large pagesize');
+       is_deeply(
+               $index->ranges(\@data),
+               [qw(
+                       -.
+                       .-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-
+               )],
+               'default ranges'
+       );
+       is_deeply(
+               $index->ranges(\@data, { pagesize => 300 }),
+               [qw(-c d-n o-)],
+               'large pagesize'
+       );
 };
 
 subtest 'context' => sub {
        plan tests => 9;
 };
 
 subtest 'context' => sub {
        plan tests => 9;
-       my $index = List::Index->new([qw(
+       my @data = qw(
                kkeg kl km kmlu knsy    koxb kpeo kuaa kuab kuac
                kuapa kuq kur kux kzb   lc lg lgu lgua lguc
                kkeg kl km kmlu knsy    koxb kpeo kuaa kuab kuac
                kuapa kuq kur kux kzb   lc lg lgu lgua lguc
-               lguq lgur lgus lgx lka  lkq lks lln llq llx
-       )]) or return;
+               lguq lgur lgws lgx lka  lkq lks lln llq llx
+       );
+       my $index = List::Index->new({ pagesize => 10 }) or return;
+
        is_deeply(
        is_deeply(
-               $index->ranges({ pagesize=>10, context=>0, length=>5 }),
+               $index->ranges(\@data, { context => 0, length => 5 }),
                # ranges should match offsets exactly
                [qw(-kuap. kuapa-lgup lguq-)],
                'no context'
        );
        is_deeply(
                # ranges should match offsets exactly
                [qw(-kuap. kuapa-lgup lguq-)],
                'no context'
        );
        is_deeply(
-               $index->ranges({ pagesize=>10, context=>0 }),
+               $index->ranges(\@data, { context => 0 }),
                # default length limits to 4 chars
                [qw(-kuao kuap-lgup lguq-)],
                'default length'
        );
        is_deeply(
                # default length limits to 4 chars
                [qw(-kuao kuap-lgup lguq-)],
                'default length'
        );
        is_deeply(
-               $index->ranges({ pagesize=>10, context=>1 }),
+               $index->ranges(\@data, { context => 1 }),
                # lookbehinds aren't shorter (kuac<kuap, lguc<lguq)
                # 'kuap' can advance to 'kuq'
                [qw(-kup kuq-lgup lguq-)],
                # lookbehinds aren't shorter (kuac<kuap, lguc<lguq)
                # 'kuap' can advance to 'kuq'
                [qw(-kup kuq-lgup lguq-)],
@@ -61,64 +83,120 @@ subtest 'context' => sub {
 TODO: {
        local $TODO = 'backtrack';
        is_deeply(
 TODO: {
        local $TODO = 'backtrack';
        is_deeply(
-               $index->ranges({ pagesize=>10, context=>2 }),
+               $index->ranges(\@data, { context => 2 }),
                # allowed to advance to 'kur', but provides no benefits over 'kuq'
                [qw(-kup kuq-lgup lguq-)],
                'minimal lookahead'
        );
 }
        is_deeply(
                # allowed to advance to 'kur', but provides no benefits over 'kuq'
                [qw(-kup kuq-lgup lguq-)],
                'minimal lookahead'
        );
 }
        is_deeply(
-               $index->ranges({ pagesize=>10, context=>3 }),
+               $index->ranges(\@data, { context => 3 }),
                # shorten 'kuap' to 'ku' because lookbehind is 'kp...'
                # 'lguq' matches 'lg', but may only backtrack to 'lgu'
                [qw(-kt ku-lgt lgu-)],
                'lookbehind'
        );
        is_deeply(
                # shorten 'kuap' to 'ku' because lookbehind is 'kp...'
                # 'lguq' matches 'lg', but may only backtrack to 'lgu'
                [qw(-kt ku-lgt lgu-)],
                'lookbehind'
        );
        is_deeply(
-               $index->ranges({ pagesize=>10, context=>4 }),
+               $index->ranges(\@data, { context => 4 }),
                [qw(-kt ku-lf lg-)],
                'maximal lookahead'
        );
        is_deeply(
                [qw(-kt ku-lf lg-)],
                'maximal lookahead'
        );
        is_deeply(
-               $index->ranges({ pagesize=>10, context=>5 }),
+               $index->ranges(\@data, { context => 5 }),
                # after forwarding 'kuap' to 'lc'
                # disallow backtracking of 'lguq' to 'lc' to prevent qw[-k l-]
                # so only lookahead (to 'lkq') remains
                [qw(-k l-lj lk-)],
                # after forwarding 'kuap' to 'lc'
                # disallow backtracking of 'lguq' to 'lc' to prevent qw[-k l-]
                # so only lookahead (to 'lkq') remains
                [qw(-k l-lj lk-)],
-               'no lookbehind after full lookahead'
+               'lookbehind forbidden'
        );
        is_deeply(
        );
        is_deeply(
-               $index->ranges({ pagesize=>10, context=>9 }),
+               $index->ranges(\@data, { context => 9 }),
                # allow a single (10-9) entry (l-lf = lc) to remain
                [qw(-k l-lf lg-)],
                # allow a single (10-9) entry (l-lf = lc) to remain
                [qw(-k l-lf lg-)],
-               'lookbehind after full lookahead'
+               'lookbehind penalty'
        );
        is_deeply(
        );
        is_deeply(
-               $index->ranges({ pagesize=>10, context=>10 }),
+               $index->ranges(\@data, { context => 10 }),
                # allow the last page to go back upto 'lc', replacing the 2nd page
                [qw(-k l-)],
                'full overlap'
        );
 };
 
                # allow the last page to go back upto 'lc', replacing the 2nd page
                [qw(-k l-)],
                'full overlap'
        );
 };
 
+subtest 'distribution' => sub {
+       plan tests => 2;
+       my @data = qw(
+               gnihka gniub go gsearnrqns gtdvcxyt gw gwoufolwcvmtueyg gysgphci h habkdgifjfxoh
+               hbbvjf hbqleexnqts hccg hd hdoeqwdmgqwaoya hfbegicieuxz hfm hj hkoysmws hmylu
+               hnvtvpievbdlkrmb hs hvdvcqn hvn hyrybeur iaiaab ib ibavqyar idfniqvxpohbk idh
+       );
+       my $index = List::Index->new({ pagesize => 10 }) or return;
+
+       is_deeply(
+               $index->ranges(\@data, { context => 7 }),
+               [qw(-g h i-)],
+               'large context'
+       );
+       is_deeply(
+               $index->ranges(\@data, { context => 6 }),
+               # after 2nd page is enlarged by lookbehind to 'h', limit subsequent lookahead
+               # to prevent the page from getting too large (17 entries if forwarded to 'i')
+               [qw(-g h-hm hn-)],
+               'lookahead penalty'
+       );
+       # page #14 [gn-g] (8): gnihka gniub go gsearnrqns gtdvcxyt gwawkvmueovdjtfj gwoufolwcvmtueyg gysgphci
+       # page #15 [h] (17): h habkdgifjfxoh hbbvjf hbqleexnqts hccgszftbaymfu hdaqzkow hdoeqwdmgqwaoya hfbegicieu hfmlpzzioqjbthz hj hkoysmws hmylu hnvtvpievbdlkrmb hsodfpkatk hvdvcqn hvn hyrybeurqtevjfmi
+       # page #16 [i-ie] (5): i iaab ibiavqyar idfniqvxpohbk idh
+};
+
+subtest 'modulo' => sub {
+       plan tests => 2;
+       my @data = qw( a b ccb   ccd  cce gf gg   gh  i j );
+       my $index = List::Index->new({ pagesize => 4, context => 0 }) or return;
+       # 10 entries at 4 per page requires 3 pages
+       # so actual target page sizes should be 3,4,3 (not 4,4,2)
+
+       is_deeply(
+               $index->ranges(\@data),
+               [qw(-ccc ccd-gg gh-)],
+               'uniform page sizes'
+       );
+{ local $TODO = 'early lookbehind causing [c-gg]';
+       is_deeply(
+               $index->ranges(\@data, { context => 1 }),
+               [qw(-b c-h i-)],
+               'context at new intervals'
+       );
+}
+};
+
 subtest 'context' => sub {
        plan tests => 4;
 subtest 'context' => sub {
        plan tests => 4;
-       my $index = List::Index->new([qw(
-               baa1 baa2  baa3 baaa  bbc cbc  daaa ea  eaaa zed
-       )]) or return;
-       is_deeply($index->ranges({pagesize => 2, context => 0}), [
-               qw(-baa. baa.-bbb bbc-daa. daaa-eaa. eaaa-)
-       ], 'no context');
-       is_deeply($index->ranges({pagesize => 2}), [
-               qw(-a b c d e-)
-       ], 'default context');  # context should be 1
-       is_deeply($index->ranges({pagesize => 2, context => 2}), [
-               qw(-a b-c d e-)
-       ], 'overlap');  # first item equals second due to large context
-       is_deeply($index->ranges({pagesize => 2, context => 0, length => 1}), [
-               qw(-a b-c d e-)
-       ], 'single char');
-
-       #pp($index->ranges({pagesize => 2, context => 2, length => 1}));
+       my @data = qw( baa1 baa2  baa3 baaa  bbc cbc  daaa ea  eaaa zed );
+       my $index = List::Index->new({ pagesize => 2 }) or return;
+
+       is_deeply(
+               $index->ranges(\@data, { context => 0 }),
+               [qw(-baa. baa.-bbb bbc-daa. daaa-eaa. eaaa-)],
+               'no context'
+       );
+       is_deeply(
+               $index->ranges(\@data, { context => undef }),
+               [qw(-a b c d e-)], #TODO
+               'default context'  # context should be 1
+       );
+       is_deeply(
+               $index->ranges(\@data, { context => 2 }),
+               # first item equals second due to large context
+               [qw(-a b-c d e-)],
+               'overlap'
+       );
+       is_deeply(
+               $index->ranges(\@data, { context => 0, length => 1 }),
+               [qw(-a b-c d e-)],
+               'single char'
+       );
+
+       #pp(List::Index->new({pagesize => 2, context => 2, length => 1}))->ranges(\@data);
 };
 
 };