import contextlib
import sys
-from typing import Optional
+from typing import Iterator, Optional
class InvalidTestPlan(RuntimeError):
- def __init__(self, msg: str):
+ def __init__(self, msg):
+ # type: (str) -> None
super().__init__(msg)
class BailOut(RuntimeError):
- def __init__(self, msg: str):
+ def __init__(self, msg):
+ # type: (str) -> None
super().__init__(msg)
class TestCase:
- def __init__(self, tap_generator: "TapGenerator", description: str):
- self._tap_generator = tap_generator
- self._result: Optional[bool] = None
- self._description = description
+ def __init__(
+ self,
+ tap_generator, # type: "TapGenerator"
+ description, # type: str
+ ):
+ self._tap_generator = tap_generator # type: "TapGenerator"
+ self._result = None # type: Optional[bool]
+ self._description = description # type: str
@property
- def result(self) -> Optional[bool]:
+ def result(self):
+ # type: () -> Optional[bool]
return self._result
@property
- def description(self) -> str:
+ def description(self):
+ # type: () -> str
return self._description
- def _set_result(self, result: bool) -> None:
+ def _set_result(self, result):
+ # type: (bool) -> None
if self._result is not None:
raise RuntimeError("Can't set test case result twice")
self._result = result
self._tap_generator.test(result, self._description)
- def success(self) -> None:
+ def success(self):
+ # type: () -> None
self._set_result(True)
- def fail(self) -> None:
+ def fail(self):
+ # type: () -> None
self._set_result(False)
# Produces a test execution report in the TAP format.
class TapGenerator:
- def __init__(self, total_test_count: int):
+ def __init__(self, total_test_count):
+ # type: (int) -> None
if total_test_count <= 0:
raise ValueError("Test count must be greater than zero")
- self._total_test_count: int = total_test_count
- self._last_test_case_id: int = 0
- self._printed_plan: bool = False
- self._has_failure: bool = False
+ self._total_test_count = total_test_count # type: int
+ self._last_test_case_id = 0 # type: int
+ self._printed_plan = False # type: bool
+ self._has_failure = False # type: bool
def __del__(self):
if self.remaining_test_cases > 0:
)
@property
- def remaining_test_cases(self) -> int:
+ def remaining_test_cases(self):
+ # type: () -> int
return self._total_test_count - self._last_test_case_id
- def _print(self, msg: str) -> None:
+ def _print(self, msg):
+ # type: (str) -> None
if not self._printed_plan:
print(
"1..{total_test_count}".format(total_test_count=self._total_test_count),
print(msg, flush=True)
- def skip_all(self, reason) -> None:
+ def skip_all(self, reason):
+ # type: (str) -> None
if self._last_test_case_id != 0:
raise RuntimeError("Can't skip all tests after running test cases")
self._last_test_case_id = self._total_test_count
- def skip(self, reason, skip_count: int = 1) -> None:
+ def skip(self, reason, skip_count=1):
+ # type: (str, int) -> None
for i in range(skip_count):
self._last_test_case_id = self._last_test_case_id + 1
self._print(
)
)
- def bail_out(self, reason: str) -> None:
+ def bail_out(self, reason):
+ # type: (str) -> None
self._print("Bail out! {reason}".format(reason=reason))
self._last_test_case_id = self._total_test_count
raise BailOut(reason)
- def test(self, result: bool, description: str) -> None:
+ def test(self, result, description):
+ # type: (bool, str) -> None
if self._last_test_case_id == self._total_test_count:
raise InvalidTestPlan("Executing too many tests")
)
)
- def ok(self, description: str) -> None:
+ def ok(self, description):
+ # type: (str) -> None
self.test(True, description)
- def fail(self, description: str) -> None:
+ def fail(self, description):
+ # type: (str) -> None
self.test(False, description)
@property
- def is_successful(self) -> bool:
+ def is_successful(self):
+ # type: () -> bool
return (
self._last_test_case_id == self._total_test_count and not self._has_failure
)
@contextlib.contextmanager
- def case(self, description: str):
+ def case(self, description):
+ # type: (str) -> Iterator[TestCase]
test_case = TestCase(self, description)
try:
yield test_case
if test_case.result is None:
test_case.success()
- def diagnostic(self, msg) -> None:
+ def diagnostic(self, msg):
+ # type: (str) -> None
print("# {msg}".format(msg=msg), file=sys.stderr, flush=True)