From b17f27672208a07318f8aa62a1bd64b18e9961d1 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 24 Dec 2015 08:49:50 -0500 Subject: WIP: measure branches with ast instead of bytecode --HG-- branch : ast-branch --- tests/test_arcs.py | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index df303d8b..f136b755 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -3,6 +3,10 @@ """Tests for coverage.py's arc measurement.""" +import collections +from itertools import cycle, product +import re + from tests.coveragetest import CoverageTest import coverage @@ -715,6 +719,180 @@ class MiscArcTest(CoverageTest): ) +class AsyncTest(CoverageTest): + def setUp(self): + if env.PYVERSION < (3, 5): + self.skip("No point testing 3.5 syntax below 3.5") + super(AsyncTest, self).setUp() + + def test_async(self): + self.check_coverage("""\ + import asyncio + + async def compute(x, y): + print("Compute %s + %s ..." % (x, y)) + await asyncio.sleep(0.001) + return x + y + + async def print_sum(x, y): + result = await compute(x, y) + print("%s + %s = %s" % (x, y, result)) + + loop = asyncio.get_event_loop() + loop.run_until_complete(print_sum(1, 2)) + loop.close() + """, + arcz= + ".1 13 38 8C CD DE E. " + ".4 45 56 6-3 " + ".9 9A A-8", + arcz_missing="", + ) + self.assertEqual(self.stdout(), "Compute 1 + 2 ...\n1 + 2 = 3\n") + + def test_async_for(self): + self.check_coverage("""\ + import asyncio + + class AsyncIteratorWrapper: # 3 + def __init__(self, obj): # 4 + self._it = iter(obj) + + async def __aiter__(self): # 7 + return self + + async def __anext__(self): # A + try: + return next(self._it) + except StopIteration: + raise StopAsyncIteration + + async def doit(): # G + async for letter in AsyncIteratorWrapper("abc"): + print(letter) + print(".") + + loop = asyncio.get_event_loop() # L + loop.run_until_complete(doit()) + loop.close() + """, + arcz= + ".1 13 3G GL LM MN N. " # module main line + ".3 34 47 7A A-3 " # class definition + ".H HI IH HJ J-G " # doit + ".5 5-4 " # __init__ + ".8 8-7 " # __aiter__ + ".B BC C-A DE ", # __anext__ + arcz_missing="", + ) + self.assertEqual(self.stdout(), "a\nb\nc\n.\n") + + def test_async_for2(self): + self.check_coverage("""\ + async def go1(): + async for x2 in y2: + try: + async for x4 in y4: + if a5: + break + else: + x8 = 1 + except: + x10 = 1 + x11 = 1 + x12 = 1 + """, + arcz=".1 1. .2 23 2C 34 45 56 6B", + ) + + def test_async_with(self): + self.check_coverage("""\ + async def go(): + async with x: + pass + """, + arcz=".1 1. .2 23 3.", + ) + + def test_async_it(self): + self.check_coverage("""\ + async def func(): + for x in g2: + x = 3 + else: + x = 5 + """, + arcz=".1 1. .2 23 32 25 5.", + ) + self.check_coverage("""\ + async def func(): + async for x in g2: + x = 3 + else: + x = 5 + """, + arcz=".1 1. .2 23 32 25 5.", + ) + + def xxxx_async_is_same_flow(self): + SOURCE = """\ + async def func(): + for x in g2: + try: + x = g4 + finally: + x = g6 + try: + with g8 as x: + x = g9 + continue + finally: + x = g12 + for x in g13: + continue + else: + break + while g17: + x = g18 + continue + else: + x = g21 + for x in g22: + x = g23 + continue + """ + + parts = re.split(r"(for |with )", SOURCE) + nchoices = len(parts) // 2 + + def only(s): + return [s] + + def maybe_async(s): + return [s, "async "+s] + + all_all_arcs = collections.defaultdict(list) + choices = [f(x) for f, x in zip(cycle([only, maybe_async]), parts)] + for i, result in enumerate(product(*choices)): + source = "".join(result) + self.make_file("async.py", source) + cov = coverage.Coverage(branch=True) + self.start_import_stop(cov, "async") + analysis = cov._analyze("async.py") + all_all_arcs[tuple(analysis.arc_possibilities())].append((i, source)) + + import pprint + pprint.pprint(list(all_all_arcs.keys())) + for arcs, numbers in all_all_arcs.items(): + print(" ".join("{0:0{1}b}".format(x[0], nchoices) for x in numbers)) + print(" {}".format(arcs)) + for i, source in numbers: + print("-" * 80) + print(source) + + assert len(all_all_arcs) == 1 + + class ExcludeTest(CoverageTest): """Tests of exclusions to indicate known partial branches.""" -- cgit v1.2.1 From b7a35186425cfef265548afc75b527752bed0c9a Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 24 Dec 2015 19:46:00 -0500 Subject: A start on try/except/finally --HG-- branch : ast-branch --- tests/test_arcs.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index f136b755..04c0df6e 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -481,6 +481,7 @@ class ExceptionArcTest(CoverageTest): def test_break_in_finally(self): + # TODO: the name and the code don't seem to match self.check_coverage("""\ a, c, d, i = 1, 1, 1, 99 try: @@ -566,6 +567,23 @@ class ExceptionArcTest(CoverageTest): arcz=".1 12 .3 3-2 24 45 56 67 7B 89 9B BC C.", arcz_missing="67 7B", arcz_unpredicted="68") + def test_multiple_except_clauses(self): + self.check_coverage("""\ + a, b, c = 1, 1, 1 + try: + a = 3 + except ValueError: + b = 5 + except IndexError: + a = 7 + finally: + c = 9 + assert a == 3 and b == 1 and c == 9 + """, + arcz=".1 12 23 45 39 59 67 79 9A A.", arcz_missing="45 59 67 79") + # TODO: do it again, with line 3 raising a caught exception + # TODO: do it again, with line 3 raising an uncaught exception. + class YieldTest(CoverageTest): """Arc tests for generators.""" -- cgit v1.2.1 From 35c09545a39e70065ce55264f2688ac87dd6a725 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Mon, 28 Dec 2015 16:48:05 -0500 Subject: Execution flows from the end of exception handlers to the finally --HG-- branch : ast-branch --- tests/test_arcs.py | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 04c0df6e..2d90b067 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -581,8 +581,50 @@ class ExceptionArcTest(CoverageTest): assert a == 3 and b == 1 and c == 9 """, arcz=".1 12 23 45 39 59 67 79 9A A.", arcz_missing="45 59 67 79") - # TODO: do it again, with line 3 raising a caught exception - # TODO: do it again, with line 3 raising an uncaught exception. + self.check_coverage("""\ + a, b, c = 1, 1, 1 + try: + a = int("xyz") # ValueError + except ValueError: + b = 5 + except IndexError: + a = 7 + finally: + c = 9 + assert a == 1 and b == 5 and c == 9 + """, + arcz=".1 12 23 45 39 59 67 79 9A A.", arcz_missing="39 67 79", + arcz_unpredicted="34") + self.check_coverage("""\ + a, b, c = 1, 1, 1 + try: + a = [1][3] # IndexError + except ValueError: + b = 5 + except IndexError: + a = 7 + finally: + c = 9 + assert a == 7 and b == 1 and c == 9 + """, + arcz=".1 12 23 45 39 59 67 79 9A A.", arcz_missing="39 45 59", + arcz_unpredicted="34 46") + self.check_coverage("""\ + a, b, c = 1, 1, 1 + try: + try: + a = 4/0 # ZeroDivisionError + except ValueError: + b = 6 + except IndexError: + a = 8 + finally: + c = 10 + except ZeroDivisionError: + pass + assert a == 1 and b == 1 and c == 10 + """, + arcz=".1 12 23 34 4A 56 6A 78 8A AB AD BC CD D.", arcz_missing="45 56 57 78") class YieldTest(CoverageTest): -- cgit v1.2.1 From 4b33f09a3d46e5dd051d060a1926567fd418cbb7 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 31 Dec 2015 15:39:30 -0500 Subject: Exception tests pass on py3 --HG-- branch : ast-branch --- tests/test_arcs.py | 79 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 31 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 2d90b067..0407b560 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -365,44 +365,50 @@ class ExceptionArcTest(CoverageTest): b = 7 assert a == 3 and b == 7 """, - arcz=".1 12 23 34 58 67 78 8.", - arcz_missing="58", arcz_unpredicted="46") + arcz=".1 12 23 34 46 58 67 78 8.", + arcz_missing="58", + ast_differs=True, + ) def test_hidden_raise(self): self.check_coverage("""\ a, b = 1, 1 def oops(x): - if x % 2: raise Exception("odd") + if x % 2: + raise Exception("odd") try: - a = 5 + a = 6 oops(1) - a = 7 + a = 8 except: - b = 9 - assert a == 5 and b == 9 + b = 10 + assert a == 6 and b == 10 """, - arcz=".1 12 .3 3-2 24 45 56 67 7A 89 9A A.", - arcz_missing="67 7A", arcz_unpredicted="68") + arcz=".1 12 .3 34 3-2 4-2 25 56 67 78 8B 9A AB B.", + arcz_missing="3-2 78 8B", arcz_unpredicted="79", + ast_differs=True, + ) def test_except_with_type(self): self.check_coverage("""\ a, b = 1, 1 def oops(x): - if x % 2: raise ValueError("odd") + if x % 2: + raise ValueError("odd") def try_it(x): try: - a = 6 + a = 7 oops(x) - a = 8 + a = 9 except ValueError: - b = 10 + b = 11 return a - assert try_it(0) == 8 # C - assert try_it(1) == 6 # D + assert try_it(0) == 9 # C + assert try_it(1) == 7 # D """, - arcz=".1 12 .3 3-2 24 4C CD D. .5 56 67 78 8B 9A AB B-4", + arcz=".1 12 .3 34 3-2 4-2 25 5D DE E. .6 67 78 89 9C AB BC C-5", arcz_missing="", - arcz_unpredicted="79") + arcz_unpredicted="8A") def test_try_finally(self): self.check_coverage("""\ @@ -425,8 +431,8 @@ class ExceptionArcTest(CoverageTest): d = 8 assert a == 4 and c == 6 and d == 1 # 9 """, - arcz=".1 12 23 34 46 67 78 89 69 9.", - arcz_missing="67 78 89", arcz_unpredicted="") + arcz=".1 12 23 34 46 78 89 69 9.", + arcz_missing="78 89", arcz_unpredicted="") self.check_coverage("""\ a, c, d = 1, 1, 1 try: @@ -440,8 +446,8 @@ class ExceptionArcTest(CoverageTest): d = 10 # A assert a == 4 and c == 8 and d == 10 # B """, - arcz=".1 12 23 34 45 68 89 8B 9A AB B.", - arcz_missing="68 8B", arcz_unpredicted="58") + arcz=".1 12 23 34 45 58 68 89 8B 9A AB B.", + arcz_missing="68 8B", arcz_unpredicted="") def test_finally_in_loop(self): self.check_coverage("""\ @@ -459,8 +465,10 @@ class ExceptionArcTest(CoverageTest): d = 12 # C assert a == 5 and c == 10 and d == 12 # D """, - arcz=".1 12 23 34 3D 45 56 67 68 8A A3 AB BC CD D.", - arcz_missing="3D", arcz_unpredicted="7A") + arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 AB BC CD D.", + arcz_missing="3D", + ast_differs=True, + ) self.check_coverage("""\ a, c, d, i = 1, 1, 1, 99 try: @@ -476,12 +484,12 @@ class ExceptionArcTest(CoverageTest): d = 12 # C assert a == 8 and c == 10 and d == 1 # D """, - arcz=".1 12 23 34 3D 45 56 67 68 8A A3 AB BC CD D.", - arcz_missing="67 AB BC CD", arcz_unpredicted="") + arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 AB BC CD D.", + arcz_missing="67 7A AB BC CD", arcz_unpredicted="", + ) - def test_break_in_finally(self): - # TODO: the name and the code don't seem to match + def test_break_through_finally(self): self.check_coverage("""\ a, c, d, i = 1, 1, 1, 99 try: @@ -497,8 +505,12 @@ class ExceptionArcTest(CoverageTest): d = 12 # C assert a == 5 and c == 10 and d == 1 # D """, - arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 AB BC CD D.", - arcz_missing="3D AB BC CD", arcz_unpredicted="AD") + arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 AD BC CD D.", + arcz_missing="3D BC CD", arcz_unpredicted="", + ) + + # TODO: shouldn't arcz_unpredicted always be empty? + # NO: it has arcs due to exceptions. def test_finally_in_loop_bug_92(self): self.check_coverage("""\ @@ -608,7 +620,8 @@ class ExceptionArcTest(CoverageTest): assert a == 7 and b == 1 and c == 9 """, arcz=".1 12 23 45 39 59 67 79 9A A.", arcz_missing="39 45 59", - arcz_unpredicted="34 46") + arcz_unpredicted="34 46", + ) self.check_coverage("""\ a, b, c = 1, 1, 1 try: @@ -624,7 +637,11 @@ class ExceptionArcTest(CoverageTest): pass assert a == 1 and b == 1 and c == 10 """, - arcz=".1 12 23 34 4A 56 6A 78 8A AB AD BC CD D.", arcz_missing="45 56 57 78") + arcz=".1 12 23 34 4A 56 6A 78 8A AD BC CD D.", + arcz_missing="4A 56 6A 78 8A AD", + arcz_unpredicted="45 57 7A AB", + ast_differs=True, # TODO: get rid of all ast_differs + ) class YieldTest(CoverageTest): -- cgit v1.2.1 From 5a6627ce5050d331095c4b03aed8e540f3ed651f Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 31 Dec 2015 16:20:09 -0500 Subject: Make other comprehensions work on py2 and py3 --HG-- branch : ast-branch --- tests/test_arcs.py | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 0407b560..a371401f 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -260,7 +260,7 @@ class LoopArcTest(CoverageTest): if env.PY3: arcz = ".1 12 23 34 45 36 63 57 7." else: - arcz = ".1 12 23 27 34 45 36 62 57 7." + arcz = ".1 12 23 34 45 36 62 57 7." self.check_coverage("""\ a, i = 1, 0 while True: @@ -341,6 +341,41 @@ class LoopArcTest(CoverageTest): """, arcz=arcz, arcz_missing="", arcz_unpredicted="") + def test_other_comprehensions(self): + # Generator expression: + self.check_coverage("""\ + o = ((1,2), (3,4)) + o = (a for a in o) + for tup in o: + x = tup[0] + y = tup[1] + """, + arcz=".1 .2 2-2 12 23 34 45 53 3.", + arcz_missing="", arcz_unpredicted="" + ) + # Set comprehension: + self.check_coverage("""\ + o = ((1,2), (3,4)) + o = {a for a in o} + for tup in o: + x = tup[0] + y = tup[1] + """, + arcz=".1 .2 2-2 12 23 34 45 53 3.", + arcz_missing="", arcz_unpredicted="" + ) + # Dict comprehension: + self.check_coverage("""\ + o = ((1,2), (3,4)) + o = {a:1 for a in o} + for tup in o: + x = tup[0] + y = tup[1] + """, + arcz=".1 .2 2-2 12 23 34 45 53 3.", + arcz_missing="", arcz_unpredicted="" + ) + class ExceptionArcTest(CoverageTest): """Arc-measuring tests involving exception handling.""" -- cgit v1.2.1 From f5acc8c5651287022e5b7d7d98e1be9393674c47 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 31 Dec 2015 16:39:17 -0500 Subject: Support exception arcs on py2, where the ast still has separate TryExcept and TryFinally nodes --HG-- branch : ast-branch --- tests/test_arcs.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index a371401f..fd4bd109 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -562,10 +562,6 @@ class ExceptionArcTest(CoverageTest): # "except Exception as e" is crucial here. def test_bug_212(self): - # Run this test only on Py2 for now. I hope to fix it on Py3 - # eventually... - if env.PY3: - self.skip("This doesn't work on Python 3") self.check_coverage("""\ def b(exc): try: @@ -582,8 +578,8 @@ class ExceptionArcTest(CoverageTest): except: pass """, - arcz=".1 .2 1A 23 34 56 67 68 8. AB BC C. DE E.", - arcz_missing="C.", arcz_unpredicted="45 7. CD") + arcz=".1 .2 1A 23 34 45 56 67 68 7. 8. AB BC C. DE E.", + arcz_missing="C.", arcz_unpredicted="CD") def test_except_finally(self): self.check_coverage("""\ -- cgit v1.2.1 From 704fa07b52715720da0f7b2d264ea41fce7441e8 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 31 Dec 2015 18:24:36 -0500 Subject: Support classdef and some async keywords --HG-- branch : ast-branch --- tests/test_arcs.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index fd4bd109..08325f6b 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -260,7 +260,7 @@ class LoopArcTest(CoverageTest): if env.PY3: arcz = ".1 12 23 34 45 36 63 57 7." else: - arcz = ".1 12 23 34 45 36 62 57 7." + arcz = ".1 12 23 27 34 45 36 62 57 7." self.check_coverage("""\ a, i = 1, 0 while True: @@ -271,6 +271,7 @@ class LoopArcTest(CoverageTest): assert a == 4 and i == 3 """, arcz=arcz, + arcz_missing="", ) def test_for_if_else_for(self): @@ -764,7 +765,7 @@ class YieldTest(CoverageTest): def test_coroutines(self): self.check_coverage("""\ def double_inputs(): - while [1]: # avoid compiler differences + while len([1]): # avoid compiler differences x = yield x *= 2 yield x @@ -890,8 +891,9 @@ class AsyncTest(CoverageTest): ".H HI IH HJ J-G " # doit ".5 5-4 " # __init__ ".8 8-7 " # __aiter__ - ".B BC C-A DE ", # __anext__ + ".B BC C-A DE E-A ", # __anext__ arcz_missing="", + arcz_unpredicted="CD", ) self.assertEqual(self.stdout(), "a\nb\nc\n.\n") -- cgit v1.2.1 From 334f95902f91e54e60600072d7e1816670627718 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Fri, 1 Jan 2016 10:53:45 -0500 Subject: Support 'with' --HG-- branch : ast-branch --- tests/test_arcs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 08325f6b..3dc05c9c 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -912,7 +912,7 @@ class AsyncTest(CoverageTest): x11 = 1 x12 = 1 """, - arcz=".1 1. .2 23 2C 34 45 56 6B", + arcz=".1 1. .2 23 2C 34 45 48 54 56 6B 8B 9A AB B2 C.", ) def test_async_with(self): -- cgit v1.2.1 From 9edd625b8fdb09b5494471d460eba11148104e28 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Fri, 1 Jan 2016 12:18:57 -0500 Subject: All test_arcs.py tests pass on py27 and py35 --HG-- branch : ast-branch --- tests/test_arcs.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 3dc05c9c..a9533e78 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -804,7 +804,21 @@ class MiscArcTest(CoverageTest): } assert d """, - arcz=arcz) + arcz=arcz, + ) + self.check_coverage("""\ + d = \\ + { 'a': 2, + 'b': 3, + 'c': { + 'd': 5, + 'e': 6, + } + } + assert d + """, + arcz=".1 19 9-2", + ) def test_pathologically_long_code_object(self): # https://bitbucket.org/ned/coveragepy/issue/359 @@ -814,17 +828,18 @@ class MiscArcTest(CoverageTest): code = """\ data = [ """ + "".join("""\ - [{i}, {i}, {i}, {i}, {i}, {i}, {i}, {i}, {i}, {i}], + [ + {i}, {i}, {i}, {i}, {i}, {i}, {i}, {i}, {i}, {i}], """.format(i=i) for i in range(2000) ) + """\ ] - if __name__ == "__main__": - print(len(data)) + print(len(data)) """ self.check_coverage( code, - arcs=[(-1, 1), (1, 2004), (2004, -2), (2004, 2005), (2005, -2)], + arcs=[(-1, 1), (1, 4004), (4004, -3)], + arcs_missing=[], arcs_unpredicted=[], ) -- cgit v1.2.1 From d6e221c8058259460cadfe62d5ca1bb0d93822cc Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Fri, 1 Jan 2016 13:38:06 -0500 Subject: test_arcs now passes for all Python versions --HG-- branch : ast-branch --- tests/test_arcs.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index a9533e78..ea79d495 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -342,7 +342,7 @@ class LoopArcTest(CoverageTest): """, arcz=arcz, arcz_missing="", arcz_unpredicted="") - def test_other_comprehensions(self): + def test_generator_expression(self): # Generator expression: self.check_coverage("""\ o = ((1,2), (3,4)) @@ -354,6 +354,10 @@ class LoopArcTest(CoverageTest): arcz=".1 .2 2-2 12 23 34 45 53 3.", arcz_missing="", arcz_unpredicted="" ) + + def test_other_comprehensions(self): + if env.PYVERSION < (2, 7): + self.skip("Don't have set or dict comprehensions before 2.7") # Set comprehension: self.check_coverage("""\ o = ((1,2), (3,4)) -- cgit v1.2.1 From c9464bbc696d393799c0989e4ca132987cc2fbb3 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Fri, 1 Jan 2016 13:39:29 -0500 Subject: Remove temporary ast_differs --HG-- branch : ast-branch --- tests/test_arcs.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index ea79d495..a64ab89e 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -407,7 +407,6 @@ class ExceptionArcTest(CoverageTest): """, arcz=".1 12 23 34 46 58 67 78 8.", arcz_missing="58", - ast_differs=True, ) def test_hidden_raise(self): @@ -426,7 +425,6 @@ class ExceptionArcTest(CoverageTest): """, arcz=".1 12 .3 34 3-2 4-2 25 56 67 78 8B 9A AB B.", arcz_missing="3-2 78 8B", arcz_unpredicted="79", - ast_differs=True, ) def test_except_with_type(self): @@ -507,7 +505,6 @@ class ExceptionArcTest(CoverageTest): """, arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 AB BC CD D.", arcz_missing="3D", - ast_differs=True, ) self.check_coverage("""\ a, c, d, i = 1, 1, 1, 99 @@ -676,7 +673,6 @@ class ExceptionArcTest(CoverageTest): arcz=".1 12 23 34 4A 56 6A 78 8A AD BC CD D.", arcz_missing="4A 56 6A 78 8A AD", arcz_unpredicted="45 57 7A AB", - ast_differs=True, # TODO: get rid of all ast_differs ) -- cgit v1.2.1 From f1e583f91035983237d248b417b8ca9831ceac39 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Fri, 1 Jan 2016 16:10:50 -0500 Subject: check_coverage now assumes empty missing and unpredicted, and uses branch always --HG-- branch : ast-branch --- tests/test_arcs.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index a64ab89e..1f1bdd1d 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -653,7 +653,7 @@ class ExceptionArcTest(CoverageTest): assert a == 7 and b == 1 and c == 9 """, arcz=".1 12 23 45 39 59 67 79 9A A.", arcz_missing="39 45 59", - arcz_unpredicted="34 46", + arcz_unpredicted="34 46", # TODO: 46 can be predicted. ) self.check_coverage("""\ a, b, c = 1, 1, 1 @@ -672,7 +672,7 @@ class ExceptionArcTest(CoverageTest): """, arcz=".1 12 23 34 4A 56 6A 78 8A AD BC CD D.", arcz_missing="4A 56 6A 78 8A AD", - arcz_unpredicted="45 57 7A AB", + arcz_unpredicted="45 57 7A AB", # TODO: 57 7A can be predicted. ) @@ -783,6 +783,24 @@ class YieldTest(CoverageTest): arcz_unpredicted="") self.assertEqual(self.stdout(), "20\n12\n") + def test_yield_from(self): + if env.PYVERSION < (3, 3): + self.skip("Python before 3.3 doesn't have 'yield from'") + self.check_coverage("""\ + def gen(inp): + i = 2 + for n in inp: + i = 4 + yield from range(3) + i = 6 + i = 7 + + list(gen([1,2,3])) + """, + arcz=".1 19 9. .2 23 34 45 56 5. 63 37 7.", + arcz_missing="", + arcz_unpredicted="") + class MiscArcTest(CoverageTest): """Miscellaneous arc-measuring tests.""" -- cgit v1.2.1 From 6f69dc8997ba560a7d8e7b820d692d452b5d24e7 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Fri, 1 Jan 2016 16:29:01 -0500 Subject: Clean up after making arcz_missing and arcz_unpredicted default to empty. --HG-- branch : ast-branch --- tests/test_arcs.py | 80 ++++++++++++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 42 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 1f1bdd1d..a55b5d39 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -87,7 +87,8 @@ class SimpleArcTest(CoverageTest): if len([]) == 0: a = 2 assert a == 2 """, - arcz=".1 12 23 3.", arcz_missing="") + arcz=".1 12 23 3.", + ) self.check_coverage("""\ def fn(x): if x % 2: return True @@ -106,7 +107,8 @@ class SimpleArcTest(CoverageTest): b = \\ 6 """, - arcz=".1 15 5-2", arcz_missing="") + arcz=".1 15 5-2", + ) def test_if_return(self): self.check_coverage("""\ @@ -118,8 +120,8 @@ class SimpleArcTest(CoverageTest): x = if_ret(0) + if_ret(1) assert x == 8 """, - arcz=".1 16 67 7. .2 23 24 3. 45 5.", arcz_missing="" - ) + arcz=".1 16 67 7. .2 23 24 3. 45 5.", + ) def test_dont_confuse_exit_and_else(self): self.check_coverage("""\ @@ -192,7 +194,8 @@ class LoopArcTest(CoverageTest): a = i assert a == 9 """, - arcz=".1 12 21 13 3.", arcz_missing="") + arcz=".1 12 21 13 3.", + ) self.check_coverage("""\ a = -1 for i in range(0): @@ -208,7 +211,8 @@ class LoopArcTest(CoverageTest): a = i + j assert a == 4 """, - arcz=".1 12 23 32 21 14 4.", arcz_missing="") + arcz=".1 12 23 32 21 14 4.", + ) def test_break(self): self.check_coverage("""\ @@ -271,8 +275,7 @@ class LoopArcTest(CoverageTest): assert a == 4 and i == 3 """, arcz=arcz, - arcz_missing="", - ) + ) def test_for_if_else_for(self): self.check_coverage("""\ @@ -329,7 +332,8 @@ class LoopArcTest(CoverageTest): x = tup[0] y = tup[1] """, - arcz=arcz, arcz_missing="", arcz_unpredicted="") + arcz=arcz, + ) if env.PY3: arcz = ".1 12 .2 2-2 23 34 42 2." else: @@ -340,7 +344,8 @@ class LoopArcTest(CoverageTest): x = tup[0] y = tup[1] """, - arcz=arcz, arcz_missing="", arcz_unpredicted="") + arcz=arcz, + ) def test_generator_expression(self): # Generator expression: @@ -352,7 +357,6 @@ class LoopArcTest(CoverageTest): y = tup[1] """, arcz=".1 .2 2-2 12 23 34 45 53 3.", - arcz_missing="", arcz_unpredicted="" ) def test_other_comprehensions(self): @@ -367,7 +371,6 @@ class LoopArcTest(CoverageTest): y = tup[1] """, arcz=".1 .2 2-2 12 23 34 45 53 3.", - arcz_missing="", arcz_unpredicted="" ) # Dict comprehension: self.check_coverage("""\ @@ -378,7 +381,6 @@ class LoopArcTest(CoverageTest): y = tup[1] """, arcz=".1 .2 2-2 12 23 34 45 53 3.", - arcz_missing="", arcz_unpredicted="" ) @@ -445,8 +447,8 @@ class ExceptionArcTest(CoverageTest): assert try_it(1) == 7 # D """, arcz=".1 12 .3 34 3-2 4-2 25 5D DE E. .6 67 78 89 9C AB BC C-5", - arcz_missing="", - arcz_unpredicted="8A") + arcz_unpredicted="8A", + ) def test_try_finally(self): self.check_coverage("""\ @@ -457,7 +459,8 @@ class ExceptionArcTest(CoverageTest): c = 5 assert a == 3 and c == 5 """, - arcz=".1 12 23 35 56 6.", arcz_missing="") + arcz=".1 12 23 35 56 6.", + ) self.check_coverage("""\ a, c, d = 1, 1, 1 try: @@ -470,7 +473,8 @@ class ExceptionArcTest(CoverageTest): assert a == 4 and c == 6 and d == 1 # 9 """, arcz=".1 12 23 34 46 78 89 69 9.", - arcz_missing="78 89", arcz_unpredicted="") + arcz_missing="78 89", + ) self.check_coverage("""\ a, c, d = 1, 1, 1 try: @@ -485,7 +489,8 @@ class ExceptionArcTest(CoverageTest): assert a == 4 and c == 8 and d == 10 # B """, arcz=".1 12 23 34 45 58 68 89 8B 9A AB B.", - arcz_missing="68 8B", arcz_unpredicted="") + arcz_missing="68 8B", + ) def test_finally_in_loop(self): self.check_coverage("""\ @@ -522,7 +527,7 @@ class ExceptionArcTest(CoverageTest): assert a == 8 and c == 10 and d == 1 # D """, arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 AB BC CD D.", - arcz_missing="67 7A AB BC CD", arcz_unpredicted="", + arcz_missing="67 7A AB BC CD", ) @@ -543,12 +548,9 @@ class ExceptionArcTest(CoverageTest): assert a == 5 and c == 10 and d == 1 # D """, arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 AD BC CD D.", - arcz_missing="3D BC CD", arcz_unpredicted="", + arcz_missing="3D BC CD", ) - # TODO: shouldn't arcz_unpredicted always be empty? - # NO: it has arcs due to exceptions. - def test_finally_in_loop_bug_92(self): self.check_coverage("""\ for i in range(5): @@ -560,7 +562,7 @@ class ExceptionArcTest(CoverageTest): h = 7 """, arcz=".1 12 23 35 56 61 17 7.", - arcz_missing="", arcz_unpredicted="") + ) # "except Exception as e" is crucial here. def test_bug_212(self): @@ -688,8 +690,7 @@ class YieldTest(CoverageTest): list(gen([1,2,3])) """, arcz=".1 .2 23 2. 32 15 5.", - arcz_missing="", - arcz_unpredicted="") + ) def test_padded_yield_in_loop(self): self.check_coverage("""\ @@ -704,8 +705,7 @@ class YieldTest(CoverageTest): list(gen([1,2,3])) """, arcz=".1 19 9. .2 23 34 45 56 63 37 7.", - arcz_missing="", - arcz_unpredicted="") + ) def test_bug_308(self): self.check_coverage("""\ @@ -717,8 +717,7 @@ class YieldTest(CoverageTest): print(f()) """, arcz=".1 15 56 65 5. .2 23 32 2. .3 3-3", - arcz_missing="", - arcz_unpredicted="") + ) self.check_coverage("""\ def run(): @@ -730,8 +729,7 @@ class YieldTest(CoverageTest): print(f()) """, arcz=".1 16 67 76 6. .2 23 34 43 3. 2-2 .4 4-4", - arcz_missing="", - arcz_unpredicted="") + ) self.check_coverage("""\ def run(): @@ -741,8 +739,7 @@ class YieldTest(CoverageTest): print(f()) """, arcz=".1 14 45 54 4. .2 2. 2-2", - arcz_missing="", - arcz_unpredicted="") + ) def test_bug_324(self): # This code is tricky: the list() call pulls all the values from gen(), @@ -760,7 +757,7 @@ class YieldTest(CoverageTest): ".2 23 32 2. " # The gen() function ".3 3-3", # The generator expression arcz_missing=".3 3-3", - arcz_unpredicted="") + ) def test_coroutines(self): self.check_coverage("""\ @@ -780,7 +777,7 @@ class YieldTest(CoverageTest): ".1 17 78 89 9A AB B. " ".2 23 34 45 52 2.", arcz_missing="2.", - arcz_unpredicted="") + ) self.assertEqual(self.stdout(), "20\n12\n") def test_yield_from(self): @@ -798,8 +795,7 @@ class YieldTest(CoverageTest): list(gen([1,2,3])) """, arcz=".1 19 9. .2 23 34 45 56 5. 63 37 7.", - arcz_missing="", - arcz_unpredicted="") + ) class MiscArcTest(CoverageTest): @@ -888,7 +884,6 @@ class AsyncTest(CoverageTest): ".1 13 38 8C CD DE E. " ".4 45 56 6-3 " ".9 9A A-8", - arcz_missing="", ) self.assertEqual(self.stdout(), "Compute 1 + 2 ...\n1 + 2 = 3\n") @@ -925,7 +920,6 @@ class AsyncTest(CoverageTest): ".5 5-4 " # __init__ ".8 8-7 " # __aiter__ ".B BC C-A DE E-A ", # __anext__ - arcz_missing="", arcz_unpredicted="CD", ) self.assertEqual(self.stdout(), "a\nb\nc\n.\n") @@ -1053,7 +1047,8 @@ class ExcludeTest(CoverageTest): f = 9 """, [1,2,3,4,5,6,7,8,9], - arcz=".1 12 23 24 34 45 56 57 67 78 89 9. 8.", arcz_missing="") + arcz=".1 12 23 24 34 45 56 57 67 78 89 9. 8.", + ) def test_custom_pragmas(self): self.check_coverage("""\ @@ -1065,7 +1060,8 @@ class ExcludeTest(CoverageTest): """, [1,2,3,4,5], partials=["only some"], - arcz=".1 12 23 34 45 25 5.", arcz_missing="") + arcz=".1 12 23 34 45 25 5.", + ) class LineDataTest(CoverageTest): -- cgit v1.2.1 From d7cae8f7aeafd87a1e665b60035ac173c5de2187 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Fri, 1 Jan 2016 17:51:30 -0500 Subject: Remove some async tests we aren't going to use --HG-- branch : ast-branch --- tests/test_arcs.py | 100 ++--------------------------------------------------- 1 file changed, 3 insertions(+), 97 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index a55b5d39..303b10e6 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -860,7 +860,7 @@ class MiscArcTest(CoverageTest): class AsyncTest(CoverageTest): def setUp(self): if env.PYVERSION < (3, 5): - self.skip("No point testing 3.5 syntax below 3.5") + self.skip("Async features are new in Python 3.5") super(AsyncTest, self).setUp() def test_async(self): @@ -924,111 +924,17 @@ class AsyncTest(CoverageTest): ) self.assertEqual(self.stdout(), "a\nb\nc\n.\n") - def test_async_for2(self): - self.check_coverage("""\ - async def go1(): - async for x2 in y2: - try: - async for x4 in y4: - if a5: - break - else: - x8 = 1 - except: - x10 = 1 - x11 = 1 - x12 = 1 - """, - arcz=".1 1. .2 23 2C 34 45 48 54 56 6B 8B 9A AB B2 C.", - ) - def test_async_with(self): self.check_coverage("""\ async def go(): async with x: pass """, + # TODO: we don't run any code, so many arcs are missing. arcz=".1 1. .2 23 3.", + arcz_missing=".2 23 3.", ) - def test_async_it(self): - self.check_coverage("""\ - async def func(): - for x in g2: - x = 3 - else: - x = 5 - """, - arcz=".1 1. .2 23 32 25 5.", - ) - self.check_coverage("""\ - async def func(): - async for x in g2: - x = 3 - else: - x = 5 - """, - arcz=".1 1. .2 23 32 25 5.", - ) - - def xxxx_async_is_same_flow(self): - SOURCE = """\ - async def func(): - for x in g2: - try: - x = g4 - finally: - x = g6 - try: - with g8 as x: - x = g9 - continue - finally: - x = g12 - for x in g13: - continue - else: - break - while g17: - x = g18 - continue - else: - x = g21 - for x in g22: - x = g23 - continue - """ - - parts = re.split(r"(for |with )", SOURCE) - nchoices = len(parts) // 2 - - def only(s): - return [s] - - def maybe_async(s): - return [s, "async "+s] - - all_all_arcs = collections.defaultdict(list) - choices = [f(x) for f, x in zip(cycle([only, maybe_async]), parts)] - for i, result in enumerate(product(*choices)): - source = "".join(result) - self.make_file("async.py", source) - cov = coverage.Coverage(branch=True) - self.start_import_stop(cov, "async") - analysis = cov._analyze("async.py") - all_all_arcs[tuple(analysis.arc_possibilities())].append((i, source)) - - import pprint - pprint.pprint(list(all_all_arcs.keys())) - for arcs, numbers in all_all_arcs.items(): - print(" ".join("{0:0{1}b}".format(x[0], nchoices) for x in numbers)) - print(" {}".format(arcs)) - for i, source in numbers: - print("-" * 80) - print(source) - - assert len(all_all_arcs) == 1 - class ExcludeTest(CoverageTest): """Tests of exclusions to indicate known partial branches.""" -- cgit v1.2.1 From 6eb046c5937b9c78dab3451fae9348c4c721d6f9 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sat, 2 Jan 2016 10:18:04 -0500 Subject: Handle yield-from and await. All tests pass --HG-- branch : ast-branch --- tests/test_arcs.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 303b10e6..6ba663bc 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -867,23 +867,25 @@ class AsyncTest(CoverageTest): self.check_coverage("""\ import asyncio - async def compute(x, y): + async def compute(x, y): # 3 print("Compute %s + %s ..." % (x, y)) await asyncio.sleep(0.001) - return x + y + return x + y # 6 - async def print_sum(x, y): - result = await compute(x, y) + async def print_sum(x, y): # 8 + result = (0 + + await compute(x, y) # A + ) print("%s + %s = %s" % (x, y, result)) - loop = asyncio.get_event_loop() + loop = asyncio.get_event_loop() # E loop.run_until_complete(print_sum(1, 2)) - loop.close() + loop.close() # G """, arcz= - ".1 13 38 8C CD DE E. " - ".4 45 56 6-3 " - ".9 9A A-8", + ".1 13 38 8E EF FG G. " + ".4 45 56 5-3 6-3 " + ".9 9-8 9C C-8", ) self.assertEqual(self.stdout(), "Compute 1 + 2 ...\n1 + 2 = 3\n") -- cgit v1.2.1 From f98d5bfb6e939f046478b502e2041ac82f91632d Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sat, 2 Jan 2016 14:30:28 -0500 Subject: Better exception support, include except-except arcs, and except-else --HG-- branch : ast-branch --- tests/test_arcs.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 6ba663bc..cd3aafff 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -627,7 +627,9 @@ class ExceptionArcTest(CoverageTest): c = 9 assert a == 3 and b == 1 and c == 9 """, - arcz=".1 12 23 45 39 59 67 79 9A A.", arcz_missing="45 59 67 79") + arcz=".1 12 23 45 46 39 59 67 79 69 9A A.", + arcz_missing="45 59 46 67 79 69", + ) self.check_coverage("""\ a, b, c = 1, 1, 1 try: @@ -640,8 +642,10 @@ class ExceptionArcTest(CoverageTest): c = 9 assert a == 1 and b == 5 and c == 9 """, - arcz=".1 12 23 45 39 59 67 79 9A A.", arcz_missing="39 67 79", - arcz_unpredicted="34") + arcz=".1 12 23 45 46 69 39 59 67 79 9A A.", + arcz_missing="39 46 67 79 69", + arcz_unpredicted="34", + ) self.check_coverage("""\ a, b, c = 1, 1, 1 try: @@ -654,8 +658,9 @@ class ExceptionArcTest(CoverageTest): c = 9 assert a == 7 and b == 1 and c == 9 """, - arcz=".1 12 23 45 39 59 67 79 9A A.", arcz_missing="39 45 59", - arcz_unpredicted="34 46", # TODO: 46 can be predicted. + arcz=".1 12 23 45 46 39 59 67 79 69 9A A.", + arcz_missing="39 45 59 69", + arcz_unpredicted="34", ) self.check_coverage("""\ a, b, c = 1, 1, 1 @@ -672,9 +677,9 @@ class ExceptionArcTest(CoverageTest): pass assert a == 1 and b == 1 and c == 10 """, - arcz=".1 12 23 34 4A 56 6A 78 8A AD BC CD D.", + arcz=".1 12 23 34 4A 56 6A 57 78 8A 7A AD BC CD D.", arcz_missing="4A 56 6A 78 8A AD", - arcz_unpredicted="45 57 7A AB", # TODO: 57 7A can be predicted. + arcz_unpredicted="45 AB", ) -- cgit v1.2.1 From 3440e214df5ddd0f507ecd76c2350eb8d9dd6a75 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sat, 2 Jan 2016 16:14:35 -0500 Subject: Support returning through a finally --HG-- branch : ast-branch --- tests/test_arcs.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index cd3aafff..88442049 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -682,6 +682,21 @@ class ExceptionArcTest(CoverageTest): arcz_unpredicted="45 AB", ) + def test_return_finally(self): + self.check_coverage("""\ + a = [1] + def func(): + try: + return 10 + finally: + a.append(6) + + assert func() == 10 + assert a == [1, 6] + """, + arcz=".1 12 28 89 9. .3 34 46 6-2", + ) + class YieldTest(CoverageTest): """Arc tests for generators.""" -- cgit v1.2.1 From 5698ff871885333897392483d845fb7ce12f680f Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sat, 2 Jan 2016 16:33:59 -0500 Subject: Remove unused imports --HG-- branch : ast-branch --- tests/test_arcs.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 37e8b9b7..91811e45 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -3,10 +3,6 @@ """Tests for coverage.py's arc measurement.""" -import collections -from itertools import cycle, product -import re - from tests.coveragetest import CoverageTest import coverage -- cgit v1.2.1 From e2ac7b25ec59a7146c9a9b29e9b5b07df101b0b5 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sat, 2 Jan 2016 16:46:34 -0500 Subject: No reason to skip this test --HG-- branch : ast-branch --- tests/test_arcs.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 91811e45..607ff68e 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -143,13 +143,12 @@ class SimpleArcTest(CoverageTest): ) def test_unused_lambdas_are_confusing_bug_90(self): - self.skip("Expected failure: bug 90") self.check_coverage("""\ a = 1 fn = lambda x: x b = 3 """, - arcz=".1 12 .2 2-2 23 3." + arcz=".1 12 .2 2-2 23 3.", arcz_missing=".2 2-2", ) -- cgit v1.2.1 From a2cb815e890f092822fa211713ff3d33887afd86 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 3 Jan 2016 11:08:06 -0500 Subject: Fix arcs for function and class decorators --HG-- branch : ast-branch --- tests/test_arcs.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 607ff68e..8b524db7 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -871,6 +871,53 @@ class MiscArcTest(CoverageTest): arcs_missing=[], arcs_unpredicted=[], ) + def test_function_decorator(self): + self.check_coverage("""\ + def decorator(arg): + def _dec(f): + return f + return _dec + + @decorator(6) + @decorator( + len([8]), + ) + def my_function( + a=len([11]), + ): + x = 13 + a = 14 + my_function() + """, + arcz= + ".1 16 67 7A AE EF F. " # main line + ".2 24 4. .3 3-2 " # decorators + ".D D-6 ", # my_function + ) + + def test_class_decorator(self): + self.check_coverage("""\ + def decorator(arg): + def _dec(c): + return c + return _dec + + @decorator(6) + @decorator( + len([8]), + ) + class MyObject( + object + ): + X = 13 + a = 14 + """, + arcz= + ".1 16 67 6D 7A AE E. " # main line + ".2 24 4. .3 3-2 " # decorators + ".6 D-6 ", # MyObject + ) + class AsyncTest(CoverageTest): def setUp(self): -- cgit v1.2.1 From 4074315ac65ed79e94bc331a8059859781b5b12b Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Mon, 4 Jan 2016 20:12:55 -0500 Subject: Support comprehensions better --HG-- branch : ast-branch --- tests/test_arcs.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 8b524db7..fb4b99eb 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -378,6 +378,54 @@ class LoopArcTest(CoverageTest): arcz=".1 .2 2-2 12 23 34 45 53 3.", ) + def test_multiline_dict_comp(self): + if env.PYVERSION < (2, 7): + self.skip("Don't have set or dict comprehensions before 2.7") + if env.PY2: + arcz = ".2 2B B-4 2-4" + else: + arcz = ".2 2B B-3 2-3" + # Multiline dict comp: + self.check_coverage("""\ + # comment + d = \\ + { + i: + str(i) + for + i + in + range(9) + } + x = 11 + """, + arcz=arcz, + ) + # Multi dict comp: + if env.PY2: + arcz = ".2 2F F-4 2-4" + else: + arcz = ".2 2F F-3 2-3" + self.check_coverage("""\ + # comment + d = \\ + { + (i, j): + str(i+j) + for + i + in + range(9) + for + j + in + range(13) + } + x = 15 + """, + arcz=arcz, + ) + class ExceptionArcTest(CoverageTest): """Arc-measuring tests involving exception handling.""" -- cgit v1.2.1 From f7f56ec9adaa531019a27ef7c634db816f30040a Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Tue, 5 Jan 2016 06:54:07 -0500 Subject: Support while-else --HG-- branch : ast-branch --- tests/test_arcs.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index fb4b99eb..cab95c8f 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -314,6 +314,22 @@ class LoopArcTest(CoverageTest): arcz=".1 .2 23 32 34 47 26 67 7. 18 89 9." ) + def test_while_else(self): + self.check_coverage("""\ + def whileelse(seq): + while seq: + n = seq.pop() + if n > 4: + break + else: + n = 99 + return n + assert whileelse([1, 2]) == 99 + assert whileelse([1, 5]) == 5 + """, + arcz=".1 19 9A A. .2 23 34 45 58 42 27 78 8.", + ) + def test_confusing_for_loop_bug_175(self): if env.PY3: # Py3 counts the list comp as a separate code object. -- cgit v1.2.1 From e0cc720dad16bed5673a1e7d11ccdceeab200fc3 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Tue, 5 Jan 2016 07:17:27 -0500 Subject: Tweak the conditional for the start-point of dictcomps --HG-- branch : ast-branch --- tests/test_arcs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index cab95c8f..9af4a083 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -397,7 +397,7 @@ class LoopArcTest(CoverageTest): def test_multiline_dict_comp(self): if env.PYVERSION < (2, 7): self.skip("Don't have set or dict comprehensions before 2.7") - if env.PY2: + if env.PYVERSION < (3, 5): arcz = ".2 2B B-4 2-4" else: arcz = ".2 2B B-3 2-3" @@ -418,7 +418,7 @@ class LoopArcTest(CoverageTest): arcz=arcz, ) # Multi dict comp: - if env.PY2: + if env.PYVERSION < (3, 5): arcz = ".2 2F F-4 2-4" else: arcz = ".2 2F F-3 2-3" -- cgit v1.2.1 From 8f9b4f9d596ef4a5c0d26b4e54acfcd0558ece39 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 6 Jan 2016 07:11:32 -0500 Subject: Add some tests for uncovered cases --HG-- branch : ast-branch --- tests/test_arcs.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tests/test_arcs.py') 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.""" -- cgit v1.2.1 From cb33e6c3a41d48a37bebee3e8b3421ab35ab0ba5 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 6 Jan 2016 07:35:11 -0500 Subject: Test continue/finally --HG-- branch : ast-branch --- tests/test_arcs.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 60fdea37..bb811c01 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -617,6 +617,26 @@ class ExceptionArcTest(CoverageTest): arcz_missing="3D BC CD", ) + def test_continue_through_finally(self): + self.check_coverage("""\ + a, b, c, d, i = 1, 1, 1, 1, 99 + try: + for i in range(5): + try: + a = 5 + if i > 0: + continue + b = 8 + finally: + c = 10 + except: + d = 12 # C + assert (a, b, c, d) == (5, 8, 10, 1) # D + """, + arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 BC CD D.", + arcz_missing="BC CD", + ) + def test_finally_in_loop_bug_92(self): self.check_coverage("""\ for i in range(5): -- cgit v1.2.1 From cefd14cafc49a244c865885c87f019217d6d3a2f Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 7 Jan 2016 08:46:35 -0500 Subject: Bytecode not byte code --HG-- branch : ast-branch --- tests/test_arcs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index bb811c01..bcc6c024 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -942,9 +942,11 @@ class MiscArcTest(CoverageTest): def test_pathologically_long_code_object(self): # https://bitbucket.org/ned/coveragepy/issue/359 - # The structure of this file is such that an EXTENDED_ARG byte code is + # The structure of this file is such that an EXTENDED_ARG bytecode is # needed to encode the jump at the end. We weren't interpreting those # opcodes. + # Note that we no longer interpret bytecode at all, but it couldn't + # hurt to keep the test... code = """\ data = [ """ + "".join("""\ -- cgit v1.2.1 From 1a57255a7fe11f6a4318b728dfa90131c97b7eee Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 7 Jan 2016 08:56:40 -0500 Subject: A test that I'll fix soon --HG-- branch : ast-branch --- tests/test_arcs.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index bcc6c024..b7976889 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -964,6 +964,25 @@ class MiscArcTest(CoverageTest): arcs_missing=[], arcs_unpredicted=[], ) + def test_optimized_away_lines(self): + self.skip("TODO: fix this test") + self.check_coverage("""\ + a = 1 + if len([2]): + c = 3 + if 0: # this line isn't in the compiled code. + if len([5]): + d = 6 + e = 7 + """, + lines=[1, 2, 3, 7], + arcz=".1 12 23 27 37 7.", + ) + + +class DecoractorArcTest(CoverageTest): + """Tests of arcs with decorators.""" + def test_function_decorator(self): self.check_coverage("""\ def decorator(arg): -- cgit v1.2.1 From 152dd7d6e4b9a53e89cb7ec0cacf0f01be4abc73 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 7 Jan 2016 12:06:11 -0500 Subject: Clean up small stuff --HG-- branch : ast-branch --- tests/test_arcs.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index b7976889..28c1df72 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -1032,6 +1032,8 @@ class DecoractorArcTest(CoverageTest): class AsyncTest(CoverageTest): + """Tests of the new async and await keywords in Python 3.5""" + def setUp(self): if env.PYVERSION < (3, 5): self.skip("Async features are new in Python 3.5") -- cgit v1.2.1 From 2e48dedf1ea439988fba0c9693cea7a818ab3213 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 7 Jan 2016 19:42:42 -0500 Subject: Add tests of multiline lambdas, though i don't quite understand the line numbers involved --HG-- branch : ast-branch --- tests/test_arcs.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'tests/test_arcs.py') diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 28c1df72..c52bc8aa 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -1031,6 +1031,34 @@ class DecoractorArcTest(CoverageTest): ) +class LambdaArcTest(CoverageTest): + """Tests of lambdas""" + + def test_lambda(self): + self.check_coverage("""\ + fn = (lambda x: + x + 2 + ) + assert fn(4) == 6 + """, + arcz=".1 14 4-1 1-1", + ) + self.check_coverage("""\ + + fn = \\ + ( + lambda + x: + x + + + 8 + ) + assert fn(10) == 18 + """, + arcz=".2 2A A-4 2-4", + ) + + class AsyncTest(CoverageTest): """Tests of the new async and await keywords in Python 3.5""" @@ -1108,7 +1136,6 @@ class AsyncTest(CoverageTest): async with x: pass """, - # TODO: we don't run any code, so many arcs are missing. arcz=".1 1. .2 23 3.", arcz_missing=".2 23 3.", ) -- cgit v1.2.1