#!/usr/bin/env python3
# Copyright (c) 2012 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 io
import os.path
import subprocess
import unittest

import PRESUBMIT

from PRESUBMIT_test_mocks import MockFile, MockAffectedFile
from PRESUBMIT_test_mocks import MockInputApi, MockOutputApi


_TEST_DATA_DIR = 'base/test/data/presubmit'


class VersionControlConflictsTest(unittest.TestCase):
  def testTypicalConflict(self):
    lines = ['<<<<<<< HEAD',
             '  base::ScopedTempDir temp_dir_;',
             '=======',
             '  ScopedTempDir temp_dir_;',
             '>>>>>>> master']
    errors = PRESUBMIT._CheckForVersionControlConflictsInFile(
        MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
    self.assertEqual(3, len(errors))
    self.assertTrue('1' in errors[0])
    self.assertTrue('3' in errors[1])
    self.assertTrue('5' in errors[2])

  def testIgnoresReadmes(self):
    lines = ['A First Level Header',
             '====================',
             '',
             'A Second Level Header',
             '---------------------']
    errors = PRESUBMIT._CheckForVersionControlConflictsInFile(
        MockInputApi(), MockFile('some/polymer/README.md', lines))
    self.assertEqual(0, len(errors))


class BadExtensionsTest(unittest.TestCase):
  def testBadRejFile(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('some/path/foo.cc', ''),
      MockFile('some/path/foo.cc.rej', ''),
      MockFile('some/path2/bar.h.rej', ''),
    ]

    results = PRESUBMIT.CheckPatchFiles(mock_input_api, MockOutputApi())
    self.assertEqual(1, len(results))
    self.assertEqual(2, len(results[0].items))
    self.assertTrue('foo.cc.rej' in results[0].items[0])
    self.assertTrue('bar.h.rej' in results[0].items[1])

  def testBadOrigFile(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('other/path/qux.h.orig', ''),
      MockFile('other/path/qux.h', ''),
      MockFile('other/path/qux.cc', ''),
    ]

    results = PRESUBMIT.CheckPatchFiles(mock_input_api, MockOutputApi())
    self.assertEqual(1, len(results))
    self.assertEqual(1, len(results[0].items))
    self.assertTrue('qux.h.orig' in results[0].items[0])

  def testGoodFiles(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('other/path/qux.h', ''),
      MockFile('other/path/qux.cc', ''),
    ]
    results = PRESUBMIT.CheckPatchFiles(mock_input_api, MockOutputApi())
    self.assertEqual(0, len(results))


class CheckForSuperfluousStlIncludesInHeadersTest(unittest.TestCase):
  def testGoodFiles(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      # The check is not smart enough to figure out which definitions correspond
      # to which header.
      MockFile('other/path/foo.h',
               ['#include <string>',
                'std::vector']),
      # The check is not smart enough to do IWYU.
      MockFile('other/path/bar.h',
               ['#include "base/check.h"',
                'std::vector']),
      MockFile('other/path/qux.h',
               ['#include "base/stl_util.h"',
                'foobar']),
      MockFile('other/path/baz.h',
               ['#include "set/vector.h"',
                'bazzab']),
      # The check is only for header files.
      MockFile('other/path/not_checked.cc',
               ['#include <vector>',
                'bazbaz']),
    ]
    results = PRESUBMIT.CheckForSuperfluousStlIncludesInHeaders(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(results))

  def testBadFiles(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('other/path/foo.h',
               ['#include <vector>',
                'vector']),
      MockFile('other/path/bar.h',
               ['#include <limits>',
                '#include <set>',
                'no_std_namespace']),
    ]
    results = PRESUBMIT.CheckForSuperfluousStlIncludesInHeaders(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(results))
    self.assertTrue('foo.h: Includes STL' in results[0].message)
    self.assertTrue('bar.h: Includes STL' in results[0].message)


class CheckSingletonInHeadersTest(unittest.TestCase):
  def testSingletonInArbitraryHeader(self):
    diff_singleton_h = ['base::subtle::AtomicWord '
                        'base::Singleton<Type, Traits, DifferentiatingType>::']
    diff_foo_h = ['// base::Singleton<Foo> in comment.',
                  'friend class base::Singleton<Foo>']
    diff_foo2_h = ['  //Foo* bar = base::Singleton<Foo>::get();']
    diff_bad_h = ['Foo* foo = base::Singleton<Foo>::get();']
    mock_input_api = MockInputApi()
    mock_input_api.files = [MockAffectedFile('base/memory/singleton.h',
                                             diff_singleton_h),
                            MockAffectedFile('foo.h', diff_foo_h),
                            MockAffectedFile('foo2.h', diff_foo2_h),
                            MockAffectedFile('bad.h', diff_bad_h)]
    warnings = PRESUBMIT.CheckSingletonInHeaders(mock_input_api,
                                                  MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertEqual(1, len(warnings[0].items))
    self.assertEqual('error', warnings[0].type)
    self.assertTrue('Found base::Singleton<T>' in warnings[0].message)

  def testSingletonInCC(self):
    diff_cc = ['Foo* foo = base::Singleton<Foo>::get();']
    mock_input_api = MockInputApi()
    mock_input_api.files = [MockAffectedFile('some/path/foo.cc', diff_cc)]
    warnings = PRESUBMIT.CheckSingletonInHeaders(mock_input_api,
                                                  MockOutputApi())
    self.assertEqual(0, len(warnings))


class DeprecatedOSMacroNamesTest(unittest.TestCase):
  def testDeprecatedOSMacroNames(self):
    lines = ['#if defined(OS_WIN)',
             ' #elif defined(OS_WINDOW)',
             ' # if defined(OS_MAC) || defined(OS_CHROME)']
    errors = PRESUBMIT._CheckForDeprecatedOSMacrosInFile(
        MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
    self.assertEqual(len(lines) + 1, len(errors))
    self.assertTrue(':1: defined(OS_WIN) -> BUILDFLAG(IS_WIN)' in errors[0])


class InvalidIfDefinedMacroNamesTest(unittest.TestCase):
  def testInvalidIfDefinedMacroNames(self):
    lines = ['#if defined(TARGET_IPHONE_SIMULATOR)',
             '#if !defined(TARGET_IPHONE_SIMULATOR)',
             '#elif defined(TARGET_IPHONE_SIMULATOR)',
             '#ifdef TARGET_IPHONE_SIMULATOR',
             ' # ifdef TARGET_IPHONE_SIMULATOR',
             '# if defined(VALID) || defined(TARGET_IPHONE_SIMULATOR)',
             '# else  // defined(TARGET_IPHONE_SIMULATOR)',
             '#endif  // defined(TARGET_IPHONE_SIMULATOR)']
    errors = PRESUBMIT._CheckForInvalidIfDefinedMacrosInFile(
        MockInputApi(), MockFile('some/path/source.mm', lines))
    self.assertEqual(len(lines), len(errors))

  def testValidIfDefinedMacroNames(self):
    lines = ['#if defined(FOO)',
             '#ifdef BAR']
    errors = PRESUBMIT._CheckForInvalidIfDefinedMacrosInFile(
        MockInputApi(), MockFile('some/path/source.cc', lines))
    self.assertEqual(0, len(errors))


class CheckAddedDepsHaveTestApprovalsTest(unittest.TestCase):

  def calculate(self, old_include_rules, old_specific_include_rules,
                new_include_rules, new_specific_include_rules):
    return PRESUBMIT._CalculateAddedDeps(
        os.path, 'include_rules = %r\nspecific_include_rules = %r' % (
            old_include_rules, old_specific_include_rules),
        'include_rules = %r\nspecific_include_rules = %r' % (
            new_include_rules, new_specific_include_rules))

  def testCalculateAddedDeps(self):
    old_include_rules = [
        '+base',
        '-chrome',
        '+content',
        '-grit',
        '-grit/",',
        '+jni/fooblat.h',
        '!sandbox',
    ]
    old_specific_include_rules = {
        'compositor\.*': {
            '+cc',
        },
    }

    new_include_rules = [
        '-ash',
        '+base',
        '+chrome',
        '+components',
        '+content',
        '+grit',
        '+grit/generated_resources.h",',
        '+grit/",',
        '+jni/fooblat.h',
        '+policy',
        '+' + os.path.join('third_party', 'WebKit'),
    ]
    new_specific_include_rules = {
        'compositor\.*': {
            '+cc',
        },
        'widget\.*': {
            '+gpu',
        },
    }

    expected = set([
        os.path.join('chrome', 'DEPS'),
        os.path.join('gpu', 'DEPS'),
        os.path.join('components', 'DEPS'),
        os.path.join('policy', 'DEPS'),
        os.path.join('third_party', 'WebKit', 'DEPS'),
    ])
    self.assertEqual(
        expected,
        self.calculate(old_include_rules, old_specific_include_rules,
                       new_include_rules, new_specific_include_rules))

  def testCalculateAddedDepsIgnoresPermutations(self):
    old_include_rules = [
        '+base',
        '+chrome',
    ]
    new_include_rules = [
        '+chrome',
        '+base',
    ]
    self.assertEqual(set(),
                     self.calculate(old_include_rules, {}, new_include_rules,
                                    {}))


class JSONParsingTest(unittest.TestCase):
  def testSuccess(self):
    input_api = MockInputApi()
    filename = 'valid_json.json'
    contents = ['// This is a comment.',
                '{',
                '  "key1": ["value1", "value2"],',
                '  "key2": 3  // This is an inline comment.',
                '}'
                ]
    input_api.files = [MockFile(filename, contents)]
    self.assertEqual(None,
                     PRESUBMIT._GetJSONParseError(input_api, filename))

  def testFailure(self):
    input_api = MockInputApi()
    test_data = [
      ('invalid_json_1.json',
       ['{ x }'],
       'Expecting property name'),
      ('invalid_json_2.json',
       ['// Hello world!',
        '{ "hello": "world }'],
       'Unterminated string starting at:'),
      ('invalid_json_3.json',
       ['{ "a": "b", "c": "d", }'],
       'Expecting property name'),
      ('invalid_json_4.json',
       ['{ "a": "b" "c": "d" }'],
       "Expecting ',' delimiter:"),
    ]

    input_api.files = [MockFile(filename, contents)
                       for (filename, contents, _) in test_data]

    for (filename, _, expected_error) in test_data:
      actual_error = PRESUBMIT._GetJSONParseError(input_api, filename)
      self.assertTrue(expected_error in str(actual_error),
                      "'%s' not found in '%s'" % (expected_error, actual_error))

  def testNoEatComments(self):
    input_api = MockInputApi()
    file_with_comments = 'file_with_comments.json'
    contents_with_comments = ['// This is a comment.',
                              '{',
                              '  "key1": ["value1", "value2"],',
                              '  "key2": 3  // This is an inline comment.',
                              '}'
                              ]
    file_without_comments = 'file_without_comments.json'
    contents_without_comments = ['{',
                                 '  "key1": ["value1", "value2"],',
                                 '  "key2": 3',
                                 '}'
                                 ]
    input_api.files = [MockFile(file_with_comments, contents_with_comments),
                       MockFile(file_without_comments,
                                contents_without_comments)]

    self.assertNotEqual(None,
                        str(PRESUBMIT._GetJSONParseError(input_api,
                                                         file_with_comments,
                                                         eat_comments=False)))
    self.assertEqual(None,
                     PRESUBMIT._GetJSONParseError(input_api,
                                                  file_without_comments,
                                                  eat_comments=False))


class IDLParsingTest(unittest.TestCase):
  def testSuccess(self):
    input_api = MockInputApi()
    filename = 'valid_idl_basics.idl'
    contents = ['// Tests a valid IDL file.',
                'namespace idl_basics {',
                '  enum EnumType {',
                '    name1,',
                '    name2',
                '  };',
                '',
                '  dictionary MyType1 {',
                '    DOMString a;',
                '  };',
                '',
                '  callback Callback1 = void();',
                '  callback Callback2 = void(long x);',
                '  callback Callback3 = void(MyType1 arg);',
                '  callback Callback4 = void(EnumType type);',
                '',
                '  interface Functions {',
                '    static void function1();',
                '    static void function2(long x);',
                '    static void function3(MyType1 arg);',
                '    static void function4(Callback1 cb);',
                '    static void function5(Callback2 cb);',
                '    static void function6(Callback3 cb);',
                '    static void function7(Callback4 cb);',
                '  };',
                '',
                '  interface Events {',
                '    static void onFoo1();',
                '    static void onFoo2(long x);',
                '    static void onFoo2(MyType1 arg);',
                '    static void onFoo3(EnumType type);',
                '  };',
                '};'
                ]
    input_api.files = [MockFile(filename, contents)]
    self.assertEqual(None,
                     PRESUBMIT._GetIDLParseError(input_api, filename))

  def testFailure(self):
    input_api = MockInputApi()
    test_data = [
      ('invalid_idl_1.idl',
       ['//',
        'namespace test {',
        '  dictionary {',
        '    DOMString s;',
        '  };',
        '};'],
       'Unexpected "{" after keyword "dictionary".\n'),
      # TODO(yoz): Disabled because it causes the IDL parser to hang.
      # See crbug.com/363830.
      # ('invalid_idl_2.idl',
      #  (['namespace test {',
      #    '  dictionary MissingSemicolon {',
      #    '    DOMString a',
      #    '    DOMString b;',
      #    '  };',
      #    '};'],
      #   'Unexpected symbol DOMString after symbol a.'),
      ('invalid_idl_3.idl',
       ['//',
        'namespace test {',
        '  enum MissingComma {',
        '    name1',
        '    name2',
        '  };',
        '};'],
       'Unexpected symbol name2 after symbol name1.'),
      ('invalid_idl_4.idl',
       ['//',
        'namespace test {',
        '  enum TrailingComma {',
        '    name1,',
        '    name2,',
        '  };',
        '};'],
       'Trailing comma in block.'),
      ('invalid_idl_5.idl',
       ['//',
        'namespace test {',
        '  callback Callback1 = void(;',
        '};'],
       'Unexpected ";" after "(".'),
      ('invalid_idl_6.idl',
       ['//',
        'namespace test {',
        '  callback Callback1 = void(long );',
        '};'],
       'Unexpected ")" after symbol long.'),
      ('invalid_idl_7.idl',
       ['//',
        'namespace test {',
        '  interace Events {',
        '    static void onFoo1();',
        '  };',
        '};'],
       'Unexpected symbol Events after symbol interace.'),
      ('invalid_idl_8.idl',
       ['//',
        'namespace test {',
        '  interface NotEvent {',
        '    static void onFoo1();',
        '  };',
        '};'],
       'Did not process Interface Interface(NotEvent)'),
      ('invalid_idl_9.idl',
       ['//',
        'namespace test {',
        '  interface {',
        '    static void function1();',
        '  };',
        '};'],
       'Interface missing name.'),
    ]

    input_api.files = [MockFile(filename, contents)
                       for (filename, contents, _) in test_data]

    for (filename, _, expected_error) in test_data:
      actual_error = PRESUBMIT._GetIDLParseError(input_api, filename)
      self.assertTrue(expected_error in str(actual_error),
                      "'%s' not found in '%s'" % (expected_error, actual_error))


class UserMetricsActionTest(unittest.TestCase):
  def testUserMetricsActionInActions(self):
    input_api = MockInputApi()
    file_with_user_action = 'file_with_user_action.cc'
    contents_with_user_action = [
      'base::UserMetricsAction("AboutChrome")'
    ]

    input_api.files = [MockFile(file_with_user_action,
                                contents_with_user_action)]

    self.assertEqual(
      [], PRESUBMIT.CheckUserActionUpdate(input_api, MockOutputApi()))

  def testUserMetricsActionNotAddedToActions(self):
    input_api = MockInputApi()
    file_with_user_action = 'file_with_user_action.cc'
    contents_with_user_action = [
      'base::UserMetricsAction("NotInActionsXml")'
    ]

    input_api.files = [MockFile(file_with_user_action,
                                contents_with_user_action)]

    output = PRESUBMIT.CheckUserActionUpdate(input_api, MockOutputApi())
    self.assertEqual(
      ('File %s line %d: %s is missing in '
       'tools/metrics/actions/actions.xml. Please run '
       'tools/metrics/actions/extract_actions.py to update.'
       % (file_with_user_action, 1, 'NotInActionsXml')),
      output[0].message)

  def testUserMetricsActionInTestFile(self):
    input_api = MockInputApi()
    file_with_user_action = 'file_with_user_action_unittest.cc'
    contents_with_user_action = [
      'base::UserMetricsAction("NotInActionsXml")'
    ]

    input_api.files = [MockFile(file_with_user_action,
                                contents_with_user_action)]

    self.assertEqual(
      [], PRESUBMIT.CheckUserActionUpdate(input_api, MockOutputApi()))


class PydepsNeedsUpdatingTest(unittest.TestCase):
  class MockPopen:
    def __init__(self, stdout_func):
      self._stdout_func = stdout_func

    def wait(self):
      self.stdout = io.StringIO(self._stdout_func())
      return 0

  class MockSubprocess:
    CalledProcessError = subprocess.CalledProcessError
    PIPE = 0

    def __init__(self):
      self._popen_func = None

    def SetPopenCallback(self, func):
      self._popen_func = func

    def Popen(self, cmd, *args, **kwargs):
      return PydepsNeedsUpdatingTest.MockPopen(lambda: self._popen_func(cmd))

  def _MockParseGclientArgs(self, is_android=True):
    return lambda: {'checkout_android': 'true' if is_android else 'false' }

  def setUp(self):
    mock_all_pydeps = ['A.pydeps', 'B.pydeps', 'D.pydeps']
    self.old_ALL_PYDEPS_FILES = PRESUBMIT._ALL_PYDEPS_FILES
    PRESUBMIT._ALL_PYDEPS_FILES = mock_all_pydeps
    mock_android_pydeps = ['D.pydeps']
    self.old_ANDROID_SPECIFIC_PYDEPS_FILES = (
        PRESUBMIT._ANDROID_SPECIFIC_PYDEPS_FILES)
    PRESUBMIT._ANDROID_SPECIFIC_PYDEPS_FILES = mock_android_pydeps
    self.old_ParseGclientArgs = PRESUBMIT._ParseGclientArgs
    PRESUBMIT._ParseGclientArgs = self._MockParseGclientArgs()
    self.mock_input_api = MockInputApi()
    self.mock_output_api = MockOutputApi()
    self.mock_input_api.subprocess = PydepsNeedsUpdatingTest.MockSubprocess()
    self.checker = PRESUBMIT.PydepsChecker(self.mock_input_api, mock_all_pydeps)
    self.checker._file_cache = {
        'A.pydeps': '# Generated by:\n# CMD --output A.pydeps A\nA.py\nC.py\n',
        'B.pydeps': '# Generated by:\n# CMD --output B.pydeps B\nB.py\nC.py\n',
        'D.pydeps': '# Generated by:\n# CMD --output D.pydeps D\nD.py\n',
    }

  def tearDown(self):
    PRESUBMIT._ALL_PYDEPS_FILES = self.old_ALL_PYDEPS_FILES
    PRESUBMIT._ANDROID_SPECIFIC_PYDEPS_FILES = (
        self.old_ANDROID_SPECIFIC_PYDEPS_FILES)
    PRESUBMIT._ParseGclientArgs = self.old_ParseGclientArgs

  def _RunCheck(self):
    return PRESUBMIT.CheckPydepsNeedsUpdating(self.mock_input_api,
                                               self.mock_output_api,
                                               checker_for_tests=self.checker)

  def testAddedPydep(self):
    # PRESUBMIT.CheckPydepsNeedsUpdating is only implemented for Linux.
    if not self.mock_input_api.platform.startswith('linux'):
      return []

    self.mock_input_api.files = [
      MockAffectedFile('new.pydeps', [], action='A'),
    ]

    self.mock_input_api.CreateMockFileInPath(
        [x.LocalPath() for x in self.mock_input_api.AffectedFiles(
            include_deletes=True)])
    results = self._RunCheck()
    self.assertEqual(1, len(results))
    self.assertIn('PYDEPS_FILES', str(results[0]))

  def testPydepNotInSrc(self):
    self.mock_input_api.files = [
      MockAffectedFile('new.pydeps', [], action='A'),
    ]
    self.mock_input_api.CreateMockFileInPath([])
    results = self._RunCheck()
    self.assertEqual(0, len(results))

  def testRemovedPydep(self):
    # PRESUBMIT.CheckPydepsNeedsUpdating is only implemented for Linux.
    if not self.mock_input_api.platform.startswith('linux'):
      return []

    self.mock_input_api.files = [
      MockAffectedFile(PRESUBMIT._ALL_PYDEPS_FILES[0], [], action='D'),
    ]
    self.mock_input_api.CreateMockFileInPath(
        [x.LocalPath() for x in self.mock_input_api.AffectedFiles(
            include_deletes=True)])
    results = self._RunCheck()
    self.assertEqual(1, len(results))
    self.assertIn('PYDEPS_FILES', str(results[0]))

  def testRandomPyIgnored(self):
    # PRESUBMIT.CheckPydepsNeedsUpdating is only implemented for Linux.
    if not self.mock_input_api.platform.startswith('linux'):
      return []

    self.mock_input_api.files = [
      MockAffectedFile('random.py', []),
    ]

    results = self._RunCheck()
    self.assertEqual(0, len(results), 'Unexpected results: %r' % results)

  def testRelevantPyNoChange(self):
    # PRESUBMIT.CheckPydepsNeedsUpdating is only implemented for Linux.
    if not self.mock_input_api.platform.startswith('linux'):
      return []

    self.mock_input_api.files = [
      MockAffectedFile('A.py', []),
    ]

    def popen_callback(cmd):
      self.assertEqual('CMD --output A.pydeps A --output ""', cmd)
      return self.checker._file_cache['A.pydeps']

    self.mock_input_api.subprocess.SetPopenCallback(popen_callback)

    results = self._RunCheck()
    self.assertEqual(0, len(results), 'Unexpected results: %r' % results)

  def testRelevantPyOneChange(self):
    # PRESUBMIT.CheckPydepsNeedsUpdating is only implemented for Linux.
    if not self.mock_input_api.platform.startswith('linux'):
      return []

    self.mock_input_api.files = [
      MockAffectedFile('A.py', []),
    ]

    def popen_callback(cmd):
      self.assertEqual('CMD --output A.pydeps A --output ""', cmd)
      return 'changed data'

    self.mock_input_api.subprocess.SetPopenCallback(popen_callback)

    results = self._RunCheck()
    self.assertEqual(1, len(results))
    # Check that --output "" is not included.
    self.assertNotIn('""', str(results[0]))
    self.assertIn('File is stale', str(results[0]))

  def testRelevantPyTwoChanges(self):
    # PRESUBMIT.CheckPydepsNeedsUpdating is only implemented for Linux.
    if not self.mock_input_api.platform.startswith('linux'):
      return []

    self.mock_input_api.files = [
      MockAffectedFile('C.py', []),
    ]

    def popen_callback(cmd):
      return 'changed data'

    self.mock_input_api.subprocess.SetPopenCallback(popen_callback)

    results = self._RunCheck()
    self.assertEqual(2, len(results))
    self.assertIn('File is stale', str(results[0]))
    self.assertIn('File is stale', str(results[1]))

  def testRelevantAndroidPyInNonAndroidCheckout(self):
    # PRESUBMIT.CheckPydepsNeedsUpdating is only implemented for Linux.
    if not self.mock_input_api.platform.startswith('linux'):
      return []

    self.mock_input_api.files = [
      MockAffectedFile('D.py', []),
    ]

    def popen_callback(cmd):
      self.assertEqual('CMD --output D.pydeps D --output ""', cmd)
      return 'changed data'

    self.mock_input_api.subprocess.SetPopenCallback(popen_callback)
    PRESUBMIT._ParseGclientArgs = self._MockParseGclientArgs(is_android=False)

    results = self._RunCheck()
    self.assertEqual(1, len(results))
    self.assertIn('Android', str(results[0]))
    self.assertIn('D.pydeps', str(results[0]))

  def testGnPathsAndMissingOutputFlag(self):
    # PRESUBMIT.CheckPydepsNeedsUpdating is only implemented for Linux.
    if not self.mock_input_api.platform.startswith('linux'):
      return []

    self.checker._file_cache = {
        'A.pydeps': '# Generated by:\n# CMD --gn-paths A\n//A.py\n//C.py\n',
        'B.pydeps': '# Generated by:\n# CMD --gn-paths B\n//B.py\n//C.py\n',
        'D.pydeps': '# Generated by:\n# CMD --gn-paths D\n//D.py\n',
    }

    self.mock_input_api.files = [
      MockAffectedFile('A.py', []),
    ]

    def popen_callback(cmd):
      self.assertEqual('CMD --gn-paths A --output A.pydeps --output ""', cmd)
      return 'changed data'

    self.mock_input_api.subprocess.SetPopenCallback(popen_callback)

    results = self._RunCheck()
    self.assertEqual(1, len(results))
    self.assertIn('File is stale', str(results[0]))


class IncludeGuardTest(unittest.TestCase):
  def testIncludeGuardChecks(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()
    mock_input_api.files = [
        MockAffectedFile('content/browser/thing/foo.h', [
          '// Comment',
          '#ifndef CONTENT_BROWSER_THING_FOO_H_',
          '#define CONTENT_BROWSER_THING_FOO_H_',
          'struct McBoatFace;',
          '#endif  // CONTENT_BROWSER_THING_FOO_H_',
        ]),
        MockAffectedFile('content/browser/thing/bar.h', [
          '#ifndef CONTENT_BROWSER_THING_BAR_H_',
          '#define CONTENT_BROWSER_THING_BAR_H_',
          'namespace content {',
          '#endif  // CONTENT_BROWSER_THING_BAR_H_',
          '}  // namespace content',
        ]),
        MockAffectedFile('content/browser/test1.h', [
          'namespace content {',
          '}  // namespace content',
        ]),
        MockAffectedFile('content\\browser\\win.h', [
          '#ifndef CONTENT_BROWSER_WIN_H_',
          '#define CONTENT_BROWSER_WIN_H_',
          'struct McBoatFace;',
          '#endif  // CONTENT_BROWSER_WIN_H_',
        ]),
        MockAffectedFile('content/browser/test2.h', [
          '// Comment',
          '#ifndef CONTENT_BROWSER_TEST2_H_',
          'struct McBoatFace;',
          '#endif  // CONTENT_BROWSER_TEST2_H_',
        ]),
        MockAffectedFile('content/browser/internal.h', [
          '// Comment',
          '#ifndef CONTENT_BROWSER_INTERNAL_H_',
          '#define CONTENT_BROWSER_INTERNAL_H_',
          '// Comment',
          '#ifndef INTERNAL_CONTENT_BROWSER_INTERNAL_H_',
          '#define INTERNAL_CONTENT_BROWSER_INTERNAL_H_',
          'namespace internal {',
          '}  // namespace internal',
          '#endif  // INTERNAL_CONTENT_BROWSER_THING_BAR_H_',
          'namespace content {',
          '}  // namespace content',
          '#endif  // CONTENT_BROWSER_THING_BAR_H_',
        ]),
        MockAffectedFile('content/browser/thing/foo.cc', [
          '// This is a non-header.',
        ]),
        MockAffectedFile('content/browser/disabled.h', [
          '// no-include-guard-because-multiply-included',
          'struct McBoatFace;',
        ]),
        # New files don't allow misspelled include guards.
        MockAffectedFile('content/browser/spleling.h', [
          '#ifndef CONTENT_BROWSER_SPLLEING_H_',
          '#define CONTENT_BROWSER_SPLLEING_H_',
          'struct McBoatFace;',
          '#endif  // CONTENT_BROWSER_SPLLEING_H_',
        ]),
        # New files don't allow + in include guards.
        MockAffectedFile('content/browser/foo+bar.h', [
          '#ifndef CONTENT_BROWSER_FOO+BAR_H_',
          '#define CONTENT_BROWSER_FOO+BAR_H_',
          'struct McBoatFace;',
          '#endif  // CONTENT_BROWSER_FOO+BAR_H_',
        ]),
        # Old files allow misspelled include guards (for now).
        MockAffectedFile('chrome/old.h', [
          '// New contents',
          '#ifndef CHROME_ODL_H_',
          '#define CHROME_ODL_H_',
          '#endif  // CHROME_ODL_H_',
        ], [
          '// Old contents',
          '#ifndef CHROME_ODL_H_',
          '#define CHROME_ODL_H_',
          '#endif  // CHROME_ODL_H_',
        ]),
        # Using a Blink style include guard outside Blink is wrong.
        MockAffectedFile('content/NotInBlink.h', [
          '#ifndef NotInBlink_h',
          '#define NotInBlink_h',
          'struct McBoatFace;',
          '#endif  // NotInBlink_h',
        ]),
        # Using a Blink style include guard in Blink is no longer ok.
        MockAffectedFile('third_party/blink/InBlink.h', [
          '#ifndef InBlink_h',
          '#define InBlink_h',
          'struct McBoatFace;',
          '#endif  // InBlink_h',
        ]),
        # Using a bad include guard in Blink is not ok.
        MockAffectedFile('third_party/blink/AlsoInBlink.h', [
          '#ifndef WrongInBlink_h',
          '#define WrongInBlink_h',
          'struct McBoatFace;',
          '#endif  // WrongInBlink_h',
        ]),
        # Using a bad include guard in Blink is not accepted even if
        # it's an old file.
        MockAffectedFile('third_party/blink/StillInBlink.h', [
          '// New contents',
          '#ifndef AcceptedInBlink_h',
          '#define AcceptedInBlink_h',
          'struct McBoatFace;',
          '#endif  // AcceptedInBlink_h',
        ], [
          '// Old contents',
          '#ifndef AcceptedInBlink_h',
          '#define AcceptedInBlink_h',
          'struct McBoatFace;',
          '#endif  // AcceptedInBlink_h',
        ]),
        # Using a non-Chromium include guard in third_party
        # (outside blink) is accepted.
        MockAffectedFile('third_party/foo/some_file.h', [
          '#ifndef REQUIRED_RPCNDR_H_',
          '#define REQUIRED_RPCNDR_H_',
          'struct SomeFileFoo;',
          '#endif  // REQUIRED_RPCNDR_H_',
        ]),
        # Not having proper include guard in *_message_generator.h
        # for old IPC messages is allowed.
        MockAffectedFile('content/common/content_message_generator.h', [
          '#undef CONTENT_COMMON_FOO_MESSAGES_H_',
          '#include "content/common/foo_messages.h"',
          '#ifndef CONTENT_COMMON_FOO_MESSAGES_H_',
          '#error "Failed to include content/common/foo_messages.h"',
          '#endif',
        ]),
      ]
    msgs = PRESUBMIT.CheckForIncludeGuards(
        mock_input_api, mock_output_api)
    expected_fail_count = 8
    self.assertEqual(expected_fail_count, len(msgs),
                     'Expected %d items, found %d: %s'
                     % (expected_fail_count, len(msgs), msgs))
    self.assertEqual(msgs[0].items, ['content/browser/thing/bar.h'])
    self.assertEqual(msgs[0].message,
                     'Include guard CONTENT_BROWSER_THING_BAR_H_ '
                     'not covering the whole file')

    self.assertEqual(msgs[1].items, ['content/browser/test1.h'])
    self.assertEqual(msgs[1].message,
                     'Missing include guard CONTENT_BROWSER_TEST1_H_')

    self.assertEqual(msgs[2].items, ['content/browser/test2.h:3'])
    self.assertEqual(msgs[2].message,
                     'Missing "#define CONTENT_BROWSER_TEST2_H_" for '
                     'include guard')

    self.assertEqual(msgs[3].items, ['content/browser/spleling.h:1'])
    self.assertEqual(msgs[3].message,
                     'Header using the wrong include guard name '
                     'CONTENT_BROWSER_SPLLEING_H_')

    self.assertEqual(msgs[4].items, ['content/browser/foo+bar.h'])
    self.assertEqual(msgs[4].message,
                     'Missing include guard CONTENT_BROWSER_FOO_BAR_H_')

    self.assertEqual(msgs[5].items, ['content/NotInBlink.h:1'])
    self.assertEqual(msgs[5].message,
                     'Header using the wrong include guard name '
                     'NotInBlink_h')

    self.assertEqual(msgs[6].items, ['third_party/blink/InBlink.h:1'])
    self.assertEqual(msgs[6].message,
                     'Header using the wrong include guard name '
                     'InBlink_h')

    self.assertEqual(msgs[7].items, ['third_party/blink/AlsoInBlink.h:1'])
    self.assertEqual(msgs[7].message,
                     'Header using the wrong include guard name '
                     'WrongInBlink_h')

class AccessibilityRelnotesFieldTest(unittest.TestCase):
  def testRelnotesPresent(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [MockAffectedFile('ui/accessibility/foo.bar', [''])]
    mock_input_api.change.DescriptionText = lambda : 'Commit description'
    mock_input_api.change.footers['AX-Relnotes'] = [
        'Important user facing change']

    msgs = PRESUBMIT.CheckAccessibilityRelnotesField(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

  def testRelnotesMissingFromAccessibilityChange(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
        MockAffectedFile('some/file', ['']),
        MockAffectedFile('ui/accessibility/foo.bar', ['']),
        MockAffectedFile('some/other/file', [''])
    ]
    mock_input_api.change.DescriptionText = lambda : 'Commit description'

    msgs = PRESUBMIT.CheckAccessibilityRelnotesField(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (1, len(msgs), msgs))
    self.assertTrue("Missing 'AX-Relnotes:' field" in msgs[0].message,
                    'Missing AX-Relnotes field message not found in errors')

  # The relnotes footer is not required for changes which do not touch any
  # accessibility directories.
  def testIgnoresNonAccesssibilityCode(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
        MockAffectedFile('some/file', ['']),
        MockAffectedFile('some/other/file', [''])
    ]
    mock_input_api.change.DescriptionText = lambda : 'Commit description'

    msgs = PRESUBMIT.CheckAccessibilityRelnotesField(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

  # Test that our presubmit correctly raises an error for a set of known paths.
  def testExpectedPaths(self):
    filesToTest = [
      "chrome/browser/accessibility/foo.py",
      "chrome/browser/ash/arc/accessibility/foo.cc",
      "chrome/browser/ui/views/accessibility/foo.h",
      "chrome/browser/extensions/api/automation/foo.h",
      "chrome/browser/extensions/api/automation_internal/foo.cc",
      "chrome/renderer/extensions/accessibility_foo.h",
      "chrome/tests/data/accessibility/foo.html",
      "content/browser/accessibility/foo.cc",
      "content/renderer/accessibility/foo.h",
      "content/tests/data/accessibility/foo.cc",
      "extensions/renderer/api/automation/foo.h",
      "ui/accessibility/foo/bar/baz.cc",
      "ui/views/accessibility/foo/bar/baz.h",
    ]

    for testFile in filesToTest:
      mock_input_api = MockInputApi()
      mock_output_api = MockOutputApi()

      mock_input_api.files = [
          MockAffectedFile(testFile, [''])
      ]
      mock_input_api.change.DescriptionText = lambda : 'Commit description'

      msgs = PRESUBMIT.CheckAccessibilityRelnotesField(
          mock_input_api, mock_output_api)
      self.assertEqual(1, len(msgs),
                       'Expected %d messages, found %d: %s, for file %s'
                       % (1, len(msgs), msgs, testFile))
      self.assertTrue("Missing 'AX-Relnotes:' field" in msgs[0].message,
                      ('Missing AX-Relnotes field message not found in errors '
                       ' for file %s' % (testFile)))

  # Test that AX-Relnotes field can appear in the commit description (as long
  # as it appears at the beginning of a line).
  def testRelnotesInCommitDescription(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
        MockAffectedFile('ui/accessibility/foo.bar', ['']),
    ]
    mock_input_api.change.DescriptionText = lambda : ('Description:\n' +
        'AX-Relnotes: solves all accessibility issues forever')

    msgs = PRESUBMIT.CheckAccessibilityRelnotesField(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

  # Test that we don't match AX-Relnotes if it appears in the middle of a line.
  def testRelnotesMustAppearAtBeginningOfLine(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
        MockAffectedFile('ui/accessibility/foo.bar', ['']),
    ]
    mock_input_api.change.DescriptionText = lambda : ('Description:\n' +
        'This change has no AX-Relnotes: we should print a warning')

    msgs = PRESUBMIT.CheckAccessibilityRelnotesField(
        mock_input_api, mock_output_api)
    self.assertTrue("Missing 'AX-Relnotes:' field" in msgs[0].message,
                    'Missing AX-Relnotes field message not found in errors')

  # Tests that the AX-Relnotes field can be lowercase and use a '=' in place
  # of a ':'.
  def testRelnotesLowercaseWithEqualSign(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
        MockAffectedFile('ui/accessibility/foo.bar', ['']),
    ]
    mock_input_api.change.DescriptionText = lambda : ('Description:\n' +
        'ax-relnotes= this is a valid format for accessibiliy relnotes')

    msgs = PRESUBMIT.CheckAccessibilityRelnotesField(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

class AccessibilityEventsTestsAreIncludedForAndroidTest(unittest.TestCase):
  # Test that no warning is raised when the Android file is also modified.
  def testAndroidChangeIncluded(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/event/foo.html',
          [''], action='A'),
        MockAffectedFile(
          'accessibility/WebContentsAccessibilityEventsTest.java',
          [''], action='M')
    ]

    msgs = PRESUBMIT.CheckAccessibilityEventsTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

  # Test that a warning is raised when the Android file is not modified.
  def testAndroidChangeMissing(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/event/foo.html',
          [''], action='A'),
    ]

    msgs = PRESUBMIT.CheckAccessibilityEventsTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (1, len(msgs), msgs))

  # Test that Android change is not required when no html file is added/removed.
  def testIgnoreNonHtmlFiles(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/event/foo.txt',
          [''], action='A'),
        MockAffectedFile('content/test/data/accessibility/event/foo.cc',
          [''], action='A'),
        MockAffectedFile('content/test/data/accessibility/event/foo.h',
          [''], action='A'),
        MockAffectedFile('content/test/data/accessibility/event/foo.py',
          [''], action='A')
    ]

    msgs = PRESUBMIT.CheckAccessibilityEventsTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

  # Test that Android change is not required for unrelated html files.
  def testIgnoreNonRelatedHtmlFiles(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/aria/foo.html',
          [''], action='A'),
        MockAffectedFile('content/test/data/accessibility/html/foo.html',
          [''], action='A'),
        MockAffectedFile('chrome/tests/data/accessibility/foo.html',
          [''], action='A')
    ]

    msgs = PRESUBMIT.CheckAccessibilityEventsTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

  # Test that only modifying an html file will not trigger the warning.
  def testIgnoreModifiedFiles(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/event/foo.html',
          [''], action='M')
    ]

    msgs = PRESUBMIT.CheckAccessibilityEventsTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

  # Test that deleting an html file will trigger the warning.
  def testAndroidChangeMissingOnDeletedFile(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/event/foo.html',
          [], action='D')
    ]

    msgs = PRESUBMIT.CheckAccessibilityEventsTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (1, len(msgs), msgs))

class AccessibilityTreeTestsAreIncludedForAndroidTest(unittest.TestCase):
  # Test that no warning is raised when the Android file is also modified.
  def testAndroidChangeIncluded(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/aria/foo.html',
          [''], action='A'),
        MockAffectedFile(
          'accessibility/WebContentsAccessibilityTreeTest.java',
          [''], action='M')
    ]

    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

  # Test that no warning is raised when the Android file is also modified.
  def testAndroidChangeIncludedManyFiles(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/accname/foo.html',
          [''], action='A'),
        MockAffectedFile('content/test/data/accessibility/aria/foo.html',
          [''], action='A'),
        MockAffectedFile('content/test/data/accessibility/css/foo.html',
          [''], action='A'),
        MockAffectedFile('content/test/data/accessibility/html/foo.html',
          [''], action='A'),
        MockAffectedFile(
          'accessibility/WebContentsAccessibilityTreeTest.java',
          [''], action='M')
    ]

    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

  # Test that a warning is raised when the Android file is not modified.
  def testAndroidChangeMissing(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/aria/foo.html',
          [''], action='A'),
    ]

    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (1, len(msgs), msgs))

  # Test that Android change is not required when no html file is added/removed.
  def testIgnoreNonHtmlFiles(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/accname/foo.txt',
          [''], action='A'),
        MockAffectedFile('content/test/data/accessibility/aria/foo.cc',
          [''], action='A'),
        MockAffectedFile('content/test/data/accessibility/css/foo.h',
          [''], action='A'),
        MockAffectedFile('content/test/data/accessibility/tree/foo.py',
          [''], action='A')
    ]

    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

  # Test that Android change is not required for unrelated html files.
  def testIgnoreNonRelatedHtmlFiles(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/event/foo.html',
          [''], action='A'),
    ]

    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

  # Test that only modifying an html file will not trigger the warning.
  def testIgnoreModifiedFiles(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/aria/foo.html',
          [''], action='M')
    ]

    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (0, len(msgs), msgs))

  # Test that deleting an html file will trigger the warning.
  def testAndroidChangeMissingOnDeletedFile(self):
    mock_input_api = MockInputApi()

    mock_input_api.files = [
        MockAffectedFile('content/test/data/accessibility/accname/foo.html',
          [], action='D')
    ]

    msgs = PRESUBMIT.CheckAccessibilityTreeTestsAreIncludedForAndroid(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(msgs),
                     'Expected %d messages, found %d: %s'
                     % (1, len(msgs), msgs))

