blob: 3856a2cf19c50f0eae8506d666fed55e3689b96f [file] [log] [blame]
"""Tests for Coverage.py's arc measurement."""
import sys
from tests.coveragetest import CoverageTest
class SimpleArcTest(CoverageTest):
"""Tests for Coverage.py's arc measurement."""
def test_simple_sequence(self):
self.check_coverage("""\
a = 1
b = 2
""",
arcz=".1 12 2.")
self.check_coverage("""\
a = 1
b = 3
""",
arcz=".1 13 3.")
self.check_coverage("""\
a = 2
b = 3
c = 5
""",
arcz=".2 23 35 5-2")
def test_function_def(self):
self.check_coverage("""\
def foo():
a = 2
foo()
""",
arcz=".1 .2 14 2. 4.")
def test_if(self):
self.check_coverage("""\
a = 1
if len([]) == 0:
a = 3
assert a == 3
""",
arcz=".1 12 23 24 34 4.", arcz_missing="24")
self.check_coverage("""\
a = 1
if len([]) == 1:
a = 3
assert a == 1
""",
arcz=".1 12 23 24 34 4.", arcz_missing="23 34")
def test_if_else(self):
self.check_coverage("""\
if len([]) == 0:
a = 2
else:
a = 4
assert a == 2
""",
arcz=".1 12 25 14 45 5.", arcz_missing="14 45")
self.check_coverage("""\
if len([]) == 1:
a = 2
else:
a = 4
assert a == 4
""",
arcz=".1 12 25 14 45 5.", arcz_missing="12 25")
def test_compact_if(self):
self.check_coverage("""\
a = 1
if len([]) == 0: a = 2
assert a == 2
""",
arcz=".1 12 23 3.", arcz_missing="")
self.check_coverage("""\
def fn(x):
if x % 2: return True
return False
a = fn(1)
assert a == True
""",
arcz=".1 14 45 5. .2 2. 23 3.", arcz_missing="23 3.")
def test_multiline(self):
self.check_coverage("""\
a = (
2 +
3
)
b = \\
6
""",
arcz=".1 15 5-2", arcz_missing="")
def test_if_return(self):
self.check_coverage("""\
def if_ret(a):
if a:
return 3
b = 4
return 5
x = if_ret(0) + if_ret(1)
assert x == 8
""",
arcz=".1 16 67 7. .2 23 24 3. 45 5.", arcz_missing=""
)
def test_dont_confuse_exit_and_else(self):
self.check_coverage("""\
def foo():
if foo:
a = 3
else:
a = 5
return a
assert foo() == 3 # 7
""",
arcz=".1 17 7. .2 23 36 25 56 6.", arcz_missing="25 56"
)
self.check_coverage("""\
def foo():
if foo:
a = 3
else:
a = 5
foo() # 6
""",
arcz=".1 16 6. .2 23 3. 25 5.", arcz_missing="25 5."
)
if 0: # expected failure
def test_unused_lambdas_are_confusing_bug_90(self):
self.check_coverage("""\
a = 1
fn = lambda x: x
b = 3
""",
arcz=".1 12 .2 2-2 23 3."
)
class WithTest(CoverageTest):
"""Arc-measuring tests involving context managers."""
def test_with(self):
self.check_coverage("""\
def example():
with open("test", "w") as f: # exit
f.write("")
return 1
example()
""",
arcz=".1 .2 23 34 4. 16 6."
)
def test_bug_146(self):
# https://bitbucket.org/ned/coveragepy/issue/146
self.check_coverage("""\
for i in range(2):
with open("test", "w") as f:
print(3)
print(4)
print(5)
""",
arcz=".1 12 23 34 41 15 5."
)
class LoopArcTest(CoverageTest):
"""Arc-measuring tests involving loops."""
def test_loop(self):
self.check_coverage("""\
for i in range(10):
a = i
assert a == 9
""",
arcz=".1 12 21 13 3.", arcz_missing="")
self.check_coverage("""\
a = -1
for i in range(0):
a = i
assert a == -1
""",
arcz=".1 12 23 32 24 4.", arcz_missing="23 32")
def test_nested_loop(self):
self.check_coverage("""\
for i in range(3):
for j in range(3):
a = i + j
assert a == 4
""",
arcz=".1 12 23 32 21 14 4.", arcz_missing="")
def test_break(self):
self.check_coverage("""\
for i in range(10):
a = i
break # 3
a = 99
assert a == 0 # 5
""",
arcz=".1 12 23 35 15 41 5.", arcz_missing="15 41")
def test_continue(self):
self.check_coverage("""\
for i in range(10):
a = i
continue # 3
a = 99
assert a == 9 # 5
""",
arcz=".1 12 23 31 15 41 5.", arcz_missing="41")
def test_nested_breaks(self):
self.check_coverage("""\
for i in range(3):
for j in range(3):
a = i + j
break # 4
if i == 2:
break
assert a == 2 and i == 2 # 7
""",
arcz=".1 12 23 34 45 25 56 51 67 17 7.", arcz_missing="17 25")
def test_while_true(self):
# With "while 1", the loop knows it's constant.
self.check_coverage("""\
a, i = 1, 0
while 1:
if i >= 3:
a = 4
break
i += 1
assert a == 4 and i == 3
""",
arcz=".1 12 23 34 45 36 63 57 7.",
)
# With "while True", 2.x thinks it's computation, 3.x thinks it's
# constant.
if sys.version_info >= (3, 0):
arcz = ".1 12 23 34 45 36 63 57 7."
else:
arcz = ".1 12 23 27 34 45 36 62 57 7."
self.check_coverage("""\
a, i = 1, 0
while True:
if i >= 3:
a = 4
break
i += 1
assert a == 4 and i == 3
""",
arcz=arcz,
)
def test_for_if_else_for(self):
self.check_coverage("""\
def branches_2(l):
if l:
for e in l:
a = 4
else:
a = 6
def branches_3(l):
for x in l:
if x:
for e in l:
a = 12
else:
a = 14
branches_2([0,1])
branches_3([0,1])
""",
arcz=
".1 18 8G GH H. "
".2 23 34 43 26 3. 6. "
".9 9A 9-8 AB BC CB B9 AE E9",
arcz_missing="26 6."
)
def test_for_else(self):
self.check_coverage("""\
def forelse(seq):
for n in seq:
if n > 5:
break
else:
print('None of the values were greater than 5')
print('Done')
forelse([1,2])
forelse([1,6])
""",
arcz=".1 .2 23 32 34 47 26 67 7. 18 89 9."
)
def test_confusing_for_loop_bug_175(self):
if sys.version_info >= (3, 0):
# Py3 counts the list comp as a separate code object.
arcz = ".1 .2 2-2 12 23 34 45 53 3."
else:
arcz = ".1 12 23 34 45 53 3."
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=arcz, arcz_missing="", arcz_unpredicted="")
if sys.version_info >= (3, 0):
arcz = ".1 12 .2 2-2 23 34 42 2."
else:
arcz = ".1 12 23 34 42 2."
self.check_coverage("""\
o = [(1,2), (3,4)]
for tup in [a for a in o]:
x = tup[0]
y = tup[1]
""",
arcz=arcz, arcz_missing="", arcz_unpredicted="")
class ExceptionArcTest(CoverageTest):
"""Arc-measuring tests involving exception handling."""
def test_try_except(self):
self.check_coverage("""\
a, b = 1, 1
try:
a = 3
except:
b = 5
assert a == 3 and b == 1
""",
arcz=".1 12 23 36 45 56 6.", arcz_missing="45 56")
self.check_coverage("""\
a, b = 1, 1
try:
a = 3
raise Exception("Yikes!")
a = 5
except:
b = 7
assert a == 3 and b == 7
""",
arcz=".1 12 23 34 58 67 78 8.",
arcz_missing="58", arcz_unpredicted="46")
def test_hidden_raise(self):
self.check_coverage("""\
a, b = 1, 1
def oops(x):
if x % 2: raise Exception("odd")
try:
a = 5
oops(1)
a = 7
except:
b = 9
assert a == 5 and b == 9
""",
arcz=".1 12 .3 3-2 24 45 56 67 7A 89 9A A.",
arcz_missing="67 7A", arcz_unpredicted="68")
def test_except_with_type(self):
self.check_coverage("""\
a, b = 1, 1
def oops(x):
if x % 2: raise ValueError("odd")
def try_it(x):
try:
a = 6
oops(x)
a = 8
except ValueError:
b = 10
return a
assert try_it(0) == 8 # C
assert try_it(1) == 6 # D
""",
arcz=".1 12 .3 3-2 24 4C CD D. .5 56 67 78 8B 9A AB B-4",
arcz_missing="",
arcz_unpredicted="79")
def test_try_finally(self):
self.check_coverage("""\
a, c = 1, 1
try:
a = 3
finally:
c = 5
assert a == 3 and c == 5
""",
arcz=".1 12 23 35 56 6.", arcz_missing="")
self.check_coverage("""\
a, c, d = 1, 1, 1
try:
try:
a = 4
finally:
c = 6
except:
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="")
self.check_coverage("""\
a, c, d = 1, 1, 1
try:
try:
a = 4
raise Exception("Yikes!")
a = 6
finally:
c = 8
except:
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")
def test_finally_in_loop(self):
self.check_coverage("""\
a, c, d, i = 1, 1, 1, 99
try:
for i in range(5):
try:
a = 5
if i > 0:
raise Exception("Yikes!")
a = 8
finally:
c = 10
except:
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")
self.check_coverage("""\
a, c, d, i = 1, 1, 1, 99
try:
for i in range(5):
try:
a = 5
if i > 10:
raise Exception("Yikes!")
a = 8
finally:
c = 10
except:
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="")
def test_break_in_finally(self):
self.check_coverage("""\
a, c, d, i = 1, 1, 1, 99
try:
for i in range(5):
try:
a = 5
if i > 0:
break
a = 8
finally:
c = 10
except:
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")
def test_finally_in_loop_bug_92(self):
self.check_coverage("""\
for i in range(5):
try:
j = 3
finally:
f = 5
g = 6
h = 7
""",
arcz=".1 12 23 35 56 61 17 7.",
arcz_missing="", arcz_unpredicted="")
# Run this test only on Py2 for now. I hope to fix it on Py3
# eventually...
if sys.version_info < (3, 0):
# "except Exception as e" is crucial here.
def test_bug_212(self):
self.check_coverage("""\
def b(exc):
try:
while 1:
raise Exception(exc) # 4
except Exception as e:
if exc != 'expected':
raise
q = 8
b('expected')
try:
b('unexpected') # C
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")
def test_except_finally(self):
self.check_coverage("""\
a, b, c = 1, 1, 1
try:
a = 3
except:
b = 5
finally:
c = 7
assert a == 3 and b == 1 and c == 7
""",
arcz=".1 12 23 45 37 57 78 8.", arcz_missing="45 57")
self.check_coverage("""\
a, b, c = 1, 1, 1
def oops(x):
if x % 2: raise Exception("odd")
try:
a = 5
oops(1)
a = 7
except:
b = 9
finally:
c = 11
assert a == 5 and b == 9 and c == 11
""",
arcz=".1 12 .3 3-2 24 45 56 67 7B 89 9B BC C.",
arcz_missing="67 7B", arcz_unpredicted="68")
class MiscArcTest(CoverageTest):
"""Miscellaneous arc-measuring tests."""
def test_dict_literal(self):
self.check_coverage("""\
d = {
'a': 2,
'b': 3,
'c': {
'd': 5,
'e': 6,
}
}
assert d
""",
arcz=".1 19 9.")
class ExcludeTest(CoverageTest):
"""Tests of exclusions to indicate known partial branches."""
def test_default(self):
# A number of forms of pragma comment are accepted.
self.check_coverage("""\
a = 1
if a: #pragma: no branch
b = 3
c = 4
if c: # pragma NOBRANCH
d = 6
e = 7
if e:#\tpragma:\tno branch
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="")
def test_custom_pragmas(self):
self.check_coverage("""\
a = 1
while a: # [only some]
c = 3
break
assert c == 5-2
""",
[1,2,3,4,5],
partials=["only some"],
arcz=".1 12 23 34 45 25 5.", arcz_missing="")