Attempts to prevent use of functions intended only for testing in non-testing code. For now this is just a best-effort implementation that ignores header files and may have some false positives. A better implementation would probably need a proper C++ parser.
(input_api, output_api)
| 415 | |
| 416 | |
| 417 | def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api): |
| 418 | """Attempts to prevent use of functions intended only for testing in |
| 419 | non-testing code. For now this is just a best-effort implementation |
| 420 | that ignores header files and may have some false positives. A |
| 421 | better implementation would probably need a proper C++ parser. |
| 422 | """ |
| 423 | # We only scan .cc files, as the declaration of for-testing functions in |
| 424 | # header files are hard to distinguish from calls to such functions without a |
| 425 | # proper C++ parser. |
| 426 | file_inclusion_pattern = r'.+\.cc' |
| 427 | |
| 428 | base_function_pattern = r'[ :]test::[^\s]+|ForTest(ing)?|for_test(ing)?' |
| 429 | inclusion_pattern = input_api.re.compile( |
| 430 | r'({})\s*\('.format(base_function_pattern)) |
| 431 | comment_pattern = input_api.re.compile( |
| 432 | r'//.*({})'.format(base_function_pattern)) |
| 433 | exclusion_pattern = input_api.re.compile( |
| 434 | r'::[A-Za-z0-9_]+({})|({})[^;]+'.format(base_function_pattern, |
| 435 | base_function_pattern) + '\{') |
| 436 | |
| 437 | def FilterFile(affected_file): |
| 438 | files_to_skip = (_EXCLUDED_PATHS + |
| 439 | _TEST_CODE_EXCLUDED_PATHS + |
| 440 | input_api.DEFAULT_FILES_TO_SKIP) |
| 441 | return input_api.FilterSourceFile( |
| 442 | affected_file, |
| 443 | files_to_check=(file_inclusion_pattern, ), |
| 444 | files_to_skip=files_to_skip) |
| 445 | |
| 446 | problems = [] |
| 447 | for f in input_api.AffectedSourceFiles(FilterFile): |
| 448 | local_path = f.LocalPath() |
| 449 | for line_number, line in f.ChangedContents(): |
| 450 | if (inclusion_pattern.search(line) and |
| 451 | not comment_pattern.search(line) and |
| 452 | not exclusion_pattern.search(line)): |
| 453 | problems.append('{}:{}\n {}'.format(local_path, line_number, |
| 454 | line.strip())) |
| 455 | |
| 456 | if problems: |
| 457 | return [output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)] |
| 458 | else: |
| 459 | return [] |
| 460 | |
| 461 | |
| 462 | def _CheckGenderNeutralInLicenses(input_api, output_api): |