class AndroidDeprecatedTestAnnotationTest(unittest.TestCase):
  def testCheckAndroidTestAnnotationUsage(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
        MockAffectedFile('LalaLand.java', [
          'random stuff'
        ]),
        MockAffectedFile('CorrectUsage.java', [
          'import android.support.test.filters.LargeTest;',
          'import android.support.test.filters.MediumTest;',
          'import android.support.test.filters.SmallTest;',
        ]),
        MockAffectedFile('UsedDeprecatedLargeTestAnnotation.java', [
          'import android.test.suitebuilder.annotation.LargeTest;',
        ]),
        MockAffectedFile('UsedDeprecatedMediumTestAnnotation.java', [
          'import android.test.suitebuilder.annotation.MediumTest;',
        ]),
        MockAffectedFile('UsedDeprecatedSmallTestAnnotation.java', [
          'import android.test.suitebuilder.annotation.SmallTest;',
        ]),
        MockAffectedFile('UsedDeprecatedSmokeAnnotation.java', [
          'import android.test.suitebuilder.annotation.Smoke;',
        ])
    ]
    msgs = PRESUBMIT._CheckAndroidTestAnnotationUsage(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(msgs),
                     'Expected %d items, found %d: %s'
                     % (1, len(msgs), msgs))
    self.assertEqual(4, len(msgs[0].items),
                     'Expected %d items, found %d: %s'
                     % (4, len(msgs[0].items), msgs[0].items))
    self.assertTrue('UsedDeprecatedLargeTestAnnotation.java:1' in msgs[0].items,
                    'UsedDeprecatedLargeTestAnnotation not found in errors')
    self.assertTrue('UsedDeprecatedMediumTestAnnotation.java:1'
                    in msgs[0].items,
                    'UsedDeprecatedMediumTestAnnotation not found in errors')
    self.assertTrue('UsedDeprecatedSmallTestAnnotation.java:1' in msgs[0].items,
                    'UsedDeprecatedSmallTestAnnotation not found in errors')
    self.assertTrue('UsedDeprecatedSmokeAnnotation.java:1' in msgs[0].items,
                    'UsedDeprecatedSmokeAnnotation not found in errors')


