OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 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 json | |
7 import os | 6 import os |
8 import sys | 7 import sys |
9 import unittest | 8 import unittest |
10 from xml.etree import ElementTree | 9 from xml.etree import ElementTree |
11 | 10 |
12 import emma_coverage_stats | 11 import emma_coverage_stats |
13 from pylib import constants | 12 from pylib import constants |
14 | 13 |
15 sys.path.append(os.path.join( | 14 sys.path.append(os.path.join( |
16 constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) | 15 constants.DIR_SOURCE_ROOT, 'third_party', 'pymock')) |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 calls = [mock.call('fake/dir/index.html'), | 225 calls = [mock.call('fake/dir/index.html'), |
227 mock.call('fake/dir/_files/1.html'), | 226 mock.call('fake/dir/_files/1.html'), |
228 mock.call('fake/dir/_files/0.html')] | 227 mock.call('fake/dir/_files/0.html')] |
229 mock_open.assert_has_calls(calls) | 228 mock_open.assert_has_calls(calls) |
230 | 229 |
231 def testGetPackageNameToEmmaFileDict_noPackageElements(self): | 230 def testGetPackageNameToEmmaFileDict_noPackageElements(self): |
232 self.parser._FindElements = mock.Mock(return_value=[]) | 231 self.parser._FindElements = mock.Mock(return_value=[]) |
233 return_dict = self.parser.GetPackageNameToEmmaFileDict() | 232 return_dict = self.parser.GetPackageNameToEmmaFileDict() |
234 self.assertDictEqual({}, return_dict) | 233 self.assertDictEqual({}, return_dict) |
235 | 234 |
236 def testGetPackageNameToEmmaFileDict_badFilePath(self): | |
237 self.parser._FindElements = mock.Mock(return_value=[]) | |
238 return_dict = self.parser.GetPackageNameToEmmaFileDict() | |
239 self.assertEqual(return_dict, {}) | |
240 | |
241 def testGetLineCoverage_status_basic(self): | 235 def testGetLineCoverage_status_basic(self): |
242 line_coverage = self.GetLineCoverageWithFakeElements([self.covered_tr_html]) | 236 line_coverage = self.GetLineCoverageWithFakeElements([self.covered_tr_html]) |
243 self.assertEqual(line_coverage[0].covered_status, | 237 self.assertEqual(line_coverage[0].covered_status, |
244 emma_coverage_stats.COVERED) | 238 emma_coverage_stats.COVERED) |
245 | 239 |
246 def testGetLineCoverage_status_statusMissing(self): | 240 def testGetLineCoverage_status_statusMissing(self): |
247 line_coverage = self.GetLineCoverageWithFakeElements( | 241 line_coverage = self.GetLineCoverageWithFakeElements( |
248 [self.not_executable_tr_html]) | 242 [self.not_executable_tr_html]) |
249 self.assertEqual(line_coverage[0].covered_status, | 243 self.assertEqual(line_coverage[0].covered_status, |
250 emma_coverage_stats.NOT_EXECUTABLE) | 244 emma_coverage_stats.NOT_EXECUTABLE) |
(...skipping 23 matching lines...) Expand all Loading... |
274 self.assertEqual(line_coverage[0].source, | 268 self.assertEqual(line_coverage[0].source, |
275 ' if (mSelectors.get(index) != null) {') | 269 ' if (mSelectors.get(index) != null) {') |
276 | 270 |
277 def testGetLineCoverage_multipleElements(self): | 271 def testGetLineCoverage_multipleElements(self): |
278 line_coverage = self.GetLineCoverageWithFakeElements( | 272 line_coverage = self.GetLineCoverageWithFakeElements( |
279 [self.covered_tr_html, self.partially_covered_tr_html, | 273 [self.covered_tr_html, self.partially_covered_tr_html, |
280 self.tr_with_extra_a_tag]) | 274 self.tr_with_extra_a_tag]) |
281 self.assertEqual(len(line_coverage), 3) | 275 self.assertEqual(len(line_coverage), 3) |
282 | 276 |
283 def GetLineCoverageWithFakeElements(self, html_elements): | 277 def GetLineCoverageWithFakeElements(self, html_elements): |
284 """Wraps GetLineCoverage to work with extra whitespace characters. | 278 """Wraps GetLineCoverage so mock HTML can easily be used. |
285 | |
286 The test HTML strings include extra whitespace characters to make the HTML | |
287 human readable. This isn't the case with EMMA HTML files, so we need to | |
288 remove all the unnecessary whitespace. | |
289 | 279 |
290 Args: | 280 Args: |
291 html_elements: List of strings each representing an HTML element. | 281 html_elements: List of strings each representing an HTML element. |
292 | 282 |
293 Returns: | 283 Returns: |
294 A list of LineCoverage objects. | 284 A list of LineCoverage objects. |
295 """ | 285 """ |
296 elements = [ElementTree.fromstring(string) for string in html_elements] | 286 elements = [ElementTree.fromstring(string) for string in html_elements] |
297 with mock.patch('emma_coverage_stats._EmmaHtmlParser._FindElements', | 287 with mock.patch('emma_coverage_stats._EmmaHtmlParser._FindElements', |
298 return_value=elements): | 288 return_value=elements): |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 } | 376 } |
387 with mock.patch('os.path.exists', return_value=True): | 377 with mock.patch('os.path.exists', return_value=True): |
388 coverage_stats = self.simple_coverage | 378 coverage_stats = self.simple_coverage |
389 coverage_stats._emma_parser.GetPackageNameToEmmaFileDict = mock.MagicMock( | 379 coverage_stats._emma_parser.GetPackageNameToEmmaFileDict = mock.MagicMock( |
390 return_value=package_to_emma) | 380 return_value=package_to_emma) |
391 coverage_stats.GetPackageNameFromFile = lambda x: package_names[x] | 381 coverage_stats.GetPackageNameFromFile = lambda x: package_names[x] |
392 result_dict = coverage_stats._GetSourceFileToEmmaFileDict( | 382 result_dict = coverage_stats._GetSourceFileToEmmaFileDict( |
393 package_names.keys()) | 383 package_names.keys()) |
394 self.assertDictEqual(result_dict, self.good_source_to_emma) | 384 self.assertDictEqual(result_dict, self.good_source_to_emma) |
395 | 385 |
396 def testGetLineCoverageForFile_basic(self): | |
397 java_file_path = '/path/to/1/File1.java' | |
398 line_coverage = emma_coverage_stats.LineCoverage( | |
399 1, '', emma_coverage_stats.COVERED, 1.0) | |
400 expected_line_coverage = list(line_coverage) | |
401 coverage_stats = self.simple_coverage | |
402 coverage_stats._source_to_emma = self.good_source_to_emma | |
403 coverage_stats._emma_parser.GetLineCoverage = mock.MagicMock( | |
404 return_value=expected_line_coverage) | |
405 coverage_info = coverage_stats._GetLineCoverageForFile(java_file_path) | |
406 self.assertListEqual(coverage_info, expected_line_coverage) | |
407 | |
408 def testGetLineCoverageForFile_noInfo(self): | |
409 with mock.patch('os.path.exists', return_value=False): | |
410 coverage_info = self.simple_coverage._GetLineCoverageForFile('fake_path') | |
411 self.assertIsNone(coverage_info) | |
412 | |
413 def testGetCoverageDictForFile(self): | 386 def testGetCoverageDictForFile(self): |
414 line_coverage = self.line_coverage | 387 line_coverage = self.line_coverage |
415 self.simple_coverage._GetLineCoverageForFile = mock.Mock( | 388 self.simple_coverage._emma_parser.GetLineCoverage = lambda x: line_coverage |
416 return_value=line_coverage) | 389 self.simple_coverage._source_to_emma = {'/fake/src': 'fake/emma'} |
417 lines = self.lines_for_coverage | 390 lines = self.lines_for_coverage |
418 expected_dict = { | 391 expected_dict = { |
419 'absolute': { | 392 'absolute': { |
420 'covered': 3.05, | 393 'covered': 3.05, |
421 'total': 5 | 394 'total': 5 |
422 }, | 395 }, |
423 'incremental': { | 396 'incremental': { |
424 'covered': 2.05, | 397 'covered': 2.05, |
425 'total': 3 | 398 'total': 3 |
426 }, | 399 }, |
(...skipping 24 matching lines...) Expand all Loading... |
451 'changed': True | 424 'changed': True |
452 }, | 425 }, |
453 { | 426 { |
454 'line': line_coverage[5].source, | 427 'line': line_coverage[5].source, |
455 'coverage': line_coverage[5].covered_status, | 428 'coverage': line_coverage[5].covered_status, |
456 'changed': True | 429 'changed': True |
457 } | 430 } |
458 ] | 431 ] |
459 } | 432 } |
460 result_dict = self.simple_coverage.GetCoverageDictForFile( | 433 result_dict = self.simple_coverage.GetCoverageDictForFile( |
461 line_coverage, lines) | 434 '/fake/src', lines) |
462 self.assertDictEqual(result_dict, expected_dict) | 435 self.assertDictEqual(result_dict, expected_dict) |
463 | 436 |
464 def testGetCoverageDictForFile_emptyCoverage(self): | 437 def testGetCoverageDictForFile_emptyCoverage(self): |
465 expected_dict = { | 438 expected_dict = { |
466 'absolute': {'covered': 0, 'total': 0}, | 439 'absolute': {'covered': 0, 'total': 0}, |
467 'incremental': {'covered': 0, 'total': 0}, | 440 'incremental': {'covered': 0, 'total': 0}, |
468 'source': [] | 441 'source': [] |
469 } | 442 } |
470 self.simple_coverage._GetLineCoverageForFile = mock.Mock(return_value=[]) | 443 self.simple_coverage._emma_parser.GetLineCoverage = lambda x: [] |
| 444 self.simple_coverage._source_to_emma = {'fake_dir': 'fake/emma'} |
471 result_dict = self.simple_coverage.GetCoverageDictForFile('fake_dir', {}) | 445 result_dict = self.simple_coverage.GetCoverageDictForFile('fake_dir', {}) |
472 self.assertDictEqual(result_dict, expected_dict) | 446 self.assertDictEqual(result_dict, expected_dict) |
473 | 447 |
474 def testGetCoverageDictFor_basic(self): | 448 def testGetCoverageDictForFile_missingCoverage(self): |
| 449 self.simple_coverage._source_to_emma = {} |
| 450 result_dict = self.simple_coverage.GetCoverageDictForFile('fake_file', {}) |
| 451 self.assertIsNone(result_dict) |
| 452 |
| 453 def testGetCoverageDict_basic(self): |
475 files_for_coverage = { | 454 files_for_coverage = { |
476 '/path/to/1/File1.java': [1, 3, 4], | 455 '/path/to/1/File1.java': [1, 3, 4], |
477 '/path/2/File2.java': [1, 2] | 456 '/path/2/File2.java': [1, 2] |
478 } | 457 } |
| 458 self.simple_coverage._source_to_emma = { |
| 459 '/path/to/1/File1.java': 'emma_1', |
| 460 '/path/2/File2.java': 'emma_2' |
| 461 } |
479 coverage_info = { | 462 coverage_info = { |
480 '/path/to/1/File1.java': [ | 463 'emma_1': [ |
481 emma_coverage_stats.LineCoverage( | 464 emma_coverage_stats.LineCoverage( |
482 1, '', emma_coverage_stats.COVERED, 1.0), | 465 1, '', emma_coverage_stats.COVERED, 1.0), |
483 emma_coverage_stats.LineCoverage( | 466 emma_coverage_stats.LineCoverage( |
484 2, '', emma_coverage_stats.PARTIALLY_COVERED, 0.5), | 467 2, '', emma_coverage_stats.PARTIALLY_COVERED, 0.5), |
485 emma_coverage_stats.LineCoverage( | 468 emma_coverage_stats.LineCoverage( |
486 3, '', emma_coverage_stats.NOT_EXECUTABLE, 1.0), | 469 3, '', emma_coverage_stats.NOT_EXECUTABLE, 1.0), |
487 emma_coverage_stats.LineCoverage( | 470 emma_coverage_stats.LineCoverage( |
488 4, '', emma_coverage_stats.COVERED, 1.0) | 471 4, '', emma_coverage_stats.COVERED, 1.0) |
489 ], | 472 ], |
490 '/path/2/File2.java': [ | 473 'emma_2': [ |
491 emma_coverage_stats.LineCoverage( | 474 emma_coverage_stats.LineCoverage( |
492 1, '', emma_coverage_stats.NOT_COVERED, 1.0), | 475 1, '', emma_coverage_stats.NOT_COVERED, 1.0), |
493 emma_coverage_stats.LineCoverage( | 476 emma_coverage_stats.LineCoverage( |
494 2, '', emma_coverage_stats.COVERED, 1.0) | 477 2, '', emma_coverage_stats.COVERED, 1.0) |
495 ] | 478 ] |
496 } | 479 } |
497 expected_dict = { | 480 expected_dict = { |
498 'files': { | 481 'files': { |
499 '/path/2/File2.java': { | 482 '/path/2/File2.java': { |
500 'absolute': {'covered': 1, 'total': 2}, | 483 'absolute': {'covered': 1, 'total': 2}, |
501 'incremental': {'covered': 1, 'total': 2}, | 484 'incremental': {'covered': 1, 'total': 2}, |
502 'source': [{'changed': True, 'coverage': 0, 'line': ''}, | 485 'source': [{'changed': True, 'coverage': 0, 'line': ''}, |
503 {'changed': True, 'coverage': 1, 'line': ''}] | 486 {'changed': True, 'coverage': 1, 'line': ''}] |
504 }, | 487 }, |
505 '/path/to/1/File1.java': { | 488 '/path/to/1/File1.java': { |
506 'absolute': {'covered': 2.5, 'total': 3}, | 489 'absolute': {'covered': 2.5, 'total': 3}, |
507 'incremental': {'covered': 2, 'total': 2}, | 490 'incremental': {'covered': 2, 'total': 2}, |
508 'source': [{'changed': True, 'coverage': 1, 'line': ''}, | 491 'source': [{'changed': True, 'coverage': 1, 'line': ''}, |
509 {'changed': False, 'coverage': 2, 'line': ''}, | 492 {'changed': False, 'coverage': 2, 'line': ''}, |
510 {'changed': True, 'coverage': -1, 'line': ''}, | 493 {'changed': True, 'coverage': -1, 'line': ''}, |
511 {'changed': True, 'coverage': 1, 'line': ''}] | 494 {'changed': True, 'coverage': 1, 'line': ''}] |
512 } | 495 } |
513 }, | 496 }, |
514 'patch': {'incremental': {'covered': 3, 'total': 4}} | 497 'patch': {'incremental': {'covered': 3, 'total': 4}} |
515 } | 498 } |
516 # Return the relevant coverage info for each file. We aren't testing | 499 # Return the relevant coverage info for each file. We aren't testing |
517 # _GetCoverageStatusForFile here. | 500 # _GetCoverageStatusForFile here. |
518 self.simple_coverage._GetLineCoverageForFile = lambda x: coverage_info[x] | 501 self.simple_coverage._emma_parser.GetLineCoverage = ( |
519 result_dict = self.simple_coverage.GetCoverageDict( | 502 lambda x: coverage_info[x]) |
520 files_for_coverage) | 503 result_dict = self.simple_coverage.GetCoverageDict(files_for_coverage) |
521 self.assertDictEqual(result_dict, expected_dict) | 504 self.assertDictEqual(result_dict, expected_dict) |
522 | 505 |
523 def testGetCoverageDict_noCoverage(self): | 506 def testGetCoverageDict_noCoverage(self): |
524 result_dict = self.simple_coverage.GetCoverageDict({}) | 507 result_dict = self.simple_coverage.GetCoverageDict({}) |
525 self.assertDictEqual(result_dict, EMPTY_COVERAGE_STATS_DICT) | 508 self.assertDictEqual(result_dict, EMPTY_COVERAGE_STATS_DICT) |
526 | 509 |
527 | 510 |
528 class EmmaCoverageStatsGenerateCoverageReport(unittest.TestCase): | 511 class EmmaCoverageStatsGenerateCoverageReport(unittest.TestCase): |
529 """Tests for GenerateCoverageReport.""" | 512 """Tests for GenerateCoverageReport.""" |
530 | 513 |
(...skipping 30 matching lines...) Expand all Loading... |
561 mock_open = mock.mock_open() | 544 mock_open = mock.mock_open() |
562 mock_open.side_effect = [mock.mock_open(read_data=side_effect).return_value | 545 mock_open.side_effect = [mock.mock_open(read_data=side_effect).return_value |
563 for side_effect in side_effects] | 546 for side_effect in side_effects] |
564 with mock.patch('__builtin__.open', mock_open): | 547 with mock.patch('__builtin__.open', mock_open): |
565 return func(**kwargs), mock_open | 548 return func(**kwargs), mock_open |
566 | 549 |
567 | 550 |
568 if __name__ == '__main__': | 551 if __name__ == '__main__': |
569 # Suppress logging messages. | 552 # Suppress logging messages. |
570 unittest.main(buffer=True) | 553 unittest.main(buffer=True) |
OLD | NEW |