ads2_2022/code/python/tests/tests_core/tests_calls.py

137 lines
4.8 KiB
Python

#!/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;