class CheckNoDownstreamDepsTest(unittest.TestCase):
  def testInvalidDepFromUpstream(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
        MockAffectedFile('BUILD.gn', [
          'deps = [',
          '   "//clank/target:test",',
          ']'
        ]),
        MockAffectedFile('chrome/android/BUILD.gn', [
          'deps = [ "//clank/target:test" ]'
        ]),
        MockAffectedFile('chrome/chrome_java_deps.gni', [
          'java_deps = [',
          '   "//clank/target:test",',
          ']'
        ]),
    ]
    mock_input_api.change.RepositoryRoot = lambda: 'chromium/src'
    msgs = PRESUBMIT.CheckNoUpstreamDepsOnClank(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(msgs),
                     'Expected %d items, found %d: %s'
                     % (1, len(msgs), msgs))
    self.assertEqual(3, len(msgs[0].items),
                     'Expected %d items, found %d: %s'
                     % (3, len(msgs[0].items), msgs[0].items))
    self.assertTrue(any('BUILD.gn:2' in item for item in msgs[0].items),
                    'BUILD.gn not found in errors')
    self.assertTrue(
        any('chrome/android/BUILD.gn:1' in item for item in msgs[0].items),
        'chrome/android/BUILD.gn:1 not found in errors')
    self.assertTrue(
        any('chrome/chrome_java_deps.gni:2' in item for item in msgs[0].items),
        'chrome/chrome_java_deps.gni:2 not found in errors')

  def testAllowsComments(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
        MockAffectedFile('BUILD.gn', [
          '# real implementation in //clank/target:test',
        ]),
    ]
    mock_input_api.change.RepositoryRoot = lambda: 'chromium/src'
    msgs = PRESUBMIT.CheckNoUpstreamDepsOnClank(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(msgs),
                     'Expected %d items, found %d: %s'
                     % (0, len(msgs), msgs))

  def testOnlyChecksBuildFiles(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
        MockAffectedFile('README.md', [
          'DEPS = [ "//clank/target:test" ]'
        ]),
        MockAffectedFile('chrome/android/java/file.java', [
          '//clank/ only function'
        ]),
    ]
    mock_input_api.change.RepositoryRoot = lambda: 'chromium/src'
    msgs = PRESUBMIT.CheckNoUpstreamDepsOnClank(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(msgs),
                     'Expected %d items, found %d: %s'
                     % (0, len(msgs), msgs))

  def testValidDepFromDownstream(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
        MockAffectedFile('BUILD.gn', [
          'DEPS = [',
          '   "//clank/target:test",',
          ']'
        ]),
        MockAffectedFile('java/BUILD.gn', [
          'DEPS = [ "//clank/target:test" ]'
        ]),
    ]
    mock_input_api.change.RepositoryRoot = lambda: 'chromium/src/clank'
    msgs = PRESUBMIT.CheckNoUpstreamDepsOnClank(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(msgs),
                     'Expected %d items, found %d: %s'
                     % (0, len(msgs), msgs))

class AndroidDeprecatedJUnitFrameworkTest(unittest.TestCase):
  def testCheckAndroidTestJUnitFramework(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
        MockAffectedFile('LalaLand.java', [
          'random stuff'
        ]),
        MockAffectedFile('CorrectUsage.java', [
          'import org.junit.ABC',
          'import org.junit.XYZ;',
        ]),
        MockAffectedFile('UsedDeprecatedJUnit.java', [
          'import junit.framework.*;',
        ]),
        MockAffectedFile('UsedDeprecatedJUnitAssert.java', [
          'import junit.framework.Assert;',
        ]),
    ]
    msgs = PRESUBMIT._CheckAndroidTestJUnitFrameworkImport(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(msgs),
                     'Expected %d items, found %d: %s'
                     % (1, len(msgs), msgs))
    self.assertEqual(2, len(msgs[0].items),
                     'Expected %d items, found %d: %s'
                     % (2, len(msgs[0].items), msgs[0].items))
    self.assertTrue('UsedDeprecatedJUnit.java:1' in msgs[0].items,
                    'UsedDeprecatedJUnit.java not found in errors')
    self.assertTrue('UsedDeprecatedJUnitAssert.java:1'
                    in msgs[0].items,
                    'UsedDeprecatedJUnitAssert not found in errors')


class AndroidJUnitBaseClassTest(unittest.TestCase):
  def testCheckAndroidTestJUnitBaseClass(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
        MockAffectedFile('LalaLand.java', [
          'random stuff'
        ]),
        MockAffectedFile('CorrectTest.java', [
          '@RunWith(ABC.class);'
          'public class CorrectTest {',
          '}',
        ]),
        MockAffectedFile('HistoricallyIncorrectTest.java', [
          'public class Test extends BaseCaseA {',
          '}',
        ], old_contents=[
          'public class Test extends BaseCaseB {',
          '}',
        ]),
        MockAffectedFile('CorrectTestWithInterface.java', [
          '@RunWith(ABC.class);'
          'public class CorrectTest implement Interface {',
          '}',
        ]),
        MockAffectedFile('IncorrectTest.java', [
          'public class IncorrectTest extends TestCase {',
          '}',
        ]),
        MockAffectedFile('IncorrectWithInterfaceTest.java', [
          'public class Test implements X extends BaseClass {',
          '}',
        ]),
        MockAffectedFile('IncorrectMultiLineTest.java', [
          'public class Test implements X, Y, Z',
          '        extends TestBase {',
          '}',
        ]),
    ]
    msgs = PRESUBMIT._CheckAndroidTestJUnitInheritance(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(msgs),
                     'Expected %d items, found %d: %s'
                     % (1, len(msgs), msgs))
    self.assertEqual(3, len(msgs[0].items),
                     'Expected %d items, found %d: %s'
                     % (3, len(msgs[0].items), msgs[0].items))
    self.assertTrue('IncorrectTest.java:1' in msgs[0].items,
                    'IncorrectTest not found in errors')
    self.assertTrue('IncorrectWithInterfaceTest.java:1'
                    in msgs[0].items,
                    'IncorrectWithInterfaceTest not found in errors')
    self.assertTrue('IncorrectMultiLineTest.java:2' in msgs[0].items,
                    'IncorrectMultiLineTest not found in errors')

class AndroidDebuggableBuildTest(unittest.TestCase):

  def testCheckAndroidDebuggableBuild(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
      MockAffectedFile('RandomStuff.java', [
        'random stuff'
      ]),
      MockAffectedFile('CorrectUsage.java', [
        'import org.chromium.base.BuildInfo;',
        'some random stuff',
        'boolean isOsDebuggable = BuildInfo.isDebugAndroid();',
      ]),
      MockAffectedFile('JustCheckUserdebugBuild.java', [
        'import android.os.Build;',
        'some random stuff',
        'boolean isOsDebuggable = Build.TYPE.equals("userdebug")',
      ]),
      MockAffectedFile('JustCheckEngineeringBuild.java', [
        'import android.os.Build;',
        'some random stuff',
        'boolean isOsDebuggable = "eng".equals(Build.TYPE)',
      ]),
      MockAffectedFile('UsedBuildType.java', [
        'import android.os.Build;',
        'some random stuff',
        'boolean isOsDebuggable = Build.TYPE.equals("userdebug")'
            '|| "eng".equals(Build.TYPE)',
      ]),
      MockAffectedFile('UsedExplicitBuildType.java', [
        'some random stuff',
        'boolean isOsDebuggable = android.os.Build.TYPE.equals("userdebug")'
            '|| "eng".equals(android.os.Build.TYPE)',
      ]),
    ]

    msgs = PRESUBMIT._CheckAndroidDebuggableBuild(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(msgs),
                     'Expected %d items, found %d: %s'
                     % (1, len(msgs), msgs))
    self.assertEqual(4, len(msgs[0].items),
                     'Expected %d items, found %d: %s'
                     % (4, len(msgs[0].items), msgs[0].items))
    self.assertTrue('JustCheckUserdebugBuild.java:3' in msgs[0].items)
    self.assertTrue('JustCheckEngineeringBuild.java:3' in msgs[0].items)
    self.assertTrue('UsedBuildType.java:3' in msgs[0].items)
    self.assertTrue('UsedExplicitBuildType.java:2' in msgs[0].items)


class LogUsageTest(unittest.TestCase):

  def testCheckAndroidCrLogUsage(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()

    mock_input_api.files = [
      MockAffectedFile('RandomStuff.java', [
        'random stuff'
      ]),
      MockAffectedFile('HasAndroidLog.java', [
        'import android.util.Log;',
        'some random stuff',
        'Log.d("TAG", "foo");',
      ]),
      MockAffectedFile('HasExplicitUtilLog.java', [
        'some random stuff',
        'android.util.Log.d("TAG", "foo");',
      ]),
      MockAffectedFile('IsInBasePackage.java', [
        'package org.chromium.base;',
        'private static final String TAG = "cr_Foo";',
        'Log.d(TAG, "foo");',
      ]),
      MockAffectedFile('IsInBasePackageButImportsLog.java', [
        'package org.chromium.base;',
        'import android.util.Log;',
        'private static final String TAG = "cr_Foo";',
        'Log.d(TAG, "foo");',
      ]),
      MockAffectedFile('HasBothLog.java', [
        'import org.chromium.base.Log;',
        'some random stuff',
        'private static final String TAG = "cr_Foo";',
        'Log.d(TAG, "foo");',
        'android.util.Log.d("TAG", "foo");',
      ]),
      MockAffectedFile('HasCorrectTag.java', [
        'import org.chromium.base.Log;',
        'some random stuff',
        'private static final String TAG = "cr_Foo";',
        'Log.d(TAG, "foo");',
      ]),
      MockAffectedFile('HasOldTag.java', [
        'import org.chromium.base.Log;',
        'some random stuff',
        'private static final String TAG = "cr.Foo";',
        'Log.d(TAG, "foo");',
      ]),
      MockAffectedFile('HasDottedTag.java', [
        'import org.chromium.base.Log;',
        'some random stuff',
        'private static final String TAG = "cr_foo.bar";',
        'Log.d(TAG, "foo");',
      ]),
      MockAffectedFile('HasDottedTagPublic.java', [
        'import org.chromium.base.Log;',
        'some random stuff',
        'public static final String TAG = "cr_foo.bar";',
        'Log.d(TAG, "foo");',
      ]),
      MockAffectedFile('HasNoTagDecl.java', [
        'import org.chromium.base.Log;',
        'some random stuff',
        'Log.d(TAG, "foo");',
      ]),
      MockAffectedFile('HasIncorrectTagDecl.java', [
        'import org.chromium.base.Log;',
        'private static final String TAHG = "cr_Foo";',
        'some random stuff',
        'Log.d(TAG, "foo");',
      ]),
      MockAffectedFile('HasInlineTag.java', [
        'import org.chromium.base.Log;',
        'some random stuff',
        'private static final String TAG = "cr_Foo";',
        'Log.d("TAG", "foo");',
      ]),
      MockAffectedFile('HasInlineTagWithSpace.java', [
        'import org.chromium.base.Log;',
        'some random stuff',
        'private static final String TAG = "cr_Foo";',
        'Log.d("log message", "foo");',
      ]),
      MockAffectedFile('HasUnprefixedTag.java', [
        'import org.chromium.base.Log;',
        'some random stuff',
        'private static final String TAG = "rubbish";',
        'Log.d(TAG, "foo");',
      ]),
      MockAffectedFile('HasTooLongTag.java', [
        'import org.chromium.base.Log;',
        'some random stuff',
        'private static final String TAG = "21_charachers_long___";',
        'Log.d(TAG, "foo");',
      ]),
      MockAffectedFile('HasTooLongTagWithNoLogCallsInDiff.java', [
        'import org.chromium.base.Log;',
        'some random stuff',
        'private static final String TAG = "21_charachers_long___";',
      ]),
    ]

    msgs = PRESUBMIT._CheckAndroidCrLogUsage(
        mock_input_api, mock_output_api)

    self.assertEqual(5, len(msgs),
                     'Expected %d items, found %d: %s' % (5, len(msgs), msgs))

    # Declaration format
    nb = len(msgs[0].items)
    self.assertEqual(2, nb,
                     'Expected %d items, found %d: %s' % (2, nb, msgs[0].items))
    self.assertTrue('HasNoTagDecl.java' in msgs[0].items)
    self.assertTrue('HasIncorrectTagDecl.java' in msgs[0].items)

    # Tag length
    nb = len(msgs[1].items)
    self.assertEqual(2, nb,
                     'Expected %d items, found %d: %s' % (2, nb, msgs[1].items))
    self.assertTrue('HasTooLongTag.java' in msgs[1].items)
    self.assertTrue('HasTooLongTagWithNoLogCallsInDiff.java' in msgs[1].items)

    # Tag must be a variable named TAG
    nb = len(msgs[2].items)
    self.assertEqual(3, nb,
                     'Expected %d items, found %d: %s' % (3, nb, msgs[2].items))
    self.assertTrue('HasBothLog.java:5' in msgs[2].items)
    self.assertTrue('HasInlineTag.java:4' in msgs[2].items)
    self.assertTrue('HasInlineTagWithSpace.java:4' in msgs[2].items)

    # Util Log usage
    nb = len(msgs[3].items)
    self.assertEqual(3, nb,
                     'Expected %d items, found %d: %s' % (3, nb, msgs[3].items))
    self.assertTrue('HasAndroidLog.java:3' in msgs[3].items)
    self.assertTrue('HasExplicitUtilLog.java:2' in msgs[3].items)
    self.assertTrue('IsInBasePackageButImportsLog.java:4' in msgs[3].items)

    # Tag must not contain
    nb = len(msgs[4].items)
    self.assertEqual(3, nb,
                     'Expected %d items, found %d: %s' % (2, nb, msgs[4].items))
    self.assertTrue('HasDottedTag.java' in msgs[4].items)
    self.assertTrue('HasDottedTagPublic.java' in msgs[4].items)
    self.assertTrue('HasOldTag.java' in msgs[4].items)


class GoogleAnswerUrlFormatTest(unittest.TestCase):

  def testCatchAnswerUrlId(self):
    input_api = MockInputApi()
    input_api.files = [
      MockFile('somewhere/file.cc',
               ['char* host = '
                '  "https://support.google.com/chrome/answer/123456";']),
      MockFile('somewhere_else/file.cc',
               ['char* host = '
                '  "https://support.google.com/chrome/a/answer/123456";']),
    ]

    warnings = PRESUBMIT.CheckGoogleSupportAnswerUrlOnUpload(
      input_api, MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertEqual(2, len(warnings[0].items))

  def testAllowAnswerUrlParam(self):
    input_api = MockInputApi()
    input_api.files = [
      MockFile('somewhere/file.cc',
               ['char* host = '
                '  "https://support.google.com/chrome/?p=cpn_crash_reports";']),
    ]

    warnings = PRESUBMIT.CheckGoogleSupportAnswerUrlOnUpload(
      input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))


class HardcodedGoogleHostsTest(unittest.TestCase):

  def testWarnOnAssignedLiterals(self):
    input_api = MockInputApi()
    input_api.files = [
      MockFile('content/file.cc',
               ['char* host = "https://www.google.com";']),
      MockFile('content/file.cc',
               ['char* host = "https://www.googleapis.com";']),
      MockFile('content/file.cc',
               ['char* host = "https://clients1.google.com";']),
    ]

    warnings = PRESUBMIT.CheckHardcodedGoogleHostsInLowerLayers(
      input_api, MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertEqual(3, len(warnings[0].items))

  def testAllowInComment(self):
    input_api = MockInputApi()
    input_api.files = [
      MockFile('content/file.cc',
               ['char* host = "https://www.aol.com"; // google.com'])
    ]

    warnings = PRESUBMIT.CheckHardcodedGoogleHostsInLowerLayers(
      input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))


class ChromeOsSyncedPrefRegistrationTest(unittest.TestCase):

  def testWarnsOnChromeOsDirectories(self):
    files = [
      MockFile('ash/file.cc',
               ['PrefRegistrySyncable::SYNCABLE_PREF']),
      MockFile('chrome/browser/chromeos/file.cc',
               ['PrefRegistrySyncable::SYNCABLE_PREF']),
      MockFile('chromeos/file.cc',
               ['PrefRegistrySyncable::SYNCABLE_PREF']),
      MockFile('components/arc/file.cc',
               ['PrefRegistrySyncable::SYNCABLE_PREF']),
      MockFile('components/exo/file.cc',
               ['PrefRegistrySyncable::SYNCABLE_PREF']),
    ]
    input_api = MockInputApi()
    for file in files:
      input_api.files = [file]
      warnings = PRESUBMIT.CheckChromeOsSyncedPrefRegistration(
        input_api, MockOutputApi())
      self.assertEqual(1, len(warnings))

  def testDoesNotWarnOnSyncOsPref(self):
    input_api = MockInputApi()
    input_api.files = [
      MockFile('chromeos/file.cc',
               ['PrefRegistrySyncable::SYNCABLE_OS_PREF']),
    ]
    warnings = PRESUBMIT.CheckChromeOsSyncedPrefRegistration(
      input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))

  def testDoesNotWarnOnOtherDirectories(self):
    input_api = MockInputApi()
    input_api.files = [
      MockFile('chrome/browser/ui/file.cc',
               ['PrefRegistrySyncable::SYNCABLE_PREF']),
      MockFile('components/sync/file.cc',
               ['PrefRegistrySyncable::SYNCABLE_PREF']),
      MockFile('content/browser/file.cc',
               ['PrefRegistrySyncable::SYNCABLE_PREF']),
      MockFile('a/notchromeos/file.cc',
               ['PrefRegistrySyncable::SYNCABLE_PREF']),
    ]
    warnings = PRESUBMIT.CheckChromeOsSyncedPrefRegistration(
      input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))

  def testSeparateWarningForPriorityPrefs(self):
    input_api = MockInputApi()
    input_api.files = [
      MockFile('chromeos/file.cc',
               ['PrefRegistrySyncable::SYNCABLE_PREF',
                'PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF']),
    ]
    warnings = PRESUBMIT.CheckChromeOsSyncedPrefRegistration(
      input_api, MockOutputApi())
    self.assertEqual(2, len(warnings))


