| Akron | 349747d | 2016-12-05 11:05:53 +0100 | [diff] [blame] | 1 | use Test::More; |
| 2 | use Test::Krawfish; |
| 3 | use strict; |
| 4 | use warnings; |
| 5 | |
| 6 | use_ok('Krawfish::Koral::Corpus::Builder'); |
| 7 | use_ok('Krawfish::Index'); |
| 8 | |
| 9 | my $index = Krawfish::Index->new; |
| Akron | 56422cf | 2017-08-16 14:17:01 +0200 | [diff] [blame] | 10 | ok_index($index, { |
| Akron | 92d9f67 | 2017-08-16 12:23:11 +0200 | [diff] [blame] | 11 | integer_id => 2, |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 12 | author => 'Peter', |
| 13 | genre => 'novel', |
| Akron | 92d9f67 | 2017-08-16 12:23:11 +0200 | [diff] [blame] | 14 | integer_age => 4 |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 15 | } => [qw/aa bb/], 'Add complex document'); |
| Akron | 7b4e4d9 | 2017-09-25 12:18:29 +0200 | [diff] [blame] | 16 | |
| Akron | 56422cf | 2017-08-16 14:17:01 +0200 | [diff] [blame] | 17 | ok_index($index, { |
| Akron | 92d9f67 | 2017-08-16 12:23:11 +0200 | [diff] [blame] | 18 | integer_id => 3, |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 19 | author => 'Peter', |
| 20 | genre => 'novel', |
| Akron | 92d9f67 | 2017-08-16 12:23:11 +0200 | [diff] [blame] | 21 | integer_age => 3 |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 22 | } => [qw/aa bb/], 'Add complex document'); |
| Akron | 56422cf | 2017-08-16 14:17:01 +0200 | [diff] [blame] | 23 | ok_index($index, { |
| Akron | 92d9f67 | 2017-08-16 12:23:11 +0200 | [diff] [blame] | 24 | integer_id => 5, |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 25 | author => 'Peter', |
| 26 | genre => 'newsletter', |
| Akron | 92d9f67 | 2017-08-16 12:23:11 +0200 | [diff] [blame] | 27 | integer_age => 4 |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 28 | } => [qw/aa bb/], 'Add complex document'); |
| Akron | 56422cf | 2017-08-16 14:17:01 +0200 | [diff] [blame] | 29 | ok_index($index, { |
| Akron | 92d9f67 | 2017-08-16 12:23:11 +0200 | [diff] [blame] | 30 | integer_id => 6, |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 31 | author => 'Michael', |
| 32 | genre => 'newsletter', |
| Akron | 92d9f67 | 2017-08-16 12:23:11 +0200 | [diff] [blame] | 33 | integer_age => 7 |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 34 | } => [qw/aa bb/], 'Add complex document'); |
| Akron | 349747d | 2016-12-05 11:05:53 +0100 | [diff] [blame] | 35 | |
| 36 | ok(my $cb = Krawfish::Koral::Corpus::Builder->new, 'Create CorpusBuilder'); |
| 37 | |
| Akron | b945c57 | 2017-07-23 14:55:00 +0200 | [diff] [blame] | 38 | ok(my $query = $cb->bool_and( |
| Akron | 349747d | 2016-12-05 11:05:53 +0100 | [diff] [blame] | 39 | $cb->string('author')->eq('Peter'), |
| 40 | $cb->string('age')->eq('4') |
| 41 | ), 'Create corpus query'); |
| 42 | |
| Akron | 0e782bc | 2017-05-14 14:04:41 +0200 | [diff] [blame] | 43 | is($query->to_string, 'age=4&author=Peter', 'Stringification'); |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 44 | ok(!$query->is_negative, 'Check negativity'); |
| Akron | 349747d | 2016-12-05 11:05:53 +0100 | [diff] [blame] | 45 | |
| Akron | 7b4e4d9 | 2017-09-25 12:18:29 +0200 | [diff] [blame] | 46 | |
| Akron | 3ab2e97 | 2017-08-02 19:10:10 +0200 | [diff] [blame] | 47 | ok(my $plan = $query->normalize->identify($index->dict)->optimize($index->segment), 'Planning'); |
| Akron | 349747d | 2016-12-05 11:05:53 +0100 | [diff] [blame] | 48 | |
| Akron | 92d9f67 | 2017-08-16 12:23:11 +0200 | [diff] [blame] | 49 | is($plan->to_string, "and(#2,#6)", 'Stringification'); |
| Akron | 349747d | 2016-12-05 11:05:53 +0100 | [diff] [blame] | 50 | |
| 51 | ok($plan->next, 'Init vc'); |
| 52 | is($plan->current->to_string, '[0]', 'First doc'); |
| 53 | ok($plan->next, 'More next'); |
| 54 | is($plan->current->to_string, '[2]', 'First doc'); |
| 55 | ok(!$plan->next, 'No more next'); |
| 56 | |
| Akron | 349747d | 2016-12-05 11:05:53 +0100 | [diff] [blame] | 57 | # Complex virtual corpus |
| Akron | b945c57 | 2017-07-23 14:55:00 +0200 | [diff] [blame] | 58 | ok($query = $cb->bool_or( |
| 59 | $cb->bool_and( |
| Akron | 349747d | 2016-12-05 11:05:53 +0100 | [diff] [blame] | 60 | $cb->string('author')->eq('Peter'), |
| 61 | $cb->string('age')->eq(3) |
| 62 | ), |
| 63 | $cb->string('id')->eq(2) |
| 64 | ), 'Create corpus query'); |
| 65 | |
| Akron | 0e782bc | 2017-05-14 14:04:41 +0200 | [diff] [blame] | 66 | is($query->to_string, '(age=3&author=Peter)|id=2', 'Stringification'); |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 67 | ok(!$query->is_negative, 'Check negativity'); |
| Akron | 349747d | 2016-12-05 11:05:53 +0100 | [diff] [blame] | 68 | |
| Akron | 3ab2e97 | 2017-08-02 19:10:10 +0200 | [diff] [blame] | 69 | ok($plan = $query->normalize->identify($index->dict)->optimize($index->segment), 'Planning'); |
| Akron | 349747d | 2016-12-05 11:05:53 +0100 | [diff] [blame] | 70 | |
| Akron | 92d9f67 | 2017-08-16 12:23:11 +0200 | [diff] [blame] | 71 | is($plan->to_string, "or(#8,and(#2,#13))", 'Stringification'); |
| Akron | 349747d | 2016-12-05 11:05:53 +0100 | [diff] [blame] | 72 | |
| 73 | ok($plan->next, 'Init vc'); |
| 74 | is($plan->current->to_string, '[0]', 'First doc'); |
| 75 | ok($plan->next, 'More next'); |
| 76 | is($plan->current->to_string, '[1]', 'First doc'); |
| 77 | ok(!$plan->next, 'No more next'); |
| 78 | |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 79 | # Complex virtual corpus with negation |
| Akron | b945c57 | 2017-07-23 14:55:00 +0200 | [diff] [blame] | 80 | ok($query = $cb->bool_and( |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 81 | $cb->string('author')->eq('Peter'), |
| 82 | $cb->string('age')->ne(4) |
| 83 | ), |
| 84 | , 'Create corpus query'); |
| 85 | |
| Akron | b3e1798 | 2017-07-19 17:45:50 +0200 | [diff] [blame] | 86 | |
| Akron | 0e782bc | 2017-05-14 14:04:41 +0200 | [diff] [blame] | 87 | is($query->to_string, 'age!=4&author=Peter', 'Stringification'); |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 88 | ok(!$query->is_negative, 'Check negativity'); |
| 89 | |
| Akron | d7f5bd3 | 2017-06-06 16:13:11 +0200 | [diff] [blame] | 90 | ok(my $norm = $query->normalize, 'Plan logically'); |
| Akron | 7a97d3f | 2017-06-07 18:28:50 +0200 | [diff] [blame] | 91 | is($norm->to_string, "(author=Peter&!age=4)", 'Stringification'); |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 92 | |
| Akron | 3ab2e97 | 2017-08-02 19:10:10 +0200 | [diff] [blame] | 93 | ok(my $opt = $norm->identify($index->dict)->optimize($index->segment), 'Planning'); |
| Akron | 92d9f67 | 2017-08-16 12:23:11 +0200 | [diff] [blame] | 94 | is($opt->to_string, "andNot(#2,#6)", 'Stringification'); |
| Akron | 2ea61aa | 2017-06-03 16:30:23 +0200 | [diff] [blame] | 95 | |
| 96 | |
| Akron | 2ea61aa | 2017-06-03 16:30:23 +0200 | [diff] [blame] | 97 | ok($opt->next, 'Init vc'); |
| 98 | is($opt->current->to_string, '[1]', 'First doc'); |
| 99 | ok(!$opt->next, 'No more next'); |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 100 | |
| 101 | |
| 102 | # Complex virtual corpus with negation |
| Akron | b945c57 | 2017-07-23 14:55:00 +0200 | [diff] [blame] | 103 | ok($query = $cb->bool_and( |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 104 | $cb->string('author')->ne('Peter'), |
| 105 | $cb->string('age')->ne(4) |
| 106 | ), |
| 107 | , 'Create corpus query'); |
| 108 | |
| Akron | 0e782bc | 2017-05-14 14:04:41 +0200 | [diff] [blame] | 109 | is($query->to_string, 'age!=4&author!=Peter', 'Stringification'); |
| Akron | 2c6c716 | 2017-05-15 18:15:33 +0200 | [diff] [blame] | 110 | ok(!$query->is_negative, 'Check negativity'); |
| Akron | d3355ba | 2017-05-17 21:16:35 +0200 | [diff] [blame] | 111 | |
| Akron | 2ea61aa | 2017-06-03 16:30:23 +0200 | [diff] [blame] | 112 | |
| Akron | 1811acc | 2017-06-07 02:13:16 +0200 | [diff] [blame] | 113 | # Plan a query and finalize it |
| Akron | d7f5bd3 | 2017-06-06 16:13:11 +0200 | [diff] [blame] | 114 | ok($plan = $query->normalize, 'Planning'); |
| 115 | is($plan->to_string, "!(age=4|author=Peter)", 'Stringification'); |
| 116 | ok($plan = $plan->finalize, 'Planning'); |
| Akron | 7a97d3f | 2017-06-07 18:28:50 +0200 | [diff] [blame] | 117 | is($plan->to_string, "([1]&!(age=4|author=Peter))", 'Stringification'); |
| Akron | 3ab2e97 | 2017-08-02 19:10:10 +0200 | [diff] [blame] | 118 | ok($plan = $plan->identify($index->dict)->optimize($index->segment), 'Optimizing'); |
| Akron | 92d9f67 | 2017-08-16 12:23:11 +0200 | [diff] [blame] | 119 | is($plan->to_string, "andNot([1],or(#6,#2))", 'Stringification'); |
| Akron | d7f5bd3 | 2017-06-06 16:13:11 +0200 | [diff] [blame] | 120 | |
| Akron | 1811acc | 2017-06-07 02:13:16 +0200 | [diff] [blame] | 121 | ok($plan->next, 'More next'); |
| 122 | is($plan->current->to_string, '[3]', 'First doc'); |
| 123 | ok(!$plan->next, 'No more next'); |
| Akron | d7f5bd3 | 2017-06-06 16:13:11 +0200 | [diff] [blame] | 124 | |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 125 | |
| Akron | d3355ba | 2017-05-17 21:16:35 +0200 | [diff] [blame] | 126 | done_testing; |
| 127 | __END__ |
| 128 | |
| 129 | |
| Akron | 2ea61aa | 2017-06-03 16:30:23 +0200 | [diff] [blame] | 130 | |
| 131 | |
| 132 | |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 133 | |
| 134 | # Complex virtual corpus with negation |
| Akron | b945c57 | 2017-07-23 14:55:00 +0200 | [diff] [blame] | 135 | ok($query = $cb->bool_and( |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 136 | $cb->string('genre')->eq('novel'), |
| 137 | $cb->string('author')->ne('Peter'), |
| 138 | $cb->string('age')->ne(4) |
| 139 | ), |
| 140 | , 'Create corpus query'); |
| 141 | |
| Akron | 0e782bc | 2017-05-14 14:04:41 +0200 | [diff] [blame] | 142 | ok(!$query->has_classes, 'Contains classes'); |
| 143 | |
| 144 | is($query->to_string, 'age!=4&author!=Peter&genre=novel', 'Stringification'); |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 145 | ok(!$query->is_negative, 'Check negativity'); |
| 146 | ok($plan = $query->plan_for($index), 'Planning'); |
| Akron | 0e782bc | 2017-05-14 14:04:41 +0200 | [diff] [blame] | 147 | is($plan->to_string, "without('genre:novel',or('age:4','author:Peter'))", |
| Akron | 373df82 | 2016-12-28 15:25:14 +0100 | [diff] [blame] | 148 | 'Stringification'); |
| 149 | |
| Akron | f9260ac | 2017-05-12 22:29:34 +0200 | [diff] [blame] | 150 | diag 'Test further'; |
| 151 | |
| 152 | # Especially: |
| 153 | # - First operand is negative, second is positive |
| 154 | # etc. |
| 155 | # - First operands have freq=0, first valid is negative |
| 156 | |
| Akron | 349747d | 2016-12-05 11:05:53 +0100 | [diff] [blame] | 157 | |
| 158 | done_testing; |
| 159 | __END__ |