diff --git a/presubmit_canned_checks.py b/presubmit_canned_checks.py index 88fe905d8..321858933 100644 --- a/presubmit_canned_checks.py +++ b/presubmit_canned_checks.py @@ -1957,7 +1957,7 @@ _NON_INCLUSIVE_TERMS = ( # ...' will not. This may require some tweaking to catch these cases # without triggering a lot of false positives. Leaving it naive and # less matchy for now. - r'/\b(?i)((black|white)list|slave)\b', # nocheck + r'/(?i)\b((black|white)list|slave)\b', # nocheck ( 'Please don\'t use blacklist, whitelist, ' # nocheck 'or slave in your', # nocheck @@ -1966,7 +1966,7 @@ _NON_INCLUSIVE_TERMS = ( 'at the end of the offending line will bypass this PRESUBMIT error', 'but avoid using this whenever possible. Reach out to', 'community@chromium.org if you have questions'), - True),) + True), ) def _GetMessageForMatchingTerm(input_api, affected_file, line_number, line, diff --git a/presubmit_canned_checks_test.py b/presubmit_canned_checks_test.py deleted file mode 100644 index d53a39ded..000000000 --- a/presubmit_canned_checks_test.py +++ /dev/null @@ -1,279 +0,0 @@ -#!/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 unittest - -from presubmit_canned_checks_test_mocks import MockFile, MockAffectedFile -from presubmit_canned_checks_test_mocks import MockInputApi, MockOutputApi -from presubmit_canned_checks_test_mocks import MockChange - -import presubmit_canned_checks - -class InclusiveLanguageCheckTest(unittest.TestCase): - def testBlockedTerms(self): - input_api = MockInputApi() - input_api.change.RepositoryRoot = lambda: '' - input_api.presubmit_local_path = '' - - input_api.files = [ - MockFile('infra/inclusive_language_presubmit_exempt_dirs.txt', [ - 'some/dir 2 1', - 'some/other/dir 2 1', - ]), - MockFile('some/ios/file.mm', - ['TEST(SomeClassTest, SomeInteraction, blacklist) {', # nocheck - '}']), - MockFile('some/mac/file.mm', - ['TEST(SomeClassTest, SomeInteraction, BlackList) {', # nocheck - '}']), - MockFile('another/ios_file.mm', - ['class SomeTest : public testing::Test blocklist {};']), - MockFile('some/ios/file_egtest.mm', - ['- (void)testSomething { V(whitelist); }']), # nocheck - MockFile('some/ios/file_unittest.mm', - ['TEST_F(SomeTest, Whitelist) { V(allowlist); }']), # nocheck - MockFile('some/doc/file.md', - ['# Title', - 'Some markdown text includes master.', # nocheck - ]), - MockFile('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('some/doc/branch_name_file.md', - ['# Title', - # Matches appearing before `//` still trigger the check. - '[src/master](https://git/p.git/+/master/foo)', # nocheck - ]), - MockFile('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('some/java/file/TestJava.java', - ['class TestJava {', - ' public String master;', # nocheck - '}']), - MockFile('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('some/ios/file.mm' in errors[0].message) - self.assertTrue('another/ios_file.mm' not in errors[0].message) - self.assertTrue('some/mac/file.mm' in errors[0].message) - self.assertTrue('some/ios/file_egtest.mm' in errors[0].message) - self.assertTrue('some/ios/file_unittest.mm' in errors[0].message) - self.assertTrue('some/doc/file.md' not in errors[0].message) - self.assertTrue('some/doc/ok_file.md' not in errors[0].message) - self.assertTrue('some/doc/branch_name_file.md' not in errors[0].message) - self.assertTrue('some/java/file/TestJavaDoc.java' not in errors[0].message) - self.assertTrue('some/java/file/TestJava.java' not in errors[0].message) - self.assertTrue('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('infra/inclusive_language_presubmit_exempt_dirs.txt', [ - 'some/ios 2 1', - 'some/other/dir 2 1', - ]), - MockFile('some/ios/file.mm', - ['TEST(SomeClassTest, SomeInteraction, blacklist) {', # nocheck - '}']), - MockFile('some/ios/subdir/file.mm', - ['TEST(SomeClassTest, SomeInteraction, blacklist) {', # nocheck - '}']), - MockFile('some/mac/file.mm', - ['TEST(SomeClassTest, SomeInteraction, BlackList) {', # nocheck - '}']), - MockFile('another/ios_file.mm', - ['class SomeTest : public testing::Test blocklist {};']), - MockFile('some/ios/file_egtest.mm', - ['- (void)testSomething { V(whitelist); }']), # nocheck - MockFile('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('some/ios/file.mm' not in errors[0].message) - self.assertTrue('some/ios/subdir/file.mm' in errors[0].message) - self.assertTrue('another/ios_file.mm' not in errors[0].message) - self.assertTrue('some/mac/file.mm' in errors[0].message) - self.assertTrue('some/ios/file_egtest.mm' not in errors[0].message) - self.assertTrue('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('infra/inclusive_language_presubmit_exempt_dirs.txt', [ - 'some/dir 2 1', - 'some/other/dir 2 1', - ]), - MockFile('some/ios/file.mm', - ['TEST(SomeClassTest, SomeInteraction, ', - ' blacklist) { // nocheck', # nocheck - '}']), - MockFile('some/mac/file.mm', - ['TEST(SomeClassTest, SomeInteraction, ', - 'BlackList) { // nocheck', # nocheck - '}']), - MockFile('another/ios_file.mm', - ['class SomeTest : public testing::Test blocklist {};']), - MockFile('some/ios/file_egtest.mm', - ['- (void)testSomething { ', - 'V(whitelist); } // nocheck']), # nocheck - MockFile('some/ios/file_unittest.mm', - ['TEST_F(SomeTest, Whitelist) // nocheck', # nocheck - ' { V(allowlist); }']), - MockFile('some/doc/file.md', - ['Master in markdown ', # nocheck - '## Subheading is okay']), - MockFile('some/java/file/TestJava.java', - ['class TestJava {', - ' public String master; // nocheck', # nocheck - '}']), - MockFile('some/html/file.html', - ['<-- an existing html multiline comment', - 'says "master" here -->', # nocheck - '']) - ] - - 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('infra/inclusive_language_presubmit_exempt_dirs.txt', [ - '. 2 1', - 'some/other/dir 2 1', - ]), - MockFile('presubmit_canned_checks_test.py', - ['TEST(SomeClassTest, SomeInteraction, blacklist) {', # nocheck - '}']), - MockFile('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('presubmit_canned_checks_test.py' in errors[0].message) - self.assertTrue('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('some_file', [ - '# this is a blacklist', # nocheck - ]), - ] - errors = presubmit_canned_checks.CheckInclusiveLanguage(input_api, - MockOutputApi()) - self.assertEqual([], errors) - - -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 CheckUpdateOwnersFileReferences(unittest.TestCase): - def testShowsWarningIfDeleting(self): - input_api = MockInputApi() - input_api.files = [ - MockFile('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('new_directory/OWNERS', [], [], action='A'), - MockFile('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('foo/OWNERS', [], [], action='A'), - ] - results = presubmit_canned_checks.CheckUpdateOwnersFileReferences( - input_api, MockOutputApi()) - self.assertEqual(0, len(results)) - - -if __name__ == '__main__': - unittest.main() diff --git a/presubmit_canned_checks_test_mocks.py b/testing_support/presubmit_canned_checks_test_mocks.py similarity index 99% rename from presubmit_canned_checks_test_mocks.py rename to testing_support/presubmit_canned_checks_test_mocks.py index 66f0599fd..a1053b0ed 100644 --- a/presubmit_canned_checks_test_mocks.py +++ b/testing_support/presubmit_canned_checks_test_mocks.py @@ -72,6 +72,7 @@ class MockInputApi(object): self.sys = sys self.files = [] self.is_committing = False + self.no_diffs = False self.change = MockChange([]) self.presubmit_local_path = os.path.dirname(__file__) self.logging = logging.getLogger('PRESUBMIT') diff --git a/tests/presubmit_canned_checks_test.py b/tests/presubmit_canned_checks_test.py new file mode 100644 index 000000000..a03e640a1 --- /dev/null +++ b/tests/presubmit_canned_checks_test.py @@ -0,0 +1,366 @@ +#!/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 + +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 +from testing_support.presubmit_canned_checks_test_mocks import (MockInputApi, + MockOutputApi) +from testing_support.presubmit_canned_checks_test_mocks import MockChange + +import presubmit_canned_checks + + +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'), [ + os.path.normpath('some/dir') + ' 2 1', + os.path.normpath('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'), [ + os.path.normpath('some/ios') + ' 2 1', + os.path.normpath('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'), [ + os.path.normpath('some/dir') + ' 2 1', + os.path.normpath('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 + '## 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 + '' + ]) + ] + + 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'), [ + os.path.normpath('.') + ' 2 1', + os.path.normpath('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) + + +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 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)) + + +if __name__ == '__main__': + unittest.main()