Skip to content

Commit

Permalink
Realize cover exception message earlier
Browse files Browse the repository at this point in the history
  • Loading branch information
pschanely committed Oct 23, 2023
1 parent aa6063f commit 6761765
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
10 changes: 6 additions & 4 deletions crosshair/path_cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
LazyCreationRepr,
deep_realize,
explore_paths,
realize,
)
from crosshair.fnutil import FunctionInfo
from crosshair.options import AnalysisOptions
Expand All @@ -36,7 +37,7 @@ class PathSummary:
formatted_args: str
result: str
exc: Optional[Type[BaseException]]
exc_object: Optional[BaseException]
exc_message: Optional[str]
post_args: BoundArguments
coverage: CoverageResult

Expand Down Expand Up @@ -87,13 +88,14 @@ def on_path_complete(
debug(
"user-level exception found", type(exc), exc, test_stack(exc_stack)
)
exc_message = realize(str(exc)) if len(exc.args) > 0 else None
paths.append(
PathSummary(
pre_args,
formatted_pre_args,
ret,
type(exc),
exc,
exc_message,
post_args,
cov,
)
Expand Down Expand Up @@ -165,9 +167,9 @@ def output_pytest_paths(
lines.append(f" assert {exec_fn} == {repr(path.result)}")
else:
imports.add("import pytest")
if path.exc_object is not None and len(path.exc_object.args) > 0:
if path.exc_message is not None:
lines.append(
f" with pytest.raises({name_of_type(path.exc)}, match='{re.escape(path.exc_object.args[0])}'):"
f" with pytest.raises({name_of_type(path.exc)}, match='{re.escape(path.exc_message)}'):"
)
else:
lines.append(f" with pytest.raises({name_of_type(path.exc)}):")
Expand Down
20 changes: 20 additions & 0 deletions crosshair/path_cover_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import functools
import re
import textwrap
from io import StringIO
from typing import Callable, Optional

Expand Down Expand Up @@ -32,6 +33,12 @@ def _exceptionex(x: int) -> int:
return x


def _symbolic_exception_example(x: str) -> str:
if x == "foobar":
raise ValueError(x)
return x


def _has_no_successful_paths(x: int) -> None:
with NoTracing():
context_statespace().defer_assumption("fail", lambda: False)
Expand All @@ -42,6 +49,7 @@ def _has_no_successful_paths(x: int) -> None:
decorated_foo = FunctionInfo.from_fn(functools.lru_cache()(_foo))
regex = FunctionInfo.from_fn(_regex)
exceptionex = FunctionInfo.from_fn(_exceptionex)
symbolic_exception_example = FunctionInfo.from_fn(_symbolic_exception_example)
has_no_successful_paths = FunctionInfo.from_fn(_has_no_successful_paths)


Expand Down Expand Up @@ -74,6 +82,18 @@ def test_path_cover_exception_example() -> None:
assert "_exceptionex(42)" in out.getvalue()


def test_path_cover_symbolic_exception_message() -> None:
paths = list(path_cover(symbolic_exception_example, OPTS, CoverageType.OPCODE))
_imports, lines = output_pytest_paths(_symbolic_exception_example, paths)
expected = textwrap.dedent(
"""\
def test__symbolic_exception_example():
with pytest.raises(ValueError, match='foobar'):
_symbolic_exception_example('foobar')"""
)
assert expected in "\n".join(lines)


def test_has_no_successful_paths() -> None:
assert list(path_cover(has_no_successful_paths, OPTS, CoverageType.OPCODE)) == []

Expand Down

0 comments on commit 6761765

Please sign in to comment.