summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt7
-rw-r--r--coverage/collector.py6
-rw-r--r--coverage/data.py165
-rw-r--r--tests/test_cmdline.py4
-rw-r--r--tests/test_data.py179
-rw-r--r--tests/test_pickle2json.py4
6 files changed, 224 insertions, 141 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index b84bc8c7..16548b69 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -12,6 +12,12 @@ Latest
- 4.0b1 broke --append creating new data files. This is now fixed, closing
`issue 392`_.
+- ``py.test --cov`` can write empty data, then touch files due to ``--source``,
+ which made coverage.py mistakenly force the data file to record lines instead
+ of arcs. This would lead to a "Can't combine line data with arc data" error
+ message. This is now fixed, and changed some method names in the
+ CoverageData interface. Fixes `issue 399`_.
+
- When using ``report --skip-covered``, a message will now be included in the
report output indicating how many files were skipped, and if all files are
skipped, coverage.py won't accidentally scold you for having no data to
@@ -23,6 +29,7 @@ Latest
.. _issue 392: https://bitbucket.org/ned/coveragepy/issues/392/run-append-doesnt-create-coverage-file
.. _issue 395: https://bitbucket.org/ned/coveragepy/issues/395/rfe-read-pickled-files-as-well-for
+.. _issue 399: https://bitbucket.org/ned/coveragepy/issues/399/coverageexception-cant-combine-line-data
Version 4.0b1 --- 2 August 2015
diff --git a/coverage/collector.py b/coverage/collector.py
index 48b017ce..de111169 100644
--- a/coverage/collector.py
+++ b/coverage/collector.py
@@ -318,9 +318,9 @@ class Collector(object):
return dict((abs_file(k), v) for k, v in iitems(d))
if self.branch:
- covdata.set_arcs(abs_file_dict(self.data))
+ covdata.add_arcs(abs_file_dict(self.data))
else:
- covdata.set_lines(abs_file_dict(self.data))
- covdata.set_file_tracers(abs_file_dict(self.file_tracers))
+ covdata.add_lines(abs_file_dict(self.data))
+ covdata.add_file_tracers(abs_file_dict(self.file_tracers))
self.reset()
diff --git a/coverage/data.py b/coverage/data.py
index c09816df..89c5b36e 100644
--- a/coverage/data.py
+++ b/coverage/data.py
@@ -66,8 +66,8 @@ class CoverageData(object):
Most data files will be created by coverage.py itself, but you can use
- methods here to create data files if you like. The :meth:`set_lines`,
- :meth:`set_arcs`, and :meth:`set_file_tracers` methods add data, in ways
+ methods here to create data files if you like. The :meth:`add_lines`,
+ :meth:`add_arcs`, and :meth:`add_file_tracers` methods add data, in ways
that are convenient for coverage.py. The :meth:`add_run_info` method adds
key-value pairs to the run information.
@@ -121,14 +121,14 @@ class CoverageData(object):
#
# { 'filename1.py': [12, 47, 1001], ... }
#
- self._lines = {}
+ self._lines = None
# A map from canonical Python source file name to a dictionary with an
# entry for each pair of line numbers forming an arc:
#
# { 'filename1.py': [(12,14), (47,48), ... ], ... }
#
- self._arcs = {}
+ self._arcs = None
# A map from canonical source file name to a plugin module name:
#
@@ -139,6 +139,15 @@ class CoverageData(object):
# A list of dicts of information about the coverage.py runs.
self._runs = []
+ def __repr__(self):
+ return "<{klass} lines={lines} arcs={arcs} tracers={tracers} runs={runs}>".format(
+ klass=self.__class__.__name__,
+ lines="None" if self._lines is None else "{{{0}}}".format(len(self._lines)),
+ arcs="None" if self._arcs is None else "{{{0}}}".format(len(self._arcs)),
+ tracers="{{{0}}}".format(len(self._file_tracers)),
+ runs="[{0}]".format(len(self._runs)),
+ )
+
##
## Reading data
##
@@ -164,10 +173,10 @@ class CoverageData(object):
executed in the file. The list is in no particular order.
"""
- if self._arcs:
+ if self._arcs is not None:
if filename in self._arcs:
return [s for s, __ in self._arcs[filename] if s > 0]
- else:
+ elif self._lines is not None:
if filename in self._lines:
return self._lines[filename]
return None
@@ -189,8 +198,9 @@ class CoverageData(object):
starts at line N.
"""
- if filename in self._arcs:
- return self._arcs[filename]
+ if self._arcs is not None:
+ if filename in self._arcs:
+ return self._arcs[filename]
return None
def file_tracer(self, filename):
@@ -204,7 +214,7 @@ class CoverageData(object):
# Because the vast majority of files involve no plugin, we don't store
# them explicitly in self._file_tracers. Check the measured data
# instead to see if it was a known file with no plugin.
- if filename in (self._arcs or self._lines):
+ if filename in (self._arcs or self._lines or {}):
return self._file_tracers.get(filename, "")
return None
@@ -220,7 +230,7 @@ class CoverageData(object):
def measured_files(self):
"""A list of all files that had been measured."""
- return list(self._arcs or self._lines)
+ return list(self._arcs or self._lines or {})
def line_counts(self, fullpath=False):
"""Return a dict summarizing the line coverage data.
@@ -242,7 +252,7 @@ class CoverageData(object):
return summ
def __nonzero__(self):
- return bool(self._lines) or bool(self._arcs)
+ return bool(self._lines or self._arcs)
__bool__ = __nonzero__
@@ -254,11 +264,15 @@ class CoverageData(object):
"""
data = self._read_raw_data(file_obj)
- self._lines = data.get('lines', {})
- self._arcs = dict(
- (fname, [tuple(pair) for pair in arcs])
- for fname, arcs in iitems(data.get('arcs', {}))
- )
+ self._lines = self._arcs = None
+
+ if 'lines' in data:
+ self._lines = data['lines']
+ if 'arcs' in data:
+ self._arcs = dict(
+ (fname, [tuple(pair) for pair in arcs])
+ for fname, arcs in iitems(data['arcs'])
+ )
self._file_tracers = data.get('file_tracers', {})
self._runs = data.get('runs', [])
@@ -308,60 +322,68 @@ class CoverageData(object):
## Writing data
##
- def set_lines(self, line_data):
- """Add executed line data.
+ def add_lines(self, line_data):
+ """Add measured line data.
- `line_data` is a dictionary mapping filenames to dictionaries::
+ `line_data` is a dictionary mapping file names to dictionaries::
{ filename: { lineno: None, ... }, ...}
- Do not call this more than once, it will not update data, it only sets
- data.
-
"""
if self._debug and self._debug.should('dataop'):
- self._debug.write("Setting lines: %d files, %d lines total" % (
+ self._debug.write("Adding lines: %d files, %d lines total" % (
len(line_data), sum(len(lines) for lines in line_data.values())
))
if self._has_arcs():
raise CoverageException("Can't add lines to existing arc data")
+ if self._lines is None:
+ self._lines = {}
for filename, linenos in iitems(line_data):
+ if filename in self._lines:
+ new_linenos = set(self._lines[filename])
+ new_linenos.update(linenos)
+ linenos = new_linenos
self._lines[filename] = list(linenos)
self._validate()
- def set_arcs(self, arc_data):
+ def add_arcs(self, arc_data):
"""Add measured arc data.
- `arc_data` is { filename: { (l1,l2): None, ... }, ...}
+ `arc_data` is a dictionary mapping file names to dictionaries::
- Do not call this more than once, it will not update data, it only sets
- data.
+ { filename: { (l1,l2): None, ... }, ...}
"""
if self._debug and self._debug.should('dataop'):
- self._debug.write("Setting arcs: %d files, %d arcs total" % (
+ self._debug.write("Adding arcs: %d files, %d arcs total" % (
len(arc_data), sum(len(arcs) for arcs in arc_data.values())
))
if self._has_lines():
raise CoverageException("Can't add arcs to existing line data")
+ if self._arcs is None:
+ self._arcs = {}
for filename, arcs in iitems(arc_data):
+ if filename in self._arcs:
+ new_arcs = set(self._arcs[filename])
+ new_arcs.update(arcs)
+ arcs = new_arcs
self._arcs[filename] = list(arcs)
self._validate()
- def set_file_tracers(self, file_tracers):
+ def add_file_tracers(self, file_tracers):
"""Add per-file plugin information.
`file_tracers` is { filename: plugin_name, ... }
"""
if self._debug and self._debug.should('dataop'):
- self._debug.write("Setting file tracers: %d files" % (len(file_tracers),))
+ self._debug.write("Adding file tracers: %d files" % (len(file_tracers),))
- existing_files = self._arcs or self._lines
+ existing_files = self._arcs or self._lines or {}
for filename, plugin_name in iitems(file_tracers):
if filename not in existing_files:
raise CoverageException(
@@ -397,7 +419,15 @@ class CoverageData(object):
"""Ensure that `filename` appears in the data, empty if needed."""
if self._debug and self._debug.should('dataop'):
self._debug.write("Touching %r" % (filename,))
- (self._arcs or self._lines).setdefault(filename, [])
+ if not self._has_arcs() and not self._has_lines():
+ raise CoverageException("Can't touch files in an empty CoverageData")
+
+ if self._has_arcs():
+ where = self._arcs
+ else:
+ where = self._lines
+ where.setdefault(filename, [])
+
self._validate()
def write(self, file_obj):
@@ -406,9 +436,10 @@ class CoverageData(object):
# Create the file data.
file_data = {}
- if self._arcs:
+ if self._has_arcs():
file_data['arcs'] = self._arcs
- else:
+
+ if self._has_lines():
file_data['lines'] = self._lines
if self._file_tracers:
@@ -430,8 +461,8 @@ class CoverageData(object):
def erase(self):
"""Erase the data in this object."""
- self._lines = {}
- self._arcs = {}
+ self._lines = None
+ self._arcs = None
self._file_tracers = {}
self._runs = []
self._validate()
@@ -471,22 +502,28 @@ class CoverageData(object):
self._runs.extend(other_data._runs)
# _lines: merge dicts.
- for filename, file_lines in iitems(other_data._lines):
- filename = aliases.map(filename)
- if filename in self._lines:
- lines = set(self._lines[filename])
- lines.update(file_lines)
- file_lines = list(lines)
- self._lines[filename] = file_lines
+ if other_data._has_lines():
+ if self._lines is None:
+ self._lines = {}
+ for filename, file_lines in iitems(other_data._lines):
+ filename = aliases.map(filename)
+ if filename in self._lines:
+ lines = set(self._lines[filename])
+ lines.update(file_lines)
+ file_lines = list(lines)
+ self._lines[filename] = file_lines
# _arcs: merge dicts.
- for filename, file_arcs in iitems(other_data._arcs):
- filename = aliases.map(filename)
- if filename in self._arcs:
- arcs = set(self._arcs[filename])
- arcs.update(file_arcs)
- file_arcs = list(arcs)
- self._arcs[filename] = file_arcs
+ if other_data._has_arcs():
+ if self._arcs is None:
+ self._arcs = {}
+ for filename, file_arcs in iitems(other_data._arcs):
+ filename = aliases.map(filename)
+ if filename in self._arcs:
+ arcs = set(self._arcs[filename])
+ arcs.update(file_arcs)
+ file_arcs = list(arcs)
+ self._arcs[filename] = file_arcs
self._validate()
@@ -507,18 +544,20 @@ class CoverageData(object):
)
# _lines should be a dict of lists of ints.
- for fname, lines in iitems(self._lines):
- assert isinstance(fname, string_class), "Key in _lines shouldn't be %r" % (fname,)
- assert all(isinstance(x, int) for x in lines), (
- "_lines[%r] shouldn't be %r" % (fname, lines)
- )
+ if self._has_lines():
+ for fname, lines in iitems(self._lines):
+ assert isinstance(fname, string_class), "Key in _lines shouldn't be %r" % (fname,)
+ assert all(isinstance(x, int) for x in lines), (
+ "_lines[%r] shouldn't be %r" % (fname, lines)
+ )
# _arcs should be a dict of lists of pairs of ints.
- for fname, arcs in iitems(self._arcs):
- assert isinstance(fname, string_class), "Key in _arcs shouldn't be %r" % (fname,)
- assert all(isinstance(x, int) and isinstance(y, int) for x, y in arcs), (
- "_arcs[%r] shouldn't be %r" % (fname, arcs)
- )
+ if self._has_arcs():
+ for fname, arcs in iitems(self._arcs):
+ assert isinstance(fname, string_class), "Key in _arcs shouldn't be %r" % (fname,)
+ assert all(isinstance(x, int) and isinstance(y, int) for x, y in arcs), (
+ "_arcs[%r] shouldn't be %r" % (fname, arcs)
+ )
# _file_tracers should have only non-empty strings as values.
for fname, plugin in iitems(self._file_tracers):
@@ -543,7 +582,7 @@ class CoverageData(object):
data.
"""
- if self._arcs:
+ if self._has_arcs():
hasher.update(sorted(self.arcs(filename)))
else:
hasher.update(sorted(self.lines(filename)))
@@ -555,11 +594,11 @@ class CoverageData(object):
def _has_lines(self):
"""Do we have data in self._lines?"""
- return bool(self._lines)
+ return self._lines is not None
def _has_arcs(self):
"""Do we have data in self._arcs?"""
- return bool(self._arcs)
+ return self._arcs is not None
class CoverageDataFiles(object):
diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py
index 4c54088a..919b0354 100644
--- a/tests/test_cmdline.py
+++ b/tests/test_cmdline.py
@@ -565,11 +565,11 @@ class CmdLineWithFilesTest(BaseCmdLineTest):
def test_debug_data(self):
data = CoverageData()
- data.set_lines({
+ data.add_lines({
"file1.py": dict.fromkeys(range(1, 18)),
"file2.py": dict.fromkeys(range(1, 24)),
})
- data.set_file_tracers({"file1.py": "a_plugin"})
+ data.add_file_tracers({"file1.py": "a_plugin"})
data_files = CoverageDataFiles()
data_files.write(data)
diff --git a/tests/test_data.py b/tests/test_data.py
index 9e0a04a6..653a401a 100644
--- a/tests/test_data.py
+++ b/tests/test_data.py
@@ -112,50 +112,75 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
def test_line_data_is_true(self):
covdata = CoverageData()
- covdata.set_lines(LINES_1)
+ covdata.add_lines(LINES_1)
self.assertTrue(covdata)
def test_arc_data_is_true(self):
covdata = CoverageData()
- covdata.set_arcs(ARCS_3)
+ covdata.add_arcs(ARCS_3)
self.assertTrue(covdata)
+ def test_empty_line_data_is_false(self):
+ covdata = CoverageData()
+ covdata.add_lines({})
+ self.assertFalse(covdata)
+
+ def test_empty_arc_data_is_false(self):
+ covdata = CoverageData()
+ covdata.add_arcs({})
+ self.assertFalse(covdata)
+
def test_adding_lines(self):
covdata = CoverageData()
- covdata.set_lines(LINES_1)
+ covdata.add_lines(LINES_1)
+ self.assert_lines1_data(covdata)
def test_adding_arcs(self):
covdata = CoverageData()
- covdata.set_arcs(ARCS_3)
+ covdata.add_arcs(ARCS_3)
self.assert_arcs3_data(covdata)
- def test_cant_set_arcs_with_lines(self):
+ def test_ok_to_add_lines_twice(self):
+ covdata = CoverageData()
+ covdata.add_lines(LINES_1)
+ covdata.add_lines(LINES_2)
+ self.assert_line_counts(covdata, SUMMARY_1_2)
+ self.assert_measured_files(covdata, MEASURED_FILES_1_2)
+
+ def test_ok_to_add_arcs_twice(self):
covdata = CoverageData()
- covdata.set_lines(LINES_1)
+ covdata.add_arcs(ARCS_3)
+ covdata.add_arcs(ARCS_4)
+ self.assert_line_counts(covdata, SUMMARY_3_4)
+ self.assert_measured_files(covdata, MEASURED_FILES_3_4)
+
+ def test_cant_add_arcs_with_lines(self):
+ covdata = CoverageData()
+ covdata.add_lines(LINES_1)
with self.assertRaisesRegex(CoverageException, "Can't add arcs to existing line data"):
- covdata.set_arcs(ARCS_3)
+ covdata.add_arcs(ARCS_3)
- def test_cant_set_lines_with_arcs(self):
+ def test_cant_add_lines_with_arcs(self):
covdata = CoverageData()
- covdata.set_arcs(ARCS_3)
+ covdata.add_arcs(ARCS_3)
with self.assertRaisesRegex(CoverageException, "Can't add lines to existing arc data"):
- covdata.set_lines(LINES_1)
+ covdata.add_lines(LINES_1)
def test_touch_file_with_lines(self):
covdata = CoverageData()
- covdata.set_lines(LINES_1)
+ covdata.add_lines(LINES_1)
covdata.touch_file('zzz.py')
self.assert_measured_files(covdata, MEASURED_FILES_1 + ['zzz.py'])
def test_touch_file_with_arcs(self):
covdata = CoverageData()
- covdata.set_arcs(ARCS_3)
+ covdata.add_arcs(ARCS_3)
covdata.touch_file('zzz.py')
self.assert_measured_files(covdata, MEASURED_FILES_3 + ['zzz.py'])
def test_no_lines_vs_unmeasured_file(self):
covdata = CoverageData()
- covdata.set_lines(LINES_1)
+ covdata.add_lines(LINES_1)
covdata.touch_file('zzz.py')
self.assertEqual(covdata.lines('zzz.py'), [])
self.assertIsNone(covdata.lines('no_such_file.py'))
@@ -170,7 +195,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
def test_no_arcs_vs_unmeasured_file(self):
covdata = CoverageData()
- covdata.set_arcs(ARCS_3)
+ covdata.add_arcs(ARCS_3)
covdata.touch_file('zzz.py')
self.assertEqual(covdata.lines('zzz.py'), [])
self.assertIsNone(covdata.lines('no_such_file.py'))
@@ -179,12 +204,12 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
def test_file_tracer_name(self):
covdata = CoverageData()
- covdata.set_lines({
+ covdata.add_lines({
"p1.foo": dict.fromkeys([1, 2, 3]),
"p2.html": dict.fromkeys([10, 11, 12]),
"main.py": dict.fromkeys([20]),
})
- covdata.set_file_tracers({"p1.foo": "p1.plugin", "p2.html": "p2.plugin"})
+ covdata.add_file_tracers({"p1.foo": "p1.plugin", "p2.html": "p2.plugin"})
self.assertEqual(covdata.file_tracer("p1.foo"), "p1.plugin")
self.assertEqual(covdata.file_tracer("main.py"), "")
self.assertIsNone(covdata.file_tracer("p3.not_here"))
@@ -193,27 +218,27 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
covdata = CoverageData()
msg = "Can't add file tracer data for unmeasured file 'p1.foo'"
with self.assertRaisesRegex(CoverageException, msg):
- covdata.set_file_tracers({"p1.foo": "p1.plugin"})
+ covdata.add_file_tracers({"p1.foo": "p1.plugin"})
- covdata.set_lines({"p2.html": dict.fromkeys([10, 11, 12])})
+ covdata.add_lines({"p2.html": dict.fromkeys([10, 11, 12])})
with self.assertRaisesRegex(CoverageException, msg):
- covdata.set_file_tracers({"p1.foo": "p1.plugin"})
+ covdata.add_file_tracers({"p1.foo": "p1.plugin"})
def test_cant_change_file_tracer_name(self):
covdata = CoverageData()
- covdata.set_lines({"p1.foo": dict.fromkeys([1, 2, 3])})
- covdata.set_file_tracers({"p1.foo": "p1.plugin"})
+ covdata.add_lines({"p1.foo": dict.fromkeys([1, 2, 3])})
+ covdata.add_file_tracers({"p1.foo": "p1.plugin"})
msg = "Conflicting file tracer name for 'p1.foo': 'p1.plugin' vs 'p1.plugin.foo'"
with self.assertRaisesRegex(CoverageException, msg):
- covdata.set_file_tracers({"p1.foo": "p1.plugin.foo"})
+ covdata.add_file_tracers({"p1.foo": "p1.plugin.foo"})
def test_update_lines(self):
covdata1 = CoverageData()
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
covdata2 = CoverageData()
- covdata2.set_lines(LINES_2)
+ covdata2.add_lines(LINES_2)
covdata3 = CoverageData()
covdata3.update(covdata1)
@@ -225,10 +250,10 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
def test_update_arcs(self):
covdata1 = CoverageData()
- covdata1.set_arcs(ARCS_3)
+ covdata1.add_arcs(ARCS_3)
covdata2 = CoverageData()
- covdata2.set_arcs(ARCS_4)
+ covdata2.add_arcs(ARCS_4)
covdata3 = CoverageData()
covdata3.update(covdata1)
@@ -240,11 +265,11 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
def test_update_run_info(self):
covdata1 = CoverageData()
- covdata1.set_arcs(ARCS_3)
+ covdata1.add_arcs(ARCS_3)
covdata1.add_run_info(hello="there", count=17)
covdata2 = CoverageData()
- covdata2.set_arcs(ARCS_4)
+ covdata2.add_arcs(ARCS_4)
covdata2.add_run_info(hello="goodbye", count=23)
covdata3 = CoverageData()
@@ -258,10 +283,10 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
def test_update_cant_mix_lines_and_arcs(self):
covdata1 = CoverageData()
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
covdata2 = CoverageData()
- covdata2.set_arcs(ARCS_3)
+ covdata2.add_arcs(ARCS_3)
with self.assertRaisesRegex(CoverageException, "Can't combine arc data with line data"):
covdata1.update(covdata2)
@@ -271,24 +296,24 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
def test_update_file_tracers(self):
covdata1 = CoverageData()
- covdata1.set_lines({
+ covdata1.add_lines({
"p1.html": dict.fromkeys([1, 2, 3, 4]),
"p2.html": dict.fromkeys([5, 6, 7]),
"main.py": dict.fromkeys([10, 11, 12]),
})
- covdata1.set_file_tracers({
+ covdata1.add_file_tracers({
"p1.html": "html.plugin",
"p2.html": "html.plugin2",
})
covdata2 = CoverageData()
- covdata2.set_lines({
+ covdata2.add_lines({
"p1.html": dict.fromkeys([3, 4, 5, 6]),
"p2.html": dict.fromkeys([7, 8, 9]),
"p3.foo": dict.fromkeys([1000, 1001]),
"main.py": dict.fromkeys([10, 11, 12]),
})
- covdata2.set_file_tracers({
+ covdata2.add_file_tracers({
"p1.html": "html.plugin",
"p2.html": "html.plugin2",
"p3.foo": "foo_plugin",
@@ -304,12 +329,12 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
def test_update_conflicting_file_tracers(self):
covdata1 = CoverageData()
- covdata1.set_lines({"p1.html": dict.fromkeys([1, 2, 3])})
- covdata1.set_file_tracers({"p1.html": "html.plugin"})
+ covdata1.add_lines({"p1.html": dict.fromkeys([1, 2, 3])})
+ covdata1.add_file_tracers({"p1.html": "html.plugin"})
covdata2 = CoverageData()
- covdata2.set_lines({"p1.html": dict.fromkeys([1, 2, 3])})
- covdata2.set_file_tracers({"p1.html": "html.other_plugin"})
+ covdata2.add_lines({"p1.html": dict.fromkeys([1, 2, 3])})
+ covdata2.add_file_tracers({"p1.html": "html.other_plugin"})
msg = "Conflicting file tracer name for 'p1.html': 'html.plugin' vs 'html.other_plugin'"
with self.assertRaisesRegex(CoverageException, msg):
@@ -321,11 +346,11 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
def test_update_file_tracer_vs_no_file_tracer(self):
covdata1 = CoverageData()
- covdata1.set_lines({"p1.html": dict.fromkeys([1, 2, 3])})
- covdata1.set_file_tracers({"p1.html": "html.plugin"})
+ covdata1.add_lines({"p1.html": dict.fromkeys([1, 2, 3])})
+ covdata1.add_file_tracers({"p1.html": "html.plugin"})
covdata2 = CoverageData()
- covdata2.set_lines({"p1.html": dict.fromkeys([1, 2, 3])})
+ covdata2.add_lines({"p1.html": dict.fromkeys([1, 2, 3])})
msg = "Conflicting file tracer name for 'p1.html': 'html.plugin' vs ''"
with self.assertRaisesRegex(CoverageException, msg):
@@ -337,7 +362,7 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
def test_add_to_hash_with_lines(self):
covdata = CoverageData()
- covdata.set_lines(LINES_1)
+ covdata.add_lines(LINES_1)
hasher = mock.Mock()
covdata.add_to_hash("a.py", hasher)
self.assertEqual(hasher.method_calls, [
@@ -347,8 +372,8 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
def test_add_to_hash_with_arcs(self):
covdata = CoverageData()
- covdata.set_arcs(ARCS_3)
- covdata.set_file_tracers({"y.py": "hologram_plugin"})
+ covdata.add_arcs(ARCS_3)
+ covdata.add_file_tracers({"y.py": "hologram_plugin"})
hasher = mock.Mock()
covdata.add_to_hash("y.py", hasher)
self.assertEqual(hasher.method_calls, [
@@ -356,13 +381,25 @@ class CoverageDataTest(DataTestHelpers, CoverageTest):
mock.call.update("hologram_plugin"), # file_tracer name
])
+ def test_empty_lines_are_still_lines(self):
+ covdata = CoverageData()
+ covdata.add_lines({})
+ covdata.touch_file("abc.py")
+ self.assertFalse(covdata.has_arcs())
+
+ def test_empty_arcs_are_still_arcs(self):
+ covdata = CoverageData()
+ covdata.add_arcs({})
+ covdata.touch_file("abc.py")
+ self.assertTrue(covdata.has_arcs())
+
class CoverageDataTestInTempDir(DataTestHelpers, CoverageTest):
"""Tests of CoverageData that need a temporary directory to make files."""
def test_read_write_lines(self):
covdata1 = CoverageData()
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
covdata1.write_file("lines.dat")
covdata2 = CoverageData()
@@ -371,7 +408,7 @@ class CoverageDataTestInTempDir(DataTestHelpers, CoverageTest):
def test_read_write_arcs(self):
covdata1 = CoverageData()
- covdata1.set_arcs(ARCS_3)
+ covdata1.add_arcs(ARCS_3)
covdata1.write_file("arcs.dat")
covdata2 = CoverageData()
@@ -402,13 +439,13 @@ class CoverageDataTestInTempDir(DataTestHelpers, CoverageTest):
def test_debug_main(self):
covdata1 = CoverageData()
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
covdata1.write_file(".coverage")
debug_main([])
covdata2 = CoverageData()
- covdata2.set_arcs(ARCS_3)
- covdata2.set_file_tracers({"y.py": "magic_plugin"})
+ covdata2.add_arcs(ARCS_3)
+ covdata2.add_file_tracers({"y.py": "magic_plugin"})
covdata2.add_run_info(version="v3.14", chunks=["z", "a"])
covdata2.write_file("arcs.dat")
@@ -436,7 +473,7 @@ class CoverageDataTestInTempDir(DataTestHelpers, CoverageTest):
},
],
},
- "empty.dat": {"lines": {}},
+ "empty.dat": {},
}
pieces = re.split(r"(?m)-+ ([\w.]+) -+$", self.stdout())
for name, json_out in zip(pieces[1::2], pieces[2::2]):
@@ -470,7 +507,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
def test_writing_and_reading(self):
covdata1 = CoverageData()
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
self.data_files.write(covdata1)
covdata2 = CoverageData()
@@ -482,7 +519,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
# writing files.
debug = DebugControlString(options=["dataio"])
covdata1 = CoverageData(debug=debug)
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
self.data_files.write(covdata1)
covdata2 = CoverageData(debug=debug)
@@ -500,7 +537,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
# output.
debug = DebugControlString(options=[])
covdata1 = CoverageData(debug=debug)
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
self.data_files.write(covdata1)
covdata2 = CoverageData(debug=debug)
@@ -512,7 +549,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
def test_explicit_suffix(self):
self.assert_doesnt_exist(".coverage.SUFFIX")
covdata = CoverageData()
- covdata.set_lines(LINES_1)
+ covdata.add_lines(LINES_1)
self.data_files.write(covdata, suffix='SUFFIX')
self.assert_exists(".coverage.SUFFIX")
self.assert_doesnt_exist(".coverage")
@@ -522,7 +559,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
# suffix=True will make a randomly named data file.
covdata1 = CoverageData()
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
self.data_files.write(covdata1, suffix=True)
self.assert_doesnt_exist(".coverage")
data_files1 = glob.glob(".coverage.*")
@@ -530,7 +567,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
# Another suffix=True will choose a different name.
covdata2 = CoverageData()
- covdata2.set_lines(LINES_1)
+ covdata2.add_lines(LINES_1)
self.data_files.write(covdata2, suffix=True)
self.assert_doesnt_exist(".coverage")
data_files2 = glob.glob(".coverage.*")
@@ -544,13 +581,13 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
self.assert_doesnt_exist(".coverage.2")
covdata1 = CoverageData()
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
self.data_files.write(covdata1, suffix='1')
self.assert_exists(".coverage.1")
self.assert_doesnt_exist(".coverage.2")
covdata2 = CoverageData()
- covdata2.set_lines(LINES_2)
+ covdata2.add_lines(LINES_2)
self.data_files.write(covdata2, suffix='2')
self.assert_exists(".coverage.2")
@@ -563,7 +600,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
def test_erasing(self):
covdata1 = CoverageData()
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
self.data_files.write(covdata1)
covdata1.erase()
@@ -594,7 +631,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
def test_file_format(self):
# Write with CoverageData, then read the JSON explicitly.
covdata = CoverageData()
- covdata.set_lines(LINES_1)
+ covdata.add_lines(LINES_1)
self.data_files.write(covdata)
data = self.read_json_data_file(".coverage")
@@ -611,7 +648,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
def test_file_format_with_arcs(self):
# Write with CoverageData, then read the JSON explicitly.
covdata = CoverageData()
- covdata.set_arcs(ARCS_3)
+ covdata.add_arcs(ARCS_3)
self.data_files.write(covdata)
data = self.read_json_data_file(".coverage")
@@ -627,7 +664,7 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
def test_writing_to_other_file(self):
data_files = CoverageDataFiles(".otherfile")
covdata = CoverageData()
- covdata.set_lines(LINES_1)
+ covdata.add_lines(LINES_1)
data_files.write(covdata)
self.assert_doesnt_exist(".coverage")
self.assert_exists(".otherfile")
@@ -638,18 +675,18 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
def test_combining_with_aliases(self):
covdata1 = CoverageData()
- covdata1.set_lines({
+ covdata1.add_lines({
'/home/ned/proj/src/a.py': {1: None, 2: None},
'/home/ned/proj/src/sub/b.py': {3: None},
'/home/ned/proj/src/template.html': {10: None},
})
- covdata1.set_file_tracers({
+ covdata1.add_file_tracers({
'/home/ned/proj/src/template.html': 'html.plugin',
})
self.data_files.write(covdata1, suffix='1')
covdata2 = CoverageData()
- covdata2.set_lines({
+ covdata2.add_lines({
r'c:\ned\test\a.py': {4: None, 5: None},
r'c:\ned\test\sub\b.py': {3: None, 6: None},
})
@@ -671,18 +708,18 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
def test_combining_from_different_directories(self):
covdata1 = CoverageData()
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
os.makedirs('cov1')
covdata1.write_file('cov1/.coverage.1')
covdata2 = CoverageData()
- covdata2.set_lines(LINES_2)
+ covdata2.add_lines(LINES_2)
os.makedirs('cov2')
covdata2.write_file('cov2/.coverage.2')
# This data won't be included.
covdata_xxx = CoverageData()
- covdata_xxx.set_arcs(ARCS_3)
+ covdata_xxx.add_arcs(ARCS_3)
covdata_xxx.write_file('.coverage.xxx')
covdata3 = CoverageData()
@@ -696,18 +733,18 @@ class CoverageDataFilesTest(DataTestHelpers, CoverageTest):
def test_combining_from_files(self):
covdata1 = CoverageData()
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
os.makedirs('cov1')
covdata1.write_file('cov1/.coverage.1')
covdata2 = CoverageData()
- covdata2.set_lines(LINES_2)
+ covdata2.add_lines(LINES_2)
os.makedirs('cov2')
covdata2.write_file('cov2/.coverage.2')
# This data won't be included.
covdata_xxx = CoverageData()
- covdata_xxx.set_arcs(ARCS_3)
+ covdata_xxx.add_arcs(ARCS_3)
covdata_xxx.write_file('.coverage.xxx')
covdata_xxx.write_file('cov2/.coverage.xxx')
diff --git a/tests/test_pickle2json.py b/tests/test_pickle2json.py
index 296f3dc8..433dade6 100644
--- a/tests/test_pickle2json.py
+++ b/tests/test_pickle2json.py
@@ -33,7 +33,7 @@ class Pickle2JsonTestInTempDir(DataTestHelpers, CoverageTest):
def test_read_write_lines_pickle(self):
# Test the old pickle format.
covdata1 = CoverageData()
- covdata1.set_lines(LINES_1)
+ covdata1.add_lines(LINES_1)
self.write_pickled_file(covdata1, "lines.pkl")
pickle2json("lines.pkl", "lines.json")
@@ -45,7 +45,7 @@ class Pickle2JsonTestInTempDir(DataTestHelpers, CoverageTest):
def test_read_write_arcs_pickle(self):
# Test the old pickle format.
covdata1 = CoverageData()
- covdata1.set_arcs(ARCS_3)
+ covdata1.add_arcs(ARCS_3)
self.write_pickled_file(covdata1, "arcs.pkl")
pickle2json("arcs.pkl", "arcs.json")