master > master: code py - unit tests aktualisiert

This commit is contained in:
RD 2022-06-11 14:02:09 +02:00
parent 17ea04cfee
commit d454f71bfa
12 changed files with 434 additions and 42 deletions

View File

@ -12,7 +12,6 @@ omit =
**/__init__.py
# ignore main.py
main.py
# TODO: increase code-coverage:
precision = 0
exclude_lines =
pragma: no cover

View File

@ -5,21 +5,42 @@
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from unittest import TestCase;
from pytest import fixture;
from src.thirdparty.run import *;
from src.thirdparty.types import *;
from tests.thirdparty.unit import *;
from src.core.log import log_dev;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CONSTANTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LOOP: Optional[AbstractEventLoop] = None;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# FIXTURES
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@fixture(scope='module')
def test():
@fixture(scope='module', autouse=True)
def test() -> TestCase:
return TestCase();
@fixture(scope='module')
def debug():
def log(*lines: str):
with open('logs/debug.log', 'a') as fp:
for line in lines:
print(line, end='\n', file=fp);
return log;
@fixture(scope='module', autouse=True)
def debug() -> Callable[..., None]:
'''
Fixture for development purposes only.
Logs to file 'logs/debug.log'.
'''
return log_dev;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# FIXTURES for async
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# NOTE: !!! Must be called 'event_loop' !!!
@fixture(scope='session', autouse=True)
def event_loop() -> AbstractEventLoop:
global LOOP;
if LOOP is None or LOOP.is_closed():
LOOP = asyncio_new_event_loop();
asyncio_set_event_loop(loop=LOOP);
return LOOP;

View File

@ -5,8 +5,7 @@
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from pytest import mark;
from pytest import fixture;
from tests.thirdparty.unit import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CONSTANTS

View File