class ForwardDeclarationTest(unittest.TestCase):
  def testCheckHeadersOnlyOutsideThirdParty(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('somewhere/file.cc', [
        'class DummyClass;'
      ]),
      MockAffectedFile('third_party/header.h', [
        'class DummyClass;'
      ])
    ]
    warnings = PRESUBMIT.CheckUselessForwardDeclarations(mock_input_api,
                                                          MockOutputApi())
    self.assertEqual(0, len(warnings))

  def testNoNestedDeclaration(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('somewhere/header.h', [
        'class SomeClass {',
        ' protected:',
        '  class NotAMatch;',
        '};'
      ])
    ]
    warnings = PRESUBMIT.CheckUselessForwardDeclarations(mock_input_api,
                                                          MockOutputApi())
    self.assertEqual(0, len(warnings))

  def testSubStrings(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('somewhere/header.h', [
        'class NotUsefulClass;',
        'struct SomeStruct;',
        'UsefulClass *p1;',
        'SomeStructPtr *p2;'
      ])
    ]
    warnings = PRESUBMIT.CheckUselessForwardDeclarations(mock_input_api,
                                                          MockOutputApi())
    self.assertEqual(2, len(warnings))

  def testUselessForwardDeclaration(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('somewhere/header.h', [
        'class DummyClass;',
        'struct DummyStruct;',
        'class UsefulClass;',
        'std::unique_ptr<UsefulClass> p;'
      ])
    ]
    warnings = PRESUBMIT.CheckUselessForwardDeclarations(mock_input_api,
                                                          MockOutputApi())
    self.assertEqual(2, len(warnings))

  def testBlinkHeaders(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('third_party/blink/header.h', [
        'class DummyClass;',
        'struct DummyStruct;',
      ]),
      MockAffectedFile('third_party\\blink\\header.h', [
        'class DummyClass;',
        'struct DummyStruct;',
      ])
    ]
    warnings = PRESUBMIT.CheckUselessForwardDeclarations(mock_input_api,
                                                          MockOutputApi())
    self.assertEqual(4, len(warnings))


class RelativeIncludesTest(unittest.TestCase):
  def testThirdPartyNotWebKitIgnored(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('third_party/test.cpp', '#include "../header.h"'),
      MockAffectedFile('third_party/test/test.cpp', '#include "../header.h"'),
    ]

    mock_output_api = MockOutputApi()

    errors = PRESUBMIT.CheckForRelativeIncludes(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(errors))

  def testNonCppFileIgnored(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('test.py', '#include "../header.h"'),
    ]

    mock_output_api = MockOutputApi()

    errors = PRESUBMIT.CheckForRelativeIncludes(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(errors))

  def testInnocuousChangesAllowed(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('test.cpp', '#include "header.h"'),
      MockAffectedFile('test2.cpp', '../'),
    ]

    mock_output_api = MockOutputApi()

    errors = PRESUBMIT.CheckForRelativeIncludes(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(errors))

  def testRelativeIncludeNonWebKitProducesError(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('test.cpp', ['#include "../header.h"']),
    ]

    mock_output_api = MockOutputApi()

    errors = PRESUBMIT.CheckForRelativeIncludes(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(errors))

  def testRelativeIncludeWebKitProducesError(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('third_party/blink/test.cpp',
                       ['#include "../header.h']),
    ]

    mock_output_api = MockOutputApi()

    errors = PRESUBMIT.CheckForRelativeIncludes(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(errors))


class CCIncludeTest(unittest.TestCase):
  def testThirdPartyNotBlinkIgnored(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('third_party/test.cpp', '#include "file.cc"'),
    ]

    mock_output_api = MockOutputApi()

    errors = PRESUBMIT.CheckForCcIncludes(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(errors))

  def testPythonFileIgnored(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('test.py', '#include "file.cc"'),
    ]

    mock_output_api = MockOutputApi()

    errors = PRESUBMIT.CheckForCcIncludes(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(errors))

  def testIncFilesAccepted(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('test.py', '#include "file.inc"'),
    ]

    mock_output_api = MockOutputApi()

    errors = PRESUBMIT.CheckForCcIncludes(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(errors))

  def testInnocuousChangesAllowed(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('test.cpp', '#include "header.h"'),
      MockAffectedFile('test2.cpp', 'Something "file.cc"'),
    ]

    mock_output_api = MockOutputApi()

    errors = PRESUBMIT.CheckForCcIncludes(
        mock_input_api, mock_output_api)
    self.assertEqual(0, len(errors))

  def testCcIncludeNonBlinkProducesError(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('test.cpp', ['#include "file.cc"']),
    ]

    mock_output_api = MockOutputApi()

    errors = PRESUBMIT.CheckForCcIncludes(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(errors))

  def testCppIncludeBlinkProducesError(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('third_party/blink/test.cpp',
                       ['#include "foo/file.cpp"']),
    ]

    mock_output_api = MockOutputApi()

    errors = PRESUBMIT.CheckForCcIncludes(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(errors))


class GnGlobForwardTest(unittest.TestCase):
  def testAddBareGlobs(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('base/stuff.gni', [
          'forward_variables_from(invoker, "*")']),
      MockAffectedFile('base/BUILD.gn', [
          'forward_variables_from(invoker, "*")']),
    ]
    warnings = PRESUBMIT.CheckGnGlobForward(mock_input_api, MockOutputApi())
    self.assertEqual(1, len(warnings))
    msg = '\n'.join(warnings[0].items)
    self.assertIn('base/stuff.gni', msg)
    # Should not check .gn files. Local templates don't need to care about
    # visibility / testonly.
    self.assertNotIn('base/BUILD.gn', msg)

  def testValidUses(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('base/stuff.gni', [
          'forward_variables_from(invoker, "*", [])']),
      MockAffectedFile('base/stuff2.gni', [
          'forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)']),
      MockAffectedFile('base/stuff3.gni', [
          'forward_variables_from(invoker, [ "testonly" ])']),
    ]
    warnings = PRESUBMIT.CheckGnGlobForward(mock_input_api, MockOutputApi())
    self.assertEqual([], warnings)


