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
4 # found in the LICENSE file.
6 """Unit tests for Copyright Scanner utilities."""
13 test_dir
= os
.path
.dirname(os
.path
.abspath(__file__
))
15 os
.path
.normpath(os
.path
.join(test_dir
, '..', '..', 'tools')),
16 os
.path
.join(test_dir
),
19 import find_depot_tools
20 from testing_support
.super_mox
import SuperMoxTestBase
22 import copyright_scanner
24 class FindCopyrightsTest(SuperMoxTestBase
):
26 SuperMoxTestBase
.setUp(self
)
27 self
.input_api
= self
.mox
.CreateMockAnything()
28 self
.input_api
.re
= re
29 self
.input_api
.os_path
= os
.path
30 self
.input_api
.os_walk
= os
.walk
32 def ShouldMatchReferenceOutput(self
, test_data
, expected_output
):
33 for data
in test_data
:
34 self
.input_api
.ReadFile
= lambda _1
, _2
: data
35 actual_output
= copyright_scanner
.FindCopyrights(self
.input_api
, '', [''])
39 'Input """\n%s""", expected output: "%s", actual: "%s"' % \
40 (data
, expected_output
, actual_output
));
42 def testCopyrightedFiles(self
):
44 '// (c) 2014 Google Inc.\n//\n// (a) One\n//\n// (b) Two\n//\n',
45 'Copyright 2014 Google Inc.\n',
46 'Copr. 2014 Google Inc.',
47 '\xc2\xa9 2014 Google Inc.',
48 'Copyright 2014 Google Inc.'
50 self
.ShouldMatchReferenceOutput(test_data
, [['2014 Google Inc.']])
52 def testGeneratedFiles(self
):
54 'ALL CHANGES MADE IN THIS FILE WILL BE LOST\nCopyright 2014 Google\n',
55 'GENERATED FILE. DO NOT EDIT\nCopyright 2014 Google\n',
56 'GENERATED. DO NOT DELETE THIS FILE.\nCopyright 2014 Google\n',
57 'DO NOT EDIT\nCopyright 2014 Google\n',
58 'DO NOT DELETE THIS FILE\nCopyright 2014 Google\n',
59 'All changes made in this file will be lost\nCopyright 2014 Google\n',
60 'Automatically generated file\nCopyright 2014 Google\n',
61 'Synthetically generated dummy file\nCopyright 2014 Google\n',
62 'Generated data (by gnugnu)\nCopyright 2014 Google\n'
64 self
.ShouldMatchReferenceOutput(test_data
, [['GENERATED FILE']])
66 def testNonCopyrightedFiles(self
):
68 'std::cout << "Copyright 2014 Google"\n',
69 '// Several points can be made:\n//\n// (a) One\n//\n// (b) Two\n'
70 '//\n// (c) Three\n//\n',
71 'See \'foo\' for copyright information.\n',
72 'See \'foo\' for the copyright notice.\n',
73 'See \'foo\' for the copyright and other things.\n'
75 self
.ShouldMatchReferenceOutput(test_data
, [['*No copyright*']])
77 def testNonGeneratedFiles(self
):
79 'This file was prohibited from being generated.\n',
80 'Please do not delete our files! They are valuable to us.\n',
81 'Manually generated from dice rolls.\n',
82 '"""This Python script produces generated data\n"""\n',
83 '\'\'\'This Python script produces generated data\n\'\'\'\n'
85 self
.ShouldMatchReferenceOutput(test_data
, [['*No copyright*']])
88 class FindFilesTest(SuperMoxTestBase
):
90 SuperMoxTestBase
.setUp(self
)
91 self
.input_api
= self
.mox
.CreateMockAnything()
92 self
.input_api
.re
= re
93 self
.input_api
.os_path
= os
.path
95 def testFilesAsStartPaths(self
):
96 self
.input_api
.os_path
.isfile
= lambda _
: True
108 'foo/third_party/a.cc'
109 'foo/third_party/a.txt',
112 actual
= copyright_scanner
.FindFiles(
113 self
.input_api
, root_dir
, input_files
, [''])
114 self
.assertEqual(['a.cc', 'foo/a.cc'], actual
)
115 actual
= copyright_scanner
.FindFiles(
116 self
.input_api
, root_dir
, input_files
, ['third_party'])
117 self
.assertEqual(['a.cc', 'foo/a.cc'], actual
)
118 actual
= copyright_scanner
.FindFiles(
119 self
.input_api
, root_dir
, input_files
, ['foo'])
120 self
.assertEqual(['a.cc'], actual
)
121 actual
= copyright_scanner
.FindFiles(
122 self
.input_api
, root_dir
, input_files
, ['foo', 'third_party'])
123 self
.assertEqual(['a.cc'], actual
)
124 actual
= copyright_scanner
.FindFiles(
125 self
.input_api
, root_dir
, input_files
, ['foo/third_party'])
126 self
.assertEqual(['a.cc', 'foo/a.cc'], actual
)
128 def testDirAsStartPath(self
):
129 self
.input_api
.os_path
.isfile
= lambda _
: False
130 join
= self
.input_api
.os_path
.join
131 normpath
= self
.input_api
.os_path
.normpath
134 base_path
= join(root_dir
, scan_from
)
136 def mock_os_walk(path
):
137 return lambda _
: [(join(base_path
, path
), [''], ['a', 'a.cc', 'a.txt'])]
139 self
.input_api
.os_walk
= mock_os_walk('')
140 actual
= map(normpath
, copyright_scanner
.FindFiles(
141 self
.input_api
, root_dir
, [scan_from
], ['']))
142 self
.assertEqual(['a.cc'], actual
)
144 self
.input_api
.os_walk
= mock_os_walk('third_party')
145 actual
= map(normpath
, copyright_scanner
.FindFiles(
146 self
.input_api
, root_dir
, [scan_from
], ['']))
147 self
.assertEqual([], actual
)
149 self
.input_api
.os_walk
= mock_os_walk('foo')
150 actual
= map(normpath
, copyright_scanner
.FindFiles(
151 self
.input_api
, root_dir
, [scan_from
], ['']))
152 self
.assertEqual(['foo/a.cc'], actual
)
154 self
.input_api
.os_walk
= mock_os_walk('foo')
155 actual
= map(normpath
, copyright_scanner
.FindFiles(
156 self
.input_api
, root_dir
, [scan_from
], ['foo']))
157 self
.assertEqual([], actual
)
159 self
.input_api
.os_walk
= mock_os_walk('foo/bar')
160 actual
= map(normpath
, copyright_scanner
.FindFiles(
161 self
.input_api
, root_dir
, [scan_from
], ['foo']))
162 self
.assertEqual([], actual
)
164 self
.input_api
.os_walk
= mock_os_walk('foo/third_party')
165 actual
= map(normpath
, copyright_scanner
.FindFiles(
166 self
.input_api
, root_dir
, [scan_from
], ['']))
167 self
.assertEqual([], actual
)
169 self
.input_api
.os_walk
= mock_os_walk('foo/third_party')
170 actual
= map(normpath
, copyright_scanner
.FindFiles(
171 self
.input_api
, root_dir
, [scan_from
], ['foo/third_party']))
172 self
.assertEqual([], actual
)
175 class AnalyzeScanResultsTest(SuperMoxTestBase
):
177 SuperMoxTestBase
.setUp(self
)
178 self
.input_api
= self
.mox
.CreateMockAnything()
179 self
.input_api
.os_path
= os
.path
181 def testAnalyzeScanResults(self
):
182 # Tests whitelisted vs. current files state logic.
184 # Whitelisted - in whitelist, and contains 3rd party code => OK
185 # Missing - in whitelist, but doesn't exist
186 # Stale - in whitelist, but is clean
187 # Unknown - not in whitelist, but contains 3rd party code
188 self
.input_api
.os_path
.isfile
= lambda x
: x
!= 'Missing'
190 (['Unknown'], ['Missing'], ['Stale']),
191 copyright_scanner
.AnalyzeScanResults(self
.input_api
, \
192 ['Whitelisted', 'Missing', 'Stale'], ['Whitelisted', 'Unknown']))
195 class ScanAtPresubmitTest(SuperMoxTestBase
):
197 SuperMoxTestBase
.setUp(self
)
198 self
.input_api
= self
.mox
.CreateMockAnything()
199 self
.input_api
.re
= re
200 self
.input_api
.os_path
= os
.path
201 self
.output_api
= self
.mox
.CreateMockAnything()
203 self
.mox
.UnsetStubs()
204 SuperMoxTestBase
.tearDown(self
)
206 class AffectedFileMock(object):
207 def __init__(self
, local_path
, action
):
208 self
._local
_path
= local_path
209 self
._action
= action
211 return self
._local
_path
215 def CreateAffectedFilesFunc(self
, paths_and_actions
):
217 for i
in range(0, len(paths_and_actions
), 2):
218 result
.append(ScanAtPresubmitTest
.AffectedFileMock(
219 paths_and_actions
[i
], paths_and_actions
[i
+ 1]))
220 return lambda: result
222 def CreateDoScanAtPresubmitFunc(self
):
223 self
._whitelisted
_files
= None
224 self
._files
_to
_check
= None
225 def ScanAtPresubmitStub(_
, whitelisted
, to_check
):
226 self
._whitelisted
_files
= whitelisted
227 self
._files
_to
_check
= to_check
229 return ScanAtPresubmitStub
231 def GetWhitelistedFiles(self
):
232 return sorted(self
._whitelisted
_files
)
234 def GetFilesToCheck(self
):
235 return sorted(self
._files
_to
_check
)
237 def testWhitelistedUntouched(self
):
238 # When a change doesn't touch the whitelist file, any updated files
239 # (except deleted) must be checked. The whitelist used for analysis
240 # must be trimmed to the changed files subset.
242 # A_NW.cc - added, not whitelisted => check
243 # A_W.cc - added, whitelisted => check, remain on the trimmed whitelist
244 # D_NW.cc - deleted, not whitelisted => ignore
245 # D_W.cc - deleted and whitelisted => remain on w/l
246 # M_NW.cc - modified, not whitelisted => check
247 # M_W.cc - modified and whitelisted => check, remain on w/l
248 # NM_W.cc - not modified, whitelisted => trim from w/l
249 # W - the whitelist file
251 self
.input_api
.AffectedFiles
= self
.CreateAffectedFilesFunc(
252 ['A_NW.cc', 'A', 'A_W.cc', 'A', 'D_NW.cc', 'D', 'D_W.cc', 'D',
253 'M_NW.cc', 'M', 'M_W.cc', 'M'])
254 self
.mox
.StubOutWithMock(copyright_scanner
, '_GetWhitelistFileName')
255 copyright_scanner
._GetWhitelistFileName
= lambda _
: 'W'
256 self
.mox
.StubOutWithMock(copyright_scanner
, 'LoadWhitelistedFilesList')
257 copyright_scanner
.LoadWhitelistedFilesList
= \
258 lambda _
: ['A_W.cc', 'D_W.cc', 'M_W.cc', 'NM_W.cc']
259 self
.mox
.StubOutWithMock(copyright_scanner
, '_DoScanAtPresubmit')
260 copyright_scanner
._DoScanAtPresubmit
= self
.CreateDoScanAtPresubmitFunc()
262 copyright_scanner
.ScanAtPresubmit(self
.input_api
, self
.output_api
)
264 ['A_W.cc', 'D_W.cc', 'M_W.cc'], self
.GetWhitelistedFiles())
266 ['A_NW.cc', 'A_W.cc', 'M_NW.cc', 'M_W.cc'], self
.GetFilesToCheck())
268 def testWhitelistTouched(self
):
269 # When the whitelist file is touched by the change, all the files listed in
270 # it, including deleted entries, must be re-checked. All modified files
271 # (including the deleted ones) must be checked as well. The current contents
272 # of the whitelist are used for analysis.
273 # Whitelist addition or deletion are not considered.
275 # All the files from names testWhitelistedUntouched are re-used, but now
276 # action for all of them is 'check' (except for the w/l file itself).
277 # A_DW.cc - added, deleted from w/l => check
278 # D_DW.cc - deleted from repo and w/l => check
279 # M_DW.cc - modified, deleted from w/l => check
280 self
.input_api
.AffectedFiles
= self
.CreateAffectedFilesFunc(
281 ['A_DW.cc', 'A', 'A_NW.cc', 'A', 'A_W.cc', 'A',
282 'D_DW.cc', 'D', 'D_NW.cc', 'D', 'D_W.cc', 'D',
283 'M_DW.cc', 'M', 'M_NW.cc', 'M', 'M_W.cc', 'M', 'W', 'M'])
284 self
.mox
.StubOutWithMock(copyright_scanner
, '_GetWhitelistFileName')
285 copyright_scanner
._GetWhitelistFileName
= lambda _
: 'W'
286 self
.mox
.StubOutWithMock(copyright_scanner
, '_GetDeletedContents')
287 def GetDeletedContentsStub(affected_file
):
288 self
.assertEqual('W', affected_file
.LocalPath())
289 return ['A_DW.cc', 'D_DW.cc', 'M_DW.cc']
290 copyright_scanner
._GetDeletedContents
= GetDeletedContentsStub
291 self
.mox
.StubOutWithMock(copyright_scanner
, 'LoadWhitelistedFilesList')
292 copyright_scanner
.LoadWhitelistedFilesList
= \
293 lambda _
: ['A_W.cc', 'D_W.cc', 'M_W.cc', 'NM_W.cc']
294 self
.mox
.StubOutWithMock(copyright_scanner
, '_DoScanAtPresubmit')
295 copyright_scanner
._DoScanAtPresubmit
= self
.CreateDoScanAtPresubmitFunc()
297 copyright_scanner
.ScanAtPresubmit(self
.input_api
, self
.output_api
)
299 ['A_W.cc', 'D_W.cc', 'M_W.cc', 'NM_W.cc'], self
.GetWhitelistedFiles())
301 ['A_DW.cc', 'A_NW.cc', 'A_W.cc', 'D_DW.cc', 'D_NW.cc', 'D_W.cc',
302 'M_DW.cc', 'M_NW.cc', 'M_W.cc', 'NM_W.cc' ], self
.GetFilesToCheck())
304 if __name__
== '__main__':