diff options
-rw-r--r-- | coverage/parser.py | 17 | ||||
-rw-r--r-- | tests/test_arcs.py | 7 | ||||
-rw-r--r-- | tests/test_coverage.py | 17 | ||||
-rw-r--r-- | tests/test_summary.py | 6 |
4 files changed, 36 insertions, 11 deletions
diff --git a/coverage/parser.py b/coverage/parser.py index b0e7371f..a6a8ad65 100644 --- a/coverage/parser.py +++ b/coverage/parser.py @@ -336,7 +336,7 @@ class AstArcAnalyzer(object): self.funcdefs = funcdefs self.classdefs = classdefs - if int(os.environ.get("COVERAGE_ASTDUMP", 0)): + if int(os.environ.get("COVERAGE_ASTDUMP", 0)): # pragma: debugging # Dump the AST so that failing tests have helpful output. ast_dump(self.root_node) @@ -372,7 +372,6 @@ class AstArcAnalyzer(object): if node.elts: return self.line_for_node(node.elts[0]) else: - # TODO: test case for this branch: x = [] return node.lineno def line_Module(self, node): @@ -380,7 +379,6 @@ class AstArcAnalyzer(object): return self.line_for_node(node.body[0]) else: # Modules have no line number, they always start at 1. - # TODO: test case for empty module. return 1 def line_default(self, node): @@ -426,7 +424,6 @@ class AstArcAnalyzer(object): # tests to write: # TODO: while EXPR: # TODO: while False: - # TODO: multi-target assignment with computed targets # TODO: listcomps hidden deep in other expressions # TODO: listcomps hidden in lists: x = [[i for i in range(10)]] # TODO: nested function definitions @@ -688,11 +685,17 @@ class AstArcAnalyzer(object): def add_arcs_for_code_objects(self, root_node): for node in ast.walk(root_node): node_name = node.__class__.__name__ + # TODO: should this be broken into separate methods? if node_name == "Module": start = self.line_for_node(node) - exits = self.add_body_arcs(node.body, from_line=-1) - for xit in exits: - self.arcs.add((xit, -start)) + if node.body: + exits = self.add_body_arcs(node.body, from_line=-1) + for xit in exits: + self.arcs.add((xit, -start)) + else: + # Empty module. + self.arcs.add((-1, start)) + self.arcs.add((start, -1)) elif node_name in ["FunctionDef", "AsyncFunctionDef"]: start = self.line_for_node(node) self.block_stack.append(FunctionBlock(start=start)) diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 9af4a083..60fdea37 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -151,6 +151,13 @@ class SimpleArcTest(CoverageTest): arcz=".1 12 .2 2-2 23 3.", arcz_missing=".2 2-2", ) + def test_what_is_the_sound_of_no_lines_clapping(self): + self.check_coverage("""\ + # __init__.py + """, + arcz=".1 1.", + ) + class WithTest(CoverageTest): """Arc-measuring tests involving context managers.""" diff --git a/tests/test_coverage.py b/tests/test_coverage.py index ea7604b1..c0991b04 100644 --- a/tests/test_coverage.py +++ b/tests/test_coverage.py @@ -109,7 +109,7 @@ class BasicCoverageTest(CoverageTest): import sys if not sys.path: a = 1 - """, + """, # indented last line [1,2,3], "3") def test_multiline_initializer(self): @@ -198,6 +198,21 @@ class SimpleStatementTest(CoverageTest): """, [1,2,3], "") + def test_more_assignments(self): + self.check_coverage("""\ + x = [] + d = {} + d[ + 4 + len(x) + + 5 + ] = \\ + d[ + 8 ** 2 + ] = \\ + 9 + """, + [1, 2, 3], "") + def test_attribute_assignment(self): # Attribute assignment self.check_coverage("""\ diff --git a/tests/test_summary.py b/tests/test_summary.py index 56c0b831..9d7a6fe7 100644 --- a/tests/test_summary.py +++ b/tests/test_summary.py @@ -607,7 +607,7 @@ class SummaryTest2(CoverageTest): def test_empty_files(self): # Shows that empty files like __init__.py are listed as having zero # statements, not one statement. - cov = coverage.Coverage() + cov = coverage.Coverage(branch=True) cov.start() import usepkgs # pragma: nested # pylint: disable=import-error,unused-variable cov.stop() # pragma: nested @@ -617,8 +617,8 @@ class SummaryTest2(CoverageTest): report = repout.getvalue().replace('\\', '/') report = re.sub(r"\s+", " ", report) - self.assertIn("tests/modules/pkg1/__init__.py 2 0 100%", report) - self.assertIn("tests/modules/pkg2/__init__.py 0 0 100%", report) + self.assertIn("tests/modules/pkg1/__init__.py 2 0 0 0 100%", report) + self.assertIn("tests/modules/pkg2/__init__.py 0 0 0 0 100%", report) class ReportingReturnValueTest(CoverageTest): |