class NewHeaderWithoutGnChangeTest(unittest.TestCase):
  def testAddHeaderWithoutGn(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('base/stuff.h', ''),
    ]
    warnings = PRESUBMIT.CheckNewHeaderWithoutGnChangeOnUpload(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertTrue('base/stuff.h' in warnings[0].items)

  def testModifyHeader(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('base/stuff.h', '', action='M'),
    ]
    warnings = PRESUBMIT.CheckNewHeaderWithoutGnChangeOnUpload(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))

  def testDeleteHeader(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('base/stuff.h', '', action='D'),
    ]
    warnings = PRESUBMIT.CheckNewHeaderWithoutGnChangeOnUpload(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))

  def testAddHeaderWithGn(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('base/stuff.h', ''),
      MockAffectedFile('base/BUILD.gn', 'stuff.h'),
    ]
    warnings = PRESUBMIT.CheckNewHeaderWithoutGnChangeOnUpload(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))

  def testAddHeaderWithGni(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('base/stuff.h', ''),
      MockAffectedFile('base/files.gni', 'stuff.h'),
    ]
    warnings = PRESUBMIT.CheckNewHeaderWithoutGnChangeOnUpload(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))

  def testAddHeaderWithOther(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('base/stuff.h', ''),
      MockAffectedFile('base/stuff.cc', 'stuff.h'),
    ]
    warnings = PRESUBMIT.CheckNewHeaderWithoutGnChangeOnUpload(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(warnings))

  def testAddHeaderWithWrongGn(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('base/stuff.h', ''),
      MockAffectedFile('base/BUILD.gn', 'stuff_h'),
    ]
    warnings = PRESUBMIT.CheckNewHeaderWithoutGnChangeOnUpload(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(warnings))

  def testAddHeadersWithGn(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('base/stuff.h', ''),
      MockAffectedFile('base/another.h', ''),
      MockAffectedFile('base/BUILD.gn', 'another.h\nstuff.h'),
    ]
    warnings = PRESUBMIT.CheckNewHeaderWithoutGnChangeOnUpload(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))

  def testAddHeadersWithWrongGn(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('base/stuff.h', ''),
      MockAffectedFile('base/another.h', ''),
      MockAffectedFile('base/BUILD.gn', 'another_h\nstuff.h'),
    ]
    warnings = PRESUBMIT.CheckNewHeaderWithoutGnChangeOnUpload(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertFalse('base/stuff.h' in warnings[0].items)
    self.assertTrue('base/another.h' in warnings[0].items)

  def testAddHeadersWithWrongGn2(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('base/stuff.h', ''),
      MockAffectedFile('base/another.h', ''),
      MockAffectedFile('base/BUILD.gn', 'another_h\nstuff_h'),
    ]
    warnings = PRESUBMIT.CheckNewHeaderWithoutGnChangeOnUpload(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertTrue('base/stuff.h' in warnings[0].items)
    self.assertTrue('base/another.h' in warnings[0].items)


class CorrectProductNameInMessagesTest(unittest.TestCase):
  def testProductNameInDesc(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('chrome/app/google_chrome_strings.grd', [
        '<message name="Foo" desc="Welcome to Chrome">',
        '  Welcome to Chrome!',
        '</message>',
      ]),
      MockAffectedFile('chrome/app/chromium_strings.grd', [
        '<message name="Bar" desc="Welcome to Chrome">',
        '  Welcome to Chromium!',
        '</message>',
      ]),
    ]
    warnings = PRESUBMIT.CheckCorrectProductNameInMessages(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))

  def testChromeInChromium(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('chrome/app/google_chrome_strings.grd', [
        '<message name="Foo" desc="Welcome to Chrome">',
        '  Welcome to Chrome!',
        '</message>',
      ]),
      MockAffectedFile('chrome/app/chromium_strings.grd', [
        '<message name="Bar" desc="Welcome to Chrome">',
        '  Welcome to Chrome!',
        '</message>',
      ]),
    ]
    warnings = PRESUBMIT.CheckCorrectProductNameInMessages(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertTrue('chrome/app/chromium_strings.grd' in warnings[0].items[0])

  def testChromiumInChrome(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('chrome/app/google_chrome_strings.grd', [
        '<message name="Foo" desc="Welcome to Chrome">',
        '  Welcome to Chromium!',
        '</message>',
      ]),
      MockAffectedFile('chrome/app/chromium_strings.grd', [
        '<message name="Bar" desc="Welcome to Chrome">',
        '  Welcome to Chromium!',
        '</message>',
      ]),
    ]
    warnings = PRESUBMIT.CheckCorrectProductNameInMessages(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertTrue(
        'chrome/app/google_chrome_strings.grd:2' in warnings[0].items[0])

  def testMultipleInstances(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('chrome/app/chromium_strings.grd', [
        '<message name="Bar" desc="Welcome to Chrome">',
        '  Welcome to Chrome!',
        '</message>',
        '<message name="Baz" desc="A correct message">',
        '  Chromium is the software you are using.',
        '</message>',
        '<message name="Bat" desc="An incorrect message">',
        '  Google Chrome is the software you are using.',
        '</message>',
      ]),
    ]
    warnings = PRESUBMIT.CheckCorrectProductNameInMessages(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertTrue(
        'chrome/app/chromium_strings.grd:2' in warnings[0].items[0])
    self.assertTrue(
        'chrome/app/chromium_strings.grd:8' in warnings[0].items[1])

  def testMultipleWarnings(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('chrome/app/chromium_strings.grd', [
        '<message name="Bar" desc="Welcome to Chrome">',
        '  Welcome to Chrome!',
        '</message>',
        '<message name="Baz" desc="A correct message">',
        '  Chromium is the software you are using.',
        '</message>',
        '<message name="Bat" desc="An incorrect message">',
        '  Google Chrome is the software you are using.',
        '</message>',
      ]),
      MockAffectedFile('components/components_google_chrome_strings.grd', [
        '<message name="Bar" desc="Welcome to Chrome">',
        '  Welcome to Chrome!',
        '</message>',
        '<message name="Baz" desc="A correct message">',
        '  Chromium is the software you are using.',
        '</message>',
        '<message name="Bat" desc="An incorrect message">',
        '  Google Chrome is the software you are using.',
        '</message>',
      ]),
    ]
    warnings = PRESUBMIT.CheckCorrectProductNameInMessages(
        mock_input_api, MockOutputApi())
    self.assertEqual(2, len(warnings))
    self.assertTrue(
        'components/components_google_chrome_strings.grd:5'
             in warnings[0].items[0])
    self.assertTrue(
        'chrome/app/chromium_strings.grd:2' in warnings[1].items[0])
    self.assertTrue(
        'chrome/app/chromium_strings.grd:8' in warnings[1].items[1])


class ServiceManifestOwnerTest(unittest.TestCase):
  def testServiceManifestChangeNeedsSecurityOwner(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('services/goat/public/cpp/manifest.cc',
                       [
                         '#include "services/goat/public/cpp/manifest.h"',
                         'const service_manager::Manifest& GetManifest() {}',
                       ])]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckSecurityOwners(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(errors))
    self.assertEqual(
        'Found OWNERS files that need to be updated for IPC security review ' +
        'coverage.\nPlease update the OWNERS files below:', errors[0].message)

  def testNonServiceManifestSourceChangesDoNotRequireSecurityOwner(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('some/non/service/thing/foo_manifest.cc',
                       [
                         'const char kNoEnforcement[] = "not a manifest!";',
                       ])]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckSecurityOwners(
        mock_input_api, mock_output_api)
    self.assertEqual([], errors)


class FuchsiaSecurityOwnerTest(unittest.TestCase):
  def testFidlChangeNeedsSecurityOwner(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('potentially/scary/ipc.fidl',
                       [
                         'library test.fidl'
                       ])]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckSecurityOwners(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(errors))
    self.assertEqual(
        'Found OWNERS files that need to be updated for IPC security review ' +
        'coverage.\nPlease update the OWNERS files below:', errors[0].message)

  def testComponentManifestV1ChangeNeedsSecurityOwner(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('potentially/scary/v2_manifest.cmx',
                       [
                         '{ "that is no": "manifest!" }'
                       ])]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckSecurityOwners(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(errors))
    self.assertEqual(
        'Found OWNERS files that need to be updated for IPC security review ' +
        'coverage.\nPlease update the OWNERS files below:', errors[0].message)

  def testComponentManifestV2NeedsSecurityOwner(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('potentially/scary/v2_manifest.cml',
                       [
                         '{ "that is no": "manifest!" }'
                       ])]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckSecurityOwners(
        mock_input_api, mock_output_api)
    self.assertEqual(1, len(errors))
    self.assertEqual(
        'Found OWNERS files that need to be updated for IPC security review ' +
        'coverage.\nPlease update the OWNERS files below:', errors[0].message)

  def testThirdPartyTestsDoNotRequireSecurityOwner(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('third_party/crashpad/test/tests.cmx',
                       [
                         'const char kNoEnforcement[] = "Security?!? Pah!";',
                       ])]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckSecurityOwners(
        mock_input_api, mock_output_api)
    self.assertEqual([], errors)

  def testOtherFuchsiaChangesDoNotRequireSecurityOwner(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('some/non/service/thing/fuchsia_fidl_cml_cmx_magic.cc',
                       [
                         'const char kNoEnforcement[] = "Security?!? Pah!";',
                       ])]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckSecurityOwners(
        mock_input_api, mock_output_api)
    self.assertEqual([], errors)


class SecurityChangeTest(unittest.TestCase):
  class _MockOwnersClient(object):
    def ListOwners(self, f):
      return ['apple@chromium.org', 'orange@chromium.org']

  def _mockChangeOwnerAndReviewers(self, input_api, owner, reviewers):
    def __MockOwnerAndReviewers(input_api, email_regexp, approval_needed=False):
      return [owner, reviewers]
    input_api.canned_checks.GetCodereviewOwnerAndReviewers = \
        __MockOwnerAndReviewers

  def testDiffGetServiceSandboxType(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockAffectedFile(
          'services/goat/teleporter_host.cc',
          [
            'template <>',
            'inline content::SandboxType',
            'content::GetServiceSandboxType<chrome::mojom::GoatTeleporter>() {',
            '#if defined(OS_WIN)',
            '  return SandboxType::kGoaty;',
            '#else',
            '  return SandboxType::kNoSandbox;',
            '#endif  // !defined(OS_WIN)',
            '}'
          ]
        ),
    ]
    files_to_functions = PRESUBMIT._GetFilesUsingSecurityCriticalFunctions(
        mock_input_api)
    self.assertEqual({
        'services/goat/teleporter_host.cc': set([
            'content::GetServiceSandboxType<>()'
        ])},
        files_to_functions)

  def testDiffRemovingLine(self):
    mock_input_api = MockInputApi()
    mock_file = MockAffectedFile('services/goat/teleporter_host.cc', '')
    mock_file._scm_diff = """--- old 2020-05-04 14:08:25.000000000 -0400
+++ new 2020-05-04 14:08:32.000000000 -0400
@@ -1,5 +1,4 @@
 template <>
 inline content::SandboxType
-content::GetServiceSandboxType<chrome::mojom::GoatTeleporter>() {
 #if defined(OS_WIN)
   return SandboxType::kGoaty;
"""
    mock_input_api.files = [mock_file]
    files_to_functions = PRESUBMIT._GetFilesUsingSecurityCriticalFunctions(
        mock_input_api)
    self.assertEqual({
        'services/goat/teleporter_host.cc': set([
            'content::GetServiceSandboxType<>()'
        ])},
        files_to_functions)

  def testChangeOwnersMissing(self):
    mock_input_api = MockInputApi()
    mock_input_api.owners_client = self._MockOwnersClient()
    mock_input_api.is_committing = False
    mock_input_api.files = [
        MockAffectedFile('file.cc', ['GetServiceSandboxType<Goat>(Sandbox)'])
    ]
    mock_output_api = MockOutputApi()
    self._mockChangeOwnerAndReviewers(
        mock_input_api, 'owner@chromium.org', ['banana@chromium.org'])
    result = PRESUBMIT.CheckSecurityChanges(mock_input_api, mock_output_api)
    self.assertEqual(1, len(result))
    self.assertEqual(result[0].type, 'notify')
    self.assertEqual(result[0].message,
        'The following files change calls to security-sensive functions\n' \
        'that need to be reviewed by ipc/SECURITY_OWNERS.\n'
        '  file.cc\n'
        '    content::GetServiceSandboxType<>()\n\n')

  def testChangeOwnersMissingAtCommit(self):
    mock_input_api = MockInputApi()
    mock_input_api.owners_client = self._MockOwnersClient()
    mock_input_api.is_committing = True
    mock_input_api.files = [
        MockAffectedFile('file.cc', ['GetServiceSandboxType<mojom::Goat>()'])
    ]
    mock_output_api = MockOutputApi()
    self._mockChangeOwnerAndReviewers(
        mock_input_api, 'owner@chromium.org', ['banana@chromium.org'])
    result = PRESUBMIT.CheckSecurityChanges(mock_input_api, mock_output_api)
    self.assertEqual(1, len(result))
    self.assertEqual(result[0].type, 'error')
    self.assertEqual(result[0].message,
        'The following files change calls to security-sensive functions\n' \
        'that need to be reviewed by ipc/SECURITY_OWNERS.\n'
        '  file.cc\n'
        '    content::GetServiceSandboxType<>()\n\n')

  def testChangeOwnersPresent(self):
    mock_input_api = MockInputApi()
    mock_input_api.owners_client = self._MockOwnersClient()
    mock_input_api.files = [
        MockAffectedFile('file.cc', ['WithSandboxType(Sandbox)'])
    ]
    mock_output_api = MockOutputApi()
    self._mockChangeOwnerAndReviewers(
        mock_input_api, 'owner@chromium.org',
        ['apple@chromium.org', 'banana@chromium.org'])
    result = PRESUBMIT.CheckSecurityChanges(mock_input_api, mock_output_api)
    self.assertEqual(0, len(result))

  def testChangeOwnerIsSecurityOwner(self):
    mock_input_api = MockInputApi()
    mock_input_api.owners_client = self._MockOwnersClient()
    mock_input_api.files = [
        MockAffectedFile('file.cc', ['GetServiceSandboxType<T>(Sandbox)'])
    ]
    mock_output_api = MockOutputApi()
    self._mockChangeOwnerAndReviewers(
        mock_input_api, 'orange@chromium.org', ['pear@chromium.org'])
    result = PRESUBMIT.CheckSecurityChanges(mock_input_api, mock_output_api)
    self.assertEqual(1, len(result))


class BannedTypeCheckTest(unittest.TestCase):

  def testBannedCppFunctions(self):
    input_api = MockInputApi()
    input_api.files = [
      MockFile('some/cpp/problematic/file.cc',
               ['using namespace std;']),
      MockFile('third_party/blink/problematic/file.cc',
               ['GetInterfaceProvider()']),
      MockFile('some/cpp/ok/file.cc',
               ['using std::string;']),
      MockFile('some/cpp/problematic/file2.cc',
               ['set_owned_by_client()']),
      MockFile('some/cpp/nocheck/file.cc',
               ['using namespace std;  // nocheck']),
      MockFile('some/cpp/comment/file.cc',
               ['  // A comment about `using namespace std;`']),
    ]

    results = PRESUBMIT.CheckNoBannedFunctions(input_api, MockOutputApi())

     # warnings are results[0], errors are results[1]
    self.assertEqual(2, len(results))
    self.assertTrue('some/cpp/problematic/file.cc' in results[1].message)
    self.assertTrue(
        'third_party/blink/problematic/file.cc' in results[0].message)
    self.assertTrue('some/cpp/ok/file.cc' not in results[1].message)
    self.assertTrue('some/cpp/problematic/file2.cc' in results[0].message)
    self.assertFalse('some/cpp/nocheck/file.cc' in results[0].message)
    self.assertFalse('some/cpp/nocheck/file.cc' in results[1].message)
    self.assertFalse('some/cpp/comment/file.cc' in results[0].message)
    self.assertFalse('some/cpp/comment/file.cc' in results[1].message)

  def testBannedIosObjcFunctions(self):
    input_api = MockInputApi()
    input_api.files = [
      MockFile('some/ios/file.mm',
               ['TEST(SomeClassTest, SomeInteraction) {',
                '}']),
      MockFile('some/mac/file.mm',
               ['TEST(SomeClassTest, SomeInteraction) {',
                '}']),
      MockFile('another/ios_file.mm',
               ['class SomeTest : public testing::Test {};']),
      MockFile('some/ios/file_egtest.mm',
               ['- (void)testSomething { EXPECT_OCMOCK_VERIFY(aMock); }']),
      MockFile('some/ios/file_unittest.mm',
               ['TEST_F(SomeTest, TestThis) { EXPECT_OCMOCK_VERIFY(aMock); }']),
    ]

    errors = PRESUBMIT.CheckNoBannedFunctions(input_api, MockOutputApi())
    self.assertEqual(1, len(errors))
    self.assertTrue('some/ios/file.mm' in errors[0].message)
    self.assertTrue('another/ios_file.mm' in errors[0].message)
    self.assertTrue('some/mac/file.mm' not in errors[0].message)
    self.assertTrue('some/ios/file_egtest.mm' in errors[0].message)
    self.assertTrue('some/ios/file_unittest.mm' not in errors[0].message)

  def testBannedMojoFunctions(self):
    input_api = MockInputApi()
    input_api.files = [
      MockFile('some/cpp/problematic/file2.cc',
               ['mojo::ConvertTo<>']),
      MockFile('third_party/blink/ok/file3.cc',
               ['mojo::ConvertTo<>']),
      MockFile('content/renderer/ok/file3.cc',
               ['mojo::ConvertTo<>']),
    ]

    results = PRESUBMIT.CheckNoBannedFunctions(input_api, MockOutputApi())

    # warnings are results[0], errors are results[1]
    self.assertEqual(1, len(results))
    self.assertTrue('some/cpp/problematic/file2.cc' in results[0].message)
    self.assertTrue('third_party/blink/ok/file3.cc' not in results[0].message)
    self.assertTrue('content/renderer/ok/file3.cc' not in results[0].message)

  def testDeprecatedMojoTypes(self):
    ok_paths = ['components/arc']
    warning_paths = ['some/cpp']
    error_paths = ['third_party/blink', 'content']
    test_cases = [
      {
        'type': 'mojo::AssociatedInterfacePtrInfo<>',
        'file': 'file4.cc'
      },
      {
        'type': 'mojo::AssociatedInterfaceRequest<>',
        'file': 'file5.cc'
      },
      {
        'type': 'mojo::InterfacePtr<>',
        'file': 'file8.cc'
      },
      {
        'type': 'mojo::InterfacePtrInfo<>',
        'file': 'file9.cc'
      },
      {
        'type': 'mojo::InterfaceRequest<>',
        'file': 'file10.cc'
      },
      {
        'type': 'mojo::MakeRequest()',
        'file': 'file11.cc'
      },
    ]

    # Build the list of MockFiles considering paths that should trigger warnings
    # as well as paths that should trigger errors.
    input_api = MockInputApi()
    input_api.files = []
    for test_case in test_cases:
      for path in ok_paths:
        input_api.files.append(MockFile(os.path.join(path, test_case['file']),
                                        [test_case['type']]))
      for path in warning_paths:
        input_api.files.append(MockFile(os.path.join(path, test_case['file']),
                                        [test_case['type']]))
      for path in error_paths:
        input_api.files.append(MockFile(os.path.join(path, test_case['file']),
                                        [test_case['type']]))

    results = PRESUBMIT.CheckNoDeprecatedMojoTypes(input_api, MockOutputApi())

    # warnings are results[0], errors are results[1]
    self.assertEqual(2, len(results))

    for test_case in test_cases:
      # Check that no warnings nor errors have been triggered for these paths.
      for path in ok_paths:
        self.assertFalse(path in results[0].message)
        self.assertFalse(path in results[1].message)

      # Check warnings have been triggered for these paths.
      for path in warning_paths:
        self.assertTrue(path in results[0].message)
        self.assertFalse(path in results[1].message)

      # Check errors have been triggered for these paths.
      for path in error_paths:
        self.assertFalse(path in results[0].message)
        self.assertTrue(path in results[1].message)


class NoProductionCodeUsingTestOnlyFunctionsTest(unittest.TestCase):
  def testTruePositives(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('some/path/foo.cc', ['foo_for_testing();']),
      MockFile('some/path/foo.mm', ['FooForTesting();']),
      MockFile('some/path/foo.cxx', ['FooForTests();']),
      MockFile('some/path/foo.cpp', ['foo_for_test();']),
    ]

    results = PRESUBMIT.CheckNoProductionCodeUsingTestOnlyFunctions(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(results))
    self.assertEqual(4, len(results[0].items))
    self.assertTrue('foo.cc' in results[0].items[0])
    self.assertTrue('foo.mm' in results[0].items[1])
    self.assertTrue('foo.cxx' in results[0].items[2])
    self.assertTrue('foo.cpp' in results[0].items[3])

  def testFalsePositives(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('some/path/foo.h', ['foo_for_testing();']),
      MockFile('some/path/foo.mm', ['FooForTesting() {']),
      MockFile('some/path/foo.cc', ['::FooForTests();']),
      MockFile('some/path/foo.cpp', ['// foo_for_test();']),
    ]

    results = PRESUBMIT.CheckNoProductionCodeUsingTestOnlyFunctions(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(results))

  def testAllowedFiles(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('path/foo_unittest.cc', ['foo_for_testing();']),
      MockFile('path/bar_unittest_mac.cc', ['foo_for_testing();']),
      MockFile('path/baz_unittests.cc', ['foo_for_testing();']),
    ]

    results = PRESUBMIT.CheckNoProductionCodeUsingTestOnlyFunctions(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(results))


class NoProductionJavaCodeUsingTestOnlyFunctionsTest(unittest.TestCase):
  def testTruePositives(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('dir/java/src/foo.java', ['FooForTesting();']),
      MockFile('dir/java/src/bar.java', ['FooForTests(x);']),
      MockFile('dir/java/src/baz.java', ['FooForTest(', 'y', ');']),
      MockFile('dir/java/src/mult.java', [
        'int x = SomethingLongHere()',
        '    * SomethingLongHereForTesting();'
      ])
    ]

    results = PRESUBMIT.CheckNoProductionCodeUsingTestOnlyFunctionsJava(
        mock_input_api, MockOutputApi())
    self.assertEqual(1, len(results))
    self.assertEqual(4, len(results[0].items))
    self.assertTrue('foo.java' in results[0].items[0])
    self.assertTrue('bar.java' in results[0].items[1])
    self.assertTrue('baz.java' in results[0].items[2])
    self.assertTrue('mult.java' in results[0].items[3])

  def testFalsePositives(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('dir/java/src/foo.xml', ['FooForTesting();']),
      MockFile('dir/java/src/foo.java', ['FooForTests() {']),
      MockFile('dir/java/src/bar.java', ['// FooForTest();']),
      MockFile('dir/java/src/bar2.java', ['x = 1; // FooForTest();']),
      MockFile('dir/java/src/bar3.java', ['@VisibleForTesting']),
      MockFile('dir/java/src/bar4.java', ['@VisibleForTesting()']),
      MockFile('dir/java/src/bar5.java', [
        '@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)'
      ]),
      MockFile('dir/javatests/src/baz.java', ['FooForTest(', 'y', ');']),
      MockFile('dir/junit/src/baz.java', ['FooForTest(', 'y', ');']),
      MockFile('dir/junit/src/javadoc.java', [
        '/** Use FooForTest(); to obtain foo in tests.'
        ' */'
      ]),
      MockFile('dir/junit/src/javadoc2.java', [
        '/** ',
        ' * Use FooForTest(); to obtain foo in tests.'
        ' */'
      ]),
    ]

    results = PRESUBMIT.CheckNoProductionCodeUsingTestOnlyFunctionsJava(
        mock_input_api, MockOutputApi())
    self.assertEqual(0, len(results))


class NewImagesWarningTest(unittest.TestCase):
  def testTruePositives(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('dir/android/res/drawable/foo.png', []),
      MockFile('dir/android/res/drawable-v21/bar.svg', []),
      MockFile('dir/android/res/mipmap-v21-en/baz.webp', []),
      MockFile('dir/android/res_gshoe/drawable-mdpi/foobar.png', []),
    ]

    results = PRESUBMIT._CheckNewImagesWarning(mock_input_api, MockOutputApi())
    self.assertEqual(1, len(results))
    self.assertEqual(4, len(results[0].items))
    self.assertTrue('foo.png' in results[0].items[0].LocalPath())
    self.assertTrue('bar.svg' in results[0].items[1].LocalPath())
    self.assertTrue('baz.webp' in results[0].items[2].LocalPath())
    self.assertTrue('foobar.png' in results[0].items[3].LocalPath())

  def testFalsePositives(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('dir/pngs/README.md', []),
      MockFile('java/test/res/drawable/foo.png', []),
      MockFile('third_party/blink/foo.png', []),
      MockFile('dir/third_party/libpng/src/foo.cc', ['foobar']),
      MockFile('dir/resources.webp/.gitignore', ['foo.png']),
    ]

    results = PRESUBMIT._CheckNewImagesWarning(mock_input_api, MockOutputApi())
    self.assertEqual(0, len(results))


class CheckUniquePtrTest(unittest.TestCase):
  def testTruePositivesNullptr(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('dir/baz.cc', ['std::unique_ptr<T>()']),
      MockFile('dir/baz-p.cc', ['std::unique_ptr<T<P>>()']),
    ]

    results = PRESUBMIT.CheckUniquePtrOnUpload(mock_input_api, MockOutputApi())
    self.assertEqual(1, len(results))
    self.assertTrue('nullptr' in results[0].message)
    self.assertEqual(2, len(results[0].items))
    self.assertTrue('baz.cc' in results[0].items[0])
    self.assertTrue('baz-p.cc' in results[0].items[1])

  def testTruePositivesConstructor(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('dir/foo.cc', ['return std::unique_ptr<T>(foo);']),
      MockFile('dir/bar.mm', ['bar = std::unique_ptr<T>(foo)']),
      MockFile('dir/mult.cc', [
        'return',
        '    std::unique_ptr<T>(barVeryVeryLongFooSoThatItWouldNotFitAbove);'
      ]),
      MockFile('dir/mult2.cc', [
        'barVeryVeryLongLongBaaaaaarSoThatTheLineLimitIsAlmostReached =',
        '    std::unique_ptr<T>(foo);'
      ]),
      MockFile('dir/mult3.cc', [
        'bar = std::unique_ptr<T>(',
        '    fooVeryVeryVeryLongStillGoingWellThisWillTakeAWhileFinallyThere);'
      ]),
      MockFile('dir/multi_arg.cc', [
          'auto p = std::unique_ptr<std::pair<T, D>>(new std::pair(T, D));']),
    ]

    results = PRESUBMIT.CheckUniquePtrOnUpload(mock_input_api, MockOutputApi())
    self.assertEqual(1, len(results))
    self.assertTrue('std::make_unique' in results[0].message)
    self.assertEqual(6, len(results[0].items))
    self.assertTrue('foo.cc' in results[0].items[0])
    self.assertTrue('bar.mm' in results[0].items[1])
    self.assertTrue('mult.cc' in results[0].items[2])
    self.assertTrue('mult2.cc' in results[0].items[3])
    self.assertTrue('mult3.cc' in results[0].items[4])
    self.assertTrue('multi_arg.cc' in results[0].items[5])

  def testFalsePositives(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('dir/foo.cc', ['return std::unique_ptr<T[]>(foo);']),
      MockFile('dir/bar.mm', ['bar = std::unique_ptr<T[]>(foo)']),
      MockFile('dir/file.cc', ['std::unique_ptr<T> p = Foo();']),
      MockFile('dir/baz.cc', [
        'std::unique_ptr<T> result = std::make_unique<T>();'
      ]),
      MockFile('dir/baz2.cc', [
        'std::unique_ptr<T> result = std::make_unique<T>('
      ]),
      MockFile('dir/nested.cc', ['set<std::unique_ptr<T>>();']),
      MockFile('dir/nested2.cc', ['map<U, std::unique_ptr<T>>();']),

      # Two-argument invocation of std::unique_ptr is exempt because there is
      # no equivalent using std::make_unique.
      MockFile('dir/multi_arg.cc', [
        'auto p = std::unique_ptr<T, D>(new T(), D());']),
    ]

    results = PRESUBMIT.CheckUniquePtrOnUpload(mock_input_api, MockOutputApi())
    self.assertEqual(0, len(results))

class CheckNoDirectIncludesHeadersWhichRedefineStrCat(unittest.TestCase):
  def testBlocksDirectIncludes(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('dir/foo_win.cc', ['#include "shlwapi.h"']),
      MockFile('dir/bar.h', ['#include <propvarutil.h>']),
      MockFile('dir/baz.h', ['#include <atlbase.h>']),
      MockFile('dir/jumbo.h', ['#include "sphelper.h"']),
    ]
    results = PRESUBMIT._CheckNoStrCatRedefines(mock_input_api, MockOutputApi())
    self.assertEqual(1, len(results))
    self.assertEqual(4, len(results[0].items))
    self.assertTrue('StrCat' in results[0].message)
    self.assertTrue('foo_win.cc' in results[0].items[0])
    self.assertTrue('bar.h' in results[0].items[1])
    self.assertTrue('baz.h' in results[0].items[2])
    self.assertTrue('jumbo.h' in results[0].items[3])

  def testAllowsToIncludeWrapper(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('dir/baz_win.cc', ['#include "base/win/shlwapi.h"']),
      MockFile('dir/baz-win.h', ['#include "base/win/atl.h"']),
    ]
    results = PRESUBMIT._CheckNoStrCatRedefines(mock_input_api, MockOutputApi())
    self.assertEqual(0, len(results))

  def testAllowsToCreateWrapper(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile('base/win/shlwapi.h', [
        '#include <shlwapi.h>',
        '#include "base/win/windows_defines.inc"']),
    ]
    results = PRESUBMIT._CheckNoStrCatRedefines(mock_input_api, MockOutputApi())
    self.assertEqual(0, len(results))


class StringTest(unittest.TestCase):
  """Tests ICU syntax check and translation screenshots check."""

  # An empty grd file.
  OLD_GRD_CONTENTS = """<?xml version="1.0" encoding="UTF-8"?>
           <grit latest_public_release="1" current_release="1">
             <release seq="1">
               <messages></messages>
             </release>
           </grit>
        """.splitlines()
  # A grd file with a single message.
  NEW_GRD_CONTENTS1 = """<?xml version="1.0" encoding="UTF-8"?>
           <grit latest_public_release="1" current_release="1">
             <release seq="1">
               <messages>
                 <message name="IDS_TEST1">
                   Test string 1
                 </message>
                 <message name="IDS_TEST_STRING_NON_TRANSLATEABLE1"
                     translateable="false">
                   Non translateable message 1, should be ignored
                 </message>
                 <message name="IDS_TEST_STRING_ACCESSIBILITY"
                     is_accessibility_with_no_ui="true">
                   Accessibility label 1, should be ignored
                 </message>
               </messages>
             </release>
           </grit>
        """.splitlines()
  # A grd file with two messages.
  NEW_GRD_CONTENTS2 = """<?xml version="1.0" encoding="UTF-8"?>
           <grit latest_public_release="1" current_release="1">
             <release seq="1">
               <messages>
                 <message name="IDS_TEST1">
                   Test string 1
                 </message>
                 <message name="IDS_TEST2">
                   Test string 2
                 </message>
                 <message name="IDS_TEST_STRING_NON_TRANSLATEABLE2"
                     translateable="false">
                   Non translateable message 2, should be ignored
                 </message>
               </messages>
             </release>
           </grit>
        """.splitlines()
  # A grd file with one ICU syntax message without syntax errors.
  NEW_GRD_CONTENTS_ICU_SYNTAX_OK1 = """<?xml version="1.0" encoding="UTF-8"?>
           <grit latest_public_release="1" current_release="1">
             <release seq="1">
               <messages>
                 <message name="IDS_TEST1">
                   {NUM, plural,
                    =1 {Test text for numeric one}
                    other {Test text for plural with {NUM} as number}}
                 </message>
               </messages>
             </release>
           </grit>
        """.splitlines()
  # A grd file with one ICU syntax message without syntax errors.
  NEW_GRD_CONTENTS_ICU_SYNTAX_OK2 = """<?xml version="1.0" encoding="UTF-8"?>
           <grit latest_public_release="1" current_release="1">
             <release seq="1">
               <messages>
                 <message name="IDS_TEST1">
                   {NUM, plural,
                    =1 {Different test text for numeric one}
                    other {Different test text for plural with {NUM} as number}}
                 </message>
               </messages>
             </release>
           </grit>
        """.splitlines()
  # A grd file with one ICU syntax message with syntax errors (misses a comma).
  NEW_GRD_CONTENTS_ICU_SYNTAX_ERROR = """<?xml version="1.0" encoding="UTF-8"?>
           <grit latest_public_release="1" current_release="1">
             <release seq="1">
               <messages>
                 <message name="IDS_TEST1">
                   {NUM, plural
                    =1 {Test text for numeric one}
                    other {Test text for plural with {NUM} as number}}
                 </message>
               </messages>
             </release>
           </grit>
        """.splitlines()

  OLD_GRDP_CONTENTS = (
    '<?xml version="1.0" encoding="utf-8"?>',
      '<grit-part>',
    '</grit-part>'
  )

  NEW_GRDP_CONTENTS1 = (
    '<?xml version="1.0" encoding="utf-8"?>',
      '<grit-part>',
        '<message name="IDS_PART_TEST1">',
          'Part string 1',
        '</message>',
    '</grit-part>')

  NEW_GRDP_CONTENTS2 = (
    '<?xml version="1.0" encoding="utf-8"?>',
      '<grit-part>',
        '<message name="IDS_PART_TEST1">',
          'Part string 1',
        '</message>',
        '<message name="IDS_PART_TEST2">',
          'Part string 2',
      '</message>',
    '</grit-part>')

  NEW_GRDP_CONTENTS3 = (
    '<?xml version="1.0" encoding="utf-8"?>',
      '<grit-part>',
        '<message name="IDS_PART_TEST1" desc="Description with typo.">',
          'Part string 1',
        '</message>',
    '</grit-part>')

  NEW_GRDP_CONTENTS4 = (
    '<?xml version="1.0" encoding="utf-8"?>',
      '<grit-part>',
        '<message name="IDS_PART_TEST1" desc="Description with typo fixed.">',
          'Part string 1',
        '</message>',
    '</grit-part>')

  NEW_GRDP_CONTENTS5 = (
    '<?xml version="1.0" encoding="utf-8"?>',
      '<grit-part>',
        '<message name="IDS_PART_TEST1" meaning="Meaning with typo.">',
          'Part string 1',
        '</message>',
    '</grit-part>')

  NEW_GRDP_CONTENTS6 = (
    '<?xml version="1.0" encoding="utf-8"?>',
      '<grit-part>',
        '<message name="IDS_PART_TEST1" meaning="Meaning with typo fixed.">',
          'Part string 1',
        '</message>',
    '</grit-part>')

  # A grdp file with one ICU syntax message without syntax errors.
  NEW_GRDP_CONTENTS_ICU_SYNTAX_OK1 = (
    '<?xml version="1.0" encoding="utf-8"?>',
      '<grit-part>',
        '<message name="IDS_PART_TEST1">',
           '{NUM, plural,',
            '=1 {Test text for numeric one}',
            'other {Test text for plural with {NUM} as number}}',
        '</message>',
    '</grit-part>')
  # A grdp file with one ICU syntax message without syntax errors.
  NEW_GRDP_CONTENTS_ICU_SYNTAX_OK2 = (
    '<?xml version="1.0" encoding="utf-8"?>',
      '<grit-part>',
        '<message name="IDS_PART_TEST1">',
           '{NUM, plural,',
            '=1 {Different test text for numeric one}',
            'other {Different test text for plural with {NUM} as number}}',
        '</message>',
    '</grit-part>')

  # A grdp file with one ICU syntax message with syntax errors (superfluent
  # whitespace).
  NEW_GRDP_CONTENTS_ICU_SYNTAX_ERROR = (
    '<?xml version="1.0" encoding="utf-8"?>',
      '<grit-part>',
        '<message name="IDS_PART_TEST1">',
           '{NUM, plural,',
            '= 1 {Test text for numeric one}',
            'other {Test text for plural with {NUM} as number}}',
        '</message>',
    '</grit-part>')

  DO_NOT_UPLOAD_PNG_MESSAGE = ('Do not include actual screenshots in the '
                               'changelist. Run '
                               'tools/translate/upload_screenshots.py to '
                               'upload them instead:')
  GENERATE_SIGNATURES_MESSAGE = ('You are adding or modifying UI strings.\n'
                                 'To ensure the best translations, take '
                                 'screenshots of the relevant UI '
                                 '(https://g.co/chrome/translation) and add '
                                 'these files to your changelist:')
  REMOVE_SIGNATURES_MESSAGE = ('You removed strings associated with these '
                               'files. Remove:')
  ICU_SYNTAX_ERROR_MESSAGE = ('ICU syntax errors were found in the following '
                              'strings (problems or feedback? Contact '
                              'rainhard@chromium.org):')

  def makeInputApi(self, files):
    input_api = MockInputApi()
    input_api.files = files
    # Override os_path.exists because the presubmit uses the actual
    # os.path.exists.
    input_api.CreateMockFileInPath(
        [x.LocalPath() for x in input_api.AffectedFiles(include_deletes=True)])
    return input_api

  """ CL modified and added messages, but didn't add any screenshots."""
  def testNoScreenshots(self):
    # No new strings (file contents same). Should not warn.
    input_api = self.makeInputApi([
      MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS1,
                       self.NEW_GRD_CONTENTS1, action='M'),
      MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS1,
                       self.NEW_GRDP_CONTENTS1, action='M')])
    warnings = PRESUBMIT.CheckStrings(input_api,
                                                      MockOutputApi())
    self.assertEqual(0, len(warnings))

    # Add two new strings. Should have two warnings.
    input_api = self.makeInputApi([
      MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS2,
                       self.NEW_GRD_CONTENTS1, action='M'),
      MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS2,
                       self.NEW_GRDP_CONTENTS1, action='M')])
    warnings = PRESUBMIT.CheckStrings(input_api,
                                                      MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[0].message)
    self.assertEqual('error', warnings[0].type)
    self.assertEqual([
      os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'),
      os.path.join('test_grd', 'IDS_TEST2.png.sha1')],
                     warnings[0].items)

    # Add four new strings. Should have four warnings.
    input_api = self.makeInputApi([
      MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS2,
                       self.OLD_GRD_CONTENTS, action='M'),
      MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS2,
                       self.OLD_GRDP_CONTENTS, action='M')])
    warnings = PRESUBMIT.CheckStrings(input_api,
                                                      MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertEqual('error', warnings[0].type)
    self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[0].message)
    self.assertEqual([
        os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'),
        os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'),
        os.path.join('test_grd', 'IDS_TEST1.png.sha1'),
        os.path.join('test_grd', 'IDS_TEST2.png.sha1'),
    ], warnings[0].items)

  def testModifiedMessageDescription(self):
    # CL modified a message description for a message that does not yet have a
    # screenshot. Should not warn.
    input_api = self.makeInputApi([
      MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS3,
                       self.NEW_GRDP_CONTENTS4, action='M')])
    warnings = PRESUBMIT.CheckStrings(input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))

    # CL modified a message description for a message that already has a
    # screenshot. Should not warn.
    input_api = self.makeInputApi([
      MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS3,
                       self.NEW_GRDP_CONTENTS4, action='M'),
      MockFile(os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'),
               'binary', action='A')])
    warnings = PRESUBMIT.CheckStrings(input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))

  def testModifiedMessageMeaning(self):
    # CL modified a message meaning for a message that does not yet have a
    # screenshot. Should warn.
    input_api = self.makeInputApi([
      MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS5,
                       self.NEW_GRDP_CONTENTS6, action='M')])
    warnings = PRESUBMIT.CheckStrings(input_api, MockOutputApi())
    self.assertEqual(1, len(warnings))

    # CL modified a message meaning for a message that already has a
    # screenshot. Should not warn.
    input_api = self.makeInputApi([
      MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS5,
                       self.NEW_GRDP_CONTENTS6, action='M'),
      MockFile(os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'),
               'binary', action='A')])
    warnings = PRESUBMIT.CheckStrings(input_api, MockOutputApi())
    self.assertEqual(0, len(warnings))

  def testPngAddedSha1NotAdded(self):
    # CL added one new message in a grd file and added the png file associated
    # with it, but did not add the corresponding sha1 file. This should warn
    # twice:
    # - Once for the added png file (because we don't want developers to upload
    #   actual images)
    # - Once for the missing .sha1 file
    input_api = self.makeInputApi([
        MockAffectedFile(
            'test.grd',
            self.NEW_GRD_CONTENTS1,
            self.OLD_GRD_CONTENTS,
            action='M'),
        MockAffectedFile(
            os.path.join('test_grd', 'IDS_TEST1.png'), 'binary', action='A')
    ])
    warnings = PRESUBMIT.CheckStrings(input_api,
                                                      MockOutputApi())
    self.assertEqual(2, len(warnings))
    self.assertEqual('error', warnings[0].type)
    self.assertEqual(self.DO_NOT_UPLOAD_PNG_MESSAGE, warnings[0].message)
    self.assertEqual([os.path.join('test_grd', 'IDS_TEST1.png')],
                     warnings[0].items)
    self.assertEqual('error', warnings[1].type)
    self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[1].message)
    self.assertEqual([os.path.join('test_grd', 'IDS_TEST1.png.sha1')],
                     warnings[1].items)

    # CL added two messages (one in grd, one in grdp) and added the png files
    # associated with the messages, but did not add the corresponding sha1
    # files. This should warn twice:
    # - Once for the added png files (because we don't want developers to upload
    #   actual images)
    # - Once for the missing .sha1 files
    input_api = self.makeInputApi([
        # Modified files:
        MockAffectedFile(
            'test.grd',
            self.NEW_GRD_CONTENTS1,
            self.OLD_GRD_CONTENTS,
            action='M'),
        MockAffectedFile(
            'part.grdp',
            self.NEW_GRDP_CONTENTS1,
            self.OLD_GRDP_CONTENTS,
            action='M'),
        # Added files:
        MockAffectedFile(
            os.path.join('test_grd', 'IDS_TEST1.png'), 'binary', action='A'),
        MockAffectedFile(
            os.path.join('part_grdp', 'IDS_PART_TEST1.png'), 'binary',
            action='A')
    ])
    warnings = PRESUBMIT.CheckStrings(input_api,
                                                      MockOutputApi())
    self.assertEqual(2, len(warnings))
    self.assertEqual('error', warnings[0].type)
    self.assertEqual(self.DO_NOT_UPLOAD_PNG_MESSAGE, warnings[0].message)
    self.assertEqual([os.path.join('part_grdp', 'IDS_PART_TEST1.png'),
                      os.path.join('test_grd', 'IDS_TEST1.png')],
                     warnings[0].items)
    self.assertEqual('error', warnings[0].type)
    self.assertEqual(self.GENERATE_SIGNATURES_MESSAGE, warnings[1].message)
    self.assertEqual([os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'),
                      os.path.join('test_grd', 'IDS_TEST1.png.sha1')],
                      warnings[1].items)

  def testScreenshotsWithSha1(self):
    # CL added four messages (two each in a grd and grdp) and their
    # corresponding .sha1 files. No warnings.
    input_api = self.makeInputApi([
        # Modified files:
        MockAffectedFile(
            'test.grd',
            self.NEW_GRD_CONTENTS2,
            self.OLD_GRD_CONTENTS,
            action='M'),
        MockAffectedFile(
            'part.grdp',
            self.NEW_GRDP_CONTENTS2,
            self.OLD_GRDP_CONTENTS,
            action='M'),
        # Added files:
        MockFile(
            os.path.join('test_grd', 'IDS_TEST1.png.sha1'),
            'binary',
            action='A'),
        MockFile(
            os.path.join('test_grd', 'IDS_TEST2.png.sha1'),
            'binary',
            action='A'),
        MockFile(
            os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'),
            'binary',
            action='A'),
        MockFile(
            os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'),
            'binary',
            action='A'),
    ])
    warnings = PRESUBMIT.CheckStrings(input_api,
                                                      MockOutputApi())
    self.assertEqual([], warnings)

  def testScreenshotsRemovedWithSha1(self):
    # Replace new contents with old contents in grd and grp files, removing
    # IDS_TEST1, IDS_TEST2, IDS_PART_TEST1 and IDS_PART_TEST2.
    # Should warn to remove the sha1 files associated with these strings.
    input_api = self.makeInputApi([
        # Modified files:
        MockAffectedFile(
            'test.grd',
            self.OLD_GRD_CONTENTS, # new_contents
            self.NEW_GRD_CONTENTS2, # old_contents
            action='M'),
        MockAffectedFile(
            'part.grdp',
            self.OLD_GRDP_CONTENTS, # new_contents
            self.NEW_GRDP_CONTENTS2, # old_contents
            action='M'),
        # Unmodified files:
        MockFile(os.path.join('test_grd', 'IDS_TEST1.png.sha1'), 'binary', ''),
        MockFile(os.path.join('test_grd', 'IDS_TEST2.png.sha1'), 'binary', ''),
        MockFile(os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'),
                 'binary', ''),
        MockFile(os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'),
                 'binary', '')
    ])
    warnings = PRESUBMIT.CheckStrings(input_api,
                                                      MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertEqual('error', warnings[0].type)
    self.assertEqual(self.REMOVE_SIGNATURES_MESSAGE, warnings[0].message)
    self.assertEqual([
        os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'),
        os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'),
        os.path.join('test_grd', 'IDS_TEST1.png.sha1'),
        os.path.join('test_grd', 'IDS_TEST2.png.sha1')
    ], warnings[0].items)

    # Same as above, but this time one of the .sha1 files is also removed.
    input_api = self.makeInputApi([
        # Modified files:
        MockAffectedFile(
            'test.grd',
            self.OLD_GRD_CONTENTS, # new_contents
            self.NEW_GRD_CONTENTS2, # old_contents
            action='M'),
        MockAffectedFile(
            'part.grdp',
            self.OLD_GRDP_CONTENTS, # new_contents
            self.NEW_GRDP_CONTENTS2, # old_contents
            action='M'),
        # Unmodified files:
        MockFile(os.path.join('test_grd', 'IDS_TEST1.png.sha1'), 'binary', ''),
        MockFile(os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'),
                 'binary', ''),
        # Deleted files:
        MockAffectedFile(
            os.path.join('test_grd', 'IDS_TEST2.png.sha1'),
            '',
            'old_contents',
            action='D'),
        MockAffectedFile(
            os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'),
            '',
            'old_contents',
            action='D')
    ])
    warnings = PRESUBMIT.CheckStrings(input_api,
                                                      MockOutputApi())
    self.assertEqual(1, len(warnings))
    self.assertEqual('error', warnings[0].type)
    self.assertEqual(self.REMOVE_SIGNATURES_MESSAGE, warnings[0].message)
    self.assertEqual([os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'),
                      os.path.join('test_grd', 'IDS_TEST1.png.sha1')
                     ], warnings[0].items)

    # Remove all sha1 files. There should be no warnings.
    input_api = self.makeInputApi([
        # Modified files:
        MockAffectedFile(
            'test.grd',
            self.OLD_GRD_CONTENTS,
            self.NEW_GRD_CONTENTS2,
            action='M'),
        MockAffectedFile(
            'part.grdp',
            self.OLD_GRDP_CONTENTS,
            self.NEW_GRDP_CONTENTS2,
            action='M'),
        # Deleted files:
        MockFile(
            os.path.join('test_grd', 'IDS_TEST1.png.sha1'),
            'binary',
            action='D'),
        MockFile(
            os.path.join('test_grd', 'IDS_TEST2.png.sha1'),
            'binary',
            action='D'),
        MockFile(
            os.path.join('part_grdp', 'IDS_PART_TEST1.png.sha1'),
            'binary',
            action='D'),
        MockFile(
            os.path.join('part_grdp', 'IDS_PART_TEST2.png.sha1'),
            'binary',
            action='D')
    ])
    warnings = PRESUBMIT.CheckStrings(input_api,
                                                      MockOutputApi())
    self.assertEqual([], warnings)

  def testIcuSyntax(self):
    # Add valid ICU syntax string. Should not raise an error.
    input_api = self.makeInputApi([
      MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS_ICU_SYNTAX_OK2,
                       self.NEW_GRD_CONTENTS1, action='M'),
      MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS_ICU_SYNTAX_OK2,
                       self.NEW_GRDP_CONTENTS1, action='M')])
    results = PRESUBMIT.CheckStrings(input_api, MockOutputApi())
    # We expect no ICU syntax errors.
    icu_errors = [e for e in results
        if e.message == self.ICU_SYNTAX_ERROR_MESSAGE]
    self.assertEqual(0, len(icu_errors))

    # Valid changes in ICU syntax. Should not raise an error.
    input_api = self.makeInputApi([
      MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS_ICU_SYNTAX_OK2,
                       self.NEW_GRD_CONTENTS_ICU_SYNTAX_OK1, action='M'),
      MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS_ICU_SYNTAX_OK2,
                       self.NEW_GRDP_CONTENTS_ICU_SYNTAX_OK1, action='M')])
    results = PRESUBMIT.CheckStrings(input_api, MockOutputApi())
    # We expect no ICU syntax errors.
    icu_errors = [e for e in results
        if e.message == self.ICU_SYNTAX_ERROR_MESSAGE]
    self.assertEqual(0, len(icu_errors))

    # Add invalid ICU syntax strings. Should raise two errors.
    input_api = self.makeInputApi([
      MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS_ICU_SYNTAX_ERROR,
                       self.NEW_GRD_CONTENTS1, action='M'),
      MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS_ICU_SYNTAX_ERROR,
                       self.NEW_GRD_CONTENTS1, action='M')])
    results = PRESUBMIT.CheckStrings(input_api, MockOutputApi())
    # We expect 2 ICU syntax errors.
    icu_errors = [e for e in results
        if e.message == self.ICU_SYNTAX_ERROR_MESSAGE]
    self.assertEqual(1, len(icu_errors))
    self.assertEqual([
        'IDS_TEST1: This message looks like an ICU plural, but does not follow '
        'ICU syntax.',
        'IDS_PART_TEST1: Variant "= 1" is not valid for plural message'
      ], icu_errors[0].items)

    # Change two strings to have ICU syntax errors. Should raise two errors.
    input_api = self.makeInputApi([
      MockAffectedFile('test.grd', self.NEW_GRD_CONTENTS_ICU_SYNTAX_ERROR,
                       self.NEW_GRD_CONTENTS_ICU_SYNTAX_OK1, action='M'),
      MockAffectedFile('part.grdp', self.NEW_GRDP_CONTENTS_ICU_SYNTAX_ERROR,
                       self.NEW_GRDP_CONTENTS_ICU_SYNTAX_OK1, action='M')])
    results = PRESUBMIT.CheckStrings(input_api, MockOutputApi())
    # We expect 2 ICU syntax errors.
    icu_errors = [e for e in results
        if e.message == self.ICU_SYNTAX_ERROR_MESSAGE]
    self.assertEqual(1, len(icu_errors))
    self.assertEqual([
        'IDS_TEST1: This message looks like an ICU plural, but does not follow '
        'ICU syntax.',
        'IDS_PART_TEST1: Variant "= 1" is not valid for plural message'
      ], icu_errors[0].items)


