Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: tools/code_coverage/croc_test.py

Issue 113980: Major refactoring of Croc.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python2.4 1 #!/usr/bin/python2.4
2 # 2 #
3 # Copyright 2009, Google Inc. 3 # Copyright 2009, Google Inc.
4 # All rights reserved. 4 # All rights reserved.
5 # 5 #
6 # Redistribution and use in source and binary forms, with or without 6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are 7 # modification, are permitted provided that the following conditions are
8 # met: 8 # met:
9 # 9 #
10 # * Redistributions of source code must retain the above copyright 10 # * Redistributions of source code must retain the above copyright
(...skipping 14 matching lines...) Expand all
25 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 31
32 """Unit tests for Crocodile.""" 32 """Unit tests for Crocodile."""
33 33
34 import os 34 import os
35 import re
36 import sys
37 import StringIO 35 import StringIO
38 import unittest 36 import unittest
39 import croc 37 import croc
40 38
41 #------------------------------------------------------------------------------ 39 #------------------------------------------------------------------------------
42 40
41
43 class TestCoverageStats(unittest.TestCase): 42 class TestCoverageStats(unittest.TestCase):
44 """Tests for croc.CoverageStats.""" 43 """Tests for croc.CoverageStats."""
45 44
46 def testAdd(self): 45 def testAdd(self):
47 """Test Add().""" 46 """Test Add()."""
48 c = croc.CoverageStats() 47 c = croc.CoverageStats()
49 48
50 # Initially empty 49 # Initially empty
51 self.assertEqual(c, {}) 50 self.assertEqual(c, {})
52 51
53 # Add items 52 # Add items
54 c['a'] = 1 53 c['a'] = 1
55 c['b'] = 0 54 c['b'] = 0
56 self.assertEqual(c, {'a':1, 'b':0}) 55 self.assertEqual(c, {'a': 1, 'b': 0})
57 56
58 # Add dict with non-overlapping items 57 # Add dict with non-overlapping items
59 c.Add({'c':5}) 58 c.Add({'c': 5})
60 self.assertEqual(c, {'a':1, 'b':0, 'c':5}) 59 self.assertEqual(c, {'a': 1, 'b': 0, 'c': 5})
61 60
62 # Add dict with overlapping items 61 # Add dict with overlapping items
63 c.Add({'a':4, 'd':3}) 62 c.Add({'a': 4, 'd': 3})
64 self.assertEqual(c, {'a':5, 'b':0, 'c':5, 'd':3}) 63 self.assertEqual(c, {'a': 5, 'b': 0, 'c': 5, 'd': 3})
65 64
66 #------------------------------------------------------------------------------ 65 #------------------------------------------------------------------------------
67 66
67
68 class TestCoveredFile(unittest.TestCase): 68 class TestCoveredFile(unittest.TestCase):
69 """Tests for croc.CoveredFile.""" 69 """Tests for croc.CoveredFile."""
70 70
71 def setUp(self): 71 def setUp(self):
72 self.cov_file = croc.CoveredFile('bob.cc', 'source', 'C++') 72 self.cov_file = croc.CoveredFile('bob.cc', group='source', language='C++')
73 73
74 def testInit(self): 74 def testInit(self):
75 """Test init.""" 75 """Test init."""
76 f = self.cov_file 76 f = self.cov_file
77 77
78 # Check initial values 78 # Check initial values
79 self.assertEqual(f.filename, 'bob.cc') 79 self.assertEqual(f.filename, 'bob.cc')
80 self.assertEqual(f.group, 'source') 80 self.assertEqual(f.attrs, {'group': 'source', 'language': 'C++'})
81 self.assertEqual(f.language, 'C++')
82 self.assertEqual(f.lines, {}) 81 self.assertEqual(f.lines, {})
83 self.assertEqual(f.stats, {}) 82 self.assertEqual(f.stats, {})
83 self.assertEqual(f.local_path, None)
84 self.assertEqual(f.in_lcov, False)
84 85
85 def testUpdateCoverageEmpty(self): 86 def testUpdateCoverageEmpty(self):
86 """Test updating coverage when empty.""" 87 """Test updating coverage when empty."""
87 f = self.cov_file 88 f = self.cov_file
88 f.UpdateCoverage() 89 f.UpdateCoverage()
89 self.assertEqual(f.stats, { 90 self.assertEqual(f.stats, {
90 'lines_executable':0, 91 'lines_executable': 0,
91 'lines_instrumented':0, 92 'lines_instrumented': 0,
92 'lines_covered':0, 93 'lines_covered': 0,
93 'files_executable':1, 94 'files_executable': 1,
94 }) 95 })
95 96
96 def testUpdateCoverageExeOnly(self): 97 def testUpdateCoverageExeOnly(self):
97 """Test updating coverage when no lines are instrumented.""" 98 """Test updating coverage when no lines are instrumented."""
98 f = self.cov_file 99 f = self.cov_file
99 f.lines = {1:None, 2:None, 4:None} 100 f.lines = {1: None, 2: None, 4: None}
100 f.UpdateCoverage() 101 f.UpdateCoverage()
101 self.assertEqual(f.stats, { 102 self.assertEqual(f.stats, {
102 'lines_executable':3, 103 'lines_executable': 3,
103 'lines_instrumented':0, 104 'lines_instrumented': 0,
104 'lines_covered':0, 105 'lines_covered': 0,
105 'files_executable':1, 106 'files_executable': 1,
107 })
108
109 # Now mark the file instrumented via in_lcov
110 f.in_lcov = True
111 f.UpdateCoverage()
112 self.assertEqual(f.stats, {
113 'lines_executable': 3,
114 'lines_instrumented': 0,
115 'lines_covered': 0,
116 'files_executable': 1,
117 'files_instrumented': 1,
106 }) 118 })
107 119
108 def testUpdateCoverageExeAndInstr(self): 120 def testUpdateCoverageExeAndInstr(self):
109 """Test updating coverage when no lines are covered.""" 121 """Test updating coverage when no lines are covered."""
110 f = self.cov_file 122 f = self.cov_file
111 f.lines = {1:None, 2:None, 4:0, 5:0, 7:None} 123 f.lines = {1: None, 2: None, 4: 0, 5: 0, 7: None}
112 f.UpdateCoverage() 124 f.UpdateCoverage()
113 self.assertEqual(f.stats, { 125 self.assertEqual(f.stats, {
114 'lines_executable':5, 126 'lines_executable': 5,
115 'lines_instrumented':2, 127 'lines_instrumented': 2,
116 'lines_covered':0, 128 'lines_covered': 0,
117 'files_executable':1, 129 'files_executable': 1,
118 'files_instrumented':1, 130 'files_instrumented': 1,
119 }) 131 })
120 132
121 def testUpdateCoverageWhenCovered(self): 133 def testUpdateCoverageWhenCovered(self):
122 """Test updating coverage when lines are covered.""" 134 """Test updating coverage when lines are covered."""
123 f = self.cov_file 135 f = self.cov_file
124 f.lines = {1:None, 2:None, 3:1, 4:0, 5:0, 6:1, 7:None} 136 f.lines = {1: None, 2: None, 3: 1, 4: 0, 5: 0, 6: 1, 7: None}
125 f.UpdateCoverage() 137 f.UpdateCoverage()
126 self.assertEqual(f.stats, { 138 self.assertEqual(f.stats, {
127 'lines_executable':7, 139 'lines_executable': 7,
128 'lines_instrumented':4, 140 'lines_instrumented': 4,
129 'lines_covered':2, 141 'lines_covered': 2,
130 'files_executable':1, 142 'files_executable': 1,
131 'files_instrumented':1, 143 'files_instrumented': 1,
132 'files_covered':1, 144 'files_covered': 1,
133 }) 145 })
134 146
135 #------------------------------------------------------------------------------ 147 #------------------------------------------------------------------------------
136 148
149
137 class TestCoveredDir(unittest.TestCase): 150 class TestCoveredDir(unittest.TestCase):
138 """Tests for croc.CoveredDir.""" 151 """Tests for croc.CoveredDir."""
139 152
140 def setUp(self): 153 def setUp(self):
141 self.cov_dir = croc.CoveredDir('/a/b/c') 154 self.cov_dir = croc.CoveredDir('/a/b/c')
142 155
143 def testInit(self): 156 def testInit(self):
144 """Test init.""" 157 """Test init."""
145 d = self.cov_dir 158 d = self.cov_dir
146 159
147 # Check initial values 160 # Check initial values
148 self.assertEqual(d.dirpath, '/a/b/c') 161 self.assertEqual(d.dirpath, '/a/b/c')
149 self.assertEqual(d.files, {}) 162 self.assertEqual(d.files, {})
150 self.assertEqual(d.subdirs, {}) 163 self.assertEqual(d.subdirs, {})
151 self.assertEqual(d.stats_by_group, {'all':{}}) 164 self.assertEqual(d.stats_by_group, {'all': {}})
152 165
153 def testGetTreeEmpty(self): 166 def testGetTreeEmpty(self):
154 """Test getting empty tree.""" 167 """Test getting empty tree."""
155 d = self.cov_dir 168 d = self.cov_dir
156 self.assertEqual(d.GetTree(), '/a/b/c/') 169 self.assertEqual(d.GetTree(), 'c/')
157 170
158 def testGetTreeStats(self): 171 def testGetTreeStats(self):
159 """Test getting tree with stats.""" 172 """Test getting tree with stats."""
160 d = self.cov_dir 173 d = self.cov_dir
161 d.stats_by_group['all'] = croc.CoverageStats( 174 d.stats_by_group['all'] = croc.CoverageStats(
162 lines_executable=50, lines_instrumented=30, lines_covered=20) 175 lines_executable=50, lines_instrumented=30, lines_covered=20)
163 d.stats_by_group['bar'] = croc.CoverageStats( 176 d.stats_by_group['bar'] = croc.CoverageStats(
164 lines_executable=0, lines_instrumented=0, lines_covered=0) 177 lines_executable=0, lines_instrumented=0, lines_covered=0)
165 d.stats_by_group['foo'] = croc.CoverageStats( 178 d.stats_by_group['foo'] = croc.CoverageStats(
166 lines_executable=33, lines_instrumented=22, lines_covered=11) 179 lines_executable=33, lines_instrumented=22, lines_covered=11)
167 # 'bar' group is skipped because it has no executable lines 180 # 'bar' group is skipped because it has no executable lines
168 self.assertEqual(d.GetTree(), 181 self.assertEqual(
169 '/a/b/c/ all:20/30/50 foo:11/22/33') 182 d.GetTree(),
183 'c/ all:20/30/50 foo:11/22/33')
170 184
171 def testGetTreeSubdir(self): 185 def testGetTreeSubdir(self):
172 """Test getting tree with subdirs.""" 186 """Test getting tree with subdirs."""
173 d1 = self.cov_dir = croc.CoveredDir('/a') 187 d1 = self.cov_dir = croc.CoveredDir('/a')
174 d2 = self.cov_dir = croc.CoveredDir('/a/b') 188 d2 = self.cov_dir = croc.CoveredDir('/a/b')
175 d3 = self.cov_dir = croc.CoveredDir('/a/c') 189 d3 = self.cov_dir = croc.CoveredDir('/a/c')
176 d4 = self.cov_dir = croc.CoveredDir('/a/b/d') 190 d4 = self.cov_dir = croc.CoveredDir('/a/b/d')
177 d5 = self.cov_dir = croc.CoveredDir('/a/b/e') 191 d5 = self.cov_dir = croc.CoveredDir('/a/b/e')
178 d1.subdirs = {'/a/b':d2, '/a/c':d3} 192 d1.subdirs = {'/a/b': d2, '/a/c': d3}
179 d2.subdirs = {'/a/b/d':d4, '/a/b/e':d5} 193 d2.subdirs = {'/a/b/d': d4, '/a/b/e': d5}
180 self.assertEqual(d1.GetTree(), 194 self.assertEqual(d1.GetTree(), 'a/\n b/\n d/\n e/\n c/')
181 '/a/\n /a/b/\n /a/b/d/\n /a/b/e/\n /a/c/')
182 195
183 #------------------------------------------------------------------------------ 196 #------------------------------------------------------------------------------
184 197
198
185 class TestCoverage(unittest.TestCase): 199 class TestCoverage(unittest.TestCase):
186 """Tests for croc.Coverage.""" 200 """Tests for croc.Coverage."""
187 201
188 def MockWalk(self, src_dir): 202 def MockWalk(self, src_dir):
189 """Mock for os.walk(). 203 """Mock for os.walk().
190 204
191 Args: 205 Args:
192 src_dir: Source directory to walk. 206 src_dir: Source directory to walk.
193 207
194 Returns: 208 Returns:
195 A list of (dirpath, dirnames, filenames) tuples. 209 A list of (dirpath, dirnames, filenames) tuples.
196 """ 210 """
197 self.mock_walk_calls.append(src_dir) 211 self.mock_walk_calls.append(src_dir)
198 return self.mock_walk_return 212 return self.mock_walk_return
199 213
214 def MockScanFile(self, filename, language):
215 """Mock for croc_scan.ScanFile().
216
217 Args:
218 filename: Path to file to scan.
219 language: Language for file.
220
221 Returns:
222 A list of executable lines.
223 """
224 self.mock_scan_calls.append([filename, language])
225 if filename in self.mock_scan_return:
226 return self.mock_scan_return[filename]
227 else:
228 return self.mock_scan_return['default']
229
200 def setUp(self): 230 def setUp(self):
201 """Per-test setup""" 231 """Per-test setup."""
202 232
203 # Empty coverage object 233 # Empty coverage object
204 self.cov = croc.Coverage() 234 self.cov = croc.Coverage()
205 235
206 # Coverage object with minimal setup 236 # Coverage object with minimal setup
207 self.cov_minimal = croc.Coverage() 237 self.cov_minimal = croc.Coverage()
208 self.cov_minimal.AddRoot('/src') 238 self.cov_minimal.AddRoot('/src')
209 self.cov_minimal.AddRoot('c:\\source') 239 self.cov_minimal.AddRoot('c:\\source')
210 self.cov_minimal.AddRule('^#/', include=1, group='my') 240 self.cov_minimal.AddRule('^_/', include=1, group='my')
211 self.cov_minimal.AddRule('.*\\.c$', language='C') 241 self.cov_minimal.AddRule('.*\\.c$', language='C')
212 self.cov_minimal.AddRule('.*\\.c##$', language='C##') # sharper than thou 242 self.cov_minimal.AddRule('.*\\.c##$', language='C##') # sharper than thou
213 243
214 # Data for MockWalk() 244 # Data for MockWalk()
215 self.mock_walk_calls = [] 245 self.mock_walk_calls = []
216 self.mock_walk_return = [] 246 self.mock_walk_return = []
217 247
248 # Data for MockScanFile()
249 self.mock_scan_calls = []
250 self.mock_scan_return = {'default': [1]}
251
218 def testInit(self): 252 def testInit(self):
219 """Test init.""" 253 """Test init."""
220 c = self.cov 254 c = self.cov
221 self.assertEqual(c.files, {}) 255 self.assertEqual(c.files, {})
222 self.assertEqual(c.root_dirs, []) 256 self.assertEqual(c.root_dirs, [])
223 self.assertEqual(c.print_stats, []) 257 self.assertEqual(c.print_stats, [])
224 258 self.assertEqual(c.rules, [])
225 # Check for the initial subdir rule
226 self.assertEqual(len(c.rules), 1)
227 r0 = c.rules[0]
228 self.assertEqual(r0[0].pattern, '.*/$')
229 self.assertEqual(r0[1:], [None, None, 'subdir'])
230 259
231 def testAddRoot(self): 260 def testAddRoot(self):
232 """Test AddRoot() and CleanupFilename().""" 261 """Test AddRoot() and CleanupFilename()."""
233 c = self.cov 262 c = self.cov
234 263
235 # Check for identity on already-clean filenames 264 # Check for identity on already-clean filenames
236 self.assertEqual(c.CleanupFilename(''), '') 265 self.assertEqual(c.CleanupFilename(''), '')
237 self.assertEqual(c.CleanupFilename('a'), 'a') 266 self.assertEqual(c.CleanupFilename('a'), 'a')
238 self.assertEqual(c.CleanupFilename('.a'), '.a') 267 self.assertEqual(c.CleanupFilename('.a'), '.a')
239 self.assertEqual(c.CleanupFilename('..a'), '..a') 268 self.assertEqual(c.CleanupFilename('..a'), '..a')
240 self.assertEqual(c.CleanupFilename('a.b'), 'a.b') 269 self.assertEqual(c.CleanupFilename('a.b'), 'a.b')
241 self.assertEqual(c.CleanupFilename('a/b/c'), 'a/b/c') 270 self.assertEqual(c.CleanupFilename('a/b/c'), 'a/b/c')
242 self.assertEqual(c.CleanupFilename('a/b/c/'), 'a/b/c/') 271 self.assertEqual(c.CleanupFilename('a/b/c/'), 'a/b/c/')
243 272
244 # Backslash to forward slash 273 # Backslash to forward slash
245 self.assertEqual(c.CleanupFilename('a\\b\\c'), 'a/b/c') 274 self.assertEqual(c.CleanupFilename('a\\b\\c'), 'a/b/c')
246 275
247 # Handle relative paths 276 # Handle relative paths
248 self.assertEqual(c.CleanupFilename('.'), 277 self.assertEqual(c.CleanupFilename('.'),
249 c.CleanupFilename(os.path.abspath('.'))) 278 c.CleanupFilename(os.path.abspath('.')))
250 self.assertEqual(c.CleanupFilename('..'), 279 self.assertEqual(c.CleanupFilename('..'),
251 c.CleanupFilename(os.path.abspath('..'))) 280 c.CleanupFilename(os.path.abspath('..')))
252 self.assertEqual(c.CleanupFilename('./foo/bar'), 281 self.assertEqual(c.CleanupFilename('./foo/bar'),
253 c.CleanupFilename(os.path.abspath('./foo/bar'))) 282 c.CleanupFilename(os.path.abspath('./foo/bar')))
254 self.assertEqual(c.CleanupFilename('../../a/b/c'), 283 self.assertEqual(c.CleanupFilename('../../a/b/c'),
255 c.CleanupFilename(os.path.abspath('../../a/b/c'))) 284 c.CleanupFilename(os.path.abspath('../../a/b/c')))
256 285
257 # Replace alt roots 286 # Replace alt roots
258 c.AddRoot('foo', '#') 287 c.AddRoot('foo')
259 self.assertEqual(c.CleanupFilename('foo'), '#') 288 self.assertEqual(c.CleanupFilename('foo'), '_')
260 self.assertEqual(c.CleanupFilename('foo/bar/baz'), '#/bar/baz') 289 self.assertEqual(c.CleanupFilename('foo/bar/baz'), '_/bar/baz')
261 self.assertEqual(c.CleanupFilename('aaa/foo'), 'aaa/foo') 290 self.assertEqual(c.CleanupFilename('aaa/foo'), 'aaa/foo')
262 291
263 # Alt root replacement is applied for all roots 292 # Alt root replacement is applied for all roots
264 c.AddRoot('foo/bar', '#B') 293 c.AddRoot('foo/bar', '_B')
265 self.assertEqual(c.CleanupFilename('foo/bar/baz'), '#B/baz') 294 self.assertEqual(c.CleanupFilename('foo/bar/baz'), '_B/baz')
266 295
267 # Can use previously defined roots in cleanup 296 # Can use previously defined roots in cleanup
268 c.AddRoot('#/nom/nom/nom', '#CANHAS') 297 c.AddRoot('_/nom/nom/nom', '_CANHAS')
269 self.assertEqual(c.CleanupFilename('foo/nom/nom/nom/cheezburger'), 298 self.assertEqual(c.CleanupFilename('foo/nom/nom/nom/cheezburger'),
270 '#CANHAS/cheezburger') 299 '_CANHAS/cheezburger')
271 300
272 # Verify roots starting with UNC paths or drive letters work, and that 301 # Verify roots starting with UNC paths or drive letters work, and that
273 # more than one root can point to the same alt_name 302 # more than one root can point to the same alt_name
274 c.AddRoot('/usr/local/foo', '#FOO') 303 c.AddRoot('/usr/local/foo', '_FOO')
275 c.AddRoot('D:\\my\\foo', '#FOO') 304 c.AddRoot('D:\\my\\foo', '_FOO')
276 self.assertEqual(c.CleanupFilename('/usr/local/foo/a/b'), '#FOO/a/b') 305 self.assertEqual(c.CleanupFilename('/usr/local/foo/a/b'), '_FOO/a/b')
277 self.assertEqual(c.CleanupFilename('D:\\my\\foo\\c\\d'), '#FOO/c/d') 306 self.assertEqual(c.CleanupFilename('D:\\my\\foo\\c\\d'), '_FOO/c/d')
307
308 # Cannot specify a blank alt_name
309 self.assertRaises(ValueError, c.AddRoot, 'some_dir', '')
278 310
279 def testAddRule(self): 311 def testAddRule(self):
280 """Test AddRule() and ClassifyFile().""" 312 """Test AddRule() and ClassifyFile()."""
281 c = self.cov 313 c = self.cov
282 314
283 # With only the default rule, nothing gets kept 315 # With only the default rule, nothing gets kept
284 self.assertEqual(c.ClassifyFile('#/src/'), (None, None)) 316 self.assertEqual(c.ClassifyFile('_/src/'), {})
285 self.assertEqual(c.ClassifyFile('#/src/a.c'), (None, None)) 317 self.assertEqual(c.ClassifyFile('_/src/a.c'), {})
286 318
287 # Add rules to include a tree and set a default group 319 # Add rules to include a tree and set a default group
288 c.AddRule('^#/src/', include=1, group='source') 320 c.AddRule('^_/src/', include=1, group='source')
289 # Now the subdir matches, but source doesn't, since no languages are 321 self.assertEqual(c.ClassifyFile('_/src/'),
290 # defined yet 322 {'include': 1, 'group': 'source'})
291 self.assertEqual(c.ClassifyFile('#/src/'), ('source', 'subdir')) 323 self.assertEqual(c.ClassifyFile('_/notsrc/'), {})
292 self.assertEqual(c.ClassifyFile('#/notsrc/'), (None, None)) 324 self.assertEqual(c.ClassifyFile('_/src/a.c'),
293 self.assertEqual(c.ClassifyFile('#/src/a.c'), (None, None)) 325 {'include': 1, 'group': 'source'})
294 326
295 # Define some languages and groups 327 # Define some languages and groups
296 c.AddRule('.*\\.(c|h)$', language='C') 328 c.AddRule('.*\\.(c|h)$', language='C')
297 c.AddRule('.*\\.py$', language='Python') 329 c.AddRule('.*\\.py$', language='Python')
298 c.AddRule('.*_test\\.', group='test') 330 c.AddRule('.*_test\\.', group='test')
299 self.assertEqual(c.ClassifyFile('#/src/a.c'), ('source', 'C')) 331 self.assertEqual(c.ClassifyFile('_/src/a.c'),
300 self.assertEqual(c.ClassifyFile('#/src/a.h'), ('source', 'C')) 332 {'include': 1, 'group': 'source', 'language': 'C'})
301 self.assertEqual(c.ClassifyFile('#/src/a.cpp'), (None, None)) 333 self.assertEqual(c.ClassifyFile('_/src/a.h'),
302 self.assertEqual(c.ClassifyFile('#/src/a_test.c'), ('test', 'C')) 334 {'include': 1, 'group': 'source', 'language': 'C'})
303 self.assertEqual(c.ClassifyFile('#/src/test_a.c'), ('source', 'C')) 335 self.assertEqual(c.ClassifyFile('_/src/a.cpp'),
304 self.assertEqual(c.ClassifyFile('#/src/foo/bar.py'), ('source', 'Python')) 336 {'include': 1, 'group': 'source'})
305 self.assertEqual(c.ClassifyFile('#/src/test.py'), ('source', 'Python')) 337 self.assertEqual(c.ClassifyFile('_/src/a_test.c'),
338 {'include': 1, 'group': 'test', 'language': 'C'})
339 self.assertEqual(c.ClassifyFile('_/src/test_a.c'),
340 {'include': 1, 'group': 'source', 'language': 'C'})
341 self.assertEqual(c.ClassifyFile('_/src/foo/bar.py'),
342 {'include': 1, 'group': 'source', 'language': 'Python'})
343 self.assertEqual(c.ClassifyFile('_/src/test.py'),
344 {'include': 1, 'group': 'source', 'language': 'Python'})
306 345
307 # Exclude a path (for example, anything in a build output dir) 346 # Exclude a path (for example, anything in a build output dir)
308 c.AddRule('.*/build/', include=0) 347 c.AddRule('.*/build/', include=0)
309 # But add back in a dir which matched the above rule but isn't a build 348 # But add back in a dir which matched the above rule but isn't a build
310 # output dir 349 # output dir
311 c.AddRule('#/src/tools/build/', include=1) 350 c.AddRule('_/src/tools/build/', include=1)
312 self.assertEqual(c.ClassifyFile('#/src/build.c'), ('source', 'C')) 351 self.assertEqual(c.ClassifyFile('_/src/build.c').get('include'), 1)
313 self.assertEqual(c.ClassifyFile('#/src/build/'), (None, None)) 352 self.assertEqual(c.ClassifyFile('_/src/build/').get('include'), 0)
314 self.assertEqual(c.ClassifyFile('#/src/build/a.c'), (None, None)) 353 self.assertEqual(c.ClassifyFile('_/src/build/a.c').get('include'), 0)
315 self.assertEqual(c.ClassifyFile('#/src/tools/build/'), ('source', 'subdir')) 354 self.assertEqual(c.ClassifyFile('_/src/tools/build/').get('include'), 1)
316 self.assertEqual(c.ClassifyFile('#/src/tools/build/t.c'), ('source', 'C')) 355 self.assertEqual(c.ClassifyFile('_/src/tools/build/t.c').get('include'), 1)
317 356
318 def testGetCoveredFile(self): 357 def testGetCoveredFile(self):
319 """Test GetCoveredFile().""" 358 """Test GetCoveredFile()."""
320 c = self.cov_minimal 359 c = self.cov_minimal
321 360
322 # Not currently any covered files 361 # Not currently any covered files
323 self.assertEqual(c.GetCoveredFile('#/a.c'), None) 362 self.assertEqual(c.GetCoveredFile('_/a.c'), None)
324 363
325 # Add some files 364 # Add some files
326 a_c = c.GetCoveredFile('#/a.c', add=True) 365 a_c = c.GetCoveredFile('_/a.c', add=True)
327 b_c = c.GetCoveredFile('#/b.c##', add=True) 366 b_c = c.GetCoveredFile('_/b.c##', add=True)
328 self.assertEqual(a_c.filename, '#/a.c') 367 self.assertEqual(a_c.filename, '_/a.c')
329 self.assertEqual(a_c.group, 'my') 368 self.assertEqual(a_c.attrs, {'include': 1, 'group': 'my', 'language': 'C'})
330 self.assertEqual(a_c.language, 'C') 369 self.assertEqual(b_c.filename, '_/b.c##')
331 self.assertEqual(b_c.filename, '#/b.c##') 370 self.assertEqual(b_c.attrs,
332 self.assertEqual(b_c.group, 'my') 371 {'include': 1, 'group': 'my', 'language': 'C##'})
333 self.assertEqual(b_c.language, 'C##')
334 372
335 # Specifying the same filename should return the existing object 373 # Specifying the same filename should return the existing object
336 self.assertEqual(c.GetCoveredFile('#/a.c'), a_c) 374 self.assertEqual(c.GetCoveredFile('_/a.c'), a_c)
337 self.assertEqual(c.GetCoveredFile('#/a.c', add=True), a_c) 375 self.assertEqual(c.GetCoveredFile('_/a.c', add=True), a_c)
338 376
339 # Filenames get cleaned on the way in, as do root paths 377 # Filenames get cleaned on the way in, as do root paths
340 self.assertEqual(c.GetCoveredFile('/src/a.c'), a_c) 378 self.assertEqual(c.GetCoveredFile('/src/a.c'), a_c)
341 self.assertEqual(c.GetCoveredFile('c:\\source\\a.c'), a_c) 379 self.assertEqual(c.GetCoveredFile('c:\\source\\a.c'), a_c)
342 380
381 # TODO: Make sure that covered files require language, group, and include
382 # (since that checking is now done in GetCoveredFile() rather than
383 # ClassifyFile())
384
385 def testRemoveCoveredFile(self):
386 """Test RemoveCoveredFile()."""
387 # TODO: TEST ME!
388
343 def testParseLcov(self): 389 def testParseLcov(self):
344 """Test ParseLcovData().""" 390 """Test ParseLcovData()."""
345 c = self.cov_minimal 391 c = self.cov_minimal
346 392
347 c.ParseLcovData([ 393 c.ParseLcovData([
348 '# Ignore unknown lines', 394 '# Ignore unknown lines',
349 # File we should include' 395 # File we should include'
350 'SF:/src/a.c', 396 'SF:/src/a.c',
351 'DA:10,1', 397 'DA:10,1',
352 'DA:11,0', 398 'DA:11,0',
353 'DA:12,1 \n', # Trailing whitespace should get stripped 399 'DA:12,1 \n', # Trailing whitespace should get stripped
354 'end_of_record', 400 'end_of_record',
355 # File we should ignore 401 # File we should ignore
356 'SF:/not_src/a.c', 402 'SF:/not_src/a.c',
357 'DA:20,1', 403 'DA:20,1',
358 'end_of_record', 404 'end_of_record',
359 # Same as first source file, but alternate root 405 # Same as first source file, but alternate root
360 'SF:c:\\source\\a.c', 406 'SF:c:\\source\\a.c',
361 'DA:30,1', 407 'DA:30,1',
362 'end_of_record', 408 'end_of_record',
363 # Ignore extra end of record 409 # Ignore extra end of record
364 'end_of_record', 410 'end_of_record',
365 # Ignore data points after end of record 411 # Ignore data points after end of record
366 'DA:40,1', 412 'DA:40,1',
367 # Instrumented but uncovered file 413 # Instrumented but uncovered file
368 'SF:/src/b.c', 414 'SF:/src/b.c',
369 'DA:50,0', 415 'DA:50,0',
370 'end_of_record', 416 'end_of_record',
417 # Empty file (instrumented but no executable lines)
418 'SF:c:\\source\\c.c',
bradn 2009/05/28 23:57:36 Does this test work on non-windows?
Randall Spangler 2009/05/29 00:02:57 Yep.
419 'end_of_record',
371 ]) 420 ])
372 421
373 # We should know about two files 422 # We should know about three files
374 self.assertEqual(sorted(c.files), ['#/a.c', '#/b.c']) 423 self.assertEqual(sorted(c.files), ['_/a.c', '_/b.c', '_/c.c'])
375 424
376 # Check expected contents 425 # Check expected contents
377 a_c = c.GetCoveredFile('#/a.c') 426 a_c = c.GetCoveredFile('_/a.c')
378 self.assertEqual(a_c.lines, {10: 1, 11: 0, 12: 1, 30: 1}) 427 self.assertEqual(a_c.lines, {10: 1, 11: 0, 12: 1, 30: 1})
379 self.assertEqual(a_c.stats, { 428 self.assertEqual(a_c.stats, {
380 'files_executable': 1, 429 'files_executable': 1,
381 'files_instrumented': 1, 430 'files_instrumented': 1,
382 'files_covered': 1, 431 'files_covered': 1,
383 'lines_instrumented': 4, 432 'lines_instrumented': 4,
384 'lines_executable': 4, 433 'lines_executable': 4,
385 'lines_covered': 3, 434 'lines_covered': 3,
386 }) 435 })
387 b_c = c.GetCoveredFile('#/b.c') 436 self.assertEqual(a_c.in_lcov, True)
437
438 b_c = c.GetCoveredFile('_/b.c')
388 self.assertEqual(b_c.lines, {50: 0}) 439 self.assertEqual(b_c.lines, {50: 0})
389 self.assertEqual(b_c.stats, { 440 self.assertEqual(b_c.stats, {
390 'files_executable': 1, 441 'files_executable': 1,
391 'files_instrumented': 1, 442 'files_instrumented': 1,
392 'lines_instrumented': 1, 443 'lines_instrumented': 1,
393 'lines_executable': 1, 444 'lines_executable': 1,
394 'lines_covered': 0, 445 'lines_covered': 0,
395 }) 446 })
447 self.assertEqual(b_c.in_lcov, True)
448
449 c_c = c.GetCoveredFile('_/c.c')
450 self.assertEqual(c_c.lines, {})
451 self.assertEqual(c_c.stats, {
452 'files_executable': 1,
453 'files_instrumented': 1,
454 'lines_instrumented': 0,
455 'lines_executable': 0,
456 'lines_covered': 0,
457 })
458 self.assertEqual(c_c.in_lcov, True)
459
460 # TODO: Test that files are marked as instrumented if they come from lcov,
461 # even if they don't have any instrumented lines. (and that in_lcov is set
462 # for those files - probably should set that via some method rather than
463 # directly...)
396 464
397 def testGetStat(self): 465 def testGetStat(self):
398 """Test GetStat() and PrintStat().""" 466 """Test GetStat() and PrintStat()."""
399 c = self.cov 467 c = self.cov
400 468
401 # Add some stats, so there's something to report 469 # Add some stats, so there's something to report
402 c.tree.stats_by_group = { 470 c.tree.stats_by_group = {
403 'all': { 471 'all': {
404 'count_a': 10, 472 'count_a': 10,
405 'count_b': 4, 473 'count_b': 4,
406 'foo': 'bar', 474 'foo': 'bar',
407 }, 475 },
408 'tests': { 476 'tests': {
409 'count_a': 2, 477 'count_a': 2,
410 'count_b': 5, 478 'count_b': 5,
411 'baz': 'bob', 479 'baz': 'bob',
412 }, 480 },
413 } 481 }
414 482
415 # Test missing stats and groups 483 # Test missing stats and groups
416 self.assertRaises(croc.CoverageStatError, c.GetStat, 'nosuch') 484 self.assertRaises(croc.CrocStatError, c.GetStat, 'nosuch')
417 self.assertRaises(croc.CoverageStatError, c.GetStat, 'baz') 485 self.assertRaises(croc.CrocStatError, c.GetStat, 'baz')
418 self.assertRaises(croc.CoverageStatError, c.GetStat, 'foo', group='tests') 486 self.assertRaises(croc.CrocStatError, c.GetStat, 'foo', group='tests')
419 self.assertRaises(croc.CoverageStatError, c.GetStat, 'foo', group='nosuch') 487 self.assertRaises(croc.CrocStatError, c.GetStat, 'foo', group='nosuch')
420 488
421 # Test returning defaults 489 # Test returning defaults
422 self.assertEqual(c.GetStat('nosuch', default=13), 13) 490 self.assertEqual(c.GetStat('nosuch', default=13), 13)
423 self.assertEqual(c.GetStat('baz', default='aaa'), 'aaa') 491 self.assertEqual(c.GetStat('baz', default='aaa'), 'aaa')
424 self.assertEqual(c.GetStat('foo', group='tests', default=0), 0) 492 self.assertEqual(c.GetStat('foo', group='tests', default=0), 0)
425 self.assertEqual(c.GetStat('foo', group='nosuch', default=''), '') 493 self.assertEqual(c.GetStat('foo', group='nosuch', default=''), '')
426 494
427 # Test getting stats 495 # Test getting stats
428 self.assertEqual(c.GetStat('count_a'), 10) 496 self.assertEqual(c.GetStat('count_a'), 10)
429 self.assertEqual(c.GetStat('count_a', group='tests'), 2) 497 self.assertEqual(c.GetStat('count_a', group='tests'), 2)
430 self.assertEqual(c.GetStat('foo', default='baz'), 'bar') 498 self.assertEqual(c.GetStat('foo', default='baz'), 'bar')
431 499
432 # Test stat math (eval) 500 # Test stat math (eval)
433 self.assertEqual(c.GetStat('count_a - count_b'), 6) 501 self.assertEqual(c.GetStat('count_a - count_b'), 6)
434 self.assertEqual(c.GetStat('100.0 * count_a / count_b', group='tests'), 502 self.assertEqual(c.GetStat('100.0 * count_a / count_b', group='tests'),
435 40.0) 503 40.0)
436 # Should catch eval errors 504 # Should catch eval errors
437 self.assertRaises(croc.CoverageStatError, c.GetStat, '100 / 0') 505 self.assertRaises(croc.CrocStatError, c.GetStat, '100 / 0')
438 self.assertRaises(croc.CoverageStatError, c.GetStat, 'count_a -') 506 self.assertRaises(croc.CrocStatError, c.GetStat, 'count_a -')
439 507
440 # Test nested stats via S() 508 # Test nested stats via S()
441 self.assertEqual(c.GetStat('count_a - S("count_a", group="tests")'), 8) 509 self.assertEqual(c.GetStat('count_a - S("count_a", group="tests")'), 8)
442 self.assertRaises(croc.CoverageStatError, c.GetStat, 'S()') 510 self.assertRaises(croc.CrocStatError, c.GetStat, 'S()')
443 self.assertRaises(croc.CoverageStatError, c.GetStat, 'S("nosuch")') 511 self.assertRaises(croc.CrocStatError, c.GetStat, 'S("nosuch")')
444 512
445 # Test PrintStat() 513 # Test PrintStat()
446 # We won't see the first print, but at least verify it doesn't assert 514 # We won't see the first print, but at least verify it doesn't assert
447 c.PrintStat('count_a', format='(test to stdout: %s)') 515 c.PrintStat('count_a', format='(test to stdout: %s)')
448 # Send subsequent prints to a file 516 # Send subsequent prints to a file
449 f = StringIO.StringIO() 517 f = StringIO.StringIO()
450 c.PrintStat('count_b', outfile=f) 518 c.PrintStat('count_b', outfile=f)
451 # Test specifying output format 519 # Test specifying output format
452 c.PrintStat('count_a', format='Count A = %05d', outfile=f) 520 c.PrintStat('count_a', format='Count A = %05d', outfile=f)
453 # Test specifing additional keyword args 521 # Test specifing additional keyword args
(...skipping 15 matching lines...) Expand all
469 537
470 def testAddConfig(self): 538 def testAddConfig(self):
471 """Test AddConfig().""" 539 """Test AddConfig()."""
472 c = self.cov 540 c = self.cov
473 lcov_queue = [] 541 lcov_queue = []
474 addfiles_queue = [] 542 addfiles_queue = []
475 543
476 c.AddConfig("""{ 544 c.AddConfig("""{
477 'roots' : [ 545 'roots' : [
478 {'root' : '/foo'}, 546 {'root' : '/foo'},
479 {'root' : '/bar', 'altname' : '#BAR'}, 547 {'root' : '/bar', 'altname' : 'BAR'},
480 ], 548 ],
481 'rules' : [ 549 'rules' : [
482 {'regexp' : '^#', 'group' : 'apple'}, 550 {'regexp' : '^_/', 'group' : 'apple'},
483 {'regexp' : 're2', 'include' : 1, 'language' : 'elvish'}, 551 {'regexp' : 're2', 'include' : 1, 'language' : 'elvish'},
484 ], 552 ],
485 'lcov_files' : ['a.lcov', 'b.lcov'], 553 'lcov_files' : ['a.lcov', 'b.lcov'],
486 'add_files' : ['/src', '#BAR/doo'], 554 'add_files' : ['/src', 'BAR/doo'],
487 'print_stats' : [ 555 'print_stats' : [
488 {'stat' : 'count_a'}, 556 {'stat' : 'count_a'},
489 {'stat' : 'count_b', 'group' : 'tests'}, 557 {'stat' : 'count_b', 'group' : 'tests'},
490 ], 558 ],
491 'extra_key' : 'is ignored', 559 'extra_key' : 'is ignored',
492 }""", lcov_queue=lcov_queue, addfiles_queue=addfiles_queue) 560 }""", lcov_queue=lcov_queue, addfiles_queue=addfiles_queue)
493 561
494 self.assertEqual(lcov_queue, ['a.lcov', 'b.lcov']) 562 self.assertEqual(lcov_queue, ['a.lcov', 'b.lcov'])
495 self.assertEqual(addfiles_queue, ['/src', '#BAR/doo']) 563 self.assertEqual(addfiles_queue, ['/src', 'BAR/doo'])
496 self.assertEqual(c.root_dirs, [['/foo', '#'], ['/bar', '#BAR']]) 564 self.assertEqual(c.root_dirs, [['/foo', '_'], ['/bar', 'BAR']])
497 self.assertEqual(c.print_stats, [ 565 self.assertEqual(c.print_stats, [
498 {'stat': 'count_a'}, 566 {'stat': 'count_a'},
499 {'stat': 'count_b', 'group': 'tests'}, 567 {'stat': 'count_b', 'group': 'tests'},
500 ]) 568 ])
501 # Convert compiled re's back to patterns for comparison 569 # Convert compiled re's back to patterns for comparison
502 rules = [[r[0].pattern] + r[1:] for r in c.rules] 570 rules = [[r[0].pattern] + r[1:] for r in c.rules]
503 self.assertEqual(rules, [ 571 self.assertEqual(rules, [
504 ['.*/$', None, None, 'subdir'], 572 ['^_/', {'group': 'apple'}],
505 ['^#', None, 'apple', None], 573 ['re2', {'include': 1, 'language': 'elvish'}],
506 ['re2', 1, None, 'elvish'],
507 ]) 574 ])
508 575
509 def testAddFilesSimple(self): 576 def testAddFilesSimple(self):
510 """Test AddFiles() simple call.""" 577 """Test AddFiles() simple call."""
511 c = self.cov_minimal 578 c = self.cov_minimal
512 c.add_files_walk = self.MockWalk 579 c.add_files_walk = self.MockWalk
580 c.scan_file = self.MockScanFile
581
513 c.AddFiles('/a/b/c') 582 c.AddFiles('/a/b/c')
514 self.assertEqual(self.mock_walk_calls, ['/a/b/c']) 583 self.assertEqual(self.mock_walk_calls, ['/a/b/c'])
584 self.assertEqual(self.mock_scan_calls, [])
515 self.assertEqual(c.files, {}) 585 self.assertEqual(c.files, {})
516 586
517 def testAddFilesRootMap(self): 587 def testAddFilesRootMap(self):
518 """Test AddFiles() with root mappings.""" 588 """Test AddFiles() with root mappings."""
519 c = self.cov_minimal 589 c = self.cov_minimal
520 c.add_files_walk = self.MockWalk 590 c.add_files_walk = self.MockWalk
521 c.AddRoot('#/subdir', '#SUBDIR') 591 c.scan_file = self.MockScanFile
522 592
523 # AddFiles() should replace the '#SUBDIR' alt_name, then match both 593 c.AddRoot('_/subdir', 'SUBDIR')
524 # possible roots for the '#' alt_name. 594
525 c.AddFiles('#SUBDIR/foo') 595 # AddFiles() should replace the 'SUBDIR' alt_name, then match both
596 # possible roots for the '_' alt_name.
597 c.AddFiles('SUBDIR/foo')
526 self.assertEqual(self.mock_walk_calls, 598 self.assertEqual(self.mock_walk_calls,
527 ['/src/subdir/foo', 'c:/source/subdir/foo']) 599 ['/src/subdir/foo', 'c:/source/subdir/foo'])
600 self.assertEqual(self.mock_scan_calls, [])
528 self.assertEqual(c.files, {}) 601 self.assertEqual(c.files, {})
529 602
530 def testAddFilesNonEmpty(self): 603 def testAddFilesNonEmpty(self):
531 """Test AddFiles() where files are returned.""" 604 """Test AddFiles() where files are returned."""
532 605
533 c = self.cov_minimal 606 c = self.cov_minimal
534 c.add_files_walk = self.MockWalk 607 c.add_files_walk = self.MockWalk
608 c.scan_file = self.MockScanFile
535 609
536 # Add a rule to exclude a subdir 610 # Add a rule to exclude a subdir
537 c.AddRule('^#/proj1/excluded/', include=0) 611 c.AddRule('^_/proj1/excluded/', include=0)
538 612
539 # Set data for mock walk 613 # Add a rule to exclude adding some fiels
614 c.AddRule('.*noscan.c$', add_if_missing=0)
615
616 # Set data for mock walk and scan
540 self.mock_walk_return = [ 617 self.mock_walk_return = [
541 [ 618 [
542 '/src/proj1', 619 '/src/proj1',
543 ['excluded', 'subdir'], 620 ['excluded', 'subdir'],
544 ['a.c', 'no.f', 'yes.c'], 621 ['a.c', 'no.f', 'yes.c', 'noexe.c', 'bob_noscan.c'],
545 ], 622 ],
546 [ 623 [
547 '/src/proj1/subdir', 624 '/src/proj1/subdir',
548 [], 625 [],
549 ['cherry.c'], 626 ['cherry.c'],
550 ], 627 ],
551 ] 628 ]
552 629
630 # Add a file with no executable lines; it should be scanned but not added
631 self.mock_scan_return['/src/proj1/noexe.c'] = []
632
553 c.AddFiles('/src/proj1') 633 c.AddFiles('/src/proj1')
554 634
555 self.assertEqual(self.mock_walk_calls, ['/src/proj1']) 635 self.assertEqual(self.mock_walk_calls, ['/src/proj1'])
636 self.assertEqual(self.mock_scan_calls, [
637 ['/src/proj1/a.c', 'C'],
638 ['/src/proj1/yes.c', 'C'],
639 ['/src/proj1/noexe.c', 'C'],
640 ['/src/proj1/subdir/cherry.c', 'C'],
641 ])
556 642
557 # Include files from the main dir and subdir 643 # Include files from the main dir and subdir
558 self.assertEqual(sorted(c.files), [ 644 self.assertEqual(sorted(c.files), [
559 '#/proj1/a.c', 645 '_/proj1/a.c',
560 '#/proj1/subdir/cherry.c', 646 '_/proj1/subdir/cherry.c',
561 '#/proj1/yes.c']) 647 '_/proj1/yes.c'])
562 648
563 # Excluded dir should have been pruned from the mock walk data dirnames. 649 # Excluded dir should have been pruned from the mock walk data dirnames.
564 # In the real os.walk() call this prunes the walk. 650 # In the real os.walk() call this prunes the walk.
565 self.assertEqual(self.mock_walk_return[0][1], ['subdir']) 651 self.assertEqual(self.mock_walk_return[0][1], ['subdir'])
566 652
567 def testUpdateTreeStats(self): 653 def testUpdateTreeStats(self):
568 """Test UpdateTreeStats().""" 654 """Test UpdateTreeStats()."""
569 655
570 c = self.cov_minimal 656 c = self.cov_minimal
571
572
573
574 c.AddRule('.*_test', group='test') 657 c.AddRule('.*_test', group='test')
575 658
576 # Fill the files list 659 # Fill the files list
577 c.ParseLcovData([ 660 c.ParseLcovData([
578 'SF:/src/a.c', 661 'SF:/src/a.c',
579 'DA:10,1', 'DA:11,1', 'DA:20,0', 662 'DA:10,1', 'DA:11,1', 'DA:20,0',
580 'end_of_record', 663 'end_of_record',
581 'SF:/src/a_test.c', 664 'SF:/src/a_test.c',
582 'DA:10,1', 'DA:11,1', 'DA:12,1', 665 'DA:10,1', 'DA:11,1', 'DA:12,1',
583 'end_of_record', 666 'end_of_record',
584 'SF:/src/foo/b.c', 667 'SF:/src/foo/b.c',
585 'DA:10,1', 'DA:11,1', 'DA:20,0', 'DA:21,0', 'DA:30,0', 668 'DA:10,1', 'DA:11,1', 'DA:20,0', 'DA:21,0', 'DA:30,0',
586 'end_of_record', 669 'end_of_record',
587 'SF:/src/foo/b_test.c', 670 'SF:/src/foo/b_test.c',
588 'DA:20,0', 'DA:21,0', 'DA:22,0', 671 'DA:20,0', 'DA:21,0', 'DA:22,0',
589 'end_of_record', 672 'end_of_record',
590 ]) 673 ])
591 c.UpdateTreeStats() 674 c.UpdateTreeStats()
592 675
593 t = c.tree 676 t = c.tree
594 self.assertEqual(t.dirpath, '') 677 self.assertEqual(t.dirpath, '')
595 self.assertEqual(sorted(t.files), []) 678 self.assertEqual(sorted(t.files), [])
596 self.assertEqual(sorted(t.subdirs), ['#']) 679 self.assertEqual(sorted(t.subdirs), ['_'])
597 self.assertEqual(t.stats_by_group, { 680 self.assertEqual(t.stats_by_group, {
598 'all': { 681 'all': {
599 'files_covered': 3, 682 'files_covered': 3,
600 'files_executable': 4, 683 'files_executable': 4,
601 'lines_executable': 14, 684 'lines_executable': 14,
602 'lines_covered': 7, 685 'lines_covered': 7,
603 'lines_instrumented': 14, 686 'lines_instrumented': 14,
604 'files_instrumented': 4, 687 'files_instrumented': 4,
605 }, 688 },
606 'my': { 689 'my': {
607 'files_covered': 2, 690 'files_covered': 2,
608 'files_executable': 2, 691 'files_executable': 2,
609 'lines_executable': 8, 692 'lines_executable': 8,
610 'lines_covered': 4, 693 'lines_covered': 4,
611 'lines_instrumented': 8, 694 'lines_instrumented': 8,
612 'files_instrumented': 2, 695 'files_instrumented': 2,
613 }, 696 },
614 'test': { 697 'test': {
615 'files_covered': 1, 698 'files_covered': 1,
616 'files_executable': 2, 699 'files_executable': 2,
617 'lines_executable': 6, 700 'lines_executable': 6,
618 'lines_covered': 3, 701 'lines_covered': 3,
619 'lines_instrumented': 6, 702 'lines_instrumented': 6,
620 'files_instrumented': 2, 703 'files_instrumented': 2,
621 }, 704 },
622 }) 705 })
623 706
624 t = t.subdirs['#'] 707 t = t.subdirs['_']
625 self.assertEqual(t.dirpath, '#') 708 self.assertEqual(t.dirpath, '_')
626 self.assertEqual(sorted(t.files), ['a.c', 'a_test.c']) 709 self.assertEqual(sorted(t.files), ['a.c', 'a_test.c'])
627 self.assertEqual(sorted(t.subdirs), ['foo']) 710 self.assertEqual(sorted(t.subdirs), ['foo'])
628 self.assertEqual(t.stats_by_group, { 711 self.assertEqual(t.stats_by_group, {
629 'all': { 712 'all': {
630 'files_covered': 3, 713 'files_covered': 3,
631 'files_executable': 4, 714 'files_executable': 4,
632 'lines_executable': 14, 715 'lines_executable': 14,
633 'lines_covered': 7, 716 'lines_covered': 7,
634 'lines_instrumented': 14, 717 'lines_instrumented': 14,
635 'files_instrumented': 4, 718 'files_instrumented': 4,
(...skipping 10 matching lines...) Expand all
646 'files_covered': 1, 729 'files_covered': 1,
647 'files_executable': 2, 730 'files_executable': 2,
648 'lines_executable': 6, 731 'lines_executable': 6,
649 'lines_covered': 3, 732 'lines_covered': 3,
650 'lines_instrumented': 6, 733 'lines_instrumented': 6,
651 'files_instrumented': 2, 734 'files_instrumented': 2,
652 }, 735 },
653 }) 736 })
654 737
655 t = t.subdirs['foo'] 738 t = t.subdirs['foo']
656 self.assertEqual(t.dirpath, 'foo') 739 self.assertEqual(t.dirpath, '_/foo')
657 self.assertEqual(sorted(t.files), ['b.c', 'b_test.c']) 740 self.assertEqual(sorted(t.files), ['b.c', 'b_test.c'])
658 self.assertEqual(sorted(t.subdirs), []) 741 self.assertEqual(sorted(t.subdirs), [])
659 self.assertEqual(t.stats_by_group, { 742 self.assertEqual(t.stats_by_group, {
660 'test': { 743 'test': {
661 'files_executable': 1, 744 'files_executable': 1,
662 'files_instrumented': 1, 745 'files_instrumented': 1,
663 'lines_executable': 3, 746 'lines_executable': 3,
664 'lines_instrumented': 3, 747 'lines_instrumented': 3,
665 'lines_covered': 0, 748 'lines_covered': 0,
666 }, 749 },
(...skipping 18 matching lines...) Expand all
685 # TODO: test: less important, since these are thin wrappers around other 768 # TODO: test: less important, since these are thin wrappers around other
686 # tested methods. 769 # tested methods.
687 # ParseConfig() 770 # ParseConfig()
688 # ParseLcovFile() 771 # ParseLcovFile()
689 # PrintTree() 772 # PrintTree()
690 773
691 #------------------------------------------------------------------------------ 774 #------------------------------------------------------------------------------
692 775
693 if __name__ == '__main__': 776 if __name__ == '__main__':
694 unittest.main() 777 unittest.main()
OLDNEW
« tools/code_coverage/croc_scan.py ('K') | « tools/code_coverage/croc_scan_test.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698