| 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 testGetCoverageDict_basic(self): |
| 475 files_for_coverage = { | 449 files_for_coverage = { |
| 476 '/path/to/1/File1.java': [1, 3, 4], | 450 '/path/to/1/File1.java': [1, 3, 4], |
| 477 '/path/2/File2.java': [1, 2] | 451 '/path/2/File2.java': [1, 2] |
| 478 } | 452 } |
| 453 self.simple_coverage._source_to_emma = { |
| 454 '/path/to/1/File1.java': 'emma_1', |
| 455 '/path/2/File2.java': 'emma_2' |
| 456 } |
| 479 coverage_info = { | 457 coverage_info = { |
| 480 '/path/to/1/File1.java': [ | 458 'emma_1': [ |
| 481 emma_coverage_stats.LineCoverage( | 459 emma_coverage_stats.LineCoverage( |
| 482 1, '', emma_coverage_stats.COVERED, 1.0), | 460 1, '', emma_coverage_stats.COVERED, 1.0), |
| 483 emma_coverage_stats.LineCoverage( | 461 emma_coverage_stats.LineCoverage( |
| 484 2, '', emma_coverage_stats.PARTIALLY_COVERED, 0.5), | 462 2, '', emma_coverage_stats.PARTIALLY_COVERED, 0.5), |
| 485 emma_coverage_stats.LineCoverage( | 463 emma_coverage_stats.LineCoverage( |
| 486 3, '', emma_coverage_stats.NOT_EXECUTABLE, 1.0), | 464 3, '', emma_coverage_stats.NOT_EXECUTABLE, 1.0), |
| 487 emma_coverage_stats.LineCoverage( | 465 emma_coverage_stats.LineCoverage( |
| 488 4, '', emma_coverage_stats.COVERED, 1.0) | 466 4, '', emma_coverage_stats.COVERED, 1.0) |
| 489 ], | 467 ], |
| 490 '/path/2/File2.java': [ | 468 'emma_2': [ |
| 491 emma_coverage_stats.LineCoverage( | 469 emma_coverage_stats.LineCoverage( |
| 492 1, '', emma_coverage_stats.NOT_COVERED, 1.0), | 470 1, '', emma_coverage_stats.NOT_COVERED, 1.0), |
| 493 emma_coverage_stats.LineCoverage( | 471 emma_coverage_stats.LineCoverage( |
| 494 2, '', emma_coverage_stats.COVERED, 1.0) | 472 2, '', emma_coverage_stats.COVERED, 1.0) |
| 495 ] | 473 ] |
| 496 } | 474 } |
| 497 expected_dict = { | 475 expected_dict = { |
| 498 'files': { | 476 'files': { |
| 499 '/path/2/File2.java': { | 477 '/path/2/File2.java': { |
| 500 'absolute': {'covered': 1, 'total': 2}, | 478 'absolute': {'covered': 1, 'total': 2}, |
| 501 'incremental': {'covered': 1, 'total': 2}, | 479 'incremental': {'covered': 1, 'total': 2}, |
| 502 'source': [{'changed': True, 'coverage': 0, 'line': ''}, | 480 'source': [{'changed': True, 'coverage': 0, 'line': ''}, |
| 503 {'changed': True, 'coverage': 1, 'line': ''}] | 481 {'changed': True, 'coverage': 1, 'line': ''}] |
| 504 }, | 482 }, |
| 505 '/path/to/1/File1.java': { | 483 '/path/to/1/File1.java': { |
| 506 'absolute': {'covered': 2.5, 'total': 3}, | 484 'absolute': {'covered': 2.5, 'total': 3}, |
| 507 'incremental': {'covered': 2, 'total': 2}, | 485 'incremental': {'covered': 2, 'total': 2}, |
| 508 'source': [{'changed': True, 'coverage': 1, 'line': ''}, | 486 'source': [{'changed': True, 'coverage': 1, 'line': ''}, |
| 509 {'changed': False, 'coverage': 2, 'line': ''}, | 487 {'changed': False, 'coverage': 2, 'line': ''}, |
| 510 {'changed': True, 'coverage': -1, 'line': ''}, | 488 {'changed': True, 'coverage': -1, 'line': ''}, |
| 511 {'changed': True, 'coverage': 1, 'line': ''}] | 489 {'changed': True, 'coverage': 1, 'line': ''}] |
| 512 } | 490 } |
| 513 }, | 491 }, |
| 514 'patch': {'incremental': {'covered': 3, 'total': 4}} | 492 'patch': {'incremental': {'covered': 3, 'total': 4}} |
| 515 } | 493 } |
| 516 # Return the relevant coverage info for each file. We aren't testing | 494 # Return the relevant coverage info for each file. We aren't testing |
| 517 # _GetCoverageStatusForFile here. | 495 # _GetCoverageStatusForFile here. |
| 518 self.simple_coverage._GetLineCoverageForFile = lambda x: coverage_info[x] | 496 self.simple_coverage._emma_parser.GetLineCoverage = ( |
| 519 result_dict = self.simple_coverage.GetCoverageDict( | 497 lambda x: coverage_info[x]) |
| 520 files_for_coverage) | 498 result_dict = self.simple_coverage.GetCoverageDict(files_for_coverage) |
| 521 self.assertDictEqual(result_dict, expected_dict) | 499 self.assertDictEqual(result_dict, expected_dict) |
| 522 | 500 |
| 523 def testGetCoverageDict_noCoverage(self): | 501 def testGetCoverageDict_noCoverage(self): |
| 524 result_dict = self.simple_coverage.GetCoverageDict({}) | 502 result_dict = self.simple_coverage.GetCoverageDict({}) |
| 525 self.assertDictEqual(result_dict, EMPTY_COVERAGE_STATS_DICT) | 503 self.assertDictEqual(result_dict, EMPTY_COVERAGE_STATS_DICT) |
| 526 | 504 |
| 527 | 505 |
| 528 class EmmaCoverageStatsGenerateCoverageReport(unittest.TestCase): | 506 class EmmaCoverageStatsGenerateCoverageReport(unittest.TestCase): |
| 529 """Tests for GenerateCoverageReport.""" | 507 """Tests for GenerateCoverageReport.""" |
| 530 | 508 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 561 mock_open = mock.mock_open() | 539 mock_open = mock.mock_open() |
| 562 mock_open.side_effect = [mock.mock_open(read_data=side_effect).return_value | 540 mock_open.side_effect = [mock.mock_open(read_data=side_effect).return_value |
| 563 for side_effect in side_effects] | 541 for side_effect in side_effects] |
| 564 with mock.patch('__builtin__.open', mock_open): | 542 with mock.patch('__builtin__.open', mock_open): |
| 565 return func(**kwargs), mock_open | 543 return func(**kwargs), mock_open |
| 566 | 544 |
| 567 | 545 |
| 568 if __name__ == '__main__': | 546 if __name__ == '__main__': |
| 569 # Suppress logging messages. | 547 # Suppress logging messages. |
| 570 unittest.main(buffer=True) | 548 unittest.main(buffer=True) |
| OLD | NEW |