@ -5,17 +5,230 @@
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from pytest import mark;
from pytest import fixture;
from src.thirdparty.log import *;
from src.thirdparty.misc import *;
from tests.thirdparty.unit import *;
from src.core.log import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# FIXTURES
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
@fixture(scope='module')
def message_1():
return lorem.sentence();
@fixture(scope='module')
def message_2():
return lorem.sentence();
@fixture(scope='module')
def message_3():
return lorem.sentence();
@fixture(scope='module')
def message_4():
return lorem.sentence();
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Test logging
# Test log debug
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
@mark.usefixtures('message_1', 'message_2', 'message_3', 'message_4')
def test_log_debug_at_debug_level(
test: TestCase,
caplog: LogCaptureFixture,
message_1: str,
message_2: str,
message_3: str,
message_4: str,
):
caplog.records.clear();
caplog.set_level(logging.DEBUG);
test.assertEqual(len(caplog.records), 0);
log_debug(message_1);
log_debug(message_2);
log_debug(message_3);
log_debug(message_4);
# check that none of the 4 debug messages were suppressed:
test.assertEqual(len(caplog.records), 4);
test.assertEqual(caplog.records[0].levelname, 'DEBUG');
test.assertEqual(caplog.records[0].message, message_1);
test.assertEqual(caplog.records[1].levelname, 'DEBUG');
test.assertEqual(caplog.records[1].message, message_2);
test.assertEqual(caplog.records[2].levelname, 'DEBUG');
test.assertEqual(caplog.records[2].message, message_3);
test.assertEqual(caplog.records[3].levelname, 'DEBUG');
test.assertEqual(caplog.records[3].message, message_4);
return;
@mark.usefixtures('message_1', 'message_2', 'message_3', 'message_4')
def test_log_debug_at_info_level(
test: TestCase,
caplog: LogCaptureFixture,
message_1: str,
message_2: str,
message_3: str,
message_4: str,
):
caplog.records.clear();
caplog.set_level(logging.INFO);
test.assertEqual(len(caplog.records), 0);
log_debug(message_1);
log_info(message_2);
log_error(message_3);
log_debug(message_4);
# check that debug messages suppressed:
test.assertNotEqual(len(caplog.records), 4);
test.assertEqual(len(caplog.records), 2);
test.assertEqual(caplog.records[0].levelname, 'INFO');
test.assertEqual(caplog.records[1].levelname, 'ERROR');
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Test log info
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@mark.parametrize(('level',), [(logging.DEBUG,), (logging.INFO,)])
@mark.usefixtures('message_1', 'message_2', 'message_3', 'message_4')
def test_log_info(
test: TestCase,
caplog: LogCaptureFixture,
message_1: str,
message_2: str,
message_3: str,
message_4: str,
level: int,
):
caplog.records.clear();
caplog.set_level(level);
test.assertEqual(len(caplog.records), 0);
log_info(message_1);
log_info(message_2);
log_info(message_3);
log_info(message_4);
# check that 4 info messages printed:
test.assertEqual(len(caplog.records), 4);
test.assertEqual(caplog.records[0].levelname, 'INFO');
test.assertEqual(caplog.records[0].message, message_1);
test.assertEqual(caplog.records[1].levelname, 'INFO');
test.assertEqual(caplog.records[1].message, message_2);
test.assertEqual(caplog.records[2].levelname, 'INFO');
test.assertEqual(caplog.records[2].message, message_3);
test.assertEqual(caplog.records[3].levelname, 'INFO');
test.assertEqual(caplog.records[3].message, message_4);
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Test log warn
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@mark.parametrize(('level',), [(logging.DEBUG,), (logging.INFO,)])
@mark.usefixtures('message_1', 'message_2', 'message_3', 'message_4')
def test_log_warn(
test: TestCase,
caplog: LogCaptureFixture,
message_1: str,
message_2: str,
message_3: str,
message_4: str,
level: int,
):
caplog.records.clear();
caplog.set_level(level);
test.assertEqual(len(caplog.records), 0);
log_warn(message_1);
log_warn(message_2);
log_warn(message_3);
log_warn(message_4);
# check that 4 warning messages printed:
test.assertEqual(len(caplog.records), 4);
test.assertEqual(caplog.records[0].levelname, 'WARNING');
test.assertEqual(caplog.records[0].message, message_1);
test.assertEqual(caplog.records[1].levelname, 'WARNING');
test.assertEqual(caplog.records[1].message, message_2);
test.assertEqual(caplog.records[2].levelname, 'WARNING');
test.assertEqual(caplog.records[2].message, message_3);
test.assertEqual(caplog.records[3].levelname, 'WARNING');
test.assertEqual(caplog.records[3].message, message_4);
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Test log error
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@mark.parametrize(('level',), [(logging.DEBUG,), (logging.INFO,)])
@mark.usefixtures('message_1', 'message_2', 'message_3', 'message_4')
def test_log_error(
test: TestCase,
caplog: LogCaptureFixture,
message_1: str,
message_2: str,
message_3: str,
message_4: str,
level: int,
):
caplog.records.clear();
caplog.set_level(level);
test.assertEqual(len(caplog.records), 0);
# assert that no sys-exit raised:
with does_not_raise():
log_error(message_1);
with does_not_raise():
log_error(message_2);
with does_not_raise():
log_error(message_3);
with does_not_raise():
log_error(message_4);
# check that 4 error messages printed:
test.assertEqual(len(caplog.records), 4);
test.assertEqual(caplog.records[0].levelname, 'ERROR');
test.assertEqual(caplog.records[0].message, message_1);
test.assertEqual(caplog.records[1].levelname, 'ERROR');
test.assertEqual(caplog.records[1].message, message_2);
test.assertEqual(caplog.records[2].levelname, 'ERROR');
test.assertEqual(caplog.records[2].message, message_3);
test.assertEqual(caplog.records[3].levelname, 'ERROR');
test.assertEqual(caplog.records[3].message, message_4);
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Test log fatal
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@mark.parametrize(('level',), [(logging.DEBUG,), (logging.INFO,)])
@mark.usefixtures('message_1', 'message_2', 'message_3', 'message_4')
def test_log_fatal(
test: TestCase,
caplog: LogCaptureFixture,
message_1: str,
message_2: str,
message_3: str,
message_4: str,
level: int,
):
caplog.records.clear();
caplog.set_level(level);
test.assertEqual(len(caplog.records), 0);
# intercept sys-exist 1:
with assert_raises(SystemExit) as caught:
log_fatal(message_1);
test.assertEqual(caught.value.code, 1);
with assert_raises(SystemExit):
log_fatal(message_2);
with assert_raises(SystemExit):
log_fatal(message_3);
with assert_raises(SystemExit):
log_fatal(message_4);
# check that 4 critical messages printed:
test.assertEqual(len(caplog.records), 4);
test.assertEqual(caplog.records[0].levelname, 'CRITICAL');
test.assertEqual(caplog.records[0].message, message_1);
test.assertEqual(caplog.records[1].levelname, 'CRITICAL');
test.assertEqual(caplog.records[1].message, message_2);
test.assertEqual(caplog.records[2].levelname, 'CRITICAL');
test.assertEqual(caplog.records[2].message, message_3);
test.assertEqual(caplog.records[3].levelname, 'CRITICAL');
test.assertEqual(caplog.records[3].message, message_4);
return;

