blob: 83e4c8b2eea0997f90d739954827aafdcbe4e372 [file] [log] [blame]
#!/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
# 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)
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))
if __name__ == '__main__':
unittest.main()