| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 import difflib | 6 import difflib |
| 7 import os | 7 import os |
| 8 import re | 8 import re |
| 9 import unittest | 9 import unittest |
| 10 | 10 |
| 11 from strict_enum_value_checker import StrictEnumValueChecker | 11 from verify_enum_custom_flags \ |
| 12 import LoginCustomFlagsChecker |
| 12 | 13 |
| 13 class MockLogging(object): | 14 class MockLogging(object): |
| 14 def __init__(self): | 15 def __init__(self): |
| 15 self.lines = [] | 16 self.lines = [] |
| 16 | 17 |
| 17 def info(self, message): | 18 def info(self, message): |
| 18 self.lines.append(message) | 19 self.lines.append(message) |
| 19 | 20 |
| 20 def debug(self, message): | 21 def debug(self, message): |
| 21 self.lines.append(message) | 22 self.lines.append(message) |
| 22 | 23 |
| 23 class MockInputApi(object): | 24 class MockInputApi(object): |
| 24 def __init__(self): | 25 def __init__(self): |
| 25 self.re = re | 26 self.re = re |
| 26 self.os_path = os.path | 27 self.os_path = os.path |
| 27 self.files = [] | 28 self.files = [] |
| 28 self.is_committing = False | 29 self.is_committing = False |
| 29 self.logging = MockLogging() | 30 self.logging = MockLogging() |
| 30 | 31 |
| 31 def AffectedFiles(self, include_deletes=None): | 32 def AffectedFiles(self, include_deletes=None): |
| 32 return self.files | 33 return self.files |
| 33 | 34 |
| 35 def basename(self, path): |
| 36 return os.path.basename(path) |
| 37 |
| 34 | 38 |
| 35 class MockOutputApi(object): | 39 class MockOutputApi(object): |
| 36 class PresubmitResult(object): | 40 class PresubmitResult(object): |
| 37 def __init__(self, message, items=None, long_text=""): | 41 def __init__(self, message, items=None, long_text=""): |
| 38 self.message = message | 42 self.message = message |
| 39 self.items = items | 43 self.items = items |
| 40 self.long_text = long_text | |
| 41 | 44 |
| 42 class PresubmitError(PresubmitResult): | 45 class PresubmitError(PresubmitResult): |
| 43 def __init__(self, message, items, long_text=""): | 46 def __init__(self, message, items, long_text=""): |
| 44 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) | 47 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) |
| 45 self.type = "error" | 48 self.type = "error" |
| 46 | 49 |
| 50 def write(self): |
| 51 print "E: " + self.message |
| 52 |
| 47 class PresubmitPromptWarning(PresubmitResult): | 53 class PresubmitPromptWarning(PresubmitResult): |
| 48 def __init__(self, message, items, long_text=""): | 54 def __init__(self, message, items, long_text=""): |
| 49 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) | 55 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) |
| 50 self.type = "warning" | 56 self.type = "warning" |
| 51 | 57 |
| 58 def write(self): |
| 59 print "W: " + self.message |
| 60 |
| 52 class PresubmitNotifyResult(PresubmitResult): | 61 class PresubmitNotifyResult(PresubmitResult): |
| 53 def __init__(self, message, items, long_text=""): | 62 def __init__(self, message, items, long_text=""): |
| 54 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) | 63 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) |
| 55 self.type = "notify" | 64 self.type = "notify" |
| 56 | 65 |
| 66 def write(self): |
| 67 print "N: " + self.message |
| 68 |
| 57 | 69 |
| 58 class MockFile(object): | 70 class MockFile(object): |
| 59 def __init__(self, local_path, old_contents, new_contents): | 71 def __init__(self, local_path, old_contents, new_contents): |
| 60 self._local_path = local_path | 72 self._local_path = local_path |
| 61 self._new_contents = new_contents | 73 self._new_contents = new_contents |
| 62 self._old_contents = old_contents | 74 self._old_contents = old_contents |
| 63 self._cached_changed_contents = None | 75 self._cached_changed_contents = None |
| 64 | 76 |
| 65 def ChangedContents(self): | 77 def ChangedContents(self): |
| 66 return self._changed_contents | 78 return self._changed_contents |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 | 124 |
| 113 | 125 |
| 114 class MockChange(object): | 126 class MockChange(object): |
| 115 def __init__(self, changed_files): | 127 def __init__(self, changed_files): |
| 116 self._changed_files = changed_files | 128 self._changed_files = changed_files |
| 117 | 129 |
| 118 def LocalPaths(self): | 130 def LocalPaths(self): |
| 119 return self._changed_files | 131 return self._changed_files |
| 120 | 132 |
| 121 | 133 |
| 122 class StrictEnumValueCheckerTest(unittest.TestCase): | 134 class LoginCustomFlagsCheckerTest(unittest.TestCase): |
| 123 TEST_FILE_PATTERN = "changed_file_%s.h" | 135 TEST_FILE_PATTERN = os.path.join("verify_enum_custom_flags_test_data", |
| 124 MOCK_FILE_LOCAL_PATH = "mock_enum.h" | 136 "changed_file_%s.xml") |
| 125 START_MARKER = "enum MockEnum {" | 137 MOCK_FILE_LOCAL_PATH = os.path.join("verify_enum_custom_flags_test_data", |
| 126 END_MARKER = " mBoundary" | 138 "mock_histograms.xml") |
| 127 | 139 |
| 128 def _ReadTextFileContents(self, path): | 140 def _ReadTextFileContents(self, path): |
| 129 """Given a path, returns a list of strings corresponding to the text lines | 141 """Given a path, returns a list of strings corresponding to the text lines |
| 130 in the file. Reads files in text format. | 142 in the file. Reads files in text format. |
| 131 | 143 |
| 132 """ | 144 """ |
| 133 fo = open(path, "r") | 145 fo = open(path, "r") |
| 134 try: | 146 try: |
| 135 contents = fo.readlines() | 147 contents = fo.readlines() |
| 136 finally: | 148 finally: |
| 137 fo.close() | 149 fo.close() |
| 138 return contents | 150 return contents |
| 139 | 151 |
| 140 def _ReadInputFile(self): | 152 def _ReadInputFile(self): |
| 141 return self._ReadTextFileContents("mock_enum.h") | 153 return self._ReadTextFileContents(self.MOCK_FILE_LOCAL_PATH) |
| 142 | 154 |
| 143 def _PrepareTest(self, new_file_path): | 155 def _PrepareTest(self, new_file_path): |
| 144 old_contents = self._ReadInputFile() | 156 old_contents = self._ReadInputFile() |
| 145 if not new_file_path: | 157 if not new_file_path: |
| 146 new_contents = [] | 158 new_contents = [] |
| 147 else: | 159 else: |
| 148 new_contents = self._ReadTextFileContents(new_file_path) | 160 new_contents = self._ReadTextFileContents(new_file_path) |
| 149 input_api = MockInputApi() | 161 input_api = MockInputApi() |
| 150 mock_file = MockFile(self.MOCK_FILE_LOCAL_PATH, | 162 mock_file = MockFile(new_file_path, |
| 151 old_contents, | 163 old_contents, |
| 152 new_contents) | 164 new_contents) |
| 153 input_api.files.append(mock_file) | 165 input_api.files.append(mock_file) |
| 154 output_api = MockOutputApi() | 166 output_api = MockOutputApi() |
| 155 return input_api, output_api | 167 return input_api, output_api |
| 156 | 168 |
| 157 def _RunTest(self, new_file_path): | 169 def _RunTest(self, new_file_path): |
| 158 input_api, output_api = self._PrepareTest(new_file_path) | 170 input_api, output_api = self._PrepareTest(new_file_path) |
| 159 checker = StrictEnumValueChecker(input_api, output_api, self.START_MARKER, | 171 checker = LoginCustomFlagsChecker(input_api, output_api, |
| 160 self.END_MARKER, self.MOCK_FILE_LOCAL_PATH) | 172 new_file_path) |
| 161 results = checker.Run() | 173 results = checker.Run() |
| 162 return results | 174 return results |
| 163 | 175 |
| 164 def testDeleteFile(self): | |
| 165 results = self._RunTest(new_file_path=None) | |
| 166 # TODO(rpaquay) How to check it's the expected warning?' | |
| 167 self.assertEquals(1, len(results), | |
| 168 "We should get a single warning about file deletion.") | |
| 169 | |
| 170 def testSimpleValidEdit(self): | 176 def testSimpleValidEdit(self): |
| 171 results = self._RunTest(self.TEST_FILE_PATTERN % "1") | 177 results = self._RunTest(self.TEST_FILE_PATTERN % "1") |
| 172 # TODO(rpaquay) How to check it's the expected warning?' | 178 self.assertEquals(True, len(results) == 0, |
| 173 self.assertEquals(0, len(results), | 179 "We should get no warning for valid addition.") |
| 174 "We should get no warning for simple edits.") | |
| 175 | 180 |
| 176 def testSingleDeletionOfEntry(self): | 181 def testSingleDeletionOfEntry(self): |
| 177 results = self._RunTest(self.TEST_FILE_PATTERN % "2") | 182 results = self._RunTest(self.TEST_FILE_PATTERN % "2") |
| 178 # TODO(rpaquay) How to check it's the expected warning?' | 183 self.assertEquals(True, len(results) > 0, |
| 179 self.assertEquals(1, len(results), | |
| 180 "We should get a warning for an entry deletion.") | 184 "We should get a warning for an entry deletion.") |
| 181 | 185 |
| 182 def testSingleRenameOfEntry(self): | 186 def testSingleRenameOfEntry(self): |
| 183 results = self._RunTest(self.TEST_FILE_PATTERN % "3") | 187 results = self._RunTest(self.TEST_FILE_PATTERN % "3") |
| 184 # TODO(rpaquay) How to check it's the expected warning?' | 188 self.assertEquals(True, len(results) == 0, |
| 185 self.assertEquals(1, len(results), | 189 str("We should get no warning for an entry description" |
| 186 "We should get a warning for an entry rename, even " | 190 "replacement.")) |
| 187 "though it is not optimal.") | |
| 188 | 191 |
| 189 def testMissingEnumStartOfEntry(self): | 192 def testSingleDeprecatedEntry(self): |
| 190 results = self._RunTest(self.TEST_FILE_PATTERN % "4") | 193 results = self._RunTest(self.TEST_FILE_PATTERN % "4") |
| 191 # TODO(rpaquay) How to check it's the expected warning?' | 194 self.assertEquals(True, len(results) == 0, |
| 192 self.assertEquals(1, len(results), | 195 "We should get no warning for entries reordering.") |
| 193 "We should get a warning for a missing enum marker.") | |
| 194 | |
| 195 def testMissingEnumEndOfEntry(self): | |
| 196 results = self._RunTest(self.TEST_FILE_PATTERN % "5") | |
| 197 # TODO(rpaquay) How to check it's the expected warning?' | |
| 198 self.assertEquals(1, len(results), | |
| 199 "We should get a warning for a missing enum marker.") | |
| 200 | |
| 201 def testInvertedEnumMarkersOfEntry(self): | |
| 202 results = self._RunTest(self.TEST_FILE_PATTERN % "6") | |
| 203 # TODO(rpaquay) How to check it's the expected warning?' | |
| 204 self.assertEquals(1, len(results), | |
| 205 "We should get a warning for inverted enum markers.") | |
| 206 | |
| 207 def testMultipleInvalidEdits(self): | |
| 208 results = self._RunTest(self.TEST_FILE_PATTERN % "7") | |
| 209 # TODO(rpaquay) How to check it's the expected warning?' | |
| 210 self.assertEquals(3, len(results), | |
| 211 "We should get 3 warnings (one per edit).") | |
| 212 | |
| 213 def testSingleInvalidInserts(self): | |
| 214 results = self._RunTest(self.TEST_FILE_PATTERN % "8") | |
| 215 # TODO(rpaquay) How to check it's the expected warning?' | |
| 216 self.assertEquals(1, len(results), | |
| 217 "We should get a warning for a single invalid " | |
| 218 "insertion inside the enum.") | |
| 219 | |
| 220 def testMulitpleValidInserts(self): | |
| 221 results = self._RunTest(self.TEST_FILE_PATTERN % "9") | |
| 222 # TODO(rpaquay) How to check it's the expected warning?' | |
| 223 self.assertEquals(0, len(results), | |
| 224 "We should not get a warning mulitple valid edits") | |
| 225 | |
| 226 def testSingleValidDeleteOutsideOfEnum(self): | |
| 227 results = self._RunTest(self.TEST_FILE_PATTERN % "10") | |
| 228 # TODO(rpaquay) How to check it's the expected warning?' | |
| 229 self.assertEquals(0, len(results), | |
| 230 "We should not get a warning for a deletion outside of " | |
| 231 "the enum") | |
| 232 | |
| 233 | 196 |
| 234 if __name__ == '__main__': | 197 if __name__ == '__main__': |
| 235 unittest.main() | 198 unittest.main() |
| OLD | NEW |