OLD | NEW |
(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 ast2ast module.""" |
| 7 |
| 8 import unittest |
| 9 |
| 10 from proto import ast_pb2 |
| 11 from proto import tracker_pb2 |
| 12 from search import ast2ast |
| 13 from search import query2ast |
| 14 from services import service_manager |
| 15 from testing import fake |
| 16 from tracker import tracker_bizobj |
| 17 |
| 18 |
| 19 BUILTIN_ISSUE_FIELDS = query2ast.BUILTIN_ISSUE_FIELDS |
| 20 ANY_FIELD = query2ast.BUILTIN_ISSUE_FIELDS['any_field'] |
| 21 OWNER_FIELD = query2ast.BUILTIN_ISSUE_FIELDS['owner'] |
| 22 OWNER_ID_FIELD = query2ast.BUILTIN_ISSUE_FIELDS['owner_id'] |
| 23 |
| 24 |
| 25 class AST2ASTTest(unittest.TestCase): |
| 26 |
| 27 def setUp(self): |
| 28 self.cnxn = 'fake cnxn' |
| 29 self.config = tracker_bizobj.MakeDefaultProjectIssueConfig(789) |
| 30 self.config.component_defs.append( |
| 31 tracker_bizobj.MakeComponentDef( |
| 32 101, 789, 'UI', 'doc', False, [], [], 0, 0)) |
| 33 self.config.component_defs.append( |
| 34 tracker_bizobj.MakeComponentDef( |
| 35 102, 789, 'UI>Search', 'doc', False, [], [], 0, 0)) |
| 36 self.config.component_defs.append( |
| 37 tracker_bizobj.MakeComponentDef( |
| 38 201, 789, 'DB', 'doc', False, [], [], 0, 0)) |
| 39 self.config.component_defs.append( |
| 40 tracker_bizobj.MakeComponentDef( |
| 41 301, 789, 'Search', 'doc', False, [], [], 0, 0)) |
| 42 self.services = service_manager.Services( |
| 43 user=fake.UserService(), |
| 44 project=fake.ProjectService(), |
| 45 issue=fake.IssueService(), |
| 46 config=fake.ConfigService()) |
| 47 self.services.user.TestAddUser('a@example.com', 111L) |
| 48 |
| 49 def testPreprocessAST_EmptyAST(self): |
| 50 ast = ast_pb2.QueryAST() # No conjunctions in it. |
| 51 new_ast = ast2ast.PreprocessAST( |
| 52 self.cnxn, ast, [789], self.services, self.config) |
| 53 self.assertEqual(ast, new_ast) |
| 54 |
| 55 def testPreprocessAST_Normal(self): |
| 56 open_field = BUILTIN_ISSUE_FIELDS['open'] |
| 57 label_field = BUILTIN_ISSUE_FIELDS['label'] |
| 58 label_id_field = BUILTIN_ISSUE_FIELDS['label_id'] |
| 59 status_id_field = BUILTIN_ISSUE_FIELDS['status_id'] |
| 60 conds = [ |
| 61 ast_pb2.MakeCond(ast_pb2.QueryOp.EQ, [open_field], [], [1]), |
| 62 ast_pb2.MakeCond(ast_pb2.QueryOp.EQ, [label_field], ['Hot'], [])] |
| 63 |
| 64 ast = ast_pb2.QueryAST() |
| 65 ast.conjunctions.append(ast_pb2.Conjunction(conds=conds)) |
| 66 new_ast = ast2ast.PreprocessAST( |
| 67 self.cnxn, ast, [789], self.services, self.config) |
| 68 self.assertEqual(2, len(new_ast.conjunctions[0].conds)) |
| 69 new_cond_1, new_cond_2 = new_ast.conjunctions[0].conds |
| 70 self.assertEqual(ast_pb2.QueryOp.NE, new_cond_1.op) |
| 71 self.assertEqual([status_id_field], new_cond_1.field_defs) |
| 72 self.assertEqual([7, 8, 9], new_cond_1.int_values) |
| 73 self.assertEqual([], new_cond_1.str_values) |
| 74 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond_2.op) |
| 75 self.assertEqual([label_id_field], new_cond_2.field_defs) |
| 76 self.assertEqual([0], new_cond_2.int_values) |
| 77 self.assertEqual([], new_cond_2.str_values) |
| 78 |
| 79 def testPreprocessIsOpenCond(self): |
| 80 open_field = BUILTIN_ISSUE_FIELDS['open'] |
| 81 status_id_field = BUILTIN_ISSUE_FIELDS['status_id'] |
| 82 |
| 83 # is:open -> status_id!=closed_status_ids |
| 84 cond = ast_pb2.MakeCond( |
| 85 ast_pb2.QueryOp.EQ, [open_field], [], [1]) |
| 86 new_cond = ast2ast._PreprocessIsOpenCond( |
| 87 self.cnxn, cond, [789], self.services, self.config) |
| 88 self.assertEqual(ast_pb2.QueryOp.NE, new_cond.op) |
| 89 self.assertEqual([status_id_field], new_cond.field_defs) |
| 90 self.assertEqual([7, 8, 9], new_cond.int_values) |
| 91 self.assertEqual([], new_cond.str_values) |
| 92 |
| 93 # -is:open -> status_id=closed_status_ids |
| 94 cond = ast_pb2.MakeCond( |
| 95 ast_pb2.QueryOp.EQ, [open_field], [], [0]) |
| 96 new_cond = ast2ast._PreprocessIsOpenCond( |
| 97 self.cnxn, cond, [789], self.services, self.config) |
| 98 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 99 self.assertEqual([status_id_field], new_cond.field_defs) |
| 100 self.assertEqual([7, 8, 9], new_cond.int_values) |
| 101 self.assertEqual([], new_cond.str_values) |
| 102 |
| 103 def testPreprocessBlockedOnCond_WithSingleProjectID(self): |
| 104 blockedon_field = BUILTIN_ISSUE_FIELDS['blockedon'] |
| 105 blockedon_id_field = BUILTIN_ISSUE_FIELDS['blockedon_id'] |
| 106 self.services.project.TestAddProject('Project1', project_id=1) |
| 107 issue1 = fake.MakeTestIssue( |
| 108 project_id=1, local_id=1, summary='sum', status='new', owner_id=2, |
| 109 issue_id=101) |
| 110 issue2 = fake.MakeTestIssue( |
| 111 project_id=1, local_id=2, summary='sum', status='new', owner_id=2, |
| 112 issue_id=102) |
| 113 self.services.issue.TestAddIssue(issue1) |
| 114 self.services.issue.TestAddIssue(issue2) |
| 115 |
| 116 for local_ids, expected in ( |
| 117 (['1'], [101]), # One existing issue. |
| 118 (['Project1:1'], [101]), # One existing issue with project prefix. |
| 119 (['1', '2'], [101, 102]), # Two existing issues. |
| 120 (['3'], [])): # Non-existant issue. |
| 121 cond = ast_pb2.MakeCond( |
| 122 ast_pb2.QueryOp.TEXT_HAS, [blockedon_field], local_ids, []) |
| 123 new_cond = ast2ast._PreprocessBlockedOnCond( |
| 124 self.cnxn, cond, [1], self.services, None) |
| 125 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 126 self.assertEqual([blockedon_id_field], new_cond.field_defs) |
| 127 self.assertEqual(expected, new_cond.int_values) |
| 128 self.assertEqual([], new_cond.str_values) |
| 129 |
| 130 def testPreprocessBlockedOnCond_WithMultipleProjectIDs(self): |
| 131 blockedon_field = BUILTIN_ISSUE_FIELDS['blockedon'] |
| 132 blockedon_id_field = BUILTIN_ISSUE_FIELDS['blockedon_id'] |
| 133 self.services.project.TestAddProject('Project1', project_id=1) |
| 134 self.services.project.TestAddProject('Project2', project_id=2) |
| 135 issue1 = fake.MakeTestIssue( |
| 136 project_id=1, local_id=1, summary='sum', status='new', owner_id=2, |
| 137 issue_id=101) |
| 138 issue2 = fake.MakeTestIssue( |
| 139 project_id=2, local_id=2, summary='sum', status='new', owner_id=2, |
| 140 issue_id=102) |
| 141 self.services.issue.TestAddIssue(issue1) |
| 142 self.services.issue.TestAddIssue(issue2) |
| 143 |
| 144 for local_ids, expected in ( |
| 145 (['Project1:1'], [101]), |
| 146 (['Project1:1', 'Project2:2'], [101, 102])): |
| 147 cond = ast_pb2.MakeCond( |
| 148 ast_pb2.QueryOp.TEXT_HAS, [blockedon_field], local_ids, []) |
| 149 new_cond = ast2ast._PreprocessBlockedOnCond( |
| 150 self.cnxn, cond, [1, 2], self.services, None) |
| 151 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 152 self.assertEqual([blockedon_id_field], new_cond.field_defs) |
| 153 self.assertEqual(expected, new_cond.int_values) |
| 154 self.assertEqual([], new_cond.str_values) |
| 155 |
| 156 def testPreprocessBlockedOnCond_WithMultipleProjectIDs_NoPrefix(self): |
| 157 blockedon_field = BUILTIN_ISSUE_FIELDS['blockedon'] |
| 158 self.services.project.TestAddProject('Project1', project_id=1) |
| 159 self.services.project.TestAddProject('Project2', project_id=2) |
| 160 issue1 = fake.MakeTestIssue( |
| 161 project_id=1, local_id=1, summary='sum', status='new', owner_id=2, |
| 162 issue_id=101) |
| 163 issue2 = fake.MakeTestIssue( |
| 164 project_id=2, local_id=2, summary='sum', status='new', owner_id=2, |
| 165 issue_id=102) |
| 166 self.services.issue.TestAddIssue(issue1) |
| 167 self.services.issue.TestAddIssue(issue2) |
| 168 |
| 169 for local_ids in (['1'], ['1', '2'], ['3']): |
| 170 cond = ast_pb2.MakeCond( |
| 171 ast_pb2.QueryOp.TEXT_HAS, [blockedon_field], local_ids, []) |
| 172 try: |
| 173 ast2ast._PreprocessBlockedOnCond( |
| 174 self.cnxn, cond, [1, 2], self.services, None) |
| 175 self.fail('Expected an Exception.') |
| 176 except ValueError, e: |
| 177 self.assertEquals( |
| 178 'Searching for issues accross multiple/all projects without ' |
| 179 'project prefixes is ambiguous and is currently not supported.', |
| 180 e.message) |
| 181 |
| 182 def testPreprocessIsBlockedCond(self): |
| 183 blocked_field = BUILTIN_ISSUE_FIELDS['blockedon_id'] |
| 184 for int_val, expected_op in ((1, ast_pb2.QueryOp.IS_DEFINED), |
| 185 (0, ast_pb2.QueryOp.IS_NOT_DEFINED)): |
| 186 cond = ast_pb2.MakeCond( |
| 187 ast_pb2.QueryOp.EQ, [blocked_field], [], [int_val]) |
| 188 new_cond = ast2ast._PreprocessIsBlockedCond( |
| 189 self.cnxn, cond, [100], self.services, None) |
| 190 self.assertEqual(expected_op, new_cond.op) |
| 191 self.assertEqual([blocked_field], new_cond.field_defs) |
| 192 self.assertEqual([], new_cond.int_values) |
| 193 self.assertEqual([], new_cond.str_values) |
| 194 |
| 195 def testPreprocessHasBlockedOnCond(self): |
| 196 blocked_field = BUILTIN_ISSUE_FIELDS['blockedon_id'] |
| 197 for op in (ast_pb2.QueryOp.IS_DEFINED, ast_pb2.QueryOp.IS_NOT_DEFINED): |
| 198 cond = ast_pb2.MakeCond(op, [blocked_field], [], []) |
| 199 new_cond = ast2ast._PreprocessBlockedOnCond( |
| 200 self.cnxn, cond, [100], self.services, None) |
| 201 self.assertEqual(op, op) |
| 202 self.assertEqual([blocked_field], new_cond.field_defs) |
| 203 self.assertEqual([], new_cond.int_values) |
| 204 self.assertEqual([], new_cond.str_values) |
| 205 |
| 206 def testPreprocessHasBlockingCond(self): |
| 207 blocking_field = BUILTIN_ISSUE_FIELDS['blocking_id'] |
| 208 for op in (ast_pb2.QueryOp.IS_DEFINED, ast_pb2.QueryOp.IS_NOT_DEFINED): |
| 209 cond = ast_pb2.MakeCond(op, [blocking_field], [], []) |
| 210 new_cond = ast2ast._PreprocessBlockingCond( |
| 211 self.cnxn, cond, [100], self.services, None) |
| 212 self.assertEqual(op, op) |
| 213 self.assertEqual([blocking_field], new_cond.field_defs) |
| 214 self.assertEqual([], new_cond.int_values) |
| 215 self.assertEqual([], new_cond.str_values) |
| 216 |
| 217 def testPreprocessBlockingCond_WithSingleProjectID(self): |
| 218 blocking_field = BUILTIN_ISSUE_FIELDS['blocking'] |
| 219 blocking_id_field = BUILTIN_ISSUE_FIELDS['blocking_id'] |
| 220 self.services.project.TestAddProject('Project1', project_id=1) |
| 221 issue1 = fake.MakeTestIssue( |
| 222 project_id=1, local_id=1, summary='sum', status='new', owner_id=2, |
| 223 issue_id=101) |
| 224 issue2 = fake.MakeTestIssue( |
| 225 project_id=1, local_id=2, summary='sum', status='new', owner_id=2, |
| 226 issue_id=102) |
| 227 self.services.issue.TestAddIssue(issue1) |
| 228 self.services.issue.TestAddIssue(issue2) |
| 229 |
| 230 for local_ids, expected in ( |
| 231 (['1'], [101]), # One existing issue. |
| 232 (['Project1:1'], [101]), # One existing issue with project prefix. |
| 233 (['1', '2'], [101, 102]), # Two existing issues. |
| 234 (['3'], [])): # Non-existant issue. |
| 235 cond = ast_pb2.MakeCond( |
| 236 ast_pb2.QueryOp.TEXT_HAS, [blocking_field], local_ids, []) |
| 237 new_cond = ast2ast._PreprocessBlockingCond( |
| 238 self.cnxn, cond, [1], self.services, None) |
| 239 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 240 self.assertEqual([blocking_id_field], new_cond.field_defs) |
| 241 self.assertEqual(expected, new_cond.int_values) |
| 242 self.assertEqual([], new_cond.str_values) |
| 243 |
| 244 def testPreprocessBlockingCond_WithMultipleProjectIDs(self): |
| 245 blocking_field = BUILTIN_ISSUE_FIELDS['blocking'] |
| 246 blocking_id_field = BUILTIN_ISSUE_FIELDS['blocking_id'] |
| 247 self.services.project.TestAddProject('Project1', project_id=1) |
| 248 self.services.project.TestAddProject('Project2', project_id=2) |
| 249 issue1 = fake.MakeTestIssue( |
| 250 project_id=1, local_id=1, summary='sum', status='new', owner_id=2, |
| 251 issue_id=101) |
| 252 issue2 = fake.MakeTestIssue( |
| 253 project_id=2, local_id=2, summary='sum', status='new', owner_id=2, |
| 254 issue_id=102) |
| 255 self.services.issue.TestAddIssue(issue1) |
| 256 self.services.issue.TestAddIssue(issue2) |
| 257 |
| 258 for local_ids, expected in ( |
| 259 (['Project1:1'], [101]), |
| 260 (['Project1:1', 'Project2:2'], [101, 102])): |
| 261 cond = ast_pb2.MakeCond( |
| 262 ast_pb2.QueryOp.TEXT_HAS, [blocking_field], local_ids, []) |
| 263 new_cond = ast2ast._PreprocessBlockingCond( |
| 264 self.cnxn, cond, [1, 2], self.services, None) |
| 265 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 266 self.assertEqual([blocking_id_field], new_cond.field_defs) |
| 267 self.assertEqual(expected, new_cond.int_values) |
| 268 self.assertEqual([], new_cond.str_values) |
| 269 |
| 270 def testPreprocessBlockingCond_WithMultipleProjectIDs_NoPrefix(self): |
| 271 blocking_field = BUILTIN_ISSUE_FIELDS['blocking'] |
| 272 self.services.project.TestAddProject('Project1', project_id=1) |
| 273 self.services.project.TestAddProject('Project2', project_id=2) |
| 274 issue1 = fake.MakeTestIssue( |
| 275 project_id=1, local_id=1, summary='sum', status='new', owner_id=2, |
| 276 issue_id=101) |
| 277 issue2 = fake.MakeTestIssue( |
| 278 project_id=2, local_id=2, summary='sum', status='new', owner_id=2, |
| 279 issue_id=102) |
| 280 self.services.issue.TestAddIssue(issue1) |
| 281 self.services.issue.TestAddIssue(issue2) |
| 282 |
| 283 for local_ids in (['1'], ['1', '2'], ['3']): |
| 284 cond = ast_pb2.MakeCond( |
| 285 ast_pb2.QueryOp.TEXT_HAS, [blocking_field], local_ids, []) |
| 286 try: |
| 287 ast2ast._PreprocessBlockingCond( |
| 288 self.cnxn, cond, [1, 2], self.services, None) |
| 289 self.fail('Expected an Exception.') |
| 290 except ValueError, e: |
| 291 self.assertEquals( |
| 292 'Searching for issues accross multiple/all projects without ' |
| 293 'project prefixes is ambiguous and is currently not supported.', |
| 294 e.message) |
| 295 |
| 296 def testPreprocessStatusCond(self): |
| 297 status_field = BUILTIN_ISSUE_FIELDS['status'] |
| 298 status_id_field = BUILTIN_ISSUE_FIELDS['status_id'] |
| 299 |
| 300 cond = ast_pb2.MakeCond( |
| 301 ast_pb2.QueryOp.IS_DEFINED, [status_field], [], []) |
| 302 new_cond = ast2ast._PreprocessStatusCond( |
| 303 self.cnxn, cond, [789], self.services, self.config) |
| 304 self.assertEqual(ast_pb2.QueryOp.IS_DEFINED, new_cond.op) |
| 305 self.assertEqual([status_id_field], new_cond.field_defs) |
| 306 self.assertEqual([], new_cond.int_values) |
| 307 self.assertEqual([], new_cond.str_values) |
| 308 |
| 309 cond = ast_pb2.MakeCond( |
| 310 ast_pb2.QueryOp.EQ, [status_field], ['New', 'Assigned'], []) |
| 311 new_cond = ast2ast._PreprocessStatusCond( |
| 312 self.cnxn, cond, [789], self.services, self.config) |
| 313 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 314 self.assertEqual([status_id_field], new_cond.field_defs) |
| 315 self.assertEqual([0, 1], new_cond.int_values) |
| 316 self.assertEqual([], new_cond.str_values) |
| 317 |
| 318 cond = ast_pb2.MakeCond( |
| 319 ast_pb2.QueryOp.TEXT_HAS, [status_field], [], []) |
| 320 new_cond = ast2ast._PreprocessStatusCond( |
| 321 self.cnxn, cond, [789], self.services, self.config) |
| 322 self.assertEqual([], new_cond.int_values) |
| 323 |
| 324 def testPrefixRegex(self): |
| 325 cond = ast_pb2.MakeCond( |
| 326 ast_pb2.QueryOp.IS_DEFINED, [BUILTIN_ISSUE_FIELDS['label']], |
| 327 ['Priority', 'Severity'], []) |
| 328 regex = ast2ast._MakePrefixRegex(cond) |
| 329 self.assertRegexpMatches('Priority-1', regex) |
| 330 self.assertRegexpMatches('Severity-3', regex) |
| 331 self.assertNotRegexpMatches('My-Priority', regex) |
| 332 |
| 333 def testKeyValueRegex(self): |
| 334 cond = ast_pb2.MakeCond( |
| 335 ast_pb2.QueryOp.KEY_HAS, [BUILTIN_ISSUE_FIELDS['label']], |
| 336 ['Type-Feature', 'Type-Security'], []) |
| 337 regex = ast2ast._MakeKeyValueRegex(cond) |
| 338 self.assertRegexpMatches('Type-Feature', regex) |
| 339 self.assertRegexpMatches('Type-Bug-Security', regex) |
| 340 self.assertNotRegexpMatches('Type-Bug', regex) |
| 341 self.assertNotRegexpMatches('Security-Feature', regex) |
| 342 |
| 343 def testKeyValueRegex_multipleKeys(self): |
| 344 cond = ast_pb2.MakeCond( |
| 345 ast_pb2.QueryOp.KEY_HAS, [BUILTIN_ISSUE_FIELDS['label']], |
| 346 ['Type-Bug', 'Security-Bug'], []) |
| 347 with self.assertRaises(ValueError): |
| 348 ast2ast._MakeKeyValueRegex(cond) |
| 349 |
| 350 def testWordBoundryRegex(self): |
| 351 cond = ast_pb2.MakeCond( |
| 352 ast_pb2.QueryOp.TEXT_HAS, [BUILTIN_ISSUE_FIELDS['label']], |
| 353 ['Type-Bug'], []) |
| 354 regex = ast2ast._MakeKeyValueRegex(cond) |
| 355 self.assertRegexpMatches('Type-Bug-Security', regex) |
| 356 self.assertNotRegexpMatches('Type-BugSecurity', regex) |
| 357 |
| 358 def testPreprocessLabelCond(self): |
| 359 label_field = BUILTIN_ISSUE_FIELDS['label'] |
| 360 label_id_field = BUILTIN_ISSUE_FIELDS['label_id'] |
| 361 |
| 362 cond = ast_pb2.MakeCond( |
| 363 ast_pb2.QueryOp.IS_DEFINED, [label_field], ['Priority'], []) |
| 364 new_cond = ast2ast._PreprocessLabelCond( |
| 365 self.cnxn, cond, [789], self.services, self.config) |
| 366 self.assertEqual(ast_pb2.QueryOp.IS_DEFINED, new_cond.op) |
| 367 self.assertEqual([label_id_field], new_cond.field_defs) |
| 368 self.assertEqual([1, 2, 3], new_cond.int_values) |
| 369 self.assertEqual([], new_cond.str_values) |
| 370 |
| 371 cond = ast_pb2.MakeCond( |
| 372 ast_pb2.QueryOp.EQ, [label_field], |
| 373 ['Priority-Low', 'Priority-High'], []) |
| 374 new_cond = ast2ast._PreprocessLabelCond( |
| 375 self.cnxn, cond, [789], self.services, self.config) |
| 376 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 377 self.assertEqual([label_id_field], new_cond.field_defs) |
| 378 self.assertEqual([0, 1], new_cond.int_values) |
| 379 self.assertEqual([], new_cond.str_values) |
| 380 |
| 381 cond = ast_pb2.MakeCond( |
| 382 ast_pb2.QueryOp.KEY_HAS, [label_field], |
| 383 ['Priority-Low', 'Priority-High'], []) |
| 384 new_cond = ast2ast._PreprocessLabelCond( |
| 385 self.cnxn, cond, [789], self.services, self.config) |
| 386 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 387 self.assertEqual([label_id_field], new_cond.field_defs) |
| 388 self.assertEqual([1, 2, 3], new_cond.int_values) |
| 389 self.assertEqual([], new_cond.str_values) |
| 390 |
| 391 def testPreprocessComponentCond_QuickOR(self): |
| 392 component_field = BUILTIN_ISSUE_FIELDS['component'] |
| 393 component_id_field = BUILTIN_ISSUE_FIELDS['component_id'] |
| 394 |
| 395 cond = ast_pb2.MakeCond( |
| 396 ast_pb2.QueryOp.IS_DEFINED, [component_field], ['UI', 'DB'], []) |
| 397 new_cond = ast2ast._PreprocessComponentCond( |
| 398 self.cnxn, cond, [789], self.services, self.config) |
| 399 self.assertEqual(ast_pb2.QueryOp.IS_DEFINED, new_cond.op) |
| 400 self.assertEqual([component_id_field], new_cond.field_defs) |
| 401 self.assertEqual([101, 102, 201], new_cond.int_values) |
| 402 self.assertEqual([], new_cond.str_values) |
| 403 |
| 404 cond = ast_pb2.MakeCond( |
| 405 ast_pb2.QueryOp.TEXT_HAS, [component_field], ['UI', 'DB'], []) |
| 406 new_cond = ast2ast._PreprocessComponentCond( |
| 407 self.cnxn, cond, [789], self.services, self.config) |
| 408 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 409 self.assertEqual([component_id_field], new_cond.field_defs) |
| 410 self.assertEqual([101, 102, 201], new_cond.int_values) |
| 411 self.assertEqual([], new_cond.str_values) |
| 412 |
| 413 cond = ast_pb2.MakeCond( |
| 414 ast_pb2.QueryOp.TEXT_HAS, [component_field], [], []) |
| 415 new_cond = ast2ast._PreprocessComponentCond( |
| 416 self.cnxn, cond, [789], self.services, self.config) |
| 417 self.assertEqual([], new_cond.int_values) |
| 418 |
| 419 cond = ast_pb2.MakeCond( |
| 420 ast_pb2.QueryOp.TEXT_HAS, [component_field], ['unknown@example.com'], |
| 421 []) |
| 422 new_cond = ast2ast._PreprocessComponentCond( |
| 423 self.cnxn, cond, [789], self.services, self.config) |
| 424 self.assertEqual([], new_cond.int_values) |
| 425 |
| 426 def testPreprocessComponentCond_RootedAndNonRooted(self): |
| 427 component_field = BUILTIN_ISSUE_FIELDS['component'] |
| 428 component_id_field = BUILTIN_ISSUE_FIELDS['component_id'] |
| 429 |
| 430 cond = ast_pb2.MakeCond( |
| 431 ast_pb2.QueryOp.TEXT_HAS, [component_field], ['UI'], []) |
| 432 new_cond = ast2ast._PreprocessComponentCond( |
| 433 self.cnxn, cond, [789], self.services, self.config) |
| 434 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 435 self.assertEqual([component_id_field], new_cond.field_defs) |
| 436 self.assertEqual([101, 102], new_cond.int_values) |
| 437 self.assertEqual([], new_cond.str_values) |
| 438 |
| 439 cond = ast_pb2.MakeCond( |
| 440 ast_pb2.QueryOp.EQ, [component_field], ['UI'], []) |
| 441 new_cond = ast2ast._PreprocessComponentCond( |
| 442 self.cnxn, cond, [789], self.services, self.config) |
| 443 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 444 self.assertEqual([component_id_field], new_cond.field_defs) |
| 445 self.assertEqual([101], new_cond.int_values) |
| 446 self.assertEqual([], new_cond.str_values) |
| 447 |
| 448 def testPreprocessExactUsers_IsDefined(self): |
| 449 cond = ast_pb2.MakeCond( |
| 450 ast_pb2.QueryOp.IS_DEFINED, [OWNER_FIELD], ['a@example.com'], []) |
| 451 new_cond = ast2ast._PreprocessExactUsers( |
| 452 self.cnxn, cond, self.services.user, [OWNER_ID_FIELD]) |
| 453 self.assertEqual(ast_pb2.QueryOp.IS_DEFINED, new_cond.op) |
| 454 self.assertEqual([OWNER_ID_FIELD], new_cond.field_defs) |
| 455 self.assertEqual([], new_cond.int_values) |
| 456 self.assertEqual([], new_cond.str_values) |
| 457 |
| 458 def testPreprocessExactUsers_UserFound(self): |
| 459 cond = ast_pb2.MakeCond( |
| 460 ast_pb2.QueryOp.TEXT_HAS, [OWNER_FIELD], ['a@example.com'], []) |
| 461 new_cond = ast2ast._PreprocessExactUsers( |
| 462 self.cnxn, cond, self.services.user, [OWNER_ID_FIELD]) |
| 463 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 464 self.assertEqual([OWNER_ID_FIELD], new_cond.field_defs) |
| 465 self.assertEqual([111L], new_cond.int_values) |
| 466 self.assertEqual([], new_cond.str_values) |
| 467 |
| 468 def testPreprocessExactUsers_UserSpecifiedByID(self): |
| 469 cond = ast_pb2.MakeCond( |
| 470 ast_pb2.QueryOp.TEXT_HAS, [OWNER_FIELD], ['123'], []) |
| 471 new_cond = ast2ast._PreprocessExactUsers( |
| 472 self.cnxn, cond, self.services.user, [OWNER_ID_FIELD]) |
| 473 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 474 self.assertEqual([OWNER_ID_FIELD], new_cond.field_defs) |
| 475 self.assertEqual([123L], new_cond.int_values) |
| 476 self.assertEqual([], new_cond.str_values) |
| 477 |
| 478 def testPreprocessExactUsers_NonEquality(self): |
| 479 cond = ast_pb2.MakeCond( |
| 480 ast_pb2.QueryOp.GE, [OWNER_ID_FIELD], ['111'], []) |
| 481 new_cond = ast2ast._PreprocessExactUsers( |
| 482 self.cnxn, cond, self.services.user, [OWNER_ID_FIELD]) |
| 483 self.assertEqual(cond, new_cond) |
| 484 |
| 485 def testPreprocessExactUsers_UserNotFound(self): |
| 486 cond = ast_pb2.MakeCond( |
| 487 ast_pb2.QueryOp.TEXT_HAS, [OWNER_FIELD], ['unknown@example.com'], []) |
| 488 new_cond = ast2ast._PreprocessExactUsers( |
| 489 self.cnxn, cond, self.services.user, [OWNER_ID_FIELD]) |
| 490 self.assertEqual(cond, new_cond) |
| 491 |
| 492 def testPreprocessCustomCond_User(self): |
| 493 fd = tracker_pb2.FieldDef( |
| 494 field_id=1, field_name='TPM', |
| 495 field_type=tracker_pb2.FieldTypes.USER_TYPE) |
| 496 cond = ast_pb2.MakeCond( |
| 497 ast_pb2.QueryOp.TEXT_HAS, [fd], ['a@example.com'], []) |
| 498 new_cond = ast2ast._PreprocessCustomCond(self.cnxn, cond, self.services) |
| 499 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 500 self.assertEqual(cond.field_defs, new_cond.field_defs) |
| 501 self.assertEqual([111L], new_cond.int_values) |
| 502 self.assertEqual([], new_cond.str_values) |
| 503 |
| 504 cond = ast_pb2.MakeCond( |
| 505 ast_pb2.QueryOp.TEXT_HAS, [fd], ['111'], []) |
| 506 new_cond = ast2ast._PreprocessCustomCond(self.cnxn, cond, self.services) |
| 507 self.assertEqual(ast_pb2.QueryOp.EQ, new_cond.op) |
| 508 self.assertEqual(cond.field_defs, new_cond.field_defs) |
| 509 self.assertEqual([111L], new_cond.int_values) |
| 510 self.assertEqual([], new_cond.str_values) |
| 511 |
| 512 cond = ast_pb2.MakeCond( |
| 513 ast_pb2.QueryOp.TEXT_HAS, [fd], ['unknown@example.com'], []) |
| 514 new_cond = ast2ast._PreprocessCustomCond(self.cnxn, cond, self.services) |
| 515 self.assertEqual(cond, new_cond) |
| 516 |
| 517 def testPreprocessCustomCond_NonUser(self): |
| 518 fd = tracker_pb2.FieldDef( |
| 519 field_id=1, field_name='TPM', |
| 520 field_type=tracker_pb2.FieldTypes.INT_TYPE) |
| 521 cond = ast_pb2.MakeCond( |
| 522 ast_pb2.QueryOp.TEXT_HAS, [fd], ['foo'], [123]) |
| 523 new_cond = ast2ast._PreprocessCustomCond(self.cnxn, cond, self.services) |
| 524 self.assertEqual(cond, new_cond) |
| 525 |
| 526 fd.field_type = tracker_pb2.FieldTypes.STR_TYPE |
| 527 new_cond = ast2ast._PreprocessCustomCond(self.cnxn, cond, self.services) |
| 528 self.assertEqual(cond, new_cond) |
| 529 |
| 530 def testPreprocessCond_NoChange(self): |
| 531 cond = ast_pb2.MakeCond(ast_pb2.QueryOp.TEXT_HAS, [ANY_FIELD], ['foo'], []) |
| 532 self.assertEqual( |
| 533 cond, ast2ast._PreprocessCond(self.cnxn, cond, [], None, None)) |
| 534 |
| 535 def testTextOpToIntOp(self): |
| 536 self.assertEqual(ast_pb2.QueryOp.EQ, |
| 537 ast2ast._TextOpToIntOp(ast_pb2.QueryOp.TEXT_HAS)) |
| 538 self.assertEqual(ast_pb2.QueryOp.EQ, |
| 539 ast2ast._TextOpToIntOp(ast_pb2.QueryOp.KEY_HAS)) |
| 540 self.assertEqual(ast_pb2.QueryOp.NE, |
| 541 ast2ast._TextOpToIntOp(ast_pb2.QueryOp.NOT_TEXT_HAS)) |
| 542 |
| 543 for enum_name, _enum_id in ast_pb2.QueryOp.to_dict().iteritems(): |
| 544 no_change_op = ast_pb2.QueryOp(enum_name) |
| 545 if no_change_op not in ( |
| 546 ast_pb2.QueryOp.TEXT_HAS, |
| 547 ast_pb2.QueryOp.NOT_TEXT_HAS, |
| 548 ast_pb2.QueryOp.KEY_HAS): |
| 549 self.assertEqual(no_change_op, |
| 550 ast2ast._TextOpToIntOp(no_change_op)) |
| 551 |
| 552 |
| 553 if __name__ == '__main__': |
| 554 unittest.main() |
OLD | NEW |