class TranslationExpectationsTest(unittest.TestCase):
  ERROR_MESSAGE_FORMAT = (
    "Failed to get a list of translatable grd files. "
    "This happens when:\n"
    " - One of the modified grd or grdp files cannot be parsed or\n"
    " - %s is not updated.\n"
    "Stack:\n"
  )
  REPO_ROOT = os.path.join('tools', 'translation', 'testdata')
  # This lists all .grd files under REPO_ROOT.
  EXPECTATIONS = os.path.join(REPO_ROOT,
                              "translation_expectations.pyl")
  # This lists all .grd files under REPO_ROOT except unlisted.grd.
  EXPECTATIONS_WITHOUT_UNLISTED_FILE = os.path.join(
      REPO_ROOT, "translation_expectations_without_unlisted_file.pyl")

  # Tests that the presubmit doesn't return when no grd or grdp files are
  # modified.
  def testExpectationsNoModifiedGrd(self):
    input_api = MockInputApi()
    input_api.files = [
        MockAffectedFile('not_used.txt', 'not used', 'not used', action='M')
    ]
    # Fake list of all grd files in the repo. This list is missing all grd/grdps
    # under tools/translation/testdata. This is OK because the presubmit won't
    # run in the first place since there are no modified grd/grps in input_api.
    grd_files = ['doesnt_exist_doesnt_matter.grd']
    warnings = PRESUBMIT.CheckTranslationExpectations(
        input_api, MockOutputApi(), self.REPO_ROOT, self.EXPECTATIONS,
        grd_files)
    self.assertEqual(0, len(warnings))


  # Tests that the list of files passed to the presubmit matches the list of
  # files in the expectations.
  def testExpectationsSuccess(self):
    # Mock input file list needs a grd or grdp file in order to run the
    # presubmit. The file itself doesn't matter.
    input_api = MockInputApi()
    input_api.files = [
        MockAffectedFile('dummy.grd', 'not used', 'not used', action='M')
    ]
    # List of all grd files in the repo.
    grd_files = ['test.grd', 'unlisted.grd', 'not_translated.grd',
                 'internal.grd']
    warnings = PRESUBMIT.CheckTranslationExpectations(
        input_api, MockOutputApi(), self.REPO_ROOT, self.EXPECTATIONS,
        grd_files)
    self.assertEqual(0, len(warnings))

  # Tests that the presubmit warns when a file is listed in expectations, but
  # does not actually exist.
  def testExpectationsMissingFile(self):
    # Mock input file list needs a grd or grdp file in order to run the
    # presubmit.
    input_api = MockInputApi()
    input_api.files = [
      MockAffectedFile('dummy.grd', 'not used', 'not used', action='M')
    ]
    # unlisted.grd is listed under tools/translation/testdata but is not
    # included in translation expectations.
    grd_files = ['unlisted.grd', 'not_translated.grd', 'internal.grd']
    warnings = PRESUBMIT.CheckTranslationExpectations(
        input_api, MockOutputApi(), self.REPO_ROOT, self.EXPECTATIONS,
        grd_files)
    self.assertEqual(1, len(warnings))
    self.assertTrue(warnings[0].message.startswith(
        self.ERROR_MESSAGE_FORMAT % self.EXPECTATIONS))
    self.assertTrue(
        ("test.grd is listed in the translation expectations, "
         "but this grd file does not exist")
        in warnings[0].message)

  # Tests that the presubmit warns when a file is not listed in expectations but
  # does actually exist.
  def testExpectationsUnlistedFile(self):
    # Mock input file list needs a grd or grdp file in order to run the
    # presubmit.
    input_api = MockInputApi()
    input_api.files = [
      MockAffectedFile('dummy.grd', 'not used', 'not used', action='M')
    ]
    # unlisted.grd is listed under tools/translation/testdata but is not
    # included in translation expectations.
    grd_files = ['test.grd', 'unlisted.grd', 'not_translated.grd',
                 'internal.grd']
    warnings = PRESUBMIT.CheckTranslationExpectations(
        input_api, MockOutputApi(), self.REPO_ROOT,
        self.EXPECTATIONS_WITHOUT_UNLISTED_FILE, grd_files)
    self.assertEqual(1, len(warnings))
    self.assertTrue(warnings[0].message.startswith(
        self.ERROR_MESSAGE_FORMAT % self.EXPECTATIONS_WITHOUT_UNLISTED_FILE))
    self.assertTrue(
        ("unlisted.grd appears to be translatable "
         "(because it contains <file> or <message> elements), "
         "but is not listed in the translation expectations.")
        in warnings[0].message)

  # Tests that the presubmit warns twice:
  # - for a non-existing file listed in expectations
  # - for an existing file not listed in expectations
  def testMultipleWarnings(self):
    # Mock input file list needs a grd or grdp file in order to run the
    # presubmit.
    input_api = MockInputApi()
    input_api.files = [
      MockAffectedFile('dummy.grd', 'not used', 'not used', action='M')
    ]
    # unlisted.grd is listed under tools/translation/testdata but is not
    # included in translation expectations.
    # test.grd is not listed under tools/translation/testdata but is included
    # in translation expectations.
    grd_files = ['unlisted.grd', 'not_translated.grd', 'internal.grd']
    warnings = PRESUBMIT.CheckTranslationExpectations(
        input_api, MockOutputApi(), self.REPO_ROOT,
        self.EXPECTATIONS_WITHOUT_UNLISTED_FILE, grd_files)
    self.assertEqual(1, len(warnings))
    self.assertTrue(warnings[0].message.startswith(
        self.ERROR_MESSAGE_FORMAT % self.EXPECTATIONS_WITHOUT_UNLISTED_FILE))
    self.assertTrue(
        ("unlisted.grd appears to be translatable "
         "(because it contains <file> or <message> elements), "
         "but is not listed in the translation expectations.")
        in warnings[0].message)
    self.assertTrue(
        ("test.grd is listed in the translation expectations, "
         "but this grd file does not exist")
        in warnings[0].message)


