| Index: tools/strict_enum_value_checker/strict_enum_value_checker_test.py
|
| diff --git a/tools/strict_enum_value_checker/strict_enum_value_checker_test.py b/tools/strict_enum_value_checker/strict_enum_value_checker_test.py
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..4f95efe0cfd66439dfad50775be5c9225ff4afdf
|
| --- /dev/null
|
| +++ b/tools/strict_enum_value_checker/strict_enum_value_checker_test.py
|
| @@ -0,0 +1,235 @@
|
| +#!/usr/bin/env python
|
| +# Copyright 2014 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 difflib
|
| +import os
|
| +import re
|
| +import unittest
|
| +
|
| +from strict_enum_value_checker import StrictEnumValueChecker
|
| +
|
| +class MockLogging(object):
|
| + def __init__(self):
|
| + self.lines = []
|
| +
|
| + def info(self, message):
|
| + self.lines.append(message)
|
| +
|
| + def debug(self, message):
|
| + self.lines.append(message)
|
| +
|
| +class MockInputApi(object):
|
| + def __init__(self):
|
| + self.re = re
|
| + self.os_path = os.path
|
| + self.files = []
|
| + self.is_committing = False
|
| + self.logging = MockLogging()
|
| +
|
| + def AffectedFiles(self, include_deletes=None):
|
| + return self.files
|
| +
|
| +
|
| +class MockOutputApi(object):
|
| + class PresubmitResult(object):
|
| + def __init__(self, message, items=None, long_text=""):
|
| + self.message = message
|
| + self.items = items
|
| + self.long_text = long_text
|
| +
|
| + class PresubmitError(PresubmitResult):
|
| + def __init__(self, message, items, long_text=""):
|
| + MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
|
| + self.type = "error"
|
| +
|
| + class PresubmitPromptWarning(PresubmitResult):
|
| + def __init__(self, message, items, long_text=""):
|
| + MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
|
| + self.type = "warning"
|
| +
|
| + class PresubmitNotifyResult(PresubmitResult):
|
| + def __init__(self, message, items, long_text=""):
|
| + MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
|
| + self.type = "notify"
|
| +
|
| +
|
| +class MockFile(object):
|
| + def __init__(self, local_path, old_contents, new_contents):
|
| + self._local_path = local_path
|
| + self._new_contents = new_contents
|
| + self._old_contents = old_contents
|
| + self._cached_changed_contents = None
|
| +
|
| + def ChangedContents(self):
|
| + return self._changed_contents
|
| +
|
| + def NewContents(self):
|
| + return self._new_contents
|
| +
|
| + def LocalPath(self):
|
| + return self._local_path
|
| +
|
| + def IsDirectory(self):
|
| + return False
|
| +
|
| + def GenerateScmDiff(self):
|
| + result = ""
|
| + for line in difflib.unified_diff(self._old_contents, self._new_contents,
|
| + self._local_path, self._local_path):
|
| + result += line
|
| + return result
|
| +
|
| + # NOTE: This method is a copy of ChangeContents method of AffectedFile in
|
| + # presubmit_support.py
|
| + def ChangedContents(self):
|
| + """Returns a list of tuples (line number, line text) of all new lines.
|
| +
|
| + This relies on the scm diff output describing each changed code section
|
| + with a line of the form
|
| +
|
| + ^@@ <old line num>,<old size> <new line num>,<new size> @@$
|
| + """
|
| + if self._cached_changed_contents is not None:
|
| + return self._cached_changed_contents[:]
|
| + self._cached_changed_contents = []
|
| + line_num = 0
|
| +
|
| + if self.IsDirectory():
|
| + return []
|
| +
|
| + for line in self.GenerateScmDiff().splitlines():
|
| + m = re.match(r"^@@ [0-9\,\+\-]+ \+([0-9]+)\,[0-9]+ @@", line)
|
| + if m:
|
| + line_num = int(m.groups(1)[0])
|
| + continue
|
| + if line.startswith("+") and not line.startswith("++"):
|
| + self._cached_changed_contents.append((line_num, line[1:]))
|
| + if not line.startswith("-"):
|
| + line_num += 1
|
| + return self._cached_changed_contents[:]
|
| +
|
| +
|
| +class MockChange(object):
|
| + def __init__(self, changed_files):
|
| + self._changed_files = changed_files
|
| +
|
| + def LocalPaths(self):
|
| + return self._changed_files
|
| +
|
| +
|
| +class StrictEnumValueCheckerTest(unittest.TestCase):
|
| + TEST_FILE_PATTERN = "changed_file_%s.h"
|
| + MOCK_FILE_LOCAL_PATH = "mock_enum.h"
|
| + START_MARKER = "enum MockEnum {"
|
| + END_MARKER = " mBoundary"
|
| +
|
| + def _ReadTextFileContents(self, path):
|
| + """Given a path, returns a list of strings corresponding to the text lines
|
| + in the file. Reads files in text format.
|
| +
|
| + """
|
| + fo = open(path, "r")
|
| + try:
|
| + contents = fo.readlines()
|
| + finally:
|
| + fo.close()
|
| + return contents
|
| +
|
| + def _ReadInputFile(self):
|
| + return self._ReadTextFileContents("mock_enum.h")
|
| +
|
| + def _PrepareTest(self, new_file_path):
|
| + old_contents = self._ReadInputFile()
|
| + if not new_file_path:
|
| + new_contents = []
|
| + else:
|
| + new_contents = self._ReadTextFileContents(new_file_path)
|
| + input_api = MockInputApi()
|
| + mock_file = MockFile(self.MOCK_FILE_LOCAL_PATH,
|
| + old_contents,
|
| + new_contents)
|
| + input_api.files.append(mock_file)
|
| + output_api = MockOutputApi()
|
| + return input_api, output_api
|
| +
|
| + def _RunTest(self, new_file_path):
|
| + input_api, output_api = self._PrepareTest(new_file_path)
|
| + checker = StrictEnumValueChecker(input_api, output_api, self.START_MARKER,
|
| + self.END_MARKER, self.MOCK_FILE_LOCAL_PATH)
|
| + results = checker.Run()
|
| + return results
|
| +
|
| + def testDeleteFile(self):
|
| + results = self._RunTest(new_file_path=None)
|
| + # TODO(rpaquay) How to check it's the expected warning?'
|
| + self.assertEquals(1, len(results),
|
| + "We should get a single warning about file deletion.")
|
| +
|
| + def testSimpleValidEdit(self):
|
| + results = self._RunTest(self.TEST_FILE_PATTERN % "1")
|
| + # TODO(rpaquay) How to check it's the expected warning?'
|
| + self.assertEquals(0, len(results),
|
| + "We should get no warning for simple edits.")
|
| +
|
| + def testSingleDeletionOfEntry(self):
|
| + results = self._RunTest(self.TEST_FILE_PATTERN % "2")
|
| + # TODO(rpaquay) How to check it's the expected warning?'
|
| + self.assertEquals(1, len(results),
|
| + "We should get a warning for an entry deletion.")
|
| +
|
| + def testSingleRenameOfEntry(self):
|
| + results = self._RunTest(self.TEST_FILE_PATTERN % "3")
|
| + # TODO(rpaquay) How to check it's the expected warning?'
|
| + self.assertEquals(1, len(results),
|
| + "We should get a warning for an entry rename, even "
|
| + "though it is not optimal.")
|
| +
|
| + def testMissingEnumStartOfEntry(self):
|
| + results = self._RunTest(self.TEST_FILE_PATTERN % "4")
|
| + # TODO(rpaquay) How to check it's the expected warning?'
|
| + self.assertEquals(1, len(results),
|
| + "We should get a warning for a missing enum marker.")
|
| +
|
| + def testMissingEnumEndOfEntry(self):
|
| + results = self._RunTest(self.TEST_FILE_PATTERN % "5")
|
| + # TODO(rpaquay) How to check it's the expected warning?'
|
| + self.assertEquals(1, len(results),
|
| + "We should get a warning for a missing enum marker.")
|
| +
|
| + def testInvertedEnumMarkersOfEntry(self):
|
| + results = self._RunTest(self.TEST_FILE_PATTERN % "6")
|
| + # TODO(rpaquay) How to check it's the expected warning?'
|
| + self.assertEquals(1, len(results),
|
| + "We should get a warning for inverted enum markers.")
|
| +
|
| + def testMultipleInvalidEdits(self):
|
| + results = self._RunTest(self.TEST_FILE_PATTERN % "7")
|
| + # TODO(rpaquay) How to check it's the expected warning?'
|
| + self.assertEquals(3, len(results),
|
| + "We should get 3 warnings (one per edit).")
|
| +
|
| + def testSingleInvalidInserts(self):
|
| + results = self._RunTest(self.TEST_FILE_PATTERN % "8")
|
| + # TODO(rpaquay) How to check it's the expected warning?'
|
| + self.assertEquals(1, len(results),
|
| + "We should get a warning for a single invalid "
|
| + "insertion inside the enum.")
|
| +
|
| + def testMulitpleValidInserts(self):
|
| + results = self._RunTest(self.TEST_FILE_PATTERN % "9")
|
| + # TODO(rpaquay) How to check it's the expected warning?'
|
| + self.assertEquals(0, len(results),
|
| + "We should not get a warning mulitple valid edits")
|
| +
|
| + def testSingleValidDeleteOutsideOfEnum(self):
|
| + results = self._RunTest(self.TEST_FILE_PATTERN % "10")
|
| + # TODO(rpaquay) How to check it's the expected warning?'
|
| + self.assertEquals(0, len(results),
|
| + "We should not get a warning for a deletion outside of "
|
| + "the enum")
|
| +
|
| +
|
| +if __name__ == '__main__':
|
| + unittest.main()
|
|
|