Compare commits
No commits in common. "222aa4547fa5c5b6500bcd0b71cfbac8c6c3d034" and "d8f6c802b2147c2c15595696e156fb84afa319d9" have entirely different histories.
222aa4547f
...
d8f6c802b2
@ -12,6 +12,7 @@ omit =
|
|||||||
**/__init__.py
|
**/__init__.py
|
||||||
# ignore main.py
|
# ignore main.py
|
||||||
main.py
|
main.py
|
||||||
|
# TODO: increase code-coverage:
|
||||||
precision = 0
|
precision = 0
|
||||||
exclude_lines =
|
exclude_lines =
|
||||||
pragma: no cover
|
pragma: no cover
|
||||||
|
@ -6,13 +6,10 @@ info:
|
|||||||
ADS2 an der Universität Leipzig (Sommersemester 2022)
|
ADS2 an der Universität Leipzig (Sommersemester 2022)
|
||||||
implementiert.
|
implementiert.
|
||||||
options:
|
options:
|
||||||
# log-level: DEBUG
|
|
||||||
log-level: INFO
|
|
||||||
verbose: &ref_verbose true
|
|
||||||
tarjan:
|
tarjan:
|
||||||
verbose: *ref_verbose
|
verbose: true
|
||||||
tsp:
|
tsp:
|
||||||
verbose: *ref_verbose
|
verbose: true
|
||||||
hirschberg:
|
hirschberg:
|
||||||
# standardwerte sind (1, 1) und (2, 1):
|
# standardwerte sind (1, 1) und (2, 1):
|
||||||
penality-gap: 1
|
penality-gap: 1
|
||||||
|
@ -11,29 +11,51 @@ import sys
|
|||||||
os.chdir(os.path.join(os.path.dirname(__file__)));
|
os.chdir(os.path.join(os.path.dirname(__file__)));
|
||||||
sys.path.insert(0, os.getcwd());
|
sys.path.insert(0, os.getcwd());
|
||||||
|
|
||||||
from src.models.config import *;
|
from src.thirdparty.maths import *;
|
||||||
from src.core import log;
|
|
||||||
from src.setup import config;
|
from models.generated.config import *;
|
||||||
from src import api;
|
from models.generated.commands import *;
|
||||||
|
from src.core.log import *;
|
||||||
|
from src.setup.config import *;
|
||||||
|
from src.models.graphs import *;
|
||||||
|
from src.algorithms.tarjan import *;
|
||||||
|
from src.algorithms.tsp import *;
|
||||||
|
from src.algorithms.hirschberg import *;
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# GLOBAL CONSTANTS/VARIABLES
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# MAIN METHOD
|
# MAIN METHOD
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
def enter(*args: str):
|
def enter():
|
||||||
# set logging level:
|
for command in COMMANDS:
|
||||||
log.configure_logging(config.LOG_LEVEL);
|
if isinstance(command, CommandTarjan):
|
||||||
|
tarjan_algorithm(
|
||||||
# process inputs:
|
G = Graph(
|
||||||
if len(args) == 0:
|
nodes=command.nodes,
|
||||||
# Führe befehle in Assets aus:
|
edges=list(map(tuple, command.edges)),
|
||||||
for command in config.COMMANDS:
|
),
|
||||||
result = api.run_command(command);
|
verbose = OPTIONS.tarjan.verbose
|
||||||
log.log_result(result, debug=True); # ignored if log-level >> DEBUG
|
);
|
||||||
else:
|
if isinstance(command, CommandTsp):
|
||||||
# Führe CLI-Befehl aus:
|
tsp_algorithm(
|
||||||
result = api.run_command_from_json(args[0]);
|
dist = np.asarray(command.dist, dtype=float),
|
||||||
log.log_result(result, debug=True); # ignored if log-level >> DEBUG
|
optimise = min if command.optimise == EnumTSPOptimise.min else max,
|
||||||
|
verbose = OPTIONS.tsp.verbose,
|
||||||
|
);
|
||||||
|
elif isinstance(command, CommandHirschberg):
|
||||||
|
hirschberg_algorithm(
|
||||||
|
X = command.word1,
|
||||||
|
Y = command.word2,
|
||||||
|
once = command.once,
|
||||||
|
verbose = OPTIONS.hirschberg.verbose,
|
||||||
|
show = OPTIONS.hirschberg.show,
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -41,5 +63,4 @@ def enter(*args: str):
|
|||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.tracebacklimit = 0;
|
enter();
|
||||||
enter(*sys.argv[1:]);
|
|
||||||
|
@ -48,17 +48,9 @@ components:
|
|||||||
Options pertaining to the rudimentary setup of the app.
|
Options pertaining to the rudimentary setup of the app.
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- log-level
|
|
||||||
- tsp
|
- tsp
|
||||||
- tarjan
|
|
||||||
- hirschberg
|
- hirschberg
|
||||||
properties:
|
properties:
|
||||||
log-level:
|
|
||||||
$ref: '#/components/schemas/EnumLogLevel'
|
|
||||||
verbose:
|
|
||||||
description: Global setting for verbosity.
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
tarjan:
|
tarjan:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
@ -114,16 +106,6 @@ components:
|
|||||||
$ref: '#/components/schemas/EnumHirschbergShow'
|
$ref: '#/components/schemas/EnumHirschbergShow'
|
||||||
default: []
|
default: []
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# Enum LogLevel
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
EnumLogLevel:
|
|
||||||
description: |-
|
|
||||||
Enumeration of settings for log level.
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- INFO
|
|
||||||
- DEBUG
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# Enum Hirschberg - Verbosity options
|
# Enum Hirschberg - Verbosity options
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
EnumHirschbergVerbosity:
|
EnumHirschbergVerbosity:
|
||||||
|
@ -14,6 +14,5 @@ from src.algorithms.hirschberg.display import *;
|
|||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'simple_algorithm',
|
|
||||||
'hirschberg_algorithm',
|
'hirschberg_algorithm',
|
||||||
];
|
];
|
||||||
|
@ -32,6 +32,7 @@ def simple_algorithm(
|
|||||||
X: str,
|
X: str,
|
||||||
Y: str,
|
Y: str,
|
||||||
verbose: List[EnumHirschbergVerbosity] = [],
|
verbose: List[EnumHirschbergVerbosity] = [],
|
||||||
|
show: List[EnumHirschbergShow] = [],
|
||||||
) -> Tuple[str, str]:
|
) -> Tuple[str, str]:
|
||||||
'''
|
'''
|
||||||
Dieser Algorithmus berechnet die Edit-Distanzen + optimale Richtungen ein Mal.
|
Dieser Algorithmus berechnet die Edit-Distanzen + optimale Richtungen ein Mal.
|
||||||
@ -49,6 +50,7 @@ def simple_algorithm(
|
|||||||
def hirschberg_algorithm(
|
def hirschberg_algorithm(
|
||||||
X: str,
|
X: str,
|
||||||
Y: str,
|
Y: str,
|
||||||
|
once: bool = False,
|
||||||
verbose: List[EnumHirschbergVerbosity] = [],
|
verbose: List[EnumHirschbergVerbosity] = [],
|
||||||
show: List[EnumHirschbergShow] = [],
|
show: List[EnumHirschbergShow] = [],
|
||||||
) -> Tuple[str, str]:
|
) -> Tuple[str, str]:
|
||||||
@ -62,6 +64,10 @@ def hirschberg_algorithm(
|
|||||||
Daraus wird unmittelbar ein optimales Alignment bestimmt.
|
Daraus wird unmittelbar ein optimales Alignment bestimmt.
|
||||||
Des Weiteren werden Zeitkosten durch Divide-and-Conquer klein gehalten.
|
Des Weiteren werden Zeitkosten durch Divide-and-Conquer klein gehalten.
|
||||||
'''
|
'''
|
||||||
|
# ggf. nur den simplen Algorithmus ausführen:
|
||||||
|
if once:
|
||||||
|
return simple_algorithm(X=X, Y=Y, verbose=verbose, show=show);
|
||||||
|
|
||||||
align = hirschberg_algorithm_step(X=X, Y=Y, depth=1, verbose=verbose, show=show);
|
align = hirschberg_algorithm_step(X=X, Y=Y, depth=1, verbose=verbose, show=show);
|
||||||
word_x = align.as_string1();
|
word_x = align.as_string1();
|
||||||
word_y = align.as_string2();
|
word_y = align.as_string2();
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from src.thirdparty.code import *;
|
|
||||||
|
|
||||||
from models.generated.commands import *;
|
|
||||||
from src.models.config import *
|
|
||||||
from src.endpoints import *;
|
|
||||||
from src.core.calls import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'run_command',
|
|
||||||
'run_command_from_json',
|
|
||||||
];
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# API METHODS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
@run_safely(tag='api-from-json')
|
|
||||||
def run_command_from_json(command_json: str) -> Result[CallResult, CallError]:
|
|
||||||
command = command_from_json(command_json);
|
|
||||||
return run_command(command);
|
|
||||||
|
|
||||||
@run_safely(tag='api-from-command')
|
|
||||||
def run_command(command: Command) -> Result[CallResult, CallError]:
|
|
||||||
if isinstance(command, CommandTarjan):
|
|
||||||
return endpoint_tarjan(command);
|
|
||||||
if isinstance(command, CommandTsp):
|
|
||||||
return endpoint_tsp(command);
|
|
||||||
elif isinstance(command, CommandHirschberg):
|
|
||||||
return endpoint_hirschberg(command);
|
|
||||||
raise Exception(f'No endpoint set for `{command.name.value}`-command type.');
|
|
@ -1,149 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from __future__ import annotations;
|
|
||||||
|
|
||||||
from src.thirdparty.code import *;
|
|
||||||
from src.thirdparty.misc import *;
|
|
||||||
from src.thirdparty.run import *;
|
|
||||||
from src.thirdparty.types import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'CallResult',
|
|
||||||
'CallError',
|
|
||||||
'run_safely',
|
|
||||||
];
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# CONSTANTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
# local usage only
|
|
||||||
T = TypeVar('T');
|
|
||||||
V = TypeVar('V');
|
|
||||||
E = TypeVar('E', bound=list);
|
|
||||||
ARGS = ParamSpec('ARGS');
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# CLASS Trace for debugging only!
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class CallResult(): # pragma: no cover
|
|
||||||
'''
|
|
||||||
An auxiliary class which keeps track of the latest return value during calls.
|
|
||||||
'''
|
|
||||||
action_taken: bool = field(default=False);
|
|
||||||
message: Optional[Any] = field(default=None);
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class CallErrorRaw(): # pragma: no cover
|
|
||||||
timestamp: str = field();
|
|
||||||
tag: str = field();
|
|
||||||
errors: List[str] = field(default_factory=list);
|
|
||||||
|
|
||||||
class CallError(CallErrorRaw):
|
|
||||||
'''
|
|
||||||
An auxiliary class which keeps track of potentially multiple errors during calls.
|
|
||||||
'''
|
|
||||||
timestamp: str;
|
|
||||||
tag: str;
|
|
||||||
errors: List[str];
|
|
||||||
|
|
||||||
def __init__(self, tag: str, err: Any = Nothing()):
|
|
||||||
self.timestamp = str(datetime.now());
|
|
||||||
self.tag = tag;
|
|
||||||
self.errors = [];
|
|
||||||
if isinstance(err, list):
|
|
||||||
for e in err:
|
|
||||||
self.append(e);
|
|
||||||
else:
|
|
||||||
self.append(err);
|
|
||||||
|
|
||||||
def __len__(self) -> int:
|
|
||||||
return len(self.errors);
|
|
||||||
|
|
||||||
def append(self, e: Any):
|
|
||||||
if isinstance(e, Nothing):
|
|
||||||
return;
|
|
||||||
if isinstance(e, Some):
|
|
||||||
e = e.unwrap();
|
|
||||||
self.errors.append(str(e));
|
|
||||||
|
|
||||||
def extend(self, E: CallError):
|
|
||||||
self.errors.extend(E.errors);
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return f'CallError(tag=\'{self.tag}\', errors={self.errors})';
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return self.__repr__();
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# DECORATOR - forces methods to run safely
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
def run_safely(tag: Union[str, None] = None, error_message: Union[str, None] = None):
|
|
||||||
'''
|
|
||||||
Creates a decorator for an action to perform it safely.
|
|
||||||
|
|
||||||
@inputs (parameters)
|
|
||||||
- `tag` - optional string to aid error tracking.
|
|
||||||
- `error_message` - optional string for an error message.
|
|
||||||
|
|
||||||
### Example usage ###
|
|
||||||
```py
|
|
||||||
@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'];
|
|
||||||
|
|
||||||
@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;
|
|
||||||
```
|
|
||||||
NOTE: in the second example, err.errors is a list containing
|
|
||||||
the stringified Exception generated when calling `int('not a number')`.
|
|
||||||
'''
|
|
||||||
def dec(action: Callable[ARGS, Result[V, CallError]]) -> Callable[ARGS, Result[V, CallError]]:
|
|
||||||
'''
|
|
||||||
Wraps action with return type Result[..., CallError],
|
|
||||||
so that it is performed safely a promise,
|
|
||||||
catching any internal exceptions as an Err(...)-component of the Result.
|
|
||||||
'''
|
|
||||||
@wraps(action)
|
|
||||||
def wrapped_action(*_, **__) -> Result[V, CallError]:
|
|
||||||
# NOTE: intercept Exceptions first, then flatten:
|
|
||||||
return Result.of(lambda: action(*_, **__)) \
|
|
||||||
.or_else(
|
|
||||||
lambda err: Err(CallError(
|
|
||||||
tag = tag or action.__name__,
|
|
||||||
err = error_message or err
|
|
||||||
))
|
|
||||||
) \
|
|
||||||
.and_then(lambda V: V);
|
|
||||||
return wrapped_action;
|
|
||||||
return dec;
|
|
@ -5,93 +5,60 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from src.thirdparty.code import *;
|
#
|
||||||
from src.thirdparty.log import *;
|
|
||||||
from src.thirdparty.types import *;
|
|
||||||
|
|
||||||
from src.core.calls import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# EXPORTS
|
# EXPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'LOG_LEVELS',
|
|
||||||
'configure_logging',
|
|
||||||
'log_info',
|
'log_info',
|
||||||
'log_debug',
|
'log_debug',
|
||||||
'log_warn',
|
'log_warn',
|
||||||
'log_error',
|
'log_error',
|
||||||
'log_fatal',
|
'log_fatal',
|
||||||
'log_result',
|
|
||||||
'log_dev',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# CONSTANTS
|
# METHODS logging
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
_LOGGING_DEBUG_FILE: str = 'logs/debug.log';
|
def log_info(*text: str):
|
||||||
|
'''
|
||||||
class LOG_LEVELS(Enum): # pragma: no cover
|
Prints an info message
|
||||||
INFO = logging.INFO;
|
'''
|
||||||
DEBUG = logging.DEBUG;
|
for line in text:
|
||||||
|
print("[\x1b[94;1mINFO\x1b[0m] {}".format(line));
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# METHODS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
def configure_logging(level: LOG_LEVELS): # pragma: no cover
|
|
||||||
logging.basicConfig(
|
|
||||||
format = '[\x1b[1m%(levelname)s\x1b[0m] %(message)s',
|
|
||||||
level = level.value,
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
def log_debug(*messages: Any):
|
def log_debug(*text: str):
|
||||||
logging.debug(*messages);
|
'''
|
||||||
|
Prints a debug message
|
||||||
|
'''
|
||||||
|
for line in text:
|
||||||
|
print("[\x1b[96;1mDEBUG\x1b[95;0m] {}".format(line));
|
||||||
|
return;
|
||||||
|
|
||||||
def log_info(*messages: Any):
|
def log_warn(*text: str):
|
||||||
logging.info(*messages);
|
'''
|
||||||
|
Prints a warning message
|
||||||
|
'''
|
||||||
|
for line in text:
|
||||||
|
print("[\x1b[93;1mWARNING\x1b[0m] {}".format(line));
|
||||||
|
return;
|
||||||
|
|
||||||
def log_warn(*messages: Any):
|
def log_error(*text: str):
|
||||||
logging.warning(*messages);
|
'''
|
||||||
|
Prints an error message
|
||||||
|
'''
|
||||||
|
for line in text:
|
||||||
|
print("[\x1b[91;1mERROR\x1b[0m] {}".format(line));
|
||||||
|
return;
|
||||||
|
|
||||||
def log_error(*messages: Any):
|
def log_fatal(*text: str):
|
||||||
logging.error(*messages);
|
'''
|
||||||
|
Prints a fatal error message + crashes
|
||||||
def log_fatal(*messages: Any):
|
'''
|
||||||
logging.fatal(*messages);
|
for line in text:
|
||||||
|
print("[\x1b[91;1mFATAL\x1b[0m] {}".format(line));
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# Special Methods
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
def log_result(result: Result[CallResult, CallError], debug: bool = False):
|
|
||||||
'''
|
|
||||||
Logs safely encapsulated result of call as either debug/info or error.
|
|
||||||
|
|
||||||
@inputs
|
|
||||||
- `result` - the result of the call.
|
|
||||||
- `debug = False` (default) - if the result is okay, will be logged as an INFO message.
|
|
||||||
- `debug = True` - if the result is okay, will be logged as a DEBUG message.
|
|
||||||
'''
|
|
||||||
if isinstance(result, Ok):
|
|
||||||
value = result.unwrap();
|
|
||||||
if debug:
|
|
||||||
log_debug(asdict(value));
|
|
||||||
else:
|
|
||||||
log_info(asdict(value));
|
|
||||||
else:
|
|
||||||
err = result.unwrap_err();
|
|
||||||
log_error(asdict(err));
|
|
||||||
return;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# DEBUG LOGGING FOR DEVELOPMENT
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
def log_dev(*messages: Any): # pragma: no cover
|
|
||||||
with open(_LOGGING_DEBUG_FILE, 'a') as fp:
|
|
||||||
print(*messages, file=fp);
|
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from src.endpoints.ep_algorithm_hirschberg import *;
|
|
||||||
from src.endpoints.ep_algorithm_tarjan import *;
|
|
||||||
from src.endpoints.ep_algorithm_tsp import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'endpoint_hirschberg',
|
|
||||||
'endpoint_tarjan',
|
|
||||||
'endpoint_tsp',
|
|
||||||
];
|
|
@ -1,42 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from src.thirdparty.code import *;
|
|
||||||
|
|
||||||
from models.generated.commands import *;
|
|
||||||
from src.core.calls import *;
|
|
||||||
from src.setup import config;
|
|
||||||
from src.algorithms.hirschberg import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'endpoint_hirschberg',
|
|
||||||
];
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# ENDPOINT
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
@run_safely()
|
|
||||||
def endpoint_hirschberg(command: CommandHirschberg) -> Result[CallResult, CallError]:
|
|
||||||
if command.once:
|
|
||||||
result = simple_algorithm(
|
|
||||||
X = command.word1,
|
|
||||||
Y = command.word2,
|
|
||||||
verbose = config.OPTIONS.hirschberg.verbose,
|
|
||||||
);
|
|
||||||
else:
|
|
||||||
result = hirschberg_algorithm(
|
|
||||||
X = command.word1,
|
|
||||||
Y = command.word2,
|
|
||||||
verbose = config.OPTIONS.hirschberg.verbose,
|
|
||||||
show = config.OPTIONS.hirschberg.show,
|
|
||||||
);
|
|
||||||
return Ok(CallResult(action_taken=True, message=result));
|
|
@ -1,37 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from src.thirdparty.code import *;
|
|
||||||
|
|
||||||
from models.generated.commands import *;
|
|
||||||
from src.core.calls import *;
|
|
||||||
from src.setup import config;
|
|
||||||
from src.models.graphs import *;
|
|
||||||
from src.algorithms.tarjan import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'endpoint_tarjan',
|
|
||||||
];
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# ENDPOINT
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
@run_safely()
|
|
||||||
def endpoint_tarjan(command: CommandTarjan) -> Result[CallResult, CallError]:
|
|
||||||
result = tarjan_algorithm(
|
|
||||||
G = Graph(
|
|
||||||
nodes=command.nodes,
|
|
||||||
edges=list(map(tuple, command.edges)),
|
|
||||||
),
|
|
||||||
verbose = config.OPTIONS.tarjan.verbose
|
|
||||||
);
|
|
||||||
return Ok(CallResult(action_taken=True, message=result));
|
|
@ -1,35 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from src.thirdparty.code import *;
|
|
||||||
from src.thirdparty.maths import *;
|
|
||||||
|
|
||||||
from models.generated.commands import *;
|
|
||||||
from src.core.calls import *;
|
|
||||||
from src.setup import config;
|
|
||||||
from src.algorithms.tsp import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'endpoint_tsp',
|
|
||||||
];
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# ENDPOINT
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
@run_safely()
|
|
||||||
def endpoint_tsp(command: CommandTsp) -> Result[CallResult, CallError]:
|
|
||||||
result = tsp_algorithm(
|
|
||||||
dist = np.asarray(command.dist, dtype=float),
|
|
||||||
optimise = min if command.optimise == EnumTSPOptimise.min else max,
|
|
||||||
verbose = config.OPTIONS.tsp.verbose,
|
|
||||||
);
|
|
||||||
return Ok(CallResult(action_taken=True, message=result));
|
|
@ -1,19 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from src.models.config.app import *;
|
|
||||||
from src.models.config.commands import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'log_level',
|
|
||||||
'command_from_json',
|
|
||||||
'interpret_command',
|
|
||||||
];
|
|
@ -1,31 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from models.generated.config import AppOptions;
|
|
||||||
from models.generated.config import EnumLogLevel;
|
|
||||||
from src.core.log import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'log_level',
|
|
||||||
];
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# METHODS log level
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
def log_level(options: AppOptions) -> LOG_LEVELS:
|
|
||||||
match options.log_level:
|
|
||||||
case EnumLogLevel.debug:
|
|
||||||
return LOG_LEVELS.DEBUG;
|
|
||||||
case EnumLogLevel.info:
|
|
||||||
return LOG_LEVELS.INFO;
|
|
||||||
case _:
|
|
||||||
return LOG_LEVELS.INFO;
|
|
@ -1,45 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
from src.thirdparty.config import *;
|
|
||||||
|
|
||||||
from models.generated.commands import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'command_from_json',
|
|
||||||
'interpret_command',
|
|
||||||
];
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# METHODS Convert to appropriate command type
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
def command_from_json(command_json: str) -> Command:
|
|
||||||
try:
|
|
||||||
instructions = json.loads(command_json);
|
|
||||||
except:
|
|
||||||
raise Exception('Invalid json!');
|
|
||||||
try:
|
|
||||||
command = Command(**instructions);
|
|
||||||
except:
|
|
||||||
raise Exception('Invalid instruction format - consult schema!');
|
|
||||||
command = interpret_command(command);
|
|
||||||
return command;
|
|
||||||
|
|
||||||
def interpret_command(command: Command) -> Command:
|
|
||||||
match command.name:
|
|
||||||
case EnumAlgorithmNames.tarjan:
|
|
||||||
return CommandTarjan(**command.dict());
|
|
||||||
case EnumAlgorithmNames.tsp:
|
|
||||||
return CommandTsp(**command.dict());
|
|
||||||
case EnumAlgorithmNames.hirschberg:
|
|
||||||
return CommandHirschberg(**command.dict());
|
|
||||||
raise command;
|
|
@ -6,7 +6,7 @@
|
|||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from src.thirdparty.types import *;
|
from src.thirdparty.types import *;
|
||||||
from src.setup import config;
|
from src.setup.config import *;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# EXPORTS
|
# EXPORTS
|
||||||
@ -23,6 +23,6 @@ __all__ = [
|
|||||||
class Directions(Enum):
|
class Directions(Enum):
|
||||||
UNSET = -1;
|
UNSET = -1;
|
||||||
# Prioritäten hier setzen
|
# Prioritäten hier setzen
|
||||||
DIAGONAL = config.OPTIONS.hirschberg.move_priorities.diagonal;
|
DIAGONAL = OPTIONS.hirschberg.move_priorities.diagonal;
|
||||||
HORIZONTAL = config.OPTIONS.hirschberg.move_priorities.horizontal;
|
HORIZONTAL = OPTIONS.hirschberg.move_priorities.horizontal;
|
||||||
VERTICAL = config.OPTIONS.hirschberg.move_priorities.vertical;
|
VERTICAL = OPTIONS.hirschberg.move_priorities.vertical;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from src.thirdparty.types import *;
|
from src.thirdparty.types import *;
|
||||||
from src.setup import config;
|
from src.setup.config import *;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# EXPORTS
|
# EXPORTS
|
||||||
@ -22,7 +22,7 @@ __all__ = [
|
|||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
def gap_penalty(x: str):
|
def gap_penalty(x: str):
|
||||||
return config.OPTIONS.hirschberg.penality_gap;
|
return OPTIONS.hirschberg.penality_gap;
|
||||||
|
|
||||||
def missmatch_penalty(x: str, y: str):
|
def missmatch_penalty(x: str, y: str):
|
||||||
return 0 if x == y else config.OPTIONS.hirschberg.penality_mismatch;
|
return 0 if x == y else OPTIONS.hirschberg.penality_mismatch;
|
||||||
|
@ -12,8 +12,6 @@ from src.thirdparty.types import *;
|
|||||||
|
|
||||||
from models.generated.config import *;
|
from models.generated.config import *;
|
||||||
from models.generated.commands import *;
|
from models.generated.commands import *;
|
||||||
from src.core.log import *;
|
|
||||||
from src.models.config import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# EXPORTS
|
# EXPORTS
|
||||||
@ -43,16 +41,21 @@ def load_assets_config(path: str) -> Config: # pragma: no cover
|
|||||||
return Config(**assets);
|
return Config(**assets);
|
||||||
|
|
||||||
def create_commands(path: str) -> List[Command]: # pragma: no cover
|
def create_commands(path: str) -> List[Command]: # pragma: no cover
|
||||||
|
commands = [];
|
||||||
with open(path, 'r') as fp:
|
with open(path, 'r') as fp:
|
||||||
assets = yaml_load(fp, Loader=yaml_FullLoader);
|
assets = yaml_load(fp, Loader=yaml_FullLoader);
|
||||||
return [
|
for command in assets:
|
||||||
interpret_command(Command(**instruction))
|
match Command(**command).name:
|
||||||
for instruction in assets or []
|
case EnumAlgorithmNames.tarjan:
|
||||||
];
|
commands.append(CommandTarjan(**command));
|
||||||
|
case EnumAlgorithmNames.tsp:
|
||||||
|
commands.append(CommandTsp(**command));
|
||||||
|
case EnumAlgorithmNames.hirschberg:
|
||||||
|
commands.append(CommandHirschberg(**command));
|
||||||
|
return commands;
|
||||||
|
|
||||||
# use lazy loaing to ensure that values only loaded (once) when used
|
# use lazy loaing to ensure that values only loaded (once) when used
|
||||||
CONFIG: Config = lazy(load_assets_config, path=PATH_ASSETS_CONFIG);
|
CONFIG: Config = lazy(load_assets_config, path=PATH_ASSETS_CONFIG);
|
||||||
INFO: Info = lazy(lambda x: x.info, CONFIG);
|
INFO: Info = lazy(lambda x: x.info, CONFIG);
|
||||||
OPTIONS: AppOptions = lazy(lambda x: x.options, CONFIG);
|
OPTIONS: AppOptions = lazy(lambda x: x.options, CONFIG);
|
||||||
LOG_LEVEL: LOG_LEVELS = lazy(log_level, OPTIONS);
|
COMMANDS: List[Command] = lazy(create_commands, path=PATH_ASSETS_COMMANDS);
|
||||||
COMMANDS: List[Command] = lazy(create_commands, path=PATH_ASSETS_COMMANDS);
|
|
||||||
|
18
code/python/src/thirdparty/log.py
vendored
18
code/python/src/thirdparty/log.py
vendored
@ -1,18 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
import logging;
|
|
||||||
from logging import LogRecord;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'logging',
|
|
||||||
'LogRecord',
|
|
||||||
];
|
|
6
code/python/src/thirdparty/misc.py
vendored
6
code/python/src/thirdparty/misc.py
vendored
@ -5,9 +5,6 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from datetime import datetime;
|
|
||||||
from datetime import timedelta;
|
|
||||||
import lorem;
|
|
||||||
import re;
|
import re;
|
||||||
from textwrap import dedent;
|
from textwrap import dedent;
|
||||||
|
|
||||||
@ -16,9 +13,6 @@ from textwrap import dedent;
|
|||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'lorem',
|
|
||||||
'datetime',
|
|
||||||
'timedelta',
|
|
||||||
're',
|
're',
|
||||||
'dedent',
|
'dedent',
|
||||||
];
|
];
|
||||||
|
41
code/python/src/thirdparty/run.py
vendored
41
code/python/src/thirdparty/run.py
vendored
@ -1,41 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# IMPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
import aiohttp;
|
|
||||||
from asyncio import Future;
|
|
||||||
from asyncio import gather as asyncio_gather;
|
|
||||||
from asyncio import get_event_loop as asyncio_get_event_loop;
|
|
||||||
from asyncio import new_event_loop as asyncio_new_event_loop;
|
|
||||||
from asyncio import set_event_loop as asyncio_set_event_loop;
|
|
||||||
from asyncio import ensure_future as asyncio_ensure_future;
|
|
||||||
from asyncio import sleep as asyncio_sleep;
|
|
||||||
from asyncio import AbstractEventLoop;
|
|
||||||
from codetiming import Timer;
|
|
||||||
|
|
||||||
from signal import Signals;
|
|
||||||
from signal import SIGINT;
|
|
||||||
from signal import SIGTERM;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# EXPORTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'aiohttp',
|
|
||||||
'Future',
|
|
||||||
'asyncio_gather',
|
|
||||||
'asyncio_ensure_future',
|
|
||||||
'asyncio_get_event_loop',
|
|
||||||
'asyncio_new_event_loop',
|
|
||||||
'asyncio_set_event_loop',
|
|
||||||
'asyncio_sleep',
|
|
||||||
'AbstractEventLoop',
|
|
||||||
'Timer',
|
|
||||||
'Signals',
|
|
||||||
'SIGINT',
|
|
||||||
'SIGTERM',
|
|
||||||
];
|
|
2
code/python/src/thirdparty/types.py
vendored
2
code/python/src/thirdparty/types.py
vendored
@ -16,7 +16,6 @@ from typing import Generator;
|
|||||||
from typing import Generic;
|
from typing import Generic;
|
||||||
from typing import List;
|
from typing import List;
|
||||||
from typing import Optional;
|
from typing import Optional;
|
||||||
from typing import ParamSpec;
|
|
||||||
from typing import Tuple;
|
from typing import Tuple;
|
||||||
from typing import Type;
|
from typing import Type;
|
||||||
from typing import TypeVar;
|
from typing import TypeVar;
|
||||||
@ -39,7 +38,6 @@ __all__ = [
|
|||||||
'Generic',
|
'Generic',
|
||||||
'List',
|
'List',
|
||||||
'Optional',
|
'Optional',
|
||||||
'ParamSpec',
|
|
||||||
'Tuple',
|
'Tuple',
|
||||||
'Type',
|
'Type',
|
||||||
'TypeVar',
|
'TypeVar',
|
||||||
|
@ -5,42 +5,21 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from src.thirdparty.run import *;
|
from unittest import TestCase;
|
||||||
from src.thirdparty.types import *;
|
from pytest import fixture;
|
||||||
from tests.thirdparty.unit import *;
|
|
||||||
from src.core.log import log_dev;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# CONSTANTS
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
LOOP: Optional[AbstractEventLoop] = None;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# FIXTURES
|
# FIXTURES
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@fixture(scope='module', autouse=True)
|
@fixture(scope='module')
|
||||||
def test() -> TestCase:
|
def test():
|
||||||
return TestCase();
|
return TestCase();
|
||||||
|
|
||||||
@fixture(scope='module', autouse=True)
|
@fixture(scope='module')
|
||||||
def debug() -> Callable[..., None]:
|
def debug():
|
||||||
'''
|
def log(*lines: str):
|
||||||
Fixture for development purposes only.
|
with open('logs/debug.log', 'a') as fp:
|
||||||
Logs to file 'logs/debug.log'.
|
for line in lines:
|
||||||
'''
|
print(line, end='\n', file=fp);
|
||||||
return log_dev;
|
return log;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
# 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;
|
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from tests.thirdparty.unit import *;
|
from pytest import mark;
|
||||||
|
from pytest import fixture;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# CONSTANTS
|
# CONSTANTS
|
||||||
|
@ -5,230 +5,17 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from src.thirdparty.log import *;
|
from pytest import mark;
|
||||||
from src.thirdparty.misc import *;
|
from pytest import fixture;
|
||||||
from tests.thirdparty.unit import *;
|
|
||||||
|
|
||||||
from src.core.log import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# FIXTURES
|
# 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 log debug
|
# Test logging
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@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;
|
|
||||||
|
@ -1,136 +0,0 @@
|
|||||||
#!/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;
|
|
@ -5,7 +5,9 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from tests.thirdparty.unit import *;
|
from unittest import TestCase;
|
||||||
|
from pytest import mark;
|
||||||
|
from pytest import fixture;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# CONSTANTS
|
# CONSTANTS
|
||||||
|
@ -5,7 +5,11 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from tests.thirdparty.unit import *;
|
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 src.models.graphs import *;
|
from src.models.graphs import *;
|
||||||
|
|
||||||
|
@ -5,9 +5,14 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from tests.thirdparty.unit import *;
|
import pytest;
|
||||||
from src.thirdparty.types import *;
|
from pytest import mark;
|
||||||
|
from pytest import fixture;
|
||||||
|
from pytest import lazy_fixture;
|
||||||
|
from unittest import TestCase;
|
||||||
|
from unittest.mock import patch;
|
||||||
|
|
||||||
|
from src.thirdparty.types import *;
|
||||||
from src.models.graphs import *;
|
from src.models.graphs import *;
|
||||||
from src.algorithms.tarjan import *;
|
from src.algorithms.tarjan import *;
|
||||||
|
|
||||||
@ -72,7 +77,7 @@ def test_tarjan(test, G, expected):
|
|||||||
@mark.parametrize(('G', 'expected'), [ (lazy_fixture('graph1'), [[1], [3], [2,4]])])
|
@mark.parametrize(('G', 'expected'), [ (lazy_fixture('graph1'), [[1], [3], [2,4]])])
|
||||||
@mark.usefixtures('test')
|
@mark.usefixtures('test')
|
||||||
def test_failable_tarjan(test, G, expected):
|
def test_failable_tarjan(test, G, expected):
|
||||||
with assert_raises(AssertionError):
|
with pytest.raises(AssertionError):
|
||||||
test_tarjan(test, G, expected);
|
test_tarjan(test, G, expected);
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from tests.thirdparty.unit import *;
|
from pytest import mark;
|
||||||
|
from pytest import fixture;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# FIXTURES
|
# FIXTURES
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from tests.thirdparty.unit import *;
|
from contextlib import nullcontext as does_not_raise
|
||||||
|
import pytest;
|
||||||
|
from pytest import mark;
|
||||||
|
from unittest import TestCase;
|
||||||
|
|
||||||
from src.models.stacks import Stack;
|
from src.models.stacks import Stack;
|
||||||
|
|
||||||
@ -53,7 +56,7 @@ def test_stack_error_po(test: TestCase):
|
|||||||
stack.push('hallo');
|
stack.push('hallo');
|
||||||
stack.push('welt');
|
stack.push('welt');
|
||||||
stack.push('!');
|
stack.push('!');
|
||||||
with assert_raises(Exception):
|
with pytest.raises(Exception):
|
||||||
stack.pop();
|
stack.pop();
|
||||||
stack.pop();
|
stack.pop();
|
||||||
stack.pop();
|
stack.pop();
|
||||||
|
39
code/python/tests/thirdparty/unit.py
vendored
39
code/python/tests/thirdparty/unit.py
vendored
@ -1,39 +0,0 @@
|
|||||||
#!/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',
|
|
||||||
];
|
|
Loading…
x
Reference in New Issue
Block a user