- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / PRESUBMIT_test.py
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 import difflib
7 import os
8 import re
9 import unittest
10
11 import PRESUBMIT
12
13 class MockLogging(object):
14   def __init__(self):
15     self.lines = []
16
17   def info(self, message):
18     self.lines.append(message)
19
20   def debug(self, message):
21     self.lines.append(message)
22
23 class MockInputApi(object):
24   def __init__(self):
25     self.re = re
26     self.os_path = os.path
27     self.files = []
28     self.is_committing = False
29     self.logging = MockLogging()
30
31   def AffectedFiles(self, include_deletes=None):
32     return self.files
33
34
35 class MockOutputApi(object):
36   class PresubmitResult(object):
37     def __init__(self, message, items=None, long_text=''):
38       self.message = message
39       self.items = items
40       self.long_text = long_text
41
42   class PresubmitError(PresubmitResult):
43     def __init__(self, message, items, long_text=''):
44       MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
45       self.type = 'error'
46
47   class PresubmitPromptWarning(PresubmitResult):
48     def __init__(self, message, items, long_text=''):
49       MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
50       self.type = 'warning'
51
52   class PresubmitNotifyResult(PresubmitResult):
53     def __init__(self, message, items, long_text=''):
54       MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
55       self.type = 'notify'
56
57
58 class MockFile(object):
59   def __init__(self, local_path, old_contents, new_contents):
60     self._local_path = local_path
61     self._new_contents = new_contents
62     self._old_contents = old_contents
63     self._cached_changed_contents = None
64
65   def ChangedContents(self):
66     return self._changed_contents
67
68   def NewContents(self):
69     return self._new_contents
70
71   def LocalPath(self):
72     return self._local_path
73
74   def IsDirectory(self):
75     return False
76
77   def GenerateScmDiff(self):
78     result = ""
79     for line in difflib.unified_diff(self._old_contents, self._new_contents,
80                                      self._local_path, self._local_path):
81       result += line
82     return result
83
84   # NOTE: This method is a copy of ChangeContents method of AffectedFile in
85   # presubmit_support.py
86   def ChangedContents(self):
87     """Returns a list of tuples (line number, line text) of all new lines.
88
89      This relies on the scm diff output describing each changed code section
90      with a line of the form
91
92      ^@@ <old line num>,<old size> <new line num>,<new size> @@$
93     """
94     if self._cached_changed_contents is not None:
95       return self._cached_changed_contents[:]
96     self._cached_changed_contents = []
97     line_num = 0
98
99     if self.IsDirectory():
100       return []
101
102     for line in self.GenerateScmDiff().splitlines():
103       m = re.match(r'^@@ [0-9\,\+\-]+ \+([0-9]+)\,[0-9]+ @@', line)
104       if m:
105         line_num = int(m.groups(1)[0])
106         continue
107       if line.startswith('+') and not line.startswith('++'):
108         self._cached_changed_contents.append((line_num, line[1:]))
109       if not line.startswith('-'):
110         line_num += 1
111     return self._cached_changed_contents[:]
112
113
114 class MockChange(object):
115   def __init__(self, changed_files):
116     self._changed_files = changed_files
117
118   def LocalPaths(self):
119     return self._changed_files
120
121
122 class HistogramValueCheckerTest(unittest.TestCase):
123   TEST_FILE_PATTERN = "PRESUBMIT_test_new_file_%s.txt"
124
125   def _ReadTextFileContents(self, path):
126     """Given a path, returns a list of strings corresponding to the text lines
127     in the file. Reads files in text format.
128
129     """
130     fo = open(path, 'r')
131     try:
132       contents = fo.readlines()
133     finally:
134       fo.close()
135     return contents
136
137   def _ReadInputFile(self):
138     return self._ReadTextFileContents("PRESUBMIT_test_old_file.txt")
139
140   def _PrepareTest(self, new_file_path):
141     old_contents = self._ReadInputFile()
142     if not new_file_path:
143       new_contents = []
144     else:
145       new_contents = self._ReadTextFileContents(new_file_path)
146     input_api = MockInputApi()
147     mock_file = MockFile(PRESUBMIT.HistogramValueChecker.LOCAL_PATH,
148                          old_contents,
149                          new_contents)
150     input_api.files.append(mock_file)
151     output_api = MockOutputApi()
152     return input_api, output_api
153
154   def _RunTest(self, new_file_path):
155     input_api, output_api = self._PrepareTest(new_file_path)
156     checker = PRESUBMIT.HistogramValueChecker(input_api, output_api)
157     results = checker.Run()
158     return results
159
160   def testDeleteFile(self):
161     results = self._RunTest(new_file_path=None)
162     # TODO(rpaquay) How to check it's the expected warning?'
163     self.assertEquals(1, len(results),
164                       "We hould get a single warning about file deletion.")
165
166   def testSimpleValidEdit(self):
167     results = self._RunTest(self.TEST_FILE_PATTERN % "1")
168     # TODO(rpaquay) How to check it's the expected warning?'
169     self.assertEquals(0, len(results),
170                       "We should get no warning for simple edits.")
171
172   def testSingleDeletionOfEntry(self):
173     results = self._RunTest(self.TEST_FILE_PATTERN % "2")
174     # TODO(rpaquay) How to check it's the expected warning?'
175     self.assertEquals(1, len(results),
176                       "We should get a warning for an entry deletion.")
177
178   def testSingleRenameOfEntry(self):
179     results = self._RunTest(self.TEST_FILE_PATTERN % "3")
180     # TODO(rpaquay) How to check it's the expected warning?'
181     self.assertEquals(1, len(results),
182                       "We should get a warning for an entry rename, even "
183                       "though it is not optimal.")
184
185   def testMissingEnumStartOfEntry(self):
186     results = self._RunTest(self.TEST_FILE_PATTERN % "4")
187     # TODO(rpaquay) How to check it's the expected warning?'
188     self.assertEquals(1, len(results),
189                       "We should get a warning for a missing enum marker.")
190
191   def testMissingEnumEndOfEntry(self):
192     results = self._RunTest(self.TEST_FILE_PATTERN % "5")
193     # TODO(rpaquay) How to check it's the expected warning?'
194     self.assertEquals(1, len(results),
195                       "We should get a warning for a missing enum marker.")
196
197   def testInvertedEnumMarkersOfEntry(self):
198     results = self._RunTest(self.TEST_FILE_PATTERN % "6")
199     # TODO(rpaquay) How to check it's the expected warning?'
200     self.assertEquals(1, len(results),
201                       "We should get a warning for inverted enum markers.")
202
203   def testMultipleInvalidEdits(self):
204     results = self._RunTest(self.TEST_FILE_PATTERN % "7")
205     # TODO(rpaquay) How to check it's the expected warning?'
206     self.assertEquals(3, len(results),
207                       "We should get 3 warnings (one per edit).")
208
209   def testSingleInvalidInserts(self):
210     results = self._RunTest(self.TEST_FILE_PATTERN % "8")
211     # TODO(rpaquay) How to check it's the expected warning?'
212     self.assertEquals(1, len(results),
213                       "We should get a warning for a single invalid "
214                       "insertion inside the enum.")
215
216   def testMulitpleValidInserts(self):
217     results = self._RunTest(self.TEST_FILE_PATTERN % "9")
218     # TODO(rpaquay) How to check it's the expected warning?'
219     self.assertEquals(0, len(results),
220                       "We should not get a warning mulitple valid edits")
221
222   def testSingleValidDeleteOutsideOfEnum(self):
223     results = self._RunTest(self.TEST_FILE_PATTERN % "10")
224     # TODO(rpaquay) How to check it's the expected warning?'
225     self.assertEquals(0, len(results),
226                       "We should not get a warning for a deletion outside of "
227                       "the enum")
228
229
230 if __name__ == '__main__':
231   unittest.main()