2 files changed
@@ -18,6 +18,7 @@ | |||
| 18 | 18 | "skipIf", | |
| 19 | 19 | "GIT_REPO", | |
| 20 | 20 | "GIT_DAEMON_PORT", | |
| 21 | + "xfail_if_raises", | ||
| 21 | 22 | ] | |
| 22 | 23 | ||
| 23 | 24 | import contextlib | |
@@ -35,8 +36,10 @@ | |||
| 35 | 36 | import time | |
| 36 | 37 | import unittest | |
| 37 | 38 | import venv | |
| 39 | + from typing import Union, Type, Tuple | ||
| 38 | 40 | ||
| 39 | 41 | import gitdb | |
| 42 | + import pytest | ||
| 40 | 43 | ||
| 41 | 44 | from git.util import rmtree, cwd | |
| 42 | 45 | ||
@@ -465,3 +468,27 @@ def _executable(self, basename): | |||
| 465 | 468 | if osp.isfile(path) or osp.islink(path): | |
| 466 | 469 | return path | |
| 467 | 470 | raise RuntimeError(f"no regular file or symlink {path!r}") | |
| 471 | + | ||
| 472 | + | ||
| 473 | + @contextlib.contextmanager | ||
| 474 | + def xfail_if_raises( | ||
| 475 | + condition: bool, | ||
| 476 | + *, | ||
| 477 | + raises: Union[Type[BaseException], Tuple[Type[BaseException], ...]], | ||
| 478 | + reason: str = "", | ||
| 479 | + strict: bool = False, | ||
| 480 | + ): | ||
| 481 | + """Approximates the behavior of @pytest.mark.xfail(..., raises=...) as a context | ||
| 482 | + manager that can be used within a test, such as when the condition is complex or has | ||
| 483 | + side effects | ||
| 484 | + | ||
| 485 | + One difference is it will not report XPASS if the test passes, but setting `strict` | ||
| 486 | + simulates it by raising an exception""" | ||
| 487 | + try: | ||
| 488 | + yield | ||
| 489 | + except raises: | ||
| 490 | + if condition: | ||
| 491 | + pytest.xfail(reason) | ||
| 492 | + raise | ||
| 493 | + if strict and condition: | ||
| 494 | + pytest.fail("[XPASS(strict)] " + reason) | ||
0 commit comments