base/threading: remove ScopedTracker placed for experiments
[chromium-blink-merge.git] / tools / vim / tests / chromium.ycm_extra_conf_unittest.py
blob97135ee036df4386b365da7c1d8e709e7ff301a0
1 #!/usr/bin/env python
3 # Copyright 2015 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
7 """Tests for chromium.ycm_extra_conf.
9 These tests should be getting picked up by the PRESUBMIT.py in /tools/vim.
10 Currently the tests only run on Linux and require 'ninja' to be available on
11 PATH. Due to these requirements, the tests should only be run on upload.
12 """
14 import imp
15 import os
16 import shutil
17 import stat
18 import string
19 import subprocess
20 import sys
21 import tempfile
22 import unittest
24 def CreateFile(path,
25 copy_from = None,
26 format_with = None,
27 make_executable = False):
28 """Creates a file.
30 If a file already exists at |path|, it will be overwritten.
32 Args:
33 path: (String) Absolute path for file to be created.
34 copy_from: (String or None) Absolute path to source file. If valid, the
35 contents of this file will be written to |path|.
36 format_with: (Dictionary or None) Only valid if |copy_from| is also valid.
37 The contents of the file at |copy_from| will be passed through
38 string.Formatter.vformat() with this parameter as the dictionary.
39 make_executable: (Boolean) If true, |file| will be made executable.
40 """
41 if not os.path.isabs(path):
42 raise Exception(
43 'Argument |path| needs to be an absolute path. Got: "{}"'.format(path))
44 with open(path, 'w') as f:
45 if copy_from:
46 with open(copy_from, 'r') as source:
47 contents = source.read()
48 if format_with:
49 formatter = string.Formatter()
50 contents = formatter.vformat(contents, None, format_with)
51 f.write(contents)
52 if make_executable:
53 statinfo = os.stat(path)
54 os.chmod(path, statinfo.st_mode | stat.S_IXUSR)
56 @unittest.skipIf(sys.platform.startswith('linux'),
57 'Tests are only valid on Linux.')
58 class Chromium_ycmExtraConfTest_NotOnLinux(unittest.TestCase):
59 def testAlwaysFailsIfNotRunningOnLinux(self):
60 self.fail('Changes to chromium.ycm_extra_conf.py currently need to be ' \
61 'uploaded from Linux since the tests only run on Linux.')
63 @unittest.skipUnless(sys.platform.startswith('linux'),
64 'Tests are only valid on Linux.')
65 class Chromium_ycmExtraConfTest(unittest.TestCase):
67 def SetUpFakeChromeTreeBelowPath(self):
68 """Create fake Chromium source tree under self.test_root.
70 The fake source tree has the following contents:
72 <self.test_root>
73 | .gclient
75 +-- src
76 | | DEPS
77 | | three.cc
78 | |
79 | +-- .git
81 +-- out
83 +-- Debug
84 build.ninja
85 """
86 self.chrome_root = os.path.abspath(os.path.normpath(
87 os.path.join(self.test_root, 'src')))
88 self.out_dir = os.path.join(self.chrome_root, 'out', 'Debug')
90 os.makedirs(self.chrome_root)
91 os.makedirs(os.path.join(self.chrome_root, '.git'))
92 os.makedirs(self.out_dir)
94 CreateFile(os.path.join(self.test_root, '.gclient'))
95 CreateFile(os.path.join(self.chrome_root, 'DEPS'))
96 CreateFile(os.path.join(self.chrome_root, 'three.cc'))
98 # Fake ninja build file. Applications of 'cxx' rule are tagged by which
99 # source file was used as input so that the test can verify that the correct
100 # build dependency was used.
101 CreateFile(os.path.join(self.out_dir, 'build.ninja'),
102 copy_from=os.path.join(self.test_data_path,
103 'fake_build_ninja.txt'))
105 def NormalizeString(self, string):
106 return string.replace(self.out_dir, '[OUT]').\
107 replace(self.chrome_root, '[SRC]')
109 def NormalizeStringsInList(self, list_of_strings):
110 return [self.NormalizeString(s) for s in list_of_strings]
112 def setUp(self):
113 self.actual_chrome_root = os.path.normpath(
114 os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../..'))
115 sys.path.append(os.path.join(self.actual_chrome_root, 'tools', 'vim'))
116 self.test_data_path = os.path.join(self.actual_chrome_root, 'tools', 'vim',
117 'tests', 'data')
118 self.ycm_extra_conf = imp.load_source('ycm_extra_conf',
119 'chromium.ycm_extra_conf.py')
120 self.test_root = tempfile.mkdtemp()
121 self.SetUpFakeChromeTreeBelowPath()
123 def tearDown(self):
124 if self.test_root:
125 shutil.rmtree(self.test_root)
127 def testNinjaIsAvailable(self):
128 p = subprocess.Popen(['ninja', '--version'], stdout=subprocess.PIPE)
129 _, _ = p.communicate()
130 self.assertFalse(p.returncode)
132 def testFindChromeSrc(self):
133 chrome_source = self.ycm_extra_conf.FindChromeSrcFromFilename(
134 os.path.join(self.chrome_root, 'chrome', 'one.cpp'))
135 self.assertEquals(chrome_source, self.chrome_root)
137 chrome_source = self.ycm_extra_conf.FindChromeSrcFromFilename(
138 os.path.join(self.chrome_root, 'one.cpp'))
139 self.assertEquals(chrome_source, self.chrome_root)
141 def testCommandLineForKnownCppFile(self):
142 command_line = self.ycm_extra_conf.GetClangCommandLineFromNinjaForSource(
143 self.out_dir, os.path.join(self.chrome_root, 'one.cpp'))
144 self.assertEquals(
145 command_line,
146 '../../fake-clang++ -Ia -Itag-one ../../one.cpp -o obj/one.o')
148 def testCommandLineForUnknownCppFile(self):
149 command_line = self.ycm_extra_conf.GetClangCommandLineFromNinjaForSource(
150 self.out_dir, os.path.join(self.chrome_root, 'unknown.cpp'))
151 self.assertEquals(command_line, None)
153 def testGetClangOptionsForKnownCppFile(self):
154 clang_options = \
155 self.ycm_extra_conf.GetClangOptionsFromNinjaForFilename(
156 self.chrome_root, os.path.join(self.chrome_root, 'one.cpp'))
157 self.assertEquals(self.NormalizeStringsInList(clang_options), [
158 '-I[SRC]',
159 '-Wno-unknown-warning-option',
160 '-I[OUT]/a',
161 '-I[OUT]/tag-one'
164 def testGetFlagsForFileForKnownCppFile(self):
165 result = self.ycm_extra_conf.FlagsForFile(
166 os.path.join(self.chrome_root, 'one.cpp'))
167 self.assertTrue(result)
168 self.assertTrue('do_cache' in result)
169 self.assertTrue(result['do_cache'])
170 self.assertTrue('flags' in result)
171 self.assertEquals(self.NormalizeStringsInList(result['flags']), [
172 '-DUSE_CLANG_COMPLETER',
173 '-std=c++11',
174 '-x', 'c++',
175 '-I[SRC]',
176 '-Wno-unknown-warning-option',
177 '-I[OUT]/a',
178 '-I[OUT]/tag-one'
181 def testGetFlagsForFileForUnknownCppFile(self):
182 result = self.ycm_extra_conf.FlagsForFile(
183 os.path.join(self.chrome_root, 'nonexistent.cpp'))
184 self.assertTrue(result)
185 self.assertTrue('do_cache' in result)
186 self.assertTrue(result['do_cache'])
187 self.assertTrue('flags' in result)
188 self.assertEquals(self.NormalizeStringsInList(result['flags']), [
189 '-DUSE_CLANG_COMPLETER',
190 '-std=c++11',
191 '-x', 'c++',
192 '-I[SRC]',
193 '-Wno-unknown-warning-option',
194 '-I[OUT]/a',
195 '-I[OUT]/tag-default'
198 def testGetFlagsForFileForUnknownHeaderFile(self):
199 result = self.ycm_extra_conf.FlagsForFile(
200 os.path.join(self.chrome_root, 'nonexistent.h'))
201 self.assertTrue(result)
202 self.assertTrue('do_cache' in result)
203 self.assertTrue(result['do_cache'])
204 self.assertTrue('flags' in result)
205 self.assertEquals(self.NormalizeStringsInList(result['flags']), [
206 '-DUSE_CLANG_COMPLETER',
207 '-std=c++11',
208 '-x', 'c++',
209 '-I[SRC]',
210 '-Wno-unknown-warning-option',
211 '-I[OUT]/a',
212 '-I[OUT]/tag-default'
215 def testGetFlagsForFileForKnownHeaderFileWithAssociatedCppFile(self):
216 result = self.ycm_extra_conf.FlagsForFile(
217 os.path.join(self.chrome_root, 'three.h'))
218 self.assertTrue(result)
219 self.assertTrue('do_cache' in result)
220 self.assertTrue(result['do_cache'])
221 self.assertTrue('flags' in result)
222 self.assertEquals(self.NormalizeStringsInList(result['flags']), [
223 '-DUSE_CLANG_COMPLETER',
224 '-std=c++11',
225 '-x', 'c++',
226 '-I[SRC]',
227 '-Wno-unknown-warning-option',
228 '-I[OUT]/a',
229 '-I[OUT]/tag-three'
232 def testSourceFileWithNonClangOutputs(self):
233 # Verify assumption that four.cc has non-compiler-output listed as the first
234 # output.
235 p = subprocess.Popen(['ninja', '-C', self.out_dir, '-t',
236 'query', '../../four.cc'],
237 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
238 stdout, _ = p.communicate()
239 self.assertFalse(p.returncode)
240 self.assertEquals(stdout,
241 '../../four.cc:\n'
242 ' outputs:\n'
243 ' obj/linker-output.o\n'
244 ' obj/four.o\n')
246 result = self.ycm_extra_conf.FlagsForFile(
247 os.path.join(self.chrome_root, 'four.cc'))
248 self.assertTrue(result)
249 self.assertTrue('do_cache' in result)
250 self.assertTrue(result['do_cache'])
251 self.assertTrue('flags' in result)
252 self.assertEquals(self.NormalizeStringsInList(result['flags']), [
253 '-DUSE_CLANG_COMPLETER',
254 '-std=c++11',
255 '-x', 'c++',
256 '-I[SRC]',
257 '-Wno-unknown-warning-option',
258 '-I[OUT]/a',
259 '-I[OUT]/tag-four'
262 def testSourceFileWithOnlyNonClangOutputs(self):
263 result = self.ycm_extra_conf.FlagsForFile(
264 os.path.join(self.chrome_root, 'five.cc'))
265 self.assertTrue(result)
266 self.assertTrue('do_cache' in result)
267 self.assertTrue(result['do_cache'])
268 self.assertTrue('flags' in result)
269 self.assertEquals(self.NormalizeStringsInList(result['flags']), [
270 '-DUSE_CLANG_COMPLETER',
271 '-std=c++11',
272 '-x', 'c++',
273 '-I[SRC]',
274 '-Wno-unknown-warning-option',
275 '-I[OUT]/a',
276 '-I[OUT]/tag-default'
279 if __name__ == '__main__':
280 unittest.main()