View File

@ -0,0 +1,136 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.thirdparty.run import *;
from src.thirdparty.code import *;
from src.thirdparty.misc import *;
from src.thirdparty.types import *;
from tests.thirdparty.unit import *;
from src.core.calls import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# FIXTURES
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@fixture(scope='function')
def func_success_1() -> Callable[..., Result[int, list]]:
return MagicMock(spec=Callable[..., Result[int, list]], return_value=Ok(41));
@fixture(scope='function')
def func_success_2() -> Callable[..., Result[int, list]]:
return MagicMock(spec=Callable[..., Result[int, list]], return_value=Ok(42));
@fixture(scope='function')
def func_error_1() -> Callable[..., Result[int, list]]:
return MagicMock(spec=Callable[..., Result[int, list]], return_value=Err(['RESULT ERROR 1']));
@fixture(scope='function')
def func_error_2() -> Callable[..., Result[int, list]]:
return MagicMock(spec=Callable[..., Result[int, list]], return_value=Err(['RESULT ERROR 2']));
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# MOCKS - for inspection
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def func_do_something1():
pass;
def func_do_something2():
pass;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Test CallResult class
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def test_callResult(test: TestCase):
with does_not_raise():
x = CallResult();
x = CallResult(message='hello');
test.assertEqual(x.action_taken, False);
test.assertIsNotNone(x.message);
x = CallResult(action_taken=True);
test.assertEqual(x.action_taken, True);
test.assertIsNone(x.message);
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Test CallError class
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def test_callerror(test: TestCase):
with does_not_raise():
e = CallError(tag='some-method');
e = CallError(tag='something');
test.assertEqual(e.errors, []);
e = CallError(tag='something', err=[]);
test.assertEqual(e.errors, []);
e = CallError(tag='something', err=Nothing());
test.assertEqual(e.errors, []);
e = CallError(tag='something', err='oh no!');
test.assertEqual(e.errors, ['oh no!']);
e = CallError(tag='something', err=Exception('oh no!'));
test.assertEqual(e.errors, ['oh no!']);
e = CallError(tag='something', err=['oh no!']);
test.assertEqual(e.errors, ['oh no!']);
e = CallError(tag='something', err=Exception('oh no!'));
test.assertEqual(len(e), 1);
e.append(Nothing());
test.assertEqual(len(e), 1);
e.append(Some('another error'));
test.assertEqual(len(e), 2);
test.assertEqual(e.errors, ['oh no!', 'another error']);
test.assertRegexpMatches(str(e), r"^CallError\(\s*tag\s*=\s*'something',\s*errors\s*=\s*\[.*\]\)$");
e2 = CallError(tag='something-else');
e2.append('yet another fail');
e.extend(e2);
test.assertEqual(len(e), 3);
test.assertEqual(e.errors, ['oh no!', 'another error', 'yet another fail']);
test.assertRegexpMatches(str(e), r"^CallError\(\s*tag\s*=\s*'something',\s*errors\s*=\s*\[.*\]\)$");
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Test run_safely
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def test_run_safely(test: TestCase):
@run_safely(tag='recognise int', error_message='unrecognise string')
def action1(x: str) -> Result[int, CallError]:
return Ok(int(x));
assert action1('5') == Ok(5);
result = action1('not a number');
assert isinstance(result, Err);
err = result.unwrap_err();
assert isinstance(err, CallError);
assert err.tag == 'recognise int';
assert err.errors == ['unrecognise string'];
def test_run_safely_no_error_message(test: TestCase):
@run_safely('recognise int')
def action2(x: str) -> Result[int, CallError]:
return Ok(int(x));
assert action2('5') == Ok(5);
result = action2('not a number');
assert isinstance(result, Err);
err = result.unwrap_err();
assert isinstance(err, CallError);
assert err.tag == 'recognise int';
assert len(err.errors) == 1;

View File

@ -5,9 +5,7 @@
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from unittest import TestCase;
from pytest import mark;
from pytest import fixture;
from tests.thirdparty.unit import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CONSTANTS

View File

@ -5,11 +5,7 @@
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from contextlib import nullcontext as does_not_raise
from collections import Counter;
from pytest import mark;
from pytest import fixture;
from unittest import TestCase;
from tests.thirdparty.unit import *;
from src.models.graphs import *;

View File

@ -5,14 +5,9 @@
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import pytest;
from pytest import mark;
from pytest import fixture;
from pytest import lazy_fixture;
from unittest import TestCase;
from unittest.mock import patch;
from tests.thirdparty.unit import *;
from src.thirdparty.types import *;
from src.models.graphs import *;
from src.algorithms.tarjan import *;
@ -77,7 +72,7 @@ def test_tarjan(test, G, expected):
@mark.parametrize(('G', 'expected'), [ (lazy_fixture('graph1'), [[1], [3], [2,4]])])
@mark.usefixtures('test')
def test_failable_tarjan(test, G, expected):
with pytest.raises(AssertionError):
with assert_raises(AssertionError):
test_tarjan(test, G, expected);
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -5,8 +5,7 @@
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from pytest import mark;
from pytest import fixture;
from tests.thirdparty.unit import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# FIXTURES

View File

@ -5,10 +5,7 @@
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from contextlib import nullcontext as does_not_raise
import pytest;
from pytest import mark;
from unittest import TestCase;
from tests.thirdparty.unit import *;
from src.models.stacks import Stack;
@ -56,7 +53,7 @@ def test_stack_error_po(test: TestCase):
stack.push('hallo');
stack.push('welt');
stack.push('!');
with pytest.raises(Exception):
with assert_raises(Exception):
stack.pop();
stack.pop();
stack.pop();

View File

39
code/python/tests/thirdparty/unit.py vendored Normal file
View File

@ -0,0 +1,39 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# for unit tests:
import anyio;
from contextlib import nullcontext as does_not_raise;
from pytest import fixture;
from pytest_lazyfixture import lazy_fixture;
from pytest import LogCaptureFixture;
from pytest import mark;
from pytest import raises as assert_raises;
from testfixtures import LogCapture;
from unittest import TestCase;
from unittest.mock import patch;
from unittest.mock import MagicMock;
from unittest.mock import PropertyMock;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'anyio',
'does_not_raise',
'fixture',
'lazy_fixture',
'LogCaptureFixture',
'mark',
'assert_raises',
'LogCapture',
'TestCase',
'patch',
'MagicMock',
'PropertyMock',
];