class DISABLETypoInTest(unittest.TestCase):

  def testPositive(self):
    # Verify the typo "DISABLE_" instead of "DISABLED_" in various contexts
    # where the desire is to disable a test.
    tests = [
        # Disabled on one platform:
        '#if defined(OS_WIN)\n'
        '#define MAYBE_FoobarTest DISABLE_FoobarTest\n'
        '#else\n'
        '#define MAYBE_FoobarTest FoobarTest\n'
        '#endif\n',
        # Disabled on one platform spread cross lines:
        '#if defined(OS_WIN)\n'
        '#define MAYBE_FoobarTest \\\n'
        '    DISABLE_FoobarTest\n'
        '#else\n'
        '#define MAYBE_FoobarTest FoobarTest\n'
        '#endif\n',
        # Disabled on all platforms:
        '  TEST_F(FoobarTest, DISABLE_Foo)\n{\n}',
        # Disabled on all platforms but multiple lines
        '  TEST_F(FoobarTest,\n   DISABLE_foo){\n}\n',
    ]

    for test in tests:
      mock_input_api = MockInputApi()
      mock_input_api.files = [
          MockFile('some/path/foo_unittest.cc', test.splitlines()),
      ]

      results = PRESUBMIT.CheckNoDISABLETypoInTests(mock_input_api,
                                                     MockOutputApi())
      self.assertEqual(
          1,
          len(results),
          msg=('expected len(results) == 1 but got %d in test: %s' %
               (len(results), test)))
      self.assertTrue(
          'foo_unittest.cc' in results[0].message,
          msg=('expected foo_unittest.cc in message but got %s in test %s' %
               (results[0].message, test)))

  def testIngoreNotTestFiles(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockFile('some/path/foo.cc', 'TEST_F(FoobarTest, DISABLE_Foo)'),
    ]

    results = PRESUBMIT.CheckNoDISABLETypoInTests(mock_input_api,
                                                   MockOutputApi())
    self.assertEqual(0, len(results))

  def testIngoreDeletedFiles(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockFile('some/path/foo.cc', 'TEST_F(FoobarTest, Foo)', action='D'),
    ]

    results = PRESUBMIT.CheckNoDISABLETypoInTests(mock_input_api,
                                                   MockOutputApi())
    self.assertEqual(0, len(results))

class ForgettingMAYBEInTests(unittest.TestCase):
  def testPositive(self):
    test = (
        '#if defined(HAS_ENERGY)\n'
        '#define MAYBE_CastExplosion DISABLED_CastExplosion\n'
        '#else\n'
        '#define MAYBE_CastExplosion CastExplosion\n'
        '#endif\n'
        'TEST_F(ArchWizard, CastExplosion) {\n'
        '#if defined(ARCH_PRIEST_IN_PARTY)\n'
        '#define MAYBE_ArchPriest ArchPriest\n'
        '#else\n'
        '#define MAYBE_ArchPriest DISABLED_ArchPriest\n'
        '#endif\n'
        'TEST_F(ArchPriest, CastNaturesBounty) {\n'
        '#if !defined(CRUSADER_IN_PARTY)\n'
        '#define MAYBE_Crusader \\\n'
        '    DISABLED_Crusader \n'
        '#else\n'
        '#define MAYBE_Crusader \\\n'
        '    Crusader\n'
        '#endif\n'
        '  TEST_F(\n'
        '    Crusader,\n'
        '    CastTaunt) { }\n'
        '#if defined(LEARNED_BASIC_SKILLS)\n'
        '#define MAYBE_CastSteal \\\n'
        '    DISABLED_CastSteal \n'
        '#else\n'
        '#define MAYBE_CastSteal \\\n'
        '    CastSteal\n'
        '#endif\n'
        '  TEST_F(\n'
        '    ThiefClass,\n'
        '    CastSteal) { }\n'
    )
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockFile('fantasyworld/classes_unittest.cc', test.splitlines()),
    ]
    results = PRESUBMIT.CheckForgettingMAYBEInTests(mock_input_api,
                                                    MockOutputApi())
    self.assertEqual(4, len(results))
    self.assertTrue('CastExplosion' in results[0].message)
    self.assertTrue('fantasyworld/classes_unittest.cc:2' in results[0].message)
    self.assertTrue('ArchPriest' in results[1].message)
    self.assertTrue('fantasyworld/classes_unittest.cc:8' in results[1].message)
    self.assertTrue('Crusader' in results[2].message)
    self.assertTrue('fantasyworld/classes_unittest.cc:14' in results[2].message)
    self.assertTrue('CastSteal' in results[3].message)
    self.assertTrue('fantasyworld/classes_unittest.cc:24' in results[3].message)

  def testNegative(self):
    test = (
        '#if defined(HAS_ENERGY)\n'
        '#define MAYBE_CastExplosion DISABLED_CastExplosion\n'
        '#else\n'
        '#define MAYBE_CastExplosion CastExplosion\n'
        '#endif\n'
        'TEST_F(ArchWizard, MAYBE_CastExplosion) {\n'
        '#if defined(ARCH_PRIEST_IN_PARTY)\n'
        '#define MAYBE_ArchPriest ArchPriest\n'
        '#else\n'
        '#define MAYBE_ArchPriest DISABLED_ArchPriest\n'
        '#endif\n'
        'TEST_F(MAYBE_ArchPriest, CastNaturesBounty) {\n'
        '#if !defined(CRUSADER_IN_PARTY)\n'
        '#define MAYBE_Crusader \\\n'
        '    DISABLED_Crusader \n'
        '#else\n'
        '#define MAYBE_Crusader \\\n'
        '    Crusader\n'
        '#endif\n'
        '  TEST_F(\n'
        '    MAYBE_Crusader,\n'
        '    CastTaunt) { }\n'
        '#if defined(LEARNED_BASIC_SKILLS)\n'
        '#define MAYBE_CastSteal \\\n'
        '    DISABLED_CastSteal \n'
        '#else\n'
        '#define MAYBE_CastSteal \\\n'
        '    CastSteal\n'
        '#endif\n'
        '  TEST_F(\n'
        '    ThiefClass,\n'
        '    MAYBE_CastSteal) { }\n'
    )

    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockFile('fantasyworld/classes_unittest.cc', test.splitlines()),
    ]
    results = PRESUBMIT.CheckForgettingMAYBEInTests(mock_input_api,
                                                    MockOutputApi())
    self.assertEqual(0, len(results))

class CheckFuzzTargetsTest(unittest.TestCase):

  def _check(self, files):
    mock_input_api = MockInputApi()
    mock_input_api.files = []
    for fname, contents in files.items():
      mock_input_api.files.append(MockFile(fname, contents.splitlines()))
    return PRESUBMIT.CheckFuzzTargetsOnUpload(mock_input_api, MockOutputApi())

  def testLibFuzzerSourcesIgnored(self):
    results = self._check({
        "third_party/lib/Fuzzer/FuzzerDriver.cpp": "LLVMFuzzerInitialize",
    })
    self.assertEqual(results, [])

  def testNonCodeFilesIgnored(self):
    results = self._check({
        "README.md": "LLVMFuzzerInitialize",
    })
    self.assertEqual(results, [])

  def testNoErrorHeaderPresent(self):
    results = self._check({
        "fuzzer.cc": (
            "#include \"testing/libfuzzer/libfuzzer_exports.h\"\n" +
            "LLVMFuzzerInitialize"
        )
    })
    self.assertEqual(results, [])

  def testErrorMissingHeader(self):
    results = self._check({
        "fuzzer.cc": "LLVMFuzzerInitialize"
    })
    self.assertEqual(len(results), 1)
    self.assertEqual(results[0].items, ['fuzzer.cc'])


class SetNoParentTest(unittest.TestCase):
  def testSetNoParentTopLevelAllowed(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('goat/OWNERS',
                       [
                         'set noparent',
                         'jochen@chromium.org',
                       ])
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckSetNoParent(mock_input_api, mock_output_api)
    self.assertEqual([], errors)

  def testSetNoParentMissing(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('services/goat/OWNERS',
                       [
                         'set noparent',
                         'jochen@chromium.org',
                         'per-file *.json=set noparent',
                         'per-file *.json=jochen@chromium.org',
                       ])
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckSetNoParent(mock_input_api, mock_output_api)
    self.assertEqual(1, len(errors))
    self.assertTrue('goat/OWNERS:1' in errors[0].long_text)
    self.assertTrue('goat/OWNERS:3' in errors[0].long_text)

  def testSetNoParentWithCorrectRule(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockAffectedFile('services/goat/OWNERS',
                       [
                         'set noparent',
                         'file://ipc/SECURITY_OWNERS',
                         'per-file *.json=set noparent',
                         'per-file *.json=file://ipc/SECURITY_OWNERS',
                       ])
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckSetNoParent(mock_input_api, mock_output_api)
    self.assertEqual([], errors)


class MojomStabilityCheckTest(unittest.TestCase):
  def runTestWithAffectedFiles(self, affected_files):
    mock_input_api = MockInputApi()
    mock_input_api.files = affected_files
    mock_output_api = MockOutputApi()
    return PRESUBMIT.CheckStableMojomChanges(
        mock_input_api, mock_output_api)

  def testSafeChangePasses(self):
    errors = self.runTestWithAffectedFiles([
      MockAffectedFile('foo/foo.mojom',
                       ['[Stable] struct S { [MinVersion=1] int32 x; };'],
                       old_contents=['[Stable] struct S {};'])
    ])
    self.assertEqual([], errors)

  def testBadChangeFails(self):
    errors = self.runTestWithAffectedFiles([
      MockAffectedFile('foo/foo.mojom',
                       ['[Stable] struct S { int32 x; };'],
                       old_contents=['[Stable] struct S {};'])
    ])
    self.assertEqual(1, len(errors))
    self.assertTrue('not backward-compatible' in errors[0].message)

  def testDeletedFile(self):
    """Regression test for https://crbug.com/1091407."""
    errors = self.runTestWithAffectedFiles([
      MockAffectedFile('a.mojom', [], old_contents=['struct S {};'],
                       action='D'),
      MockAffectedFile('b.mojom',
                       ['struct S {}; struct T { S s; };'],
                       old_contents=['import "a.mojom"; struct T { S s; };'])
    ])
    self.assertEqual([], errors)

class CheckForUseOfChromeAppsDeprecationsTest(unittest.TestCase):

  ERROR_MSG_PIECE = 'technologies which will soon be deprecated'

  # Each positive test is also a naive negative test for the other cases.

  def testWarningNMF(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockAffectedFile(
            'foo.NMF',
            ['"program"', '"Z":"content"', 'B'],
            ['"program"', 'B'],
            scm_diff='\n'.join([
                '--- foo.NMF.old  2020-12-02 20:40:54.430676385 +0100',
                '+++ foo.NMF.new  2020-12-02 20:41:02.086700197 +0100',
                '@@ -1,2 +1,3 @@',
                ' "program"',
                '+"Z":"content"',
                ' B']),
            action='M')
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckForUseOfChromeAppsDeprecations(mock_input_api,
                                                     mock_output_api)
    self.assertEqual(1, len(errors))
    self.assertTrue( self.ERROR_MSG_PIECE in errors[0].message)
    self.assertTrue( 'foo.NMF' in errors[0].message)

  def testWarningManifest(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockAffectedFile(
            'manifest.json',
            ['"app":', '"Z":"content"', 'B'],
            ['"app":"', 'B'],
            scm_diff='\n'.join([
                '--- manifest.json.old  2020-12-02 20:40:54.430676385 +0100',
                '+++ manifest.json.new  2020-12-02 20:41:02.086700197 +0100',
                '@@ -1,2 +1,3 @@',
                ' "app"',
                '+"Z":"content"',
                ' B']),
            action='M')
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckForUseOfChromeAppsDeprecations(mock_input_api,
                                                     mock_output_api)
    self.assertEqual(1, len(errors))
    self.assertTrue( self.ERROR_MSG_PIECE in errors[0].message)
    self.assertTrue( 'manifest.json' in errors[0].message)

  def testOKWarningManifestWithoutApp(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockAffectedFile(
            'manifest.json',
            ['"name":', '"Z":"content"', 'B'],
            ['"name":"', 'B'],
            scm_diff='\n'.join([
                '--- manifest.json.old  2020-12-02 20:40:54.430676385 +0100',
                '+++ manifest.json.new  2020-12-02 20:41:02.086700197 +0100',
                '@@ -1,2 +1,3 @@',
                ' "app"',
                '+"Z":"content"',
                ' B']),
            action='M')
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckForUseOfChromeAppsDeprecations(mock_input_api,
                                                     mock_output_api)
    self.assertEqual(0, len(errors))

  def testWarningPPAPI(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockAffectedFile(
            'foo.hpp',
            ['A', '#include <ppapi.h>', 'B'],
            ['A', 'B'],
            scm_diff='\n'.join([
                '--- foo.hpp.old  2020-12-02 20:40:54.430676385 +0100',
                '+++ foo.hpp.new  2020-12-02 20:41:02.086700197 +0100',
                '@@ -1,2 +1,3 @@',
                ' A',
                '+#include <ppapi.h>',
                ' B']),
            action='M')
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckForUseOfChromeAppsDeprecations(mock_input_api,
                                                     mock_output_api)
    self.assertEqual(1, len(errors))
    self.assertTrue( self.ERROR_MSG_PIECE in errors[0].message)
    self.assertTrue( 'foo.hpp' in errors[0].message)

  def testNoWarningPPAPI(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockAffectedFile(
            'foo.txt',
            ['A', 'Peppapig', 'B'],
            ['A', 'B'],
            scm_diff='\n'.join([
                '--- foo.txt.old  2020-12-02 20:40:54.430676385 +0100',
                '+++ foo.txt.new  2020-12-02 20:41:02.086700197 +0100',
                '@@ -1,2 +1,3 @@',
                ' A',
                '+Peppapig',
                ' B']),
            action='M')
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckForUseOfChromeAppsDeprecations(mock_input_api,
                                                     mock_output_api)
    self.assertEqual(0, len(errors))

class CheckDeprecationOfPreferencesTest(unittest.TestCase):
  # Test that a warning is generated if a preference registration is removed
  # from a random file.
  def testWarning(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockAffectedFile(
            'foo.cc',
            ['A', 'B'],
            ['A', 'prefs->RegisterStringPref("foo", "default");', 'B'],
            scm_diff='\n'.join([
                '--- foo.cc.old  2020-12-02 20:40:54.430676385 +0100',
                '+++ foo.cc.new  2020-12-02 20:41:02.086700197 +0100',
                '@@ -1,3 +1,2 @@',
                ' A',
                '-prefs->RegisterStringPref("foo", "default");',
                ' B']),
            action='M')
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckDeprecationOfPreferences(mock_input_api,
                                                     mock_output_api)
    self.assertEqual(1, len(errors))
    self.assertTrue(
        'Discovered possible removal of preference registrations' in
        errors[0].message)

  # Test that a warning is inhibited if the preference registration was moved
  # to the deprecation functions in browser prefs.
  def testNoWarningForMigration(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        # RegisterStringPref was removed from foo.cc.
        MockAffectedFile(
            'foo.cc',
            ['A', 'B'],
            ['A', 'prefs->RegisterStringPref("foo", "default");', 'B'],
            scm_diff='\n'.join([
                '--- foo.cc.old  2020-12-02 20:40:54.430676385 +0100',
                '+++ foo.cc.new  2020-12-02 20:41:02.086700197 +0100',
                '@@ -1,3 +1,2 @@',
                ' A',
                '-prefs->RegisterStringPref("foo", "default");',
                ' B']),
            action='M'),
        # But the preference was properly migrated.
        MockAffectedFile(
            'chrome/browser/prefs/browser_prefs.cc',
            [
                 '// BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS',
                 '// END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS',
                 '// BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS',
                 'prefs->RegisterStringPref("foo", "default");',
                 '// END_MIGRATE_OBSOLETE_PROFILE_PREFS',
            ],
            [
                 '// BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS',
                 '// END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS',
                 '// BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS',
                 '// END_MIGRATE_OBSOLETE_PROFILE_PREFS',
            ],
            scm_diff='\n'.join([
                 '--- browser_prefs.cc.old 2020-12-02 20:51:40.812686731 +0100',
                 '+++ browser_prefs.cc.new 2020-12-02 20:52:02.936755539 +0100',
                 '@@ -2,3 +2,4 @@',
                 ' // END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS',
                 ' // BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS',
                 '+prefs->RegisterStringPref("foo", "default");',
                 ' // END_MIGRATE_OBSOLETE_PROFILE_PREFS']),
            action='M'),
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckDeprecationOfPreferences(mock_input_api,
                                                     mock_output_api)
    self.assertEqual(0, len(errors))

  # Test that a warning is NOT inhibited if the preference registration was
  # moved to a place outside of the migration functions in browser_prefs.cc
  def testWarningForImproperMigration(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        # RegisterStringPref was removed from foo.cc.
        MockAffectedFile(
            'foo.cc',
            ['A', 'B'],
            ['A', 'prefs->RegisterStringPref("foo", "default");', 'B'],
            scm_diff='\n'.join([
                '--- foo.cc.old  2020-12-02 20:40:54.430676385 +0100',
                '+++ foo.cc.new  2020-12-02 20:41:02.086700197 +0100',
                '@@ -1,3 +1,2 @@',
                ' A',
                '-prefs->RegisterStringPref("foo", "default");',
                ' B']),
            action='M'),
        # The registration call was moved to a place in browser_prefs.cc that
        # is outside the migration functions.
        MockAffectedFile(
            'chrome/browser/prefs/browser_prefs.cc',
            [
                 'prefs->RegisterStringPref("foo", "default");',
                 '// BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS',
                 '// END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS',
                 '// BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS',
                 '// END_MIGRATE_OBSOLETE_PROFILE_PREFS',
            ],
            [
                 '// BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS',
                 '// END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS',
                 '// BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS',
                 '// END_MIGRATE_OBSOLETE_PROFILE_PREFS',
            ],
            scm_diff='\n'.join([
                 '--- browser_prefs.cc.old 2020-12-02 20:51:40.812686731 +0100',
                 '+++ browser_prefs.cc.new 2020-12-02 20:52:02.936755539 +0100',
                 '@@ -1,2 +1,3 @@',
                 '+prefs->RegisterStringPref("foo", "default");',
                 ' // BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS',
                 ' // END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS']),
            action='M'),
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckDeprecationOfPreferences(mock_input_api,
                                                     mock_output_api)
    self.assertEqual(1, len(errors))
    self.assertTrue(
        'Discovered possible removal of preference registrations' in
        errors[0].message)

  # Check that the presubmit fails if a marker line in brower_prefs.cc is
  # deleted.
  def testDeletedMarkerRaisesError(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockAffectedFile('chrome/browser/prefs/browser_prefs.cc',
                         [
                           '// BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS',
                           '// END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS',
                           '// BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS',
                           # The following line is deleted for this test
                           # '// END_MIGRATE_OBSOLETE_PROFILE_PREFS',
                         ])
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckDeprecationOfPreferences(mock_input_api,
                                                     mock_output_api)
    self.assertEqual(1, len(errors))
    self.assertEqual(
        'Broken .*MIGRATE_OBSOLETE_.*_PREFS markers in browser_prefs.cc.',
        errors[0].message)

class MPArchApiUsage(unittest.TestCase):
  def _assert_notify(
      self, expected_uses, msg, local_path, new_contents):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()
    mock_input_api.files = [
        MockFile(local_path, new_contents),
    ]
    result = PRESUBMIT.CheckMPArchApiUsage(mock_input_api, mock_output_api)
    self.assertEqual(
        bool(expected_uses),
        'mparch-reviews+watch@chromium.org' in mock_output_api.more_cc,
        msg)
    if expected_uses:
        self.assertEqual(1, len(result), msg)
        self.assertEqual(result[0].type, 'notify', msg)
        self.assertEqual(sorted(result[0].items), sorted(expected_uses), msg)

  def testNotify(self):
    self._assert_notify(
        ['WebContentsObserver', 'WebContentsUserData'],
        'Introduce WCO and WCUD',
        'chrome/my_feature.h',
        ['class MyFeature',
         '    : public content::WebContentsObserver,',
         '      public content::WebContentsUserData<MyFeature> {};',
        ])
    self._assert_notify(
        ['DidFinishNavigation'],
        'Introduce WCO override',
        'chrome/my_feature.h',
        ['void DidFinishNavigation(',
         '    content::NavigationHandle* navigation_handle) override;',
        ])
    self._assert_notify(
        ['IsInMainFrame'],
        'Introduce IsInMainFrame',
        'chrome/my_feature.cc',
        ['void DoSomething(content::NavigationHandle* navigation_handle) {',
         '  if (navigation_handle->IsInMainFrame())',
         '    all_of_our_page_state.reset();',
         '}',
        ])
    self._assert_notify(
        ['FromRenderFrameHost'],
        'Introduce WC::FromRenderFrameHost',
        'chrome/my_feature.cc',
        ['void DoSomething(content::RenderFrameHost* rfh) {',
         '  auto* wc = content::WebContents::FromRenderFrameHost(rfh);',
         '  ChangeTabState(wc);',
         '}',
        ])

  def testNoNotify(self):
    self._assert_notify(
        [],
        'No API usage',
        'chrome/my_feature.cc',
        ['void DoSomething() {',
         '  // TODO: Something',
         '}',
        ])
    # Something under a top level directory we're not concerned about happens
    # to share a name with a content API.
    self._assert_notify(
        [],
        'Uninteresting top level directory',
        'third_party/my_dep/my_code.cc',
        ['bool HasParent(Node* node) {',
         '  return node->GetParent();',
         '}',
        ])
    # We're not concerned with usage in test code.
    self._assert_notify(
        [],
        'Usage in test code',
        'chrome/my_feature_unittest.cc',
        ['TEST_F(MyFeatureTest, DoesSomething) {',
         '  EXPECT_TRUE(web_contents()->GetMainFrame());',
         '}',
        ])


class AssertAshOnlyCodeTest(unittest.TestCase):
    def testErrorsOnlyOnAshDirectories(self):
        files_in_ash = [
            MockFile('ash/BUILD.gn', []),
            MockFile('chrome/browser/ash/BUILD.gn', []),
        ]
        other_files = [
            MockFile('chrome/browser/BUILD.gn', []),
            MockFile('chrome/browser/BUILD.gn', ['assert(is_chromeos_ash)']),
        ]
        input_api = MockInputApi()
        input_api.files = files_in_ash
        errors = PRESUBMIT.CheckAssertAshOnlyCode(input_api, MockOutputApi())
        self.assertEqual(2, len(errors))

        input_api.files = other_files
        errors = PRESUBMIT.CheckAssertAshOnlyCode(input_api, MockOutputApi())
        self.assertEqual(0, len(errors))

    def testDoesNotErrorOnNonGNFiles(self):
        input_api = MockInputApi()
        input_api.files = [
            MockFile('ash/test.h', ['assert(is_chromeos_ash)']),
            MockFile('chrome/browser/ash/test.cc',
                     ['assert(is_chromeos_ash)']),
        ]
        errors = PRESUBMIT.CheckAssertAshOnlyCode(input_api, MockOutputApi())
        self.assertEqual(0, len(errors))

    def testDeletedFile(self):
        input_api = MockInputApi()
        input_api.files = [
            MockFile('ash/BUILD.gn', []),
            MockFile('ash/foo/BUILD.gn', [], action='D'),
        ]
        errors = PRESUBMIT.CheckAssertAshOnlyCode(input_api, MockOutputApi())
        self.assertEqual(1, len(errors))

    def testDoesNotErrorWithAssertion(self):
        input_api = MockInputApi()
        input_api.files = [
            MockFile('ash/BUILD.gn', ['assert(is_chromeos_ash)']),
            MockFile('chrome/browser/ash/BUILD.gn',
                     ['assert(is_chromeos_ash)']),
            MockFile('chrome/browser/ash/BUILD.gn',
                     ['assert(is_chromeos_ash, "test")']),
        ]
        errors = PRESUBMIT.CheckAssertAshOnlyCode(input_api, MockOutputApi())
        self.assertEqual(0, len(errors))


class CheckRawPtrUsageTest(unittest.TestCase):
  def testAllowedCases(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        # Browser-side files are allowed.
        MockAffectedFile('test10/browser/foo.h', ['raw_ptr<int>']),
        MockAffectedFile('test11/browser/foo.cc', ['raw_ptr<int>']),
        MockAffectedFile('test12/blink/common/foo.cc', ['raw_ptr<int>']),
        MockAffectedFile('test13/blink/public/common/foo.cc', ['raw_ptr<int>']),
        MockAffectedFile('test14/blink/public/platform/foo.cc',
                         ['raw_ptr<int>']),

        # Non-C++ files are allowed.
        MockAffectedFile('test20/renderer/foo.md', ['raw_ptr<int>']),

        # Mentions in a comment are allowed.
        MockAffectedFile('test30/renderer/foo.cc', ['//raw_ptr<int>']),
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckRawPtrUsage(mock_input_api, mock_output_api)
    self.assertFalse(errors)

  def testDisallowedCases(self):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
        MockAffectedFile('test1/renderer/foo.h', ['raw_ptr<int>']),
        MockAffectedFile('test2/renderer/foo.cc', ['raw_ptr<int>']),
        MockAffectedFile('test3/blink/public/web/foo.cc', ['raw_ptr<int>']),
    ]
    mock_output_api = MockOutputApi()
    errors = PRESUBMIT.CheckRawPtrUsage(mock_input_api, mock_output_api)
    self.assertEqual(len(mock_input_api.files), len(errors))
    for error in errors:
      self.assertTrue(
          'raw_ptr<T> should not be used in Renderer-only code' in
          error.message)


class AssertPythonShebangTest(unittest.TestCase):
    def testError(self):
        input_api = MockInputApi()
        input_api.files = [
            MockFile('ash/test.py', ['#!/usr/bin/python']),
            MockFile('chrome/test.py', ['#!/usr/bin/python2']),
            MockFile('third_party/blink/test.py', ['#!/usr/bin/python3']),
            MockFile('empty.py', []),
        ]
        errors = PRESUBMIT.CheckPythonShebang(input_api, MockOutputApi())
        self.assertEqual(3, len(errors))

    def testNonError(self):
        input_api = MockInputApi()
        input_api.files = [
            MockFile('chrome/browser/BUILD.gn', ['#!/usr/bin/python']),
            MockFile('third_party/blink/web_tests/external/test.py',
                     ['#!/usr/bin/python2']),
            MockFile('third_party/test/test.py', ['#!/usr/bin/python3']),
        ]
        errors = PRESUBMIT.CheckPythonShebang(input_api, MockOutputApi())
        self.assertEqual(0, len(errors))


if __name__ == '__main__':
  unittest.main()
