123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 |
- #!/usr/bin/env vpython3
- # Copyright 2015 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- # pylint: disable=protected-access
- import sys
- import unittest
- from xml.etree import ElementTree
- import emma_coverage_stats
- import mock # pylint: disable=import-error
- EMPTY_COVERAGE_STATS_DICT = {
- 'files': {},
- 'patch': {
- 'incremental': {
- 'covered': 0, 'total': 0
- }
- }
- }
- class _EmmaHtmlParserTest(unittest.TestCase):
- """Tests for _EmmaHtmlParser.
- Uses modified EMMA report HTML that contains only the subset of tags needed
- for test verification.
- """
- def setUp(self):
- self.emma_dir = 'fake/dir/'
- self.parser = emma_coverage_stats._EmmaHtmlParser(self.emma_dir)
- self.simple_html = '<TR><TD CLASS="p">Test HTML</TD></TR>'
- self.index_html = (
- '<HTML>'
- '<BODY>'
- '<TABLE CLASS="hdft" CELLSPACING="0" WIDTH="100%">'
- '</TABLE>'
- '<TABLE CELLSPACING="0" WIDTH="100%">'
- '</TABLE>'
- '<TABLE CLASS="it" CELLSPACING="0">'
- '</TABLE>'
- '<TABLE CELLSPACING="0" WIDTH="100%">'
- '<TR>'
- '<TH CLASS="f">name</TH>'
- '<TH>class, %</TH>'
- '<TH>method, %</TH>'
- '<TH>block, %</TH>'
- '<TH>line, %</TH>'
- '</TR>'
- '<TR CLASS="o">'
- '<TD><A HREF="_files/0.html"'
- '>org.chromium.chrome.browser</A></TD>'
- '<TD CLASS="h">0% (0/3)</TD>'
- '</TR>'
- '<TR>'
- '<TD><A HREF="_files/1.html"'
- '>org.chromium.chrome.browser.tabmodel</A></TD>'
- '<TD CLASS="h">0% (0/8)</TD>'
- '</TR>'
- '</TABLE>'
- '<TABLE CLASS="hdft" CELLSPACING="0" WIDTH="100%">'
- '</TABLE>'
- '</BODY>'
- '</HTML>'
- )
- self.package_1_class_list_html = (
- '<HTML>'
- '<BODY>'
- '<TABLE CLASS="hdft" CELLSPACING="0" WIDTH="100%">'
- '</TABLE>'
- '<TABLE CELLSPACING="0" WIDTH="100%">'
- '</TABLE>'
- '<TABLE CELLSPACING="0" WIDTH="100%">'
- '<TR>'
- '<TH CLASS="f">name</TH>'
- '<TH>class, %</TH>'
- '<TH>method, %</TH>'
- '<TH>block, %</TH>'
- '<TH>line, %</TH>'
- '</TR>'
- '<TR CLASS="o">'
- '<TD><A HREF="1e.html">IntentHelper.java</A></TD>'
- '<TD CLASS="h">0% (0/3)</TD>'
- '<TD CLASS="h">0% (0/9)</TD>'
- '<TD CLASS="h">0% (0/97)</TD>'
- '<TD CLASS="h">0% (0/26)</TD>'
- '</TR>'
- '</TABLE>'
- '<TABLE CLASS="hdft" CELLSPACING="0" WIDTH="100%">'
- '</TABLE>'
- '</BODY>'
- '</HTML>'
- )
- self.package_2_class_list_html = (
- '<HTML>'
- '<BODY>'
- '<TABLE CLASS="hdft" CELLSPACING="0" WIDTH="100%">'
- '</TABLE>'
- '<TABLE CELLSPACING="0" WIDTH="100%">'
- '</TABLE>'
- '<TABLE CELLSPACING="0" WIDTH="100%">'
- '<TR>'
- '<TH CLASS="f">name</TH>'
- '<TH>class, %</TH>'
- '<TH>method, %</TH>'
- '<TH>block, %</TH>'
- '<TH>line, %</TH>'
- '</TR>'
- '<TR CLASS="o">'
- '<TD><A HREF="1f.html">ContentSetting.java</A></TD>'
- '<TD CLASS="h">0% (0/1)</TD>'
- '</TR>'
- '<TR>'
- '<TD><A HREF="20.html">DevToolsServer.java</A></TD>'
- '</TR>'
- '<TR CLASS="o">'
- '<TD><A HREF="21.html">FileProviderHelper.java</A></TD>'
- '</TR>'
- '<TR>'
- '<TD><A HREF="22.html">ContextualMenuBar.java</A></TD>'
- '</TR>'
- '<TR CLASS="o">'
- '<TD><A HREF="23.html">AccessibilityUtil.java</A></TD>'
- '</TR>'
- '<TR>'
- '<TD><A HREF="24.html">NavigationPopup.java</A></TD>'
- '</TR>'
- '</TABLE>'
- '<TABLE CLASS="hdft" CELLSPACING="0" WIDTH="100%">'
- '</TABLE>'
- '</BODY>'
- '</HTML>'
- )
- self.partially_covered_tr_html = (
- '<TR CLASS="p">'
- '<TD CLASS="l" TITLE="78% line coverage (7 out of 9)">108</TD>'
- '<TD TITLE="78% line coverage (7 out of 9 instructions)">'
- 'if (index < 0 || index = mSelectors.size()) index = 0;</TD>'
- '</TR>'
- )
- self.covered_tr_html = (
- '<TR CLASS="c">'
- '<TD CLASS="l">110</TD>'
- '<TD> if (mSelectors.get(index) != null) {</TD>'
- '</TR>'
- )
- self.not_executable_tr_html = (
- '<TR>'
- '<TD CLASS="l">109</TD>'
- '<TD> </TD>'
- '</TR>'
- )
- self.tr_with_extra_a_tag = (
- '<TR CLASS="z">'
- '<TD CLASS="l">'
- '<A name="1f">54</A>'
- '</TD>'
- '<TD> }</TD>'
- '</TR>'
- )
- def testInit(self):
- emma_dir = self.emma_dir
- parser = emma_coverage_stats._EmmaHtmlParser(emma_dir)
- self.assertEqual(parser._base_dir, emma_dir)
- self.assertEqual(parser._emma_files_path, 'fake/dir/_files')
- self.assertEqual(parser._index_path, 'fake/dir/index.html')
- def testFindElements_basic(self):
- read_values = [self.simple_html]
- found, _ = MockOpenForFunction(self.parser._FindElements, read_values,
- file_path='fake', xpath_selector='.//TD')
- self.assertIs(type(found), list)
- self.assertIs(type(found[0]), ElementTree.Element)
- self.assertEqual(found[0].text, 'Test HTML')
- def testFindElements_multipleElements(self):
- multiple_trs = self.not_executable_tr_html + self.covered_tr_html
- read_values = ['<div>' + multiple_trs + '</div>']
- found, _ = MockOpenForFunction(self.parser._FindElements, read_values,
- file_path='fake', xpath_selector='.//TR')
- self.assertEqual(2, len(found))
- def testFindElements_noMatch(self):
- read_values = [self.simple_html]
- found, _ = MockOpenForFunction(self.parser._FindElements, read_values,
- file_path='fake', xpath_selector='.//TR')
- self.assertEqual(found, [])
- def testFindElements_badFilePath(self):
- with self.assertRaises(IOError):
- with mock.patch('os.path.exists', return_value=False):
- self.parser._FindElements('fake', xpath_selector='//tr')
- def testGetPackageNameToEmmaFileDict_basic(self):
- if sys.version_info.major < 3:
- expected_dict = {
- 'org.chromium.chrome.browser.AccessibilityUtil.java':
- 'fake/dir/_files/23.html',
- 'org.chromium.chrome.browser.ContextualMenuBar.java':
- 'fake/dir/_files/22.html',
- 'org.chromium.chrome.browser.tabmodel.IntentHelper.java':
- 'fake/dir/_files/1e.html',
- 'org.chromium.chrome.browser.ContentSetting.java':
- 'fake/dir/_files/1f.html',
- 'org.chromium.chrome.browser.DevToolsServer.java':
- 'fake/dir/_files/20.html',
- 'org.chromium.chrome.browser.NavigationPopup.java':
- 'fake/dir/_files/24.html',
- 'org.chromium.chrome.browser.FileProviderHelper.java':
- 'fake/dir/_files/21.html'
- }
- else:
- expected_dict = {
- 'org.chromium.chrome.browser.IntentHelper.java':
- 'fake/dir/_files/1e.html',
- 'org.chromium.chrome.browser.tabmodel.AccessibilityUtil.java':
- 'fake/dir/_files/23.html',
- 'org.chromium.chrome.browser.tabmodel.ContextualMenuBar.java':
- 'fake/dir/_files/22.html',
- 'org.chromium.chrome.browser.tabmodel.ContentSetting.java':
- 'fake/dir/_files/1f.html',
- 'org.chromium.chrome.browser.tabmodel.DevToolsServer.java':
- 'fake/dir/_files/20.html',
- 'org.chromium.chrome.browser.tabmodel.NavigationPopup.java':
- 'fake/dir/_files/24.html',
- 'org.chromium.chrome.browser.tabmodel.FileProviderHelper.java':
- 'fake/dir/_files/21.html'
- }
- read_values = [self.index_html, self.package_1_class_list_html,
- self.package_2_class_list_html]
- return_dict, mock_open = MockOpenForFunction(
- self.parser.GetPackageNameToEmmaFileDict, read_values)
- self.assertDictEqual(return_dict, expected_dict)
- self.assertEqual(mock_open.call_count, 3)
- if sys.version_info.major < 3:
- calls = [
- mock.call('fake/dir/index.html'),
- mock.call('fake/dir/_files/1.html'),
- mock.call('fake/dir/_files/0.html')
- ]
- else:
- calls = [
- mock.call('fake/dir/index.html'),
- mock.call('fake/dir/_files/0.html'),
- mock.call('fake/dir/_files/1.html')
- ]
- mock_open.assert_has_calls(calls)
- def testGetPackageNameToEmmaFileDict_noPackageElements(self):
- self.parser._FindElements = mock.Mock(return_value=[])
- return_dict = self.parser.GetPackageNameToEmmaFileDict()
- self.assertDictEqual({}, return_dict)
- def testGetLineCoverage_status_basic(self):
- line_coverage = self.GetLineCoverageWithFakeElements([self.covered_tr_html])
- self.assertEqual(line_coverage[0].covered_status,
- emma_coverage_stats.COVERED)
- def testGetLineCoverage_status_statusMissing(self):
- line_coverage = self.GetLineCoverageWithFakeElements(
- [self.not_executable_tr_html])
- self.assertEqual(line_coverage[0].covered_status,
- emma_coverage_stats.NOT_EXECUTABLE)
- def testGetLineCoverage_fractionalCoverage_basic(self):
- line_coverage = self.GetLineCoverageWithFakeElements([self.covered_tr_html])
- self.assertEqual(line_coverage[0].fractional_line_coverage, 1.0)
- def testGetLineCoverage_fractionalCoverage_partial(self):
- line_coverage = self.GetLineCoverageWithFakeElements(
- [self.partially_covered_tr_html])
- self.assertEqual(line_coverage[0].fractional_line_coverage, 0.78)
- def testGetLineCoverage_lineno_basic(self):
- line_coverage = self.GetLineCoverageWithFakeElements([self.covered_tr_html])
- self.assertEqual(line_coverage[0].lineno, 110)
- def testGetLineCoverage_lineno_withAlternativeHtml(self):
- line_coverage = self.GetLineCoverageWithFakeElements(
- [self.tr_with_extra_a_tag])
- self.assertEqual(line_coverage[0].lineno, 54)
- def testGetLineCoverage_source(self):
- self.parser._FindElements = mock.Mock(
- return_value=[ElementTree.fromstring(self.covered_tr_html)])
- line_coverage = self.parser.GetLineCoverage('fake_path')
- self.assertEqual(line_coverage[0].source,
- ' if (mSelectors.get(index) != null) {')
- def testGetLineCoverage_multipleElements(self):
- line_coverage = self.GetLineCoverageWithFakeElements(
- [self.covered_tr_html, self.partially_covered_tr_html,
- self.tr_with_extra_a_tag])
- self.assertEqual(len(line_coverage), 3)
- def GetLineCoverageWithFakeElements(self, html_elements):
- """Wraps GetLineCoverage so mock HTML can easily be used.
- Args:
- html_elements: List of strings each representing an HTML element.
- Returns:
- A list of LineCoverage objects.
- """
- elements = [ElementTree.fromstring(string) for string in html_elements]
- with mock.patch('emma_coverage_stats._EmmaHtmlParser._FindElements',
- return_value=elements):
- return self.parser.GetLineCoverage('fake_path')
- class _EmmaCoverageStatsTest(unittest.TestCase):
- """Tests for _EmmaCoverageStats."""
- def setUp(self):
- self.good_source_to_emma = {
- '/path/to/1/File1.java': '/emma/1.html',
- '/path/2/File2.java': '/emma/2.html',
- '/path/2/File3.java': '/emma/3.html'
- }
- self.line_coverage = [
- emma_coverage_stats.LineCoverage(
- 1, '', emma_coverage_stats.COVERED, 1.0),
- emma_coverage_stats.LineCoverage(
- 2, '', emma_coverage_stats.COVERED, 1.0),
- emma_coverage_stats.LineCoverage(
- 3, '', emma_coverage_stats.NOT_EXECUTABLE, 1.0),
- emma_coverage_stats.LineCoverage(
- 4, '', emma_coverage_stats.NOT_COVERED, 1.0),
- emma_coverage_stats.LineCoverage(
- 5, '', emma_coverage_stats.PARTIALLY_COVERED, 0.85),
- emma_coverage_stats.LineCoverage(
- 6, '', emma_coverage_stats.PARTIALLY_COVERED, 0.20)
- ]
- self.lines_for_coverage = [1, 3, 5, 6]
- with mock.patch('emma_coverage_stats._EmmaHtmlParser._FindElements',
- return_value=[]):
- self.simple_coverage = emma_coverage_stats._EmmaCoverageStats(
- 'fake_dir', {})
- def testInit(self):
- coverage_stats = self.simple_coverage
- self.assertIsInstance(coverage_stats._emma_parser,
- emma_coverage_stats._EmmaHtmlParser)
- self.assertIsInstance(coverage_stats._source_to_emma, dict)
- def testNeedsCoverage_withExistingJavaFile(self):
- test_file = '/path/to/file/File.java'
- with mock.patch('os.path.exists', return_value=True):
- self.assertTrue(
- emma_coverage_stats._EmmaCoverageStats.NeedsCoverage(test_file))
- def testNeedsCoverage_withNonJavaFile(self):
- test_file = '/path/to/file/File.c'
- with mock.patch('os.path.exists', return_value=True):
- self.assertFalse(
- emma_coverage_stats._EmmaCoverageStats.NeedsCoverage(test_file))
- def testNeedsCoverage_fileDoesNotExist(self):
- test_file = '/path/to/file/File.java'
- with mock.patch('os.path.exists', return_value=False):
- self.assertFalse(
- emma_coverage_stats._EmmaCoverageStats.NeedsCoverage(test_file))
- def testGetPackageNameFromFile_basic(self):
- test_file_text = """// Test Copyright
- package org.chromium.chrome.browser;
- import android.graphics.RectF;"""
- result_package, _ = MockOpenForFunction(
- emma_coverage_stats._EmmaCoverageStats.GetPackageNameFromFile,
- [test_file_text], file_path='/path/to/file/File.java')
- self.assertEqual(result_package, 'org.chromium.chrome.browser.File.java')
- def testGetPackageNameFromFile_noPackageStatement(self):
- result_package, _ = MockOpenForFunction(
- emma_coverage_stats._EmmaCoverageStats.GetPackageNameFromFile,
- ['not a package statement'], file_path='/path/to/file/File.java')
- self.assertIsNone(result_package)
- def testGetSummaryStatsForLines_basic(self):
- covered, total = self.simple_coverage.GetSummaryStatsForLines(
- self.line_coverage)
- self.assertEqual(covered, 3.05)
- self.assertEqual(total, 5)
- def testGetSourceFileToEmmaFileDict(self):
- package_names = {
- '/path/to/1/File1.java': 'org.fake.one.File1.java',
- '/path/2/File2.java': 'org.fake.File2.java',
- '/path/2/File3.java': 'org.fake.File3.java'
- }
- package_to_emma = {
- 'org.fake.one.File1.java': '/emma/1.html',
- 'org.fake.File2.java': '/emma/2.html',
- 'org.fake.File3.java': '/emma/3.html'
- }
- with mock.patch('os.path.exists', return_value=True):
- coverage_stats = self.simple_coverage
- coverage_stats._emma_parser.GetPackageNameToEmmaFileDict = mock.MagicMock(
- return_value=package_to_emma)
- coverage_stats.GetPackageNameFromFile = lambda x: package_names[x]
- result_dict = coverage_stats._GetSourceFileToEmmaFileDict(
- list(package_names.keys()))
- self.assertDictEqual(result_dict, self.good_source_to_emma)
- def testGetCoverageDictForFile(self):
- line_coverage = self.line_coverage
- self.simple_coverage._emma_parser.GetLineCoverage = lambda x: line_coverage
- self.simple_coverage._source_to_emma = {'/fake/src': 'fake/emma'}
- lines = self.lines_for_coverage
- expected_dict = {
- 'absolute': {
- 'covered': 3.05,
- 'total': 5
- },
- 'incremental': {
- 'covered': 2.05,
- 'total': 3
- },
- 'source': [
- {
- 'line': line_coverage[0].source,
- 'coverage': line_coverage[0].covered_status,
- 'changed': True,
- 'fractional_coverage': line_coverage[0].fractional_line_coverage,
- },
- {
- 'line': line_coverage[1].source,
- 'coverage': line_coverage[1].covered_status,
- 'changed': False,
- 'fractional_coverage': line_coverage[1].fractional_line_coverage,
- },
- {
- 'line': line_coverage[2].source,
- 'coverage': line_coverage[2].covered_status,
- 'changed': True,
- 'fractional_coverage': line_coverage[2].fractional_line_coverage,
- },
- {
- 'line': line_coverage[3].source,
- 'coverage': line_coverage[3].covered_status,
- 'changed': False,
- 'fractional_coverage': line_coverage[3].fractional_line_coverage,
- },
- {
- 'line': line_coverage[4].source,
- 'coverage': line_coverage[4].covered_status,
- 'changed': True,
- 'fractional_coverage': line_coverage[4].fractional_line_coverage,
- },
- {
- 'line': line_coverage[5].source,
- 'coverage': line_coverage[5].covered_status,
- 'changed': True,
- 'fractional_coverage': line_coverage[5].fractional_line_coverage,
- }
- ]
- }
- result_dict = self.simple_coverage.GetCoverageDictForFile(
- '/fake/src', lines)
- self.assertDictEqual(result_dict, expected_dict)
- def testGetCoverageDictForFile_emptyCoverage(self):
- expected_dict = {
- 'absolute': {'covered': 0, 'total': 0},
- 'incremental': {'covered': 0, 'total': 0},
- 'source': []
- }
- self.simple_coverage._emma_parser.GetLineCoverage = lambda x: []
- self.simple_coverage._source_to_emma = {'fake_dir': 'fake/emma'}
- result_dict = self.simple_coverage.GetCoverageDictForFile('fake_dir', {})
- self.assertDictEqual(result_dict, expected_dict)
- def testGetCoverageDictForFile_missingCoverage(self):
- self.simple_coverage._source_to_emma = {}
- result_dict = self.simple_coverage.GetCoverageDictForFile('fake_file', {})
- self.assertIsNone(result_dict)
- def testGetCoverageDict_basic(self):
- files_for_coverage = {
- '/path/to/1/File1.java': [1, 3, 4],
- '/path/2/File2.java': [1, 2]
- }
- self.simple_coverage._source_to_emma = {
- '/path/to/1/File1.java': 'emma_1',
- '/path/2/File2.java': 'emma_2'
- }
- coverage_info = {
- 'emma_1': [
- emma_coverage_stats.LineCoverage(
- 1, '', emma_coverage_stats.COVERED, 1.0),
- emma_coverage_stats.LineCoverage(
- 2, '', emma_coverage_stats.PARTIALLY_COVERED, 0.5),
- emma_coverage_stats.LineCoverage(
- 3, '', emma_coverage_stats.NOT_EXECUTABLE, 1.0),
- emma_coverage_stats.LineCoverage(
- 4, '', emma_coverage_stats.COVERED, 1.0)
- ],
- 'emma_2': [
- emma_coverage_stats.LineCoverage(
- 1, '', emma_coverage_stats.NOT_COVERED, 1.0),
- emma_coverage_stats.LineCoverage(
- 2, '', emma_coverage_stats.COVERED, 1.0)
- ]
- }
- expected_dict = {
- 'files': {
- '/path/2/File2.java': {
- 'absolute': {'covered': 1, 'total': 2},
- 'incremental': {'covered': 1, 'total': 2},
- 'source': [{'changed': True, 'coverage': 0,
- 'line': '', 'fractional_coverage': 1.0},
- {'changed': True, 'coverage': 1,
- 'line': '', 'fractional_coverage': 1.0}]
- },
- '/path/to/1/File1.java': {
- 'absolute': {'covered': 2.5, 'total': 3},
- 'incremental': {'covered': 2, 'total': 2},
- 'source': [{'changed': True, 'coverage': 1,
- 'line': '', 'fractional_coverage': 1.0},
- {'changed': False, 'coverage': 2,
- 'line': '', 'fractional_coverage': 0.5},
- {'changed': True, 'coverage': -1,
- 'line': '', 'fractional_coverage': 1.0},
- {'changed': True, 'coverage': 1,
- 'line': '', 'fractional_coverage': 1.0}]
- }
- },
- 'patch': {'incremental': {'covered': 3, 'total': 4}}
- }
- # Return the relevant coverage info for each file.
- self.simple_coverage._emma_parser.GetLineCoverage = (
- lambda x: coverage_info[x])
- result_dict = self.simple_coverage.GetCoverageDict(files_for_coverage)
- self.assertDictEqual(result_dict, expected_dict)
- def testGetCoverageDict_noCoverage(self):
- result_dict = self.simple_coverage.GetCoverageDict({})
- self.assertDictEqual(result_dict, EMPTY_COVERAGE_STATS_DICT)
- class EmmaCoverageStatsGenerateCoverageReport(unittest.TestCase):
- """Tests for GenerateCoverageReport."""
- def testGenerateCoverageReport_missingJsonFile(self):
- with self.assertRaises(IOError):
- with mock.patch('os.path.exists', return_value=False):
- emma_coverage_stats.GenerateCoverageReport('', '', '')
- def testGenerateCoverageReport_invalidJsonFile(self):
- with self.assertRaises(ValueError):
- with mock.patch('os.path.exists', return_value=True):
- MockOpenForFunction(emma_coverage_stats.GenerateCoverageReport, [''],
- line_coverage_file='', out_file_path='',
- coverage_dir='')
- def MockOpenForFunction(func, side_effects, **kwargs):
- """Allows easy mock open and read for callables that open multiple files.
- Will mock the python open function in a way such that each time read() is
- called on an open file, the next element in |side_effects| is returned. This
- makes it easier to test functions that call open() multiple times.
- Args:
- func: The callable to invoke once mock files are setup.
- side_effects: A list of return values for each file to return once read.
- Length of list should be equal to the number calls to open in |func|.
- **kwargs: Keyword arguments to be passed to |func|.
- Returns:
- A tuple containing the return value of |func| and the MagicMock object used
- to mock all calls to open respectively.
- """
- mock_open = mock.mock_open()
- mock_open.side_effect = [mock.mock_open(read_data=side_effect).return_value
- for side_effect in side_effects]
- if sys.version_info.major < 3:
- open_builtin_path = '__builtin__.open'
- else:
- open_builtin_path = 'builtins.open'
- with mock.patch(open_builtin_path, mock_open):
- return func(**kwargs), mock_open
- if __name__ == '__main__':
- # Suppress logging messages.
- unittest.main(buffer=True)
|