Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(219)

Side by Side Diff: appengine/monorail/search/test/query2ast_test.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is govered by a BSD-style
3 # license that can be found in the LICENSE file or at
4 # https://developers.google.com/open-source/licenses/bsd
5
6 """Tests for the query2ast module."""
7
8 import datetime
9 import time
10 import unittest
11
12 from proto import ast_pb2
13 from search import query2ast
14 from services import fulltext_helpers
15 from tracker import tracker_bizobj
16
17 BOOL = query2ast.BOOL
18 DATE = query2ast.DATE
19 NUM = query2ast.NUM
20 TXT = query2ast.TXT
21
22 BUILTIN_ISSUE_FIELDS = query2ast.BUILTIN_ISSUE_FIELDS
23 ANY_FIELD = query2ast.BUILTIN_ISSUE_FIELDS['any_field']
24
25 EQ = query2ast.EQ
26 NE = query2ast.NE
27 LT = query2ast.LT
28 GT = query2ast.GT
29 LE = query2ast.LE
30 GE = query2ast.GE
31 TEXT_HAS = query2ast.TEXT_HAS
32 NOT_TEXT_HAS = query2ast.NOT_TEXT_HAS
33 TEXT_MATCHES = query2ast.TEXT_MATCHES
34 NOT_TEXT_MATCHES = query2ast.NOT_TEXT_MATCHES
35 IS_DEFINED = query2ast.IS_DEFINED
36 IS_NOT_DEFINED = query2ast.IS_NOT_DEFINED
37 KEY_HAS = query2ast.KEY_HAS
38
39 MakeCond = ast_pb2.MakeCond
40
41
42 class QueryParsingUnitTest(unittest.TestCase):
43
44 default_config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
45
46 @unittest.skip('TODO(jrobbins): fully support OR')
47 def skip_testParseUserQuery_OrClause(self):
48 # ParseUserQuery extends _ParseORQuery with specialized
49 # handling of "OR" operators in a user query
50
51 # an "OR" query, which should look like two separate simple querys
52 # joined together by a pipe.
53 ast = query2ast.ParseUserQuery(
54 'ham OR fancy', '', BUILTIN_ISSUE_FIELDS, self.default_config)
55 conj1 = ast.conjunctions[0]
56 conj2 = ast.conjunctions[1]
57 self.assertEqual([MakeCond(TEXT_HAS, [ANY_FIELD], ['ham'], [])],
58 conj1.conds)
59 self.assertEqual([MakeCond(TEXT_HAS, [ANY_FIELD], ['fancy'], [])],
60 conj2.conds)
61
62 def testParseUserQuery_Words(self):
63 # an "ORTerm" is actually anything appearing on either side of an
64 # "OR" operator. So this could be thought of as "simple" query parsing.
65
66 # a simple query with no spaces
67 ast = query2ast.ParseUserQuery(
68 'hamfancy', '', BUILTIN_ISSUE_FIELDS, self.default_config)
69 fulltext_cond = ast.conjunctions[0].conds[0]
70 self.assertEqual(
71 MakeCond(TEXT_HAS, [ANY_FIELD], ['hamfancy'], []), fulltext_cond)
72
73 # negative word
74 ast = query2ast.ParseUserQuery(
75 '-hamfancy', '', BUILTIN_ISSUE_FIELDS, self.default_config)
76 fulltext_cond = ast.conjunctions[0].conds[0]
77 self.assertEqual(
78 # note: not NOT_TEXT_HAS.
79 MakeCond(NOT_TEXT_HAS, [ANY_FIELD], ['hamfancy'], []),
80 fulltext_cond)
81
82 # an explicit "AND" query in the "featured" context
83 warnings = []
84 query2ast.ParseUserQuery(
85 'ham AND fancy', 'label:featured', BUILTIN_ISSUE_FIELDS,
86 self.default_config, warnings=warnings)
87 self.assertEqual(
88 ['The only supported boolean operator is OR (all capitals).'],
89 warnings)
90
91 # an implicit "AND" query
92 ast = query2ast.ParseUserQuery(
93 'ham fancy', '-label:deprecated', BUILTIN_ISSUE_FIELDS,
94 self.default_config)
95 scope_cond1, ft_cond1, ft_cond2 = ast.conjunctions[0].conds
96 self.assertEqual(
97 MakeCond(NOT_TEXT_HAS, [BUILTIN_ISSUE_FIELDS['label']],
98 ['deprecated'], []),
99 scope_cond1)
100 self.assertEqual(
101 MakeCond(TEXT_HAS, [ANY_FIELD], ['ham'], []), ft_cond1)
102 self.assertEqual(
103 MakeCond(TEXT_HAS, [ANY_FIELD], ['fancy'], []), ft_cond2)
104
105 # Use word with special prefix.
106 word_with_special_prefix = '%stest' % fulltext_helpers.NON_OP_PREFIXES[0]
107 ast = query2ast.ParseUserQuery(
108 word_with_special_prefix, '', BUILTIN_ISSUE_FIELDS, self.default_config)
109 fulltext_cond = ast.conjunctions[0].conds[0]
110 self.assertEqual(
111 MakeCond(TEXT_HAS, [ANY_FIELD], [word_with_special_prefix], []),
112 fulltext_cond)
113
114 # mix positive and negative words
115 ast = query2ast.ParseUserQuery(
116 'ham -fancy', '-label:deprecated', BUILTIN_ISSUE_FIELDS,
117 self.default_config)
118 scope_cond1, ft_cond1, ft_cond2 = ast.conjunctions[0].conds
119 self.assertEqual(
120 MakeCond(NOT_TEXT_HAS, [BUILTIN_ISSUE_FIELDS['label']],
121 ['deprecated'], []),
122 scope_cond1)
123 self.assertEqual(
124 MakeCond(TEXT_HAS, [ANY_FIELD], ['ham'], []), ft_cond1)
125 self.assertEqual(
126 MakeCond(NOT_TEXT_HAS, [ANY_FIELD], ['fancy'], []), ft_cond2)
127
128 # converts terms to lower case
129 ast = query2ast.ParseUserQuery(
130 'AmDude', '-label:deprecated', BUILTIN_ISSUE_FIELDS,
131 self.default_config)
132 scope_cond1, fulltext_cond = ast.conjunctions[0].conds
133 self.assertEqual(
134 MakeCond(NOT_TEXT_HAS, [BUILTIN_ISSUE_FIELDS['label']],
135 ['deprecated'], []),
136 scope_cond1)
137 self.assertEqual(
138 MakeCond(TEXT_HAS, [ANY_FIELD], ['amdude'], []), fulltext_cond)
139
140 def testParseUserQuery_Phrases(self):
141 # positive phrases
142 ast = query2ast.ParseUserQuery(
143 '"one two"', '-label:deprecated', BUILTIN_ISSUE_FIELDS,
144 self.default_config)
145 scope_cond1, fulltext_cond = ast.conjunctions[0].conds
146 self.assertEqual(
147 MakeCond(NOT_TEXT_HAS, [BUILTIN_ISSUE_FIELDS['label']],
148 ['deprecated'], []),
149 scope_cond1)
150 self.assertEqual(
151 MakeCond(TEXT_HAS, [ANY_FIELD], ['"one two"'], []), fulltext_cond)
152
153 # negative phrases
154 ast = query2ast.ParseUserQuery(
155 '-"one two"', '-label:deprecated', BUILTIN_ISSUE_FIELDS,
156 self.default_config)
157 scope_cond1, fulltext_cond = ast.conjunctions[0].conds
158 self.assertEqual(
159 MakeCond(NOT_TEXT_HAS, [BUILTIN_ISSUE_FIELDS['label']],
160 ['deprecated'], []),
161 scope_cond1)
162 self.assertEqual(
163 MakeCond(NOT_TEXT_HAS, [ANY_FIELD], ['"one two"'], []), fulltext_cond)
164
165 # multiple phrases
166 ast = query2ast.ParseUserQuery(
167 '-"a b" "x y"', '-label:deprecated', BUILTIN_ISSUE_FIELDS,
168 self.default_config)
169 scope_cond1, ft_cond1, ft_cond2 = ast.conjunctions[0].conds
170 self.assertEqual(
171 MakeCond(NOT_TEXT_HAS, [BUILTIN_ISSUE_FIELDS['label']],
172 ['deprecated'], []),
173 scope_cond1)
174 self.assertEqual(
175 MakeCond(NOT_TEXT_HAS, [ANY_FIELD], ['"a b"'], []), ft_cond1)
176 self.assertEqual(
177 MakeCond(TEXT_HAS, [ANY_FIELD], ['"x y"'], []), ft_cond2)
178
179 def testParseUserQuery_CodeSyntaxThatWeNeedToCopeWith(self):
180 # positive phrases
181 ast = query2ast.ParseUserQuery(
182 'Base::Tuple', '', BUILTIN_ISSUE_FIELDS,
183 self.default_config)
184 cond = ast.conjunctions[0].conds[0]
185 self.assertEqual(
186 MakeCond(TEXT_HAS, [ANY_FIELD],
187 ['"base::tuple"'], []),
188 cond)
189
190 def testParseUserQuery_HasOperator(self):
191 # Search for issues with at least one attachment
192 ast = query2ast.ParseUserQuery(
193 'has:attachment', '', BUILTIN_ISSUE_FIELDS, self.default_config)
194 cond1 = ast.conjunctions[0].conds[0]
195 self.assertEqual(
196 MakeCond(IS_DEFINED, [BUILTIN_ISSUE_FIELDS['attachment']], [], []),
197 cond1)
198
199 ast = query2ast.ParseUserQuery(
200 '-has:attachment', '', BUILTIN_ISSUE_FIELDS, self.default_config)
201 cond1 = ast.conjunctions[0].conds[0]
202 self.assertEqual(
203 MakeCond(IS_NOT_DEFINED, [BUILTIN_ISSUE_FIELDS['attachment']], [], []),
204 cond1)
205
206 ast = query2ast.ParseUserQuery(
207 'has=attachment', '', BUILTIN_ISSUE_FIELDS, self.default_config)
208 cond1 = ast.conjunctions[0].conds[0]
209 self.assertEqual(
210 MakeCond(IS_DEFINED, [BUILTIN_ISSUE_FIELDS['attachment']], [], []),
211 cond1)
212
213 ast = query2ast.ParseUserQuery(
214 '-has=attachment', '', BUILTIN_ISSUE_FIELDS, self.default_config)
215 cond1 = ast.conjunctions[0].conds[0]
216 self.assertEqual(
217 MakeCond(IS_NOT_DEFINED, [BUILTIN_ISSUE_FIELDS['attachment']], [], []),
218 cond1)
219
220 # Search for numeric fields for searches with 'has' prefix
221 ast = query2ast.ParseUserQuery(
222 'has:attachments', '', BUILTIN_ISSUE_FIELDS, self.default_config)
223 cond1 = ast.conjunctions[0].conds[0]
224 self.assertEqual(
225 MakeCond(IS_DEFINED, [BUILTIN_ISSUE_FIELDS['attachments']], [], []),
226 cond1)
227
228 ast = query2ast.ParseUserQuery(
229 '-has:attachments', '', BUILTIN_ISSUE_FIELDS, self.default_config)
230 cond1 = ast.conjunctions[0].conds[0]
231 self.assertEqual(
232 MakeCond(IS_NOT_DEFINED, [BUILTIN_ISSUE_FIELDS['attachments']],
233 [], []),
234 cond1)
235
236 def testParseUserQuery_Components(self):
237 """Parse user queries for components"""
238 ast = query2ast.ParseUserQuery(
239 'component:UI', '', BUILTIN_ISSUE_FIELDS, self.default_config)
240 cond1 = ast.conjunctions[0].conds[0]
241 self.assertEqual(
242 MakeCond(TEXT_HAS, [BUILTIN_ISSUE_FIELDS['component']],
243 ['ui'], []),
244 cond1)
245
246 ast = query2ast.ParseUserQuery(
247 'Component:UI>AboutBox', '', BUILTIN_ISSUE_FIELDS, self.default_config)
248 cond1 = ast.conjunctions[0].conds[0]
249 self.assertEqual(
250 MakeCond(TEXT_HAS, [BUILTIN_ISSUE_FIELDS['component']],
251 ['ui>aboutbox'], []),
252 cond1)
253
254 def testParseUserQuery_OwnersReportersAndCc(self):
255 """Parse user queries for owner:, reporter: and cc:."""
256 ast = query2ast.ParseUserQuery(
257 'owner:user', '', BUILTIN_ISSUE_FIELDS, self.default_config)
258 cond1 = ast.conjunctions[0].conds[0]
259 self.assertEqual(
260 MakeCond(TEXT_HAS, [BUILTIN_ISSUE_FIELDS['owner']],
261 ['user'], []),
262 cond1)
263
264 ast = query2ast.ParseUserQuery(
265 'owner:user@example.com', '', BUILTIN_ISSUE_FIELDS, self.default_config)
266 cond1 = ast.conjunctions[0].conds[0]
267 self.assertEqual(
268 MakeCond(TEXT_HAS, [BUILTIN_ISSUE_FIELDS['owner']],
269 ['user@example.com'], []),
270 cond1)
271
272 ast = query2ast.ParseUserQuery(
273 'owner=user@example.com', '', BUILTIN_ISSUE_FIELDS, self.default_config)
274 cond1 = ast.conjunctions[0].conds[0]
275 self.assertEqual(
276 MakeCond(EQ, [BUILTIN_ISSUE_FIELDS['owner']],
277 ['user@example.com'], []),
278 cond1)
279
280 ast = query2ast.ParseUserQuery(
281 '-reporter=user@example.com', '', BUILTIN_ISSUE_FIELDS,
282 self.default_config)
283 cond1 = ast.conjunctions[0].conds[0]
284 self.assertEqual(
285 MakeCond(NE, [BUILTIN_ISSUE_FIELDS['reporter']],
286 ['user@example.com'], []),
287 cond1)
288
289 ast = query2ast.ParseUserQuery(
290 'cc=user@example.com,user2@example.com', '', BUILTIN_ISSUE_FIELDS,
291 self.default_config)
292 cond1 = ast.conjunctions[0].conds[0]
293 self.assertEqual(
294 MakeCond(EQ, [BUILTIN_ISSUE_FIELDS['cc']],
295 ['user@example.com', 'user2@example.com'], []),
296 cond1)
297
298 ast = query2ast.ParseUserQuery(
299 'cc:user,user2', '', BUILTIN_ISSUE_FIELDS, self.default_config)
300 cond1 = ast.conjunctions[0].conds[0]
301 self.assertEqual(
302 MakeCond(TEXT_HAS, [BUILTIN_ISSUE_FIELDS['cc']],
303 ['user', 'user2'], []),
304 cond1)
305
306 def testParseUserQuery_SearchWithinFields(self):
307 # Search for issues with certain filenames
308 ast = query2ast.ParseUserQuery(
309 'attachment:filename', '', BUILTIN_ISSUE_FIELDS, self.default_config)
310 cond1 = ast.conjunctions[0].conds[0]
311 self.assertEqual(
312 MakeCond(TEXT_HAS, [BUILTIN_ISSUE_FIELDS['attachment']],
313 ['filename'], []),
314 cond1)
315
316 ast = query2ast.ParseUserQuery(
317 '-attachment:filename', '', BUILTIN_ISSUE_FIELDS,
318 self.default_config)
319 cond1 = ast.conjunctions[0].conds[0]
320 self.assertEqual(
321 MakeCond(NOT_TEXT_HAS, [BUILTIN_ISSUE_FIELDS['attachment']],
322 ['filename'], []),
323 cond1)
324
325 # Search for issues with a certain number of attachments
326 ast = query2ast.ParseUserQuery(
327 'attachments:2', '', BUILTIN_ISSUE_FIELDS, self.default_config)
328 cond1 = ast.conjunctions[0].conds[0]
329 self.assertEqual(
330 MakeCond(TEXT_HAS, [BUILTIN_ISSUE_FIELDS['attachments']],
331 ['2'], [2]),
332 cond1)
333
334 # Searches with '=' syntax
335 ast = query2ast.ParseUserQuery(
336 'attachment=filename', '', BUILTIN_ISSUE_FIELDS, self.default_config)
337 cond1 = ast.conjunctions[0].conds[0]
338 self.assertEqual(
339 MakeCond(EQ, [BUILTIN_ISSUE_FIELDS['attachment']],
340 ['filename'], []),
341 cond1)
342
343 ast = query2ast.ParseUserQuery(
344 '-attachment=filename', '', BUILTIN_ISSUE_FIELDS, self.default_config)
345 cond1 = ast.conjunctions[0].conds[0]
346 self.assertEqual(
347 MakeCond(NE, [BUILTIN_ISSUE_FIELDS['attachment']],
348 ['filename'], []),
349 cond1)
350
351 ast = query2ast.ParseUserQuery(
352 'milestone=2009', '', BUILTIN_ISSUE_FIELDS, self.default_config)
353 cond1 = ast.conjunctions[0].conds[0]
354 self.assertEqual(
355 MakeCond(EQ, [BUILTIN_ISSUE_FIELDS['label']], ['milestone-2009'], []),
356 cond1)
357
358 ast = query2ast.ParseUserQuery(
359 '-milestone=2009', '', BUILTIN_ISSUE_FIELDS, self.default_config)
360 cond1 = ast.conjunctions[0].conds[0]
361 self.assertEqual(
362 MakeCond(NE, [BUILTIN_ISSUE_FIELDS['label']], ['milestone-2009'], []),
363 cond1)
364
365 ast = query2ast.ParseUserQuery(
366 'milestone=2009-Q1', '', BUILTIN_ISSUE_FIELDS, self.default_config)
367 cond1 = ast.conjunctions[0].conds[0]
368 self.assertEqual(
369 MakeCond(EQ, [BUILTIN_ISSUE_FIELDS['label']],
370 ['milestone-2009-q1'], []),
371 cond1)
372
373 ast = query2ast.ParseUserQuery(
374 '-milestone=2009-Q1', '', BUILTIN_ISSUE_FIELDS,
375 self.default_config)
376 cond1 = ast.conjunctions[0].conds[0]
377 self.assertEqual(
378 MakeCond(NE, [BUILTIN_ISSUE_FIELDS['label']],
379 ['milestone-2009-q1'], []),
380 cond1)
381
382 # Searches with ':' syntax
383 ast = query2ast.ParseUserQuery(
384 'summary:foo', '', BUILTIN_ISSUE_FIELDS, self.default_config)
385 cond1 = ast.conjunctions[0].conds[0]
386 self.assertEqual(
387 MakeCond(TEXT_HAS,
388 [BUILTIN_ISSUE_FIELDS['summary']], ['foo'], []),
389 cond1)
390
391 ast = query2ast.ParseUserQuery(
392 'summary:"greetings programs"', '', BUILTIN_ISSUE_FIELDS,
393 self.default_config)
394 cond1 = ast.conjunctions[0].conds[0]
395 self.assertEqual(
396 MakeCond(TEXT_HAS,
397 [BUILTIN_ISSUE_FIELDS['summary']], ['greetings programs'], []),
398 cond1)
399
400 ast = query2ast.ParseUserQuery(
401 'summary:"Ӓ"', '', BUILTIN_ISSUE_FIELDS,
402 self.default_config)
403 cond1 = ast.conjunctions[0].conds[0]
404 self.assertEqual(
405 MakeCond(TEXT_HAS,
406 [BUILTIN_ISSUE_FIELDS['summary']], ['Ӓ'], []),
407 cond1)
408
409 ast = query2ast.ParseUserQuery(
410 'priority:high', '', BUILTIN_ISSUE_FIELDS, self.default_config)
411 cond1 = ast.conjunctions[0].conds[0]
412 self.assertEqual(
413 MakeCond(KEY_HAS,
414 [BUILTIN_ISSUE_FIELDS['label']], ['priority-high'], []),
415 cond1)
416
417 ast = query2ast.ParseUserQuery(
418 'type:security', '', BUILTIN_ISSUE_FIELDS, self.default_config)
419 cond1 = ast.conjunctions[0].conds[0]
420 self.assertEqual(
421 MakeCond(KEY_HAS,
422 [BUILTIN_ISSUE_FIELDS['label']], ['type-security'], []),
423 cond1)
424
425 ast = query2ast.ParseUserQuery(
426 'label:priority-high', '', BUILTIN_ISSUE_FIELDS, self.default_config)
427 cond1 = ast.conjunctions[0].conds[0]
428 self.assertEqual(
429 MakeCond(TEXT_HAS,
430 [BUILTIN_ISSUE_FIELDS['label']], ['priority-high'], []),
431 cond1)
432
433 def testParseUserQuery_QuickOr(self):
434 # quick-or searches
435 ast = query2ast.ParseUserQuery(
436 'milestone:2008,2009,2010', '', BUILTIN_ISSUE_FIELDS,
437 self.default_config)
438 cond1 = ast.conjunctions[0].conds[0]
439 self.assertEqual(
440 MakeCond(KEY_HAS, [BUILTIN_ISSUE_FIELDS['label']],
441 ['milestone-2008', 'milestone-2009', 'milestone-2010'], []),
442 cond1)
443
444 ast = query2ast.ParseUserQuery(
445 'label:milestone-2008,milestone-2009,milestone-2010', '',
446 BUILTIN_ISSUE_FIELDS, self.default_config)
447 cond1 = ast.conjunctions[0].conds[0]
448 self.assertEqual(
449 MakeCond(TEXT_HAS, [BUILTIN_ISSUE_FIELDS['label']],
450 ['milestone-2008', 'milestone-2009', 'milestone-2010'], []),
451 cond1)
452
453 ast = query2ast.ParseUserQuery(
454 'milestone=2008,2009,2010', '', BUILTIN_ISSUE_FIELDS,
455 self.default_config)
456 cond1 = ast.conjunctions[0].conds[0]
457 self.assertEqual(
458 MakeCond(EQ, [BUILTIN_ISSUE_FIELDS['label']],
459 ['milestone-2008', 'milestone-2009', 'milestone-2010'], []),
460 cond1)
461
462 def testParseUserQuery_Dates(self):
463 # query with a daterange
464 ast = query2ast.ParseUserQuery(
465 'modified>=2009-5-12', '', BUILTIN_ISSUE_FIELDS,
466 self.default_config)
467 cond1 = ast.conjunctions[0].conds[0]
468 ts1 = int(time.mktime(datetime.datetime(2009, 5, 12).timetuple()))
469 self.assertEqual(
470 MakeCond(GE, [BUILTIN_ISSUE_FIELDS['modified']], [], [ts1]), cond1)
471
472 # query with multiple dateranges
473 ast = query2ast.ParseUserQuery(
474 'modified>=2009-5-12 opened<2008/1/1', '',
475 BUILTIN_ISSUE_FIELDS, self.default_config)
476 cond1, cond2 = ast.conjunctions[0].conds
477 ts1 = int(time.mktime(datetime.datetime(2009, 5, 12).timetuple()))
478 self.assertEqual(
479 MakeCond(GE, [BUILTIN_ISSUE_FIELDS['modified']], [], [ts1]), cond1)
480 ts2 = int(time.mktime(datetime.datetime(2008, 1, 1).timetuple()))
481 self.assertEqual(
482 MakeCond(LT, [BUILTIN_ISSUE_FIELDS['opened']], [], [ts2]), cond2)
483
484 # query with multiple dateranges plus a search term
485 ast = query2ast.ParseUserQuery(
486 'one two modified>=2009-5-12 opened<2008/1/1', '',
487 BUILTIN_ISSUE_FIELDS, self.default_config)
488 ft_cond1, ft_cond2, cond1, cond2 = ast.conjunctions[0].conds
489 ts1 = int(time.mktime(datetime.datetime(2009, 5, 12).timetuple()))
490 self.assertEqual(
491 MakeCond(TEXT_HAS, [ANY_FIELD], ['one'], []), ft_cond1)
492 self.assertEqual(
493 MakeCond(TEXT_HAS, [ANY_FIELD], ['two'], []), ft_cond2)
494 self.assertEqual(
495 MakeCond(GE, [BUILTIN_ISSUE_FIELDS['modified']], [], [ts1]), cond1)
496 ts2 = int(time.mktime(datetime.datetime(2008, 1, 1).timetuple()))
497 self.assertEqual(
498 MakeCond(LT, [BUILTIN_ISSUE_FIELDS['opened']], [], [ts2]), cond2)
499
500 # query with a date field compared to "today"
501 ast = query2ast.ParseUserQuery(
502 'modified<today', '', BUILTIN_ISSUE_FIELDS,
503 self.default_config)
504 cond1 = ast.conjunctions[0].conds[0]
505 ts1 = query2ast._CalculatePastDate(0)
506 self.assertEqual(MakeCond(LT, [BUILTIN_ISSUE_FIELDS['modified']],
507 [], [ts1]),
508 cond1)
509
510 # query with a daterange using today-N alias
511 ast = query2ast.ParseUserQuery(
512 'modified>=today-13', '', BUILTIN_ISSUE_FIELDS,
513 self.default_config)
514 cond1 = ast.conjunctions[0].conds[0]
515 ts1 = query2ast._CalculatePastDate(13)
516 self.assertEqual(MakeCond(GE, [BUILTIN_ISSUE_FIELDS['modified']],
517 [], [ts1]),
518 cond1)
519
520 ast = query2ast.ParseUserQuery(
521 'modified>today-13', '', BUILTIN_ISSUE_FIELDS, self.default_config)
522 cond1 = ast.conjunctions[0].conds[0]
523 ts1 = query2ast._CalculatePastDate(13)
524 self.assertEqual(MakeCond(GT, [BUILTIN_ISSUE_FIELDS['modified']],
525 [], [ts1]),
526 cond1)
527
528 # query with multiple old date query terms.
529 ast = query2ast.ParseUserQuery(
530 'modified-after:2009-5-12 opened-before:2008/1/1 '
531 'closed-after:2007-2-1', '',
532 BUILTIN_ISSUE_FIELDS, self.default_config)
533 cond1, cond2, cond3 = ast.conjunctions[0].conds
534 ts1 = int(time.mktime(datetime.datetime(2009, 5, 12).timetuple()))
535 self.assertEqual(
536 MakeCond(GT, [BUILTIN_ISSUE_FIELDS['modified']], [], [ts1]), cond1)
537 ts2 = int(time.mktime(datetime.datetime(2008, 1, 1).timetuple()))
538 self.assertEqual(
539 MakeCond(LT, [BUILTIN_ISSUE_FIELDS['opened']], [], [ts2]), cond2)
540 ts3 = int(time.mktime(datetime.datetime(2007, 2, 1).timetuple()))
541 self.assertEqual(
542 MakeCond(GT, [BUILTIN_ISSUE_FIELDS['closed']], [], [ts3]), cond3)
543
544
545 if __name__ == '__main__':
546 unittest.main()
OLDNEW
« no previous file with comments | « appengine/monorail/search/test/frontendsearchpipeline_test.py ('k') | appengine/monorail/search/test/searchpipeline_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698