add doc comments
This commit is contained in:
parent
1cfd674026
commit
da55d88ddf
2 changed files with 61 additions and 3 deletions
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "okipy"
|
name = "okipy"
|
||||||
version = "1.0.1"
|
version = "1.1.0"
|
||||||
description = "Minimal, typed, functional and dynamic test library."
|
description = "Minimal, typed, functional and dynamic test library."
|
||||||
keywords = ["test", "functional", "library", "testing", "dynamic", "minimal"]
|
keywords = ["test", "functional", "library", "testing", "dynamic", "minimal"]
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,16 @@ class Ctx:
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def assert_raises(self, except_kind: type[BaseException] = BaseException):
|
def assert_raises(self, except_kind: type[BaseException] = BaseException):
|
||||||
|
"""
|
||||||
|
Asserts that a section of code will raise an exception.
|
||||||
|
```py
|
||||||
|
@test()
|
||||||
|
def it_works(ctx):
|
||||||
|
a = 1
|
||||||
|
with ctx.assert_raises():
|
||||||
|
assert a + 1 == 3
|
||||||
|
```
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
yield
|
yield
|
||||||
except except_kind as exc:
|
except except_kind as exc:
|
||||||
|
@ -50,14 +60,25 @@ class TestFailure:
|
||||||
|
|
||||||
|
|
||||||
class Test:
|
class Test:
|
||||||
|
"""
|
||||||
|
Represents one test to run.
|
||||||
|
"""
|
||||||
name: str
|
name: str
|
||||||
procedure: Callable[[Ctx], Any]
|
procedure: Callable[[Ctx], Any]
|
||||||
|
|
||||||
def __init__(self, name: str, procedure: Callable[[Ctx], Any]) -> None:
|
def __init__(self, name: str, procedure: Callable[[Ctx], Any]) -> None:
|
||||||
|
"""
|
||||||
|
Takes the name of the test and the test content procedure.
|
||||||
|
"""
|
||||||
self.name = name
|
self.name = name
|
||||||
self.procedure = procedure
|
self.procedure = procedure
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
"""
|
||||||
|
Runs this test infallibly.
|
||||||
|
|
||||||
|
Returns a `TestFailure` if the test failed or `None` if it succeeded.
|
||||||
|
"""
|
||||||
with CaptureOutput() as capture:
|
with CaptureOutput() as capture:
|
||||||
try:
|
try:
|
||||||
self.procedure(Ctx(self))
|
self.procedure(Ctx(self))
|
||||||
|
@ -69,7 +90,7 @@ class Suite:
|
||||||
"""
|
"""
|
||||||
A suite of tests.
|
A suite of tests.
|
||||||
|
|
||||||
Append test with the `Suite.test` decorator :
|
Append test with the `Suite.test` decorator.
|
||||||
```py
|
```py
|
||||||
suite = Suite("Feur")
|
suite = Suite("Feur")
|
||||||
|
|
||||||
|
@ -83,11 +104,28 @@ class Suite:
|
||||||
name: Union[str, None]
|
name: Union[str, None]
|
||||||
tests: list[Test]
|
tests: list[Test]
|
||||||
|
|
||||||
def __init__(self, name: Union[str, None] = None) -> None:
|
def __init__(self, name: Optional[str] = None) -> None:
|
||||||
|
"""
|
||||||
|
Creates an empty test suite.
|
||||||
|
|
||||||
|
Naming is optionnal.
|
||||||
|
"""
|
||||||
self.name = name
|
self.name = name
|
||||||
self.tests = []
|
self.tests = []
|
||||||
|
|
||||||
def test(self):
|
def test(self):
|
||||||
|
"""
|
||||||
|
Decorator used to append a function into the suite as a test.
|
||||||
|
```py
|
||||||
|
suite = Suite("Feur")
|
||||||
|
|
||||||
|
@suite.test()
|
||||||
|
def it_works(ctx):
|
||||||
|
assert 1 + 1 == 2
|
||||||
|
|
||||||
|
suite.run()
|
||||||
|
```
|
||||||
|
"""
|
||||||
def decorate(procedure: Callable[[Ctx], Any]) -> Callable[[Ctx], Any]:
|
def decorate(procedure: Callable[[Ctx], Any]) -> Callable[[Ctx], Any]:
|
||||||
name = procedure.__name__
|
name = procedure.__name__
|
||||||
self.tests.append(Test(name, procedure))
|
self.tests.append(Test(name, procedure))
|
||||||
|
@ -95,6 +133,11 @@ class Suite:
|
||||||
return decorate
|
return decorate
|
||||||
|
|
||||||
def run(self, filters: list[str] = []):
|
def run(self, filters: list[str] = []):
|
||||||
|
"""
|
||||||
|
Runs the test suite.
|
||||||
|
|
||||||
|
Optionnally filter to run by their name : Only keep tests which names contains all filters.
|
||||||
|
"""
|
||||||
if self.name is not None:
|
if self.name is not None:
|
||||||
print(" ", green("Suite"), bold(self.name))
|
print(" ", green("Suite"), bold(self.name))
|
||||||
to_run = [*self.filter_tests(filters)]
|
to_run = [*self.filter_tests(filters)]
|
||||||
|
@ -125,6 +168,11 @@ class Suite:
|
||||||
|
|
||||||
|
|
||||||
def get_inline_suite() -> Suite:
|
def get_inline_suite() -> Suite:
|
||||||
|
"""
|
||||||
|
Accessor of a singleton the `Suite` containing all inline tests.
|
||||||
|
|
||||||
|
Intended for internal use only.
|
||||||
|
"""
|
||||||
existing: Optional[Suite] = globals().get('_okipy_inline_suite')
|
existing: Optional[Suite] = globals().get('_okipy_inline_suite')
|
||||||
if existing is None:
|
if existing is None:
|
||||||
globals()['_okipy_inline_suite'] = existing = Suite()
|
globals()['_okipy_inline_suite'] = existing = Suite()
|
||||||
|
@ -132,6 +180,16 @@ def get_inline_suite() -> Suite:
|
||||||
|
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
|
"""
|
||||||
|
Decorator for declaring inline tests.
|
||||||
|
```py
|
||||||
|
@test()
|
||||||
|
def it_works(ctx):
|
||||||
|
a = 1
|
||||||
|
with ctx.assert_raises():
|
||||||
|
assert a + 1 == 3
|
||||||
|
```
|
||||||
|
"""
|
||||||
def decorate(procedure: Callable[[Ctx], Any]) -> Callable[[Ctx], Any]:
|
def decorate(procedure: Callable[[Ctx], Any]) -> Callable[[Ctx], Any]:
|
||||||
return get_inline_suite().test()(procedure)
|
return get_inline_suite().test()(procedure)
|
||||||
return decorate
|
return decorate
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue