]> Dogcows Code - chaz/p5-File-KDBX/blob - t/query.t
add initial WIP
[chaz/p5-File-KDBX] / t / query.t
1 #!/usr/bin/env perl
2
3 use warnings;
4 use strict;
5
6 use lib 't/lib';
7 use TestCommon;
8
9 use File::KDBX::Util qw(query search simple_expression_query);
10 use Test::Deep;
11 use Test::More;
12
13 my $list = [
14 {
15 id => 1,
16 name => 'Bob',
17 age => 34,
18 married => 1,
19 notes => 'Enjoys bowling on Thursdays',
20 },
21 {
22 id => 2,
23 name => 'Ken',
24 age => 17,
25 married => 0,
26 notes => 'Eats dessert first',
27 color => '',
28 },
29 {
30 id => 3,
31 name => 'Becky',
32 age => 25,
33 married => 1,
34 notes => 'Listens to rap music on repeat',
35 color => 'orange',
36 },
37 {
38 id => 4,
39 name => 'Bobby',
40 age => 5,
41 notes => 'Loves candy and running around like a crazy person',
42 color => 'blue',
43 },
44 ];
45
46 subtest 'Declarative structure' => sub {
47 my $result = search($list, name => 'Bob');
48 cmp_deeply $result, [shallow($list->[0])], 'Find Bob'
49 or diag explain $result;
50
51 $result = search($list, name => 'Ken');
52 cmp_deeply $result, [$list->[1]], 'Find Ken'
53 or diag explain $result;
54
55 $result = search($list, age => 25);
56 cmp_deeply $result, [$list->[2]], 'Find Becky by age'
57 or diag explain $result;
58
59 $result = search($list, {name => 'Becky', age => 25});
60 cmp_deeply $result, [$list->[2]], 'Find Becky by name AND age'
61 or diag explain $result;
62
63 $result = search($list, {name => 'Becky', age => 99});
64 cmp_deeply $result, [], 'Miss Becky with wrong age'
65 or diag explain $result;
66
67 $result = search($list, [name => 'Becky', age => 17]);
68 cmp_deeply $result, [$list->[1], $list->[2]], 'Find Ken and Becky with different criteria'
69 or diag explain $result;
70
71 $result = search($list, name => 'Becky', age => 17);
72 cmp_deeply $result, [$list->[1], $list->[2]], 'Query list defaults to OR logic'
73 or diag explain $result;
74
75 $result = search($list, age => {'>=', 18});
76 cmp_deeply $result, [$list->[0], $list->[2]], 'Find adults'
77 or diag explain $result;
78
79 $result = search($list, name => {'=~', qr/^Bob/});
80 cmp_deeply $result, [$list->[0], $list->[3]], 'Find both Bobs'
81 or diag explain $result;
82
83 $result = search($list, -and => [name => 'Becky', age => 99]);
84 cmp_deeply $result, [], 'Specify AND logic explicitly'
85 or diag explain $result;
86
87 $result = search($list, {name => 'Becky', age => 99});
88 cmp_deeply $result, [], 'Specify AND logic implicitly'
89 or diag explain $result;
90
91 $result = search($list, '!' => 'married');
92 cmp_deeply $result, [$list->[1], $list->[3]], 'Find unmarried (using normal operator)'
93 or diag explain $result;
94
95 $result = search($list, -false => 'married');
96 cmp_deeply $result, [$list->[1], $list->[3]], 'Find unmarried (using special operator)'
97 or diag explain $result;
98
99 $result = search($list, -true => 'married');
100 cmp_deeply $result, [$list->[0], $list->[2]], 'Find married persons (using special operator)'
101 or diag explain $result;
102
103 $result = search($list, -not => {name => {'=~', qr/^Bob/}});
104 cmp_deeply $result, [$list->[1], $list->[2]], 'What about Bob? Inverse a complex query'
105 or diag explain $result;
106
107 $result = search($list, -nonempty => 'color');
108 cmp_deeply $result, [$list->[2], $list->[3]], 'Find the colorful'
109 or diag explain $result;
110
111 $result = search($list, color => {ne => undef});
112 cmp_deeply $result, [$list->[2], $list->[3]], 'Find the colorful (compare to undef)'
113 or diag explain $result;
114
115 $result = search($list, -empty => 'color');
116 cmp_deeply $result, [$list->[0], $list->[1]], 'Find those without color'
117 or diag explain $result;
118
119 $result = search($list, color => {eq => undef});
120 cmp_deeply $result, [$list->[0], $list->[1]], 'Find those without color (compare to undef)'
121 or diag explain $result;
122
123 $result = search($list, -defined => 'color');
124 cmp_deeply $result, [$list->[1], $list->[2], $list->[3]], 'Find defined colors'
125 or diag explain $result;
126
127 $result = search($list, -undef => 'color');
128 cmp_deeply $result, [$list->[0]], 'Find undefined colors'
129 or diag explain $result;
130
131 $result = search($list,
132 -and => [
133 name => {'=~', qr/^Bob/},
134 -and => {
135 name => {'ne', 'Bob'},
136 },
137 ],
138 -not => {'!' => 'Bobby'},
139 );
140 cmp_deeply $result, [$list->[3]], 'Complex query'
141 or diag explain $result;
142
143 my $query = query(name => 'Ken');
144 $result = search($list, $query);
145 cmp_deeply $result, [$list->[1]], 'Search using a pre-compiled query'
146 or diag explain $result;
147
148 my $custom_query = sub { shift->{name} eq 'Bobby' };
149 $result = search($list, $custom_query);
150 cmp_deeply $result, [$list->[3]], 'Search using a custom query subroutine'
151 or diag explain $result;
152 };
153
154 ##############################################################################
155
156 subtest 'Simple expressions' => sub {
157 my $simple_query = simple_expression_query('bob', qw{name notes});
158 my $result = search($list, $simple_query);
159 cmp_deeply $result, [$list->[0], $list->[3]], 'Basic one-term expression'
160 or diag explain $result;
161
162 $result = search($list, \'bob', qw{name notes});
163 cmp_deeply $result, [$list->[0], $list->[3]], 'Basic one-term expression on search'
164 or diag explain $result;
165
166 $simple_query = simple_expression_query(' Dessert ', qw{notes});
167 $result = search($list, $simple_query);
168 cmp_deeply $result, [$list->[1]], 'Whitespace is ignored'
169 or diag explain $result;
170
171 $simple_query = simple_expression_query('to music', qw{notes});
172 $result = search($list, $simple_query);
173 cmp_deeply $result, [$list->[2]], 'Multiple terms'
174 or diag explain $result;
175
176 $simple_query = simple_expression_query('"to music"', qw{notes});
177 $result = search($list, $simple_query);
178 cmp_deeply $result, [], 'One quoted term'
179 or diag explain $result;
180
181 $simple_query = simple_expression_query('candy "CRAZY PERSON" ', qw{notes});
182 $result = search($list, $simple_query);
183 cmp_deeply $result, [$list->[3]], 'Multiple terms, one quoted term'
184 or diag explain $result;
185
186 $simple_query = simple_expression_query(" bob\tcandy\n\n", qw{name notes});
187 $result = search($list, $simple_query);
188 cmp_deeply $result, [$list->[3]], 'Multiple terms in different fields'
189 or diag explain $result;
190
191 $simple_query = simple_expression_query('music -repeat', qw{notes});
192 $result = search($list, $simple_query);
193 cmp_deeply $result, [], 'Multiple terms, one negative term'
194 or diag explain $result;
195
196 $simple_query = simple_expression_query('-bob', qw{name});
197 $result = search($list, $simple_query);
198 cmp_deeply $result, [$list->[1], $list->[2]], 'Negative term'
199 or diag explain $result;
200
201 $simple_query = simple_expression_query('bob -bobby', qw{name});
202 $result = search($list, $simple_query);
203 cmp_deeply $result, [$list->[0]], 'Multiple mixed terms'
204 or diag explain $result;
205
206 $simple_query = simple_expression_query(25, '==', qw{age});
207 $result = search($list, $simple_query);
208 cmp_deeply $result, [$list->[2]], 'Custom operator'
209 or diag explain $result;
210
211 $simple_query = simple_expression_query('-25', '==', qw{age});
212 $result = search($list, $simple_query);
213 cmp_deeply $result, [$list->[0], $list->[1], $list->[3]], 'Negative term, custom operator'
214 or diag explain $result;
215 };
216
217 done_testing;
This page took 0.049373 seconds and 4 git commands to generate.