1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
import pytest
from pathlib import Path
try:
from hypothesis import given, strategies as st
except ImportError:
given = st = None
path = Path(__file__).parent.joinpath("..", "lib-python", "3", "traceback.py")
with open(path) as f:
content = f.read()
d = {}
c = compile(content, path, 'exec')
exec(c, d, d)
orig_levenshtein_distance = d['_levenshtein_distance']
def _levenshtein_distance(a, b):
return orig_levenshtein_distance(a, b, max(len(a), len(b)) * 2)
_compute_suggestion_error = d['_compute_suggestion_error']
TracebackException = d['TracebackException']
# levensthein tests
def test_levensthein():
assert _levenshtein_distance("cat", "sat") == 2
assert _levenshtein_distance("cat", "ca") == 2
assert _levenshtein_distance("cat", "caT") == 1 # case change is only edit distance 1
assert _levenshtein_distance("Kätzchen", "Satz") == 12
if given is not None:
@given(st.text())
def test_x_x(s):
assert _levenshtein_distance(s, s) == 0
@given(st.text())
def test_x_empty(s):
assert _levenshtein_distance(s, '') == 2 * len(s)
@given(st.text(), st.text())
def test_symmetric(a, b):
assert _levenshtein_distance(a, b) == _levenshtein_distance(b, a)
@given(st.text(), st.text(), st.characters())
def test_add_char(a, b, char):
d = _levenshtein_distance(a, b)
assert d == _levenshtein_distance(char + a, char + b)
assert d == _levenshtein_distance(a + char, b + char)
@given(st.text(), st.text(), st.text())
def test_triangle(a, b, c):
assert _levenshtein_distance(a, c) <= _levenshtein_distance(a, b) + _levenshtein_distance(b, c)
# suggestion tests
def test_compute_suggestion_attribute_error():
class A:
good = 1
walk = 2
assert _compute_suggestion_error(AttributeError(obj=A(), name="god"), None, "god") == "good"
assert _compute_suggestion_error(AttributeError(obj=A(), name="good"), None, "good") == None
assert _compute_suggestion_error(AttributeError(obj=A(), name="goodabcd"), None, "goodabcd") == None
def fmt(e):
return "\n".join(
TracebackException.from_exception(e).format_exception_only())
def test_format_attribute_error():
class A:
good = 1
walk = 2
a = A()
try:
a.god
except AttributeError as e:
assert fmt(e) == "AttributeError: 'A' object has no attribute 'god'. Did you mean: 'good'?\n"
def test_compute_suggestion_name_error():
def f():
abc = 1
absc # abc beats abs!
try:
f()
except NameError as e:
assert fmt(e) == "NameError: name 'absc' is not defined. Did you mean: 'abc'?\n"
def test_compute_suggestion_name_error_from_global():
def f():
test_compute_suggestion_name_error_from_globl
try:
f()
except NameError as e:
assert fmt(e) == "NameError: name 'test_compute_suggestion_name_error_from_globl' is not defined. Did you mean: 'test_compute_suggestion_name_error_from_global'?\n"
def test_compute_suggestion_name_error_from_builtin():
try:
abcs
except NameError as e:
assert fmt(e) == "NameError: name 'abcs' is not defined. Did you mean: 'abs'?\n"
def test_missing_import():
try:
math
except NameError as e:
assert fmt(e) == "NameError: name 'math' is not defined. Did you mean: 'Path'? Or did you forget to import 'math'\n"
|