123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664 |
- #!/usr/bin/env python3
- # Copyright (c) 2021 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- import os.path
- import subprocess
- import sys
- import unittest
- from unittest import mock
- ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
- sys.path.insert(0, ROOT_DIR)
- from testing_support.presubmit_canned_checks_test_mocks import (
- MockFile, MockAffectedFile, MockInputApi, MockOutputApi, MockChange)
- import presubmit_canned_checks
- # TODO: Should fix these warnings.
- # pylint: disable=line-too-long
- class InclusiveLanguageCheckTest(unittest.TestCase):
- def testBlockedTerms(self):
- input_api = MockInputApi()
- input_api.change.RepositoryRoot = lambda: ''
- input_api.presubmit_local_path = ''
- input_api.files = [
- MockFile(
- os.path.normpath(
- 'infra/inclusive_language_presubmit_exempt_dirs.txt'), [
- 'some/dir 2 1',
- 'some/other/dir 2 1',
- ]),
- MockFile(
- os.path.normpath('some/ios/file.mm'),
- [
- 'TEST(SomeClassTest, SomeInteraction, blacklist) {', # nocheck
- '}'
- ]),
- MockFile(
- os.path.normpath('some/mac/file.mm'),
- [
- 'TEST(SomeClassTest, SomeInteraction, BlackList) {', # nocheck
- '}'
- ]),
- MockFile(os.path.normpath('another/ios_file.mm'),
- ['class SomeTest : public testing::Test blocklist {};']),
- MockFile(os.path.normpath('some/ios/file_egtest.mm'),
- ['- (void)testSomething { V(whitelist); }']), # nocheck
- MockFile(
- os.path.normpath('some/ios/file_unittest.mm'),
- ['TEST_F(SomeTest, Whitelist) { V(allowlist); }']), # nocheck
- MockFile(
- os.path.normpath('some/doc/file.md'),
- [
- '# Title',
- 'Some markdown text includes master.', # nocheck
- ]),
- MockFile(
- os.path.normpath('some/doc/ok_file.md'),
- [
- '# Title',
- # This link contains a '//' which the matcher thinks is a
- # C-style comment, and the 'master' term appears after the
- # '//' in the URL, so it gets ignored as a side-effect.
- '[Ignored](https://git/project.git/+/master/foo)', # nocheck
- ]),
- MockFile(
- os.path.normpath('some/doc/branch_name_file.md'),
- [
- '# Title',
- # Matches appearing before `//` still trigger the check.
- '[src/master](https://git/p.git/+/master/foo)', # nocheck
- ]),
- MockFile(
- os.path.normpath('some/java/file/TestJavaDoc.java'),
- [
- '/**',
- ' * This line contains the word master,', # nocheck
- '* ignored because this is a comment. See {@link',
- ' * https://s/src/+/master:tools/README.md}', # nocheck
- ' */'
- ]),
- MockFile(
- os.path.normpath('some/java/file/TestJava.java'),
- [
- 'class TestJava {',
- ' public String master;', # nocheck
- '}'
- ]),
- MockFile(
- os.path.normpath('some/html/file.html'),
- [
- '<-- an existing html multiline comment',
- 'says "master" here', # nocheck
- 'in the comment -->'
- ])
- ]
- errors = presubmit_canned_checks.CheckInclusiveLanguage(
- input_api, MockOutputApi())
- self.assertEqual(1, len(errors))
- self.assertTrue(
- os.path.normpath('some/ios/file.mm') in errors[0].message)
- self.assertTrue(
- os.path.normpath('another/ios_file.mm') not in errors[0].message)
- self.assertTrue(
- os.path.normpath('some/mac/file.mm') in errors[0].message)
- self.assertTrue(
- os.path.normpath('some/ios/file_egtest.mm') in errors[0].message)
- self.assertTrue(
- os.path.normpath('some/ios/file_unittest.mm') in errors[0].message)
- self.assertTrue(
- os.path.normpath('some/doc/file.md') not in errors[0].message)
- self.assertTrue(
- os.path.normpath('some/doc/ok_file.md') not in errors[0].message)
- self.assertTrue(
- os.path.normpath('some/doc/branch_name_file.md') not in
- errors[0].message)
- self.assertTrue(
- os.path.normpath('some/java/file/TestJavaDoc.java') not in
- errors[0].message)
- self.assertTrue(
- os.path.normpath('some/java/file/TestJava.java') not in
- errors[0].message)
- self.assertTrue(
- os.path.normpath('some/html/file.html') not in errors[0].message)
- def testBlockedTermsWithLegacy(self):
- input_api = MockInputApi()
- input_api.change.RepositoryRoot = lambda: ''
- input_api.presubmit_local_path = ''
- input_api.files = [
- MockFile(
- os.path.normpath(
- 'infra/inclusive_language_presubmit_exempt_dirs.txt'), [
- 'some/ios 2 1',
- 'some/other/dir 2 1',
- ]),
- MockFile(
- os.path.normpath('some/ios/file.mm'),
- [
- 'TEST(SomeClassTest, SomeInteraction, blacklist) {', # nocheck
- '}'
- ]),
- MockFile(
- os.path.normpath('some/ios/subdir/file.mm'),
- [
- 'TEST(SomeClassTest, SomeInteraction, blacklist) {', # nocheck
- '}'
- ]),
- MockFile(
- os.path.normpath('some/mac/file.mm'),
- [
- 'TEST(SomeClassTest, SomeInteraction, BlackList) {', # nocheck
- '}'
- ]),
- MockFile(os.path.normpath('another/ios_file.mm'),
- ['class SomeTest : public testing::Test blocklist {};']),
- MockFile(os.path.normpath('some/ios/file_egtest.mm'),
- ['- (void)testSomething { V(whitelist); }']), # nocheck
- MockFile(
- os.path.normpath('some/ios/file_unittest.mm'),
- ['TEST_F(SomeTest, Whitelist) { V(allowlist); }']), # nocheck
- ]
- errors = presubmit_canned_checks.CheckInclusiveLanguage(
- input_api, MockOutputApi())
- self.assertEqual(1, len(errors))
- self.assertTrue(
- os.path.normpath('some/ios/file.mm') not in errors[0].message)
- self.assertTrue(
- os.path.normpath('some/ios/subdir/file.mm') in errors[0].message)
- self.assertTrue(
- os.path.normpath('another/ios_file.mm') not in errors[0].message)
- self.assertTrue(
- os.path.normpath('some/mac/file.mm') in errors[0].message)
- self.assertTrue(
- os.path.normpath('some/ios/file_egtest.mm') not in
- errors[0].message)
- self.assertTrue(
- os.path.normpath('some/ios/file_unittest.mm') not in
- errors[0].message)
- def testBlockedTermsWithNocheck(self):
- input_api = MockInputApi()
- input_api.change.RepositoryRoot = lambda: ''
- input_api.presubmit_local_path = ''
- input_api.files = [
- MockFile(
- os.path.normpath(
- 'infra/inclusive_language_presubmit_exempt_dirs.txt'), [
- 'some/dir 2 1',
- 'some/other/dir 2 1',
- ]),
- MockFile(
- os.path.normpath('some/ios/file.mm'),
- [
- 'TEST(SomeClassTest, SomeInteraction, ',
- ' blacklist) { // nocheck', # nocheck
- '}'
- ]),
- MockFile(
- os.path.normpath('some/mac/file.mm'),
- [
- 'TEST(SomeClassTest, SomeInteraction, ',
- 'BlackList) { // nocheck', # nocheck
- '}'
- ]),
- MockFile(os.path.normpath('another/ios_file.mm'),
- ['class SomeTest : public testing::Test blocklist {};']),
- MockFile(os.path.normpath('some/ios/file_egtest.mm'),
- ['- (void)testSomething { ', 'V(whitelist); } // nocheck'
- ]), # nocheck
- MockFile(
- os.path.normpath('some/ios/file_unittest.mm'),
- [
- 'TEST_F(SomeTest, Whitelist) // nocheck', # nocheck
- ' { V(allowlist); }'
- ]),
- MockFile(
- os.path.normpath('some/doc/file.md'),
- [
- 'Master in markdown <!-- nocheck -->', # nocheck
- '## Subheading is okay'
- ]),
- MockFile(
- os.path.normpath('some/java/file/TestJava.java'),
- [
- 'class TestJava {',
- ' public String master; // nocheck', # nocheck
- '}'
- ]),
- MockFile(
- os.path.normpath('some/html/file.html'),
- [
- '<-- an existing html multiline comment',
- 'says "master" here --><!-- nocheck -->', # nocheck
- '<!-- in the comment -->'
- ])
- ]
- errors = presubmit_canned_checks.CheckInclusiveLanguage(
- input_api, MockOutputApi())
- self.assertEqual(0, len(errors))
- def testTopLevelDirExcempt(self):
- input_api = MockInputApi()
- input_api.change.RepositoryRoot = lambda: ''
- input_api.presubmit_local_path = ''
- input_api.files = [
- MockFile(
- os.path.normpath(
- 'infra/inclusive_language_presubmit_exempt_dirs.txt'), [
- '. 2 1',
- 'some/other/dir 2 1',
- ]),
- MockFile(
- os.path.normpath('presubmit_canned_checks_test.py'),
- [
- 'TEST(SomeClassTest, SomeInteraction, blacklist) {', # nocheck
- '}'
- ]),
- MockFile(
- os.path.normpath('presubmit_canned_checks.py'),
- ['- (void)testSth { V(whitelist); } // nocheck']), # nocheck
- ]
- errors = presubmit_canned_checks.CheckInclusiveLanguage(
- input_api, MockOutputApi())
- self.assertEqual(1, len(errors))
- self.assertTrue(
- os.path.normpath('presubmit_canned_checks_test.py') in
- errors[0].message)
- self.assertTrue(
- os.path.normpath('presubmit_canned_checks.py') not in
- errors[0].message)
- def testChangeIsForSomeOtherRepo(self):
- input_api = MockInputApi()
- input_api.change.RepositoryRoot = lambda: 'v8'
- input_api.presubmit_local_path = ''
- input_api.files = [
- MockFile(
- os.path.normpath('some_file'),
- [
- '# this is a blacklist', # nocheck
- ]),
- ]
- errors = presubmit_canned_checks.CheckInclusiveLanguage(
- input_api, MockOutputApi())
- self.assertEqual([], errors)
- def testDirExemptWithComment(self):
- input_api = MockInputApi()
- input_api.change.RepositoryRoot = lambda: ''
- input_api.presubmit_local_path = ''
- input_api.files = [
- MockFile(
- os.path.normpath(
- 'infra/inclusive_language_presubmit_exempt_dirs.txt'), [
- '# this is a comment',
- 'dir1',
- '# dir2',
- ]),
- # this should be excluded
- MockFile(
- os.path.normpath('dir1/1.py'),
- [
- 'TEST(SomeClassTest, SomeInteraction, blacklist) {', # nocheck
- '}'
- ]),
- # this should not be excluded
- MockFile(os.path.normpath('dir2/2.py'),
- ['- (void)testSth { V(whitelist); }']), # nocheck
- ]
- errors = presubmit_canned_checks.CheckInclusiveLanguage(
- input_api, MockOutputApi())
- self.assertEqual(1, len(errors))
- self.assertTrue(os.path.normpath('dir1/1.py') not in errors[0].message)
- self.assertTrue(os.path.normpath('dir2/2.py') in errors[0].message)
- class DescriptionChecksTest(unittest.TestCase):
- def testCheckDescriptionUsesColonInsteadOfEquals(self):
- input_api = MockInputApi()
- input_api.change.RepositoryRoot = lambda: ''
- input_api.presubmit_local_path = ''
- # Verify error in case of the attempt to use "Bug=".
- input_api.change = MockChange([], 'Broken description\nBug=123')
- errors = presubmit_canned_checks.CheckDescriptionUsesColonInsteadOfEquals(
- input_api, MockOutputApi())
- self.assertEqual(1, len(errors))
- self.assertTrue('Bug=' in errors[0].message)
- # Verify error in case of the attempt to use "Fixed=".
- input_api.change = MockChange([], 'Broken description\nFixed=123')
- errors = presubmit_canned_checks.CheckDescriptionUsesColonInsteadOfEquals(
- input_api, MockOutputApi())
- self.assertEqual(1, len(errors))
- self.assertTrue('Fixed=' in errors[0].message)
- # Verify error in case of the attempt to use the lower case "bug=".
- input_api.change = MockChange([],
- 'Broken description lowercase\nbug=123')
- errors = presubmit_canned_checks.CheckDescriptionUsesColonInsteadOfEquals(
- input_api, MockOutputApi())
- self.assertEqual(1, len(errors))
- self.assertTrue('Bug=' in errors[0].message)
- # Verify no error in case of "Bug:"
- input_api.change = MockChange([], 'Correct description\nBug: 123')
- errors = presubmit_canned_checks.CheckDescriptionUsesColonInsteadOfEquals(
- input_api, MockOutputApi())
- self.assertEqual(0, len(errors))
- # Verify no error in case of "Fixed:"
- input_api.change = MockChange([], 'Correct description\nFixed: 123')
- errors = presubmit_canned_checks.CheckDescriptionUsesColonInsteadOfEquals(
- input_api, MockOutputApi())
- self.assertEqual(0, len(errors))
- class ChromiumDependencyMetadataCheckTest(unittest.TestCase):
- def testDefaultFileFilter(self):
- """Checks the default file filter limits the scope to Chromium dependency
- metadata files.
- """
- input_api = MockInputApi()
- input_api.change.RepositoryRoot = lambda: ''
- input_api.files = [
- MockFile(os.path.normpath('foo/README.md'), ['Shipped: no?']),
- MockFile(os.path.normpath('foo/main.py'), ['Shipped: yes?']),
- ]
- results = presubmit_canned_checks.CheckChromiumDependencyMetadata(
- input_api, MockOutputApi())
- self.assertEqual(len(results), 0)
- def testSkipDeletedFiles(self):
- """Checks validation is skipped for deleted files."""
- input_api = MockInputApi()
- input_api.change.RepositoryRoot = lambda: ''
- input_api.files = [
- MockFile(os.path.normpath('foo/README.chromium'), ['No fields'],
- action='D'),
- ]
- results = presubmit_canned_checks.CheckChromiumDependencyMetadata(
- input_api, MockOutputApi())
- self.assertEqual(len(results), 0)
- def testFeedbackForNoMetadata(self):
- """Checks presubmit results are returned for files without any metadata."""
- input_api = MockInputApi()
- input_api.change.RepositoryRoot = lambda: ''
- input_api.files = [
- MockFile(os.path.normpath('foo/README.chromium'), ['No fields']),
- ]
- results = presubmit_canned_checks.CheckChromiumDependencyMetadata(
- input_api, MockOutputApi())
- self.assertEqual(len(results), 1)
- self.assertTrue("No dependency metadata" in results[0].message)
- def testFeedbackForInvalidMetadata(self):
- """Checks presubmit results are returned for files with invalid metadata."""
- input_api = MockInputApi()
- input_api.change.RepositoryRoot = lambda: ''
- test_file = MockFile(os.path.normpath('foo/README.chromium'),
- ['Shipped: yes?'])
- input_api.files = [test_file]
- results = presubmit_canned_checks.CheckChromiumDependencyMetadata(
- input_api, MockOutputApi())
- # There should be 9 results due to
- # - missing 5 mandatory fields: Name, URL, Version, License, and
- # Security Critical
- # - 1 error for insufficent versioning info
- # - missing 2 required fields: License File, and
- # License Android Compatible
- # - Shipped should be only 'yes' or 'no'.
- self.assertEqual(len(results), 9)
- # Check each presubmit result is associated with the test file.
- for result in results:
- self.assertEqual(len(result.items), 1)
- self.assertEqual(result.items[0], test_file)
- class CheckUpdateOwnersFileReferences(unittest.TestCase):
- def testShowsWarningIfDeleting(self):
- input_api = MockInputApi()
- input_api.files = [
- MockFile(os.path.normpath('foo/OWNERS'), [], [], action='D'),
- ]
- results = presubmit_canned_checks.CheckUpdateOwnersFileReferences(
- input_api, MockOutputApi())
- self.assertEqual(1, len(results))
- self.assertEqual('warning', results[0].type)
- self.assertEqual(1, len(results[0].items))
- def testShowsWarningIfMoving(self):
- input_api = MockInputApi()
- input_api.files = [
- MockFile(os.path.normpath('new_directory/OWNERS'), [], [],
- action='A'),
- MockFile(os.path.normpath('old_directory/OWNERS'), [], [],
- action='D'),
- ]
- results = presubmit_canned_checks.CheckUpdateOwnersFileReferences(
- input_api, MockOutputApi())
- self.assertEqual(1, len(results))
- self.assertEqual('warning', results[0].type)
- self.assertEqual(1, len(results[0].items))
- def testNoWarningIfAdding(self):
- input_api = MockInputApi()
- input_api.files = [
- MockFile(os.path.normpath('foo/OWNERS'), [], [], action='A'),
- ]
- results = presubmit_canned_checks.CheckUpdateOwnersFileReferences(
- input_api, MockOutputApi())
- self.assertEqual(0, len(results))
- class CheckNoNewGitFilesAddedInDependenciesTest(unittest.TestCase):
- @mock.patch('presubmit_canned_checks._readDeps')
- def testNonNested(self, readDeps):
- readDeps.return_value = '''deps = {
- 'src/foo': {'url': 'bar', 'condition': 'non_git_source'},
- 'src/components/foo/bar': {'url': 'bar', 'condition': 'non_git_source'},
- }'''
- input_api = MockInputApi()
- input_api.files = [
- MockFile('components/foo/file1.java', ['otherFunction']),
- MockFile('components/foo/file2.java', ['hasSyncConsent']),
- MockFile('chrome/foo/file3.java', ['canSyncFeatureStart']),
- MockFile('chrome/foo/file4.java', ['isSyncFeatureEnabled']),
- MockFile('chrome/foo/file5.java', ['isSyncFeatureActive']),
- ]
- results = presubmit_canned_checks.CheckNoNewGitFilesAddedInDependencies(
- input_api, MockOutputApi())
- self.assertEqual(0, len(results))
- @mock.patch('presubmit_canned_checks._readDeps')
- def testCollision(self, readDeps):
- readDeps.return_value = '''deps = {
- 'src/foo': {'url': 'bar', 'condition': 'non_git_source'},
- 'src/baz': {'url': 'baz'},
- }'''
- input_api = MockInputApi()
- input_api.files = [
- MockAffectedFile('fo', 'content'), # no conflict
- MockAffectedFile('foo', 'content'), # conflict
- MockAffectedFile('foo/bar', 'content'), # conflict
- MockAffectedFile('baz/qux', 'content'), # conflict, but ignored
- ]
- results = presubmit_canned_checks.CheckNoNewGitFilesAddedInDependencies(
- input_api, MockOutputApi())
- self.assertEqual(2, len(results))
- self.assertIn('File: foo', str(results))
- self.assertIn('File: foo/bar', str(results))
- @mock.patch('presubmit_canned_checks._readDeps')
- def testNoDeps(self, readDeps):
- readDeps.return_value = '' # Empty deps
- input_api = MockInputApi()
- input_api.files = [
- MockAffectedFile('fo', 'content'), # no conflict
- MockAffectedFile('foo', 'content'), # conflict
- MockAffectedFile('foo/bar', 'content'), # conflict
- MockAffectedFile('baz/qux', 'content'), # conflict, but ignored
- ]
- results = presubmit_canned_checks.CheckNoNewGitFilesAddedInDependencies(
- input_api, MockOutputApi())
- self.assertEqual(0, len(results))
- class CheckNewDEPSHooksHasRequiredReviewersTest(unittest.TestCase):
- def setUp(self):
- self.input_api = MockInputApi()
- self.input_api.change = MockChange([], issue=123)
- self.input_api.change.RepositoryRoot = lambda: ''
- def test_no_gerrit_cl(self):
- self.input_api.change = MockChange([], issue=None)
- results = presubmit_canned_checks.CheckNewDEPSHooksHasRequiredReviewers(
- self.input_api, MockOutputApi())
- self.assertEqual(0, len(results))
- def test_no_deps_file_change(self):
- self.input_api.files = [
- MockAffectedFile('foo.py', 'content'),
- ]
- results = presubmit_canned_checks.CheckNewDEPSHooksHasRequiredReviewers(
- self.input_api, MockOutputApi())
- self.assertEqual(0, len(results))
- def test_new_deps_hook(self):
- gerrit_mock = mock.Mock()
- self.input_api.gerrit = gerrit_mock
- test_cases = [
- {
- 'name': 'no new hooks',
- 'old_contents': ['hooks = []'],
- 'new_contents': ['hooks = []'],
- 'reviewers': [],
- },
- {
- 'name':
- 'add new hook and require review',
- 'old_contents': ['hooks = [{"name": "old_hook"}]'],
- 'new_contents': [
- 'hooks = [{"name": "old_hook"}, {"name": "new_hook"}, {"name": "new_hook_2"}]'
- ],
- 'reviewers': [],
- 'expected_error_msg':
- 'New DEPS hooks (new_hook, new_hook_2) are found. Please '
- 'request review from one of the following reviewers:\n '
- '* foo@chromium.org\n * bar@chromium.org\n * baz@chromium.org'
- },
- {
- 'name':
- 'add new hook and require approval',
- 'old_contents': ['hooks = [{"name": "old_hook"}]'],
- 'new_contents': [
- 'hooks = [{"name": "old_hook"}, {"name": "new_hook"}, {"name": "new_hook_2"}]'
- ],
- 'submitting':
- True,
- 'reviewers': ['not_relevant@chromium.org'],
- 'expected_error_msg':
- 'New DEPS hooks (new_hook, new_hook_2) are found. The CL must '
- 'be approved by one of the following reviewers:\n'
- ' * foo@chromium.org\n * bar@chromium.org\n * baz@chromium.org'
- },
- {
- 'name':
- 'add new hook and reviewer is already added',
- 'old_contents': ['hooks = [{"name": "old_hook"}]'],
- 'new_contents': [
- 'hooks = [{"name": "old_hook"}, {"name": "new_hook"}, {"name": "new_hook_2"}]'
- ],
- 'reviewers': ['baz@chromium.org'],
- },
- {
- 'name':
- 'add new hook and reviewer already approves',
- 'old_contents': ['hooks = [{"name": "old_hook"}]'],
- 'new_contents': [
- 'hooks = [{"name": "old_hook"}, {"name": "new_hook"}, {"name": "new_hook_2"}]'
- ],
- 'submitting':
- True,
- 'reviewers': ['foo@chromium.org'],
- },
- {
- 'name':
- 'change existing hook',
- 'old_contents': [
- 'hooks = [{"name": "existing_hook", "action": ["run", "./test.sh"]}]'
- ],
- 'new_contents': [
- 'hooks = [{"name": "existing_hook", "action": ["run", "./test_v2.sh"]}]'
- ],
- 'reviewers': [],
- },
- {
- 'name':
- 'remove hook',
- 'old_contents':
- ['hooks = [{"name": "old_hook"}, {"name": "hook_to_remove"}]'],
- 'new_contents': ['hooks = [{"name": "old_hook"}]'],
- 'reviewers': [],
- },
- ]
- for case in test_cases:
- with self.subTest(case_name=case['name']):
- self.input_api.files = [
- MockFile('OWNERS', [
- 'per-file DEPS=foo@chromium.org # For new DEPS hook',
- 'per-file DEPS=bar@chromium.org, baz@chromium.org # For new DEPS hook'
- ]),
- MockAffectedFile('DEPS',
- old_contents=case['old_contents'],
- new_contents=case['new_contents']),
- ]
- if case.get('submitting', False):
- self.input_api.is_committing = True
- self.input_api.dry_run = False
- gerrit_mock.GetChangeReviewers.return_value = case['reviewers']
- results = presubmit_canned_checks.CheckNewDEPSHooksHasRequiredReviewers(
- self.input_api,
- MockOutputApi(),
- )
- if 'expected_error_msg' in case:
- self.assertEqual(1, len(results))
- self.assertEqual(case['expected_error_msg'],
- results[0].message)
- else:
- self.assertEqual(0, len(results))
- if __name__ == '__main__':
- unittest.main()
|