new models, a model is passed to the command handler instead of a dictionary, removal of checks for intersection of processed triggers in handlers and much, much more

This commit is contained in:
2025-03-31 19:14:42 +03:00
parent 2918bc9f81
commit 5c6fa5151a
24 changed files with 283 additions and 279 deletions
+7 -7
View File
@@ -56,11 +56,11 @@ if __name__ == '__main__':
import re import re
from argenta.router import Router from argenta.router import Router
from argenta.command import Command from argenta.command import Command
from argenta.command.flag.registered_flag import FlagsGroup, Flag from argenta.command.flag.registered_flag import Flags, Flag
router = Router() router = Router()
registered_flags = FlagsGroup( registered_flags = Flags(
Flag(flag_name='host', Flag(flag_name='host',
flag_prefix='--', flag_prefix='--',
possible_flag_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')), possible_flag_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')),
@@ -315,14 +315,14 @@ Router(title: str = 'Commands group title:',
```python ```python
Command(trigger: str, Command(trigger: str,
description: str = None, description: str = None,
flags: Flag | FlagsGroup = None) flags: Flag | Flags = None)
``` ```
**Аргументы:** **Аргументы:**
- **name : mean** - **name : mean**
- `trigger` (`str`): Строковый триггер - `trigger` (`str`): Строковый триггер
- `description` (`str`): Описание команды, которое будет выведено в консоль при запуске оболочки - `description` (`str`): Описание команды, которое будет выведено в консоль при запуске оболочки
- `flags` (`Flag | FlagsGroup`): Флаги, которые будут обработаны при их наличии во вводе юзера - `flags` (`Flag | Flags`): Флаги, которые будут обработаны при их наличии во вводе юзера
--- ---
@@ -338,7 +338,7 @@ Command(trigger: str,
--- ---
#### **.get_registered_flags() -> `FlagsGroup | None`** #### **.get_registered_flags() -> `Flags | None`**
*method mean* **::** возвращает зарегистрированные флаги экземпляра *method mean* **::** возвращает зарегистрированные флаги экземпляра
@@ -402,14 +402,14 @@ Flag(flag_name: str,
--- ---
## *class* :: `FlagsGroup` ## *class* :: `Flags`
Класс, объединяющий список флагов в один объект, используется в качестве Класс, объединяющий список флагов в один объект, используется в качестве
передаваемого аргумента `flags` экземпляру класса `Command`, при регистрации передаваемого аргумента `flags` экземпляру класса `Command`, при регистрации
хэндлера хэндлера
### Конструктор ### Конструктор
```python ```python
FlagsGroup(*flagы: Flag) Flags(*flagы: Flag)
``` ```
--- ---
+4 -4
View File
@@ -2,7 +2,7 @@ from typing import Callable
from inspect import getfullargspec from inspect import getfullargspec
import re import re
from argenta.command import Command from argenta.command.models import Command, InputCommand
from argenta.router import Router from argenta.router import Router
from argenta.router.defaults import system_router from argenta.router.defaults import system_router
from argenta.command.exceptions import (UnprocessedInputFlagException, from argenta.command.exceptions import (UnprocessedInputFlagException,
@@ -78,7 +78,7 @@ class App:
raw_command: str = input() raw_command: str = input()
try: try:
input_command: Command = Command.parse_input_command(raw_command=raw_command) input_command: InputCommand = InputCommand.parse_input_command(raw_command=raw_command)
except UnprocessedInputFlagException: except UnprocessedInputFlagException:
self.print_func(self.line_separate) self.print_func(self.line_separate)
self._invalid_input_flags_handler(raw_command) self._invalid_input_flags_handler(raw_command)
@@ -223,7 +223,7 @@ class App:
self.include_router(system_router) self.include_router(system_router)
def _is_exit_command(self, command: Command): def _is_exit_command(self, command: InputCommand):
if command.get_trigger().lower() == self.exit_command.lower(): if command.get_trigger().lower() == self.exit_command.lower():
if self.ignore_exit_command_register: if self.ignore_exit_command_register:
system_router.input_command_handler(command) system_router.input_command_handler(command)
@@ -235,7 +235,7 @@ class App:
return False return False
def _check_is_command_unknown(self, command: Command): def _check_is_command_unknown(self, command: InputCommand):
for router_entity in self._registered_routers: for router_entity in self._registered_routers:
for command_handler in router_entity.get_command_handlers(): for command_handler in router_entity.get_command_handlers():
handled_command_trigger = command_handler.get_handled_command().get_trigger() handled_command_trigger = command_handler.get_handled_command().get_trigger()
+1 -1
View File
@@ -1,3 +1,3 @@
__all__ = ["Command"] __all__ = ["Command"]
from .entity import Command from .models import Command
+1 -2
View File
@@ -1,5 +1,4 @@
from argenta.command.flag.input_flag.entity import InputFlag from argenta.command.flag.models import InputFlag, Flag
from argenta.command.flag.registered_flag.entity import Flag
class UnprocessedInputFlagException(Exception): class UnprocessedInputFlagException(Exception):
-41
View File
@@ -1,41 +0,0 @@
from typing import Literal, Pattern
class BaseFlag:
def __init__(self, flag_name: str,
flag_prefix: Literal['-', '--', '---'] = '--',
possible_flag_values: list[str] | Pattern[str] | False = True):
self._flag_name = flag_name
self._flag_prefix = flag_prefix
self.possible_flag_values = possible_flag_values
def get_string_entity(self):
string_entity: str = self._flag_prefix + self._flag_name
return string_entity
def get_flag_name(self):
return self._flag_name
def get_flag_prefix(self):
return self._flag_prefix
def validate_input_flag_value(self, input_flag_value: str | None):
if self.possible_flag_values is False:
if input_flag_value is None:
return True
else:
return False
elif isinstance(self.possible_flag_values, Pattern):
is_valid = bool(self.possible_flag_values.match(input_flag_value))
if bool(is_valid):
return True
else:
return False
elif isinstance(self.possible_flag_values, list):
if input_flag_value in self.possible_flag_values:
return True
else:
return False
else:
return True
+21
View File
@@ -0,0 +1,21 @@
from dataclasses import dataclass
from argenta.command.flag.models import Flag
import re
@dataclass
class DefaultFlags:
HELP = Flag(name='help', possible_values=False)
SHORT_HELP = Flag(name='h', prefix='-', possible_values=False)
INFO = Flag(name='info', possible_values=False)
SHORT_INFO = Flag(name='i', prefix='-', possible_values=False)
ALL = Flag(name='all', possible_values=False)
SHORT_ALL = Flag(name='a', prefix='-', possible_values=False)
HOST = Flag(name='host', possible_values=re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'))
SHORT_HOST = Flag(name='h', prefix='-', possible_values=re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'))
PORT = Flag(name='port', possible_values=re.compile(r'^\d{1,5}$'))
SHORT_PORT = Flag(name='p', prefix='-', possible_values=re.compile(r'^\d{1,5}$'))
@@ -1,4 +0,0 @@
__all__ = ["FlagsGroup"]
from .entity import FlagsGroup
@@ -1,36 +0,0 @@
from argenta.command.flag.input_flag.entity import InputFlag
from argenta.command.flag.registered_flag import Flag
class FlagsGroup:
def __init__(self, *flags: Flag | InputFlag):
self._flags: list[Flag | InputFlag] = [] if not flags else flags
def get_flags(self) -> list[Flag | InputFlag]:
return self._flags
def add_flag(self, flag: Flag | InputFlag):
self._flags.append(flag)
def add_flags(self, flags: list[Flag | InputFlag]):
self._flags.extend(flags)
def unparse_to_dict(self):
result_dict: dict[str, dict] = {}
for flag in self.get_flags():
result_dict[flag.get_flag_name()] = {
'name': flag.get_flag_name(),
'string_entity': flag.get_string_entity(),
'prefix': flag.get_flag_prefix(),
'value': flag.get_value()
}
return result_dict
def __iter__(self):
return iter(self._flags)
def __next__(self):
return next(iter(self))
def __getitem__(self, item):
return self._flags[item]
-18
View File
@@ -1,18 +0,0 @@
from re import Pattern
from typing import Literal
from argenta.command.flag.base_flag.entity import BaseFlag
class InputFlag(BaseFlag):
def __init__(self, flag_name: str,
flag_prefix: Literal['-', '--', '---'] = '--',
possible_flag_values: list[str] | Pattern[str] | False = True):
super().__init__(flag_name, flag_prefix, possible_flag_values)
self._flag_value = None
def get_value(self):
return self._flag_value
def set_value(self, value):
self._flag_value = value
+133
View File
@@ -0,0 +1,133 @@
from typing import Literal, Pattern
from abc import ABC, abstractmethod
class BaseFlag:
def __init__(self, name: str,
prefix: Literal['-', '--', '---'] = '--',
possible_values: list[str] | Pattern[str] | False = True):
self._name = name
self._prefix = prefix
self.possible_values = possible_values
def get_string_entity(self):
string_entity: str = self._prefix + self._name
return string_entity
def get_name(self):
return self._name
def get_prefix(self):
return self._prefix
class InputFlag(BaseFlag):
def __init__(self, name: str,
prefix: Literal['-', '--', '---'] = '--',
possible_values: list[str] | Pattern[str] | False = True):
super().__init__(name, prefix, possible_values)
self._flag_value = None
def get_value(self):
return self._flag_value
def set_value(self, value):
self._flag_value = value
class Flag(BaseFlag):
def validate_input_flag_value(self, input_flag_value: str | None):
if self.possible_values is False:
if input_flag_value is None:
return True
else:
return False
elif isinstance(self.possible_values, Pattern):
is_valid = bool(self.possible_values.match(input_flag_value))
if bool(is_valid):
return True
else:
return False
elif isinstance(self.possible_values, list):
if input_flag_value in self.possible_values:
return True
else:
return False
else:
return True
class BaseFlags(ABC):
__slots__ = ('_flags',)
@abstractmethod
def get_flags(self):
pass
@abstractmethod
def add_flag(self, flag: Flag | InputFlag):
pass
@abstractmethod
def add_flags(self, flags: list[Flag] | list[InputFlag]):
pass
@abstractmethod
def get_flag(self, name: str):
pass
def __iter__(self):
return iter(self._flags)
def __next__(self):
return next(iter(self))
def __getitem__(self, item):
return self._flags[item]
class Flags(BaseFlags, ABC):
def __init__(self, *flags: Flag):
self._flags = flags if flags else []
def get_flags(self) -> list[Flag]:
return self._flags
def add_flag(self, flag: Flag):
self._flags.append(flag)
def add_flags(self, flags: list[Flag]):
self._flags.extend(flags)
def get_flag(self, name: str) -> Flag | None:
if name in [flag.get_name() for flag in self._flags]:
return list(filter(lambda flag: flag.get_name() == name, self._flags))[0]
else:
return None
class InputFlags(BaseFlags, ABC):
def __init__(self, *flags: InputFlag):
self._flags = flags if flags else []
def get_flags(self) -> list[InputFlag]:
return self._flags
def add_flag(self, flag: InputFlag):
self._flags.append(flag)
def add_flags(self, flags: list[InputFlag]):
self._flags.extend(flags)
def get_flag(self, name: str) -> InputFlag | None:
if name in [flag.get_name() for flag in self._flags]:
return list(filter(lambda flag: flag.get_name() == name, self._flags))[0]
else:
return None
@@ -1,5 +0,0 @@
__all__ = ["Flag", "FlagsGroup"]
from .entity import Flag
from argenta.command.flag.flags_group import FlagsGroup
@@ -1,21 +0,0 @@
from dataclasses import dataclass
from argenta.command.flag.registered_flag import Flag
import re
@dataclass
class DefaultFlags:
HELP = Flag(flag_name='help', possible_flag_values=False)
SHORT_HELP = Flag(flag_name='h', flag_prefix='-', possible_flag_values=False)
INFO = Flag(flag_name='info', possible_flag_values=False)
SHORT_INFO = Flag(flag_name='i', flag_prefix='-', possible_flag_values=False)
ALL = Flag(flag_name='all', possible_flag_values=False)
SHORT_ALL = Flag(flag_name='a', flag_prefix='-', possible_flag_values=False)
HOST = Flag(flag_name='host', possible_flag_values=re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'))
SHORT_HOST = Flag(flag_name='h', flag_prefix='-', possible_flag_values=re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'))
PORT = Flag(flag_name='port', possible_flag_values=re.compile(r'^\d{1,5}$'))
SHORT_PORT = Flag(flag_name='p', flag_prefix='-', possible_flag_values=re.compile(r'^\d{1,5}$'))
@@ -1,5 +0,0 @@
from argenta.command.flag.base_flag.entity import BaseFlag
class Flag(BaseFlag):
pass
@@ -1,40 +1,40 @@
from argenta.command.flag.registered_flag.entity import Flag from argenta.command.flag.models import Flag, InputFlag, Flags, InputFlags
from argenta.command.flag.input_flag.entity import InputFlag from argenta.command.exceptions import (UnprocessedInputFlagException,
from argenta.command.flag.flags_group import FlagsGroup
from .exceptions import (UnprocessedInputFlagException,
RepeatedInputFlagsException, RepeatedInputFlagsException,
EmptyInputCommandException) EmptyInputCommandException)
from typing import Generic, TypeVar, cast, Literal from typing import Generic, TypeVar, cast, Literal
CommandType = TypeVar('CommandType') BaseCommandType = TypeVar('BaseCommandType')
class Command(Generic[CommandType]): class BaseCommand(Generic[BaseCommandType]):
def __init__(self, trigger: str, def __init__(self, trigger: str,
description: str = None, description: str = None,
flags: Flag | FlagsGroup = None): flags: Flag | Flags = None):
self._trigger = trigger self._trigger = trigger
self._description = f'description for "{self._trigger}" command' if not description else description self._description = f'description for "{self._trigger}" command' if not description else description
self._registered_flags: FlagsGroup | None = flags if isinstance(flags, FlagsGroup) else FlagsGroup(flags) if isinstance(flags, Flag) else flags
self._input_flags: FlagsGroup | None = None
def get_trigger(self) -> str: def get_trigger(self) -> str:
return self._trigger return self._trigger
def get_description(self) -> str: def get_description(self) -> str:
return self._description return self._description
def get_registered_flags(self) -> FlagsGroup | None:
class Command(BaseCommand):
def __init__(self, trigger: str,
description: str = None,
flags: Flag | Flags = None):
super().__init__(trigger, description)
self._registered_flags: Flags = flags if isinstance(flags, Flags) else Flags(flags) if isinstance(flags, Flag) else Flags()
def get_registered_flags(self) -> Flags:
return self._registered_flags return self._registered_flags
def validate_input_flag(self, flag: InputFlag): def validate_input_flag(self, flag: InputFlag):
registered_flags: FlagsGroup | None = self.get_registered_flags() registered_flags: Flags | None = self.get_registered_flags()
if registered_flags: if registered_flags:
if isinstance(registered_flags, Flag): if isinstance(registered_flags, Flag):
if registered_flags.get_string_entity() == flag.get_string_entity(): if registered_flags.get_string_entity() == flag.get_string_entity():
@@ -50,21 +50,29 @@ class Command(Generic[CommandType]):
return False return False
def _set_input_flags(self, input_flags: FlagsGroup):
class InputCommand(BaseCommand):
def __init__(self, trigger: str,
description: str = None,
input_flags: InputFlag | InputFlags = None):
super().__init__(trigger, description)
self._input_flags: InputFlags = input_flags if isinstance(input_flags, InputFlags) else InputFlags(input_flags) if isinstance(input_flags, InputFlag) else InputFlags()
def _set_input_flags(self, input_flags: InputFlags):
self._input_flags = input_flags self._input_flags = input_flags
def get_input_flags(self) -> FlagsGroup: def get_input_flags(self) -> InputFlags:
return self._input_flags return self._input_flags
@staticmethod @staticmethod
def parse_input_command(raw_command: str) -> CommandType: def parse_input_command(raw_command: str) -> BaseCommandType:
if not raw_command: if not raw_command:
raise EmptyInputCommandException() raise EmptyInputCommandException()
list_of_tokens = raw_command.split() list_of_tokens = raw_command.split()
command = list_of_tokens[0] command = list_of_tokens[0]
list_of_tokens.pop(0) list_of_tokens.pop(0)
flags: FlagsGroup = FlagsGroup() input_flags: InputFlags = InputFlags()
current_flag_name = None current_flag_name = None
current_flag_value = None current_flag_value = None
for k, _ in enumerate(list_of_tokens): for k, _ in enumerate(list_of_tokens):
@@ -80,19 +88,19 @@ class Command(Generic[CommandType]):
else: else:
current_flag_value = _ current_flag_value = _
if current_flag_name: if current_flag_name:
if not len(list_of_tokens) == k+1: if not len(list_of_tokens) == k + 1:
if not list_of_tokens[k+1].startswith('-'): if not list_of_tokens[k + 1].startswith('-'):
continue continue
flag_prefix_last_symbol_index = current_flag_name.rfind('-') flag_prefix_last_symbol_index = current_flag_name.rfind('-')
flag_prefix = current_flag_name[:flag_prefix_last_symbol_index+1] flag_prefix = current_flag_name[:flag_prefix_last_symbol_index + 1]
flag_name = current_flag_name[flag_prefix_last_symbol_index+1:] flag_name = current_flag_name[flag_prefix_last_symbol_index + 1:]
input_flag = InputFlag(flag_name=flag_name, input_flag = InputFlag(name=flag_name,
flag_prefix=cast(Literal['-', '--', '---'], flag_prefix)) prefix=cast(Literal['-', '--', '---'], flag_prefix))
input_flag.set_value(current_flag_value) input_flag.set_value(current_flag_value)
all_flags = [x.get_string_entity() for x in flags.get_flags()] all_flags = [x.get_string_entity() for x in input_flags.get_flags()]
if input_flag.get_string_entity() not in all_flags: if input_flag.get_string_entity() not in all_flags:
flags.add_flag(input_flag) input_flags.add_flag(input_flag)
else: else:
raise RepeatedInputFlagsException(input_flag) raise RepeatedInputFlagsException(input_flag)
@@ -100,12 +108,10 @@ class Command(Generic[CommandType]):
current_flag_value = None current_flag_value = None
if any([current_flag_name, current_flag_value]): if any([current_flag_name, current_flag_value]):
raise UnprocessedInputFlagException() raise UnprocessedInputFlagException()
if len(flags.get_flags()) == 0: if len(input_flags.get_flags()) == 0:
return Command(trigger=command) return InputCommand(trigger=command)
else: else:
input_command = Command(trigger=command) input_command = InputCommand(trigger=command)
input_command._set_input_flags(flags) input_command._set_input_flags(input_flags)
return input_command return input_command
+4 -3
View File
@@ -1,14 +1,15 @@
from typing import Callable from typing import Callable
from argenta.command import Command from argenta.command import Command
from argenta.command.flag.models import InputFlags
class CommandHandler: class CommandHandler:
def __init__(self, handler: Callable[[], None] | Callable[[dict], None], handled_command: Command): def __init__(self, handler: Callable[[], None] | Callable[[InputFlags], None], handled_command: Command):
self.handler = handler self.handler = handler
self.handled_command = handled_command self.handled_command = handled_command
def handling(self, input_flags: dict = None): def handling(self, input_flags: InputFlags):
if input_flags is not None: if input_flags.get_flags():
self.handler(input_flags) self.handler(input_flags)
else: else:
self.handler() self.handler()
+9 -9
View File
@@ -2,9 +2,10 @@ from typing import Callable, Any
from inspect import getfullargspec from inspect import getfullargspec
from argenta.command import Command from argenta.command import Command
from argenta.command.models import InputCommand
from argenta.router.command_handlers.entity import CommandHandlers from argenta.router.command_handlers.entity import CommandHandlers
from argenta.router.command_handler.entity import CommandHandler from argenta.router.command_handler.entity import CommandHandler
from argenta.command.flag.registered_flag import Flag, FlagsGroup from argenta.command.flag.models import Flag, Flags, InputFlags
from argenta.router.exceptions import (RepeatedFlagNameException, from argenta.router.exceptions import (RepeatedFlagNameException,
TooManyTransferredArgsException, TooManyTransferredArgsException,
RequiredArgumentNotPassedException, RequiredArgumentNotPassedException,
@@ -16,7 +17,6 @@ class Router:
def __init__(self, def __init__(self,
title: str = 'Commands group title:', title: str = 'Commands group title:',
name: str = 'Default'): name: str = 'Default'):
self._title = title self._title = title
self._name = name self._name = name
@@ -48,9 +48,9 @@ class Router:
self._not_valid_flag_handler = func self._not_valid_flag_handler = func
def input_command_handler(self, input_command: Command): def input_command_handler(self, input_command: InputCommand):
input_command_name: str = input_command.get_trigger() input_command_name: str = input_command.get_trigger()
input_command_flags: FlagsGroup = input_command.get_input_flags() input_command_flags: InputFlags = input_command.get_input_flags()
for command_handler in self._command_handlers: for command_handler in self._command_handlers:
handle_command = command_handler.get_handled_command() handle_command = command_handler.get_handled_command()
if input_command_name.lower() == handle_command.get_trigger().lower(): if input_command_name.lower() == handle_command.get_trigger().lower():
@@ -61,7 +61,7 @@ class Router:
if not is_valid: if not is_valid:
self._not_valid_flag_handler(flag) self._not_valid_flag_handler(flag)
return return
command_handler.handling(input_command_flags.unparse_to_dict()) command_handler.handling(input_command_flags)
return return
else: else:
command_handler.handling({}) command_handler.handling({})
@@ -81,7 +81,7 @@ class Router:
if command_name.find(' ') != -1: if command_name.find(' ') != -1:
raise TriggerCannotContainSpacesException() raise TriggerCannotContainSpacesException()
flags: FlagsGroup = command.get_registered_flags() flags: Flags = command.get_registered_flags()
if flags: if flags:
flags_name: list = [x.get_string_entity().lower() for x in flags] flags_name: list = [x.get_string_entity().lower() for x in flags]
if len(set(flags_name)) < len(flags_name): if len(set(flags_name)) < len(flags_name):
@@ -92,12 +92,12 @@ class Router:
def _validate_func_args(command: Command, func: Callable): def _validate_func_args(command: Command, func: Callable):
registered_args = command.get_registered_flags() registered_args = command.get_registered_flags()
transferred_args = getfullargspec(func).args transferred_args = getfullargspec(func).args
if registered_args and transferred_args: if registered_args.get_flags() and transferred_args:
if len(transferred_args) != 1: if len(transferred_args) != 1:
raise TooManyTransferredArgsException() raise TooManyTransferredArgsException()
elif registered_args and not transferred_args: elif registered_args.get_flags() and not transferred_args:
raise RequiredArgumentNotPassedException() raise RequiredArgumentNotPassedException()
elif not registered_args and transferred_args: elif not registered_args.get_flags() and transferred_args:
raise TooManyTransferredArgsException() raise TooManyTransferredArgsException()
+4 -4
View File
@@ -2,8 +2,8 @@ from pprint import pprint
from rich.console import Console from rich.console import Console
from argenta.command import Command from argenta.command import Command
from argenta.command.flag.registered_flag import FlagsGroup from argenta.command.flag.models import Flags, InputFlags
from argenta.command.flag.registered_flag.defaults import DefaultFlags from argenta.command.flag.defaults import DefaultFlags
from argenta.router import Router from argenta.router import Router
from .handlers_implementation.help_command import help_command from .handlers_implementation.help_command import help_command
@@ -22,8 +22,8 @@ def command_help():
help_command() help_command()
@work_router.command(Command(trigger='P', description='Start Solving', flags=FlagsGroup(DefaultFlags.HOST, DefaultFlags.PORT))) @work_router.command(Command(trigger='P', description='Start Solving', flags=Flags(DefaultFlags.HOST, DefaultFlags.PORT)))
def command_start_solving(args: dict): def command_start_solving(args: InputFlags):
print('Solving...') print('Solving...')
pprint(args) pprint(args)
#start_solving_command() #start_solving_command()
@@ -7,8 +7,8 @@ import re
from argenta.app import App from argenta.app import App
from argenta.command import Command from argenta.command import Command
from argenta.router import Router from argenta.router import Router
from argenta.command.flag.registered_flag import FlagsGroup from argenta.command.flag.models import Flags
from argenta.command.flag.registered_flag.defaults import DefaultFlags from argenta.command.flag.defaults import DefaultFlags
@@ -64,7 +64,7 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
output = mock_stdout.getvalue() output = mock_stdout.getvalue()
self.assertIn('\nUndefined or incorrect input registered_flag: --help\n', output) self.assertIn('\nUndefined or incorrect input flag: --help\n', output)
@patch("builtins.input", side_effect=["test --port 22", "q"]) @patch("builtins.input", side_effect=["test --port 22", "q"])
@@ -82,14 +82,14 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
output = mock_stdout.getvalue() output = mock_stdout.getvalue()
self.assertIn('\nUndefined or incorrect input registered_flag: --port 22\n', output) self.assertIn('\nUndefined or incorrect input flag: --port 22\n', output)
@patch("builtins.input", side_effect=["test --host 192.168.32.1 --port 132", "q"]) @patch("builtins.input", side_effect=["test --host 192.168.32.1 --port 132", "q"])
@patch("sys.stdout", new_callable=io.StringIO) @patch("sys.stdout", new_callable=io.StringIO)
def test_input_correct_command_with_one_correct_flag_an_one_incorrect_flag(self, mock_stdout: _io.StringIO, magick_mock: MagicMock): def test_input_correct_command_with_one_correct_flag_an_one_incorrect_flag(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
router = Router() router = Router()
flags = FlagsGroup(DefaultFlags.HOST) flags = Flags(DefaultFlags.HOST)
@router.command(Command('test', flags=flags)) @router.command(Command('test', flags=flags))
def test(args: dict): def test(args: dict):
@@ -101,7 +101,7 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
output = mock_stdout.getvalue() output = mock_stdout.getvalue()
self.assertIn('\nUndefined or incorrect input registered_flag: --port 132\n', output) self.assertIn('\nUndefined or incorrect input flag: --port 132\n', output)
@patch("builtins.input", side_effect=["test", "some", "q"]) @patch("builtins.input", side_effect=["test", "some", "q"])
@@ -159,7 +159,7 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
output = mock_stdout.getvalue() output = mock_stdout.getvalue()
self.assertIn("\nIncorrect registered_flag syntax: \"test 535 --port\"\n", output) self.assertIn("\nIncorrect flag syntax: \"test 535 --port\"\n", output)
@patch("builtins.input", side_effect=["", "q"]) @patch("builtins.input", side_effect=["", "q"])
@@ -5,10 +5,10 @@ import io
import re import re
from argenta.app import App from argenta.app import App
from argenta.command import Command from argenta.command.models import Command
from argenta.router import Router from argenta.router import Router
from argenta.command.flag.registered_flag import Flag, FlagsGroup from argenta.command.flag.models import Flag, Flags, InputFlags
from argenta.command.flag.registered_flag.defaults import DefaultFlags from argenta.command.flag.defaults import DefaultFlags
@@ -56,8 +56,8 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
flag = Flag('help', '--', False) flag = Flag('help', '--', False)
@router.command(Command('test', flags=flag)) @router.command(Command('test', flags=flag))
def test(args: dict): def test(args: InputFlags):
print(f'\nhelp for {args['help']['name']} registered_flag\n') print(f'\nhelp for {args.get_flag('help').get_name()} flag\n')
app = App() app = App()
app.include_router(router) app.include_router(router)
@@ -65,7 +65,7 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
output = mock_stdout.getvalue() output = mock_stdout.getvalue()
self.assertIn('\nhelp for help registered_flag\n', output) self.assertIn('\nhelp for help flag\n', output)
@patch("builtins.input", side_effect=["test --port 22", "q"]) @patch("builtins.input", side_effect=["test --port 22", "q"])
@patch("sys.stdout", new_callable=io.StringIO) @patch("sys.stdout", new_callable=io.StringIO)
@@ -74,8 +74,8 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
flag = Flag('port', '--', re.compile(r'^\d{1,5}$')) flag = Flag('port', '--', re.compile(r'^\d{1,5}$'))
@router.command(Command('test', flags=flag)) @router.command(Command('test', flags=flag))
def test(args: dict): def test(args: InputFlags):
print(f'registered_flag value for {args['port']['name']} registered_flag : {args["port"]["value"]}') print(f'flag value for {args.get_flag('port').get_name()} flag : {args.get_flag('port').get_value()}')
app = App() app = App()
app.include_router(router) app.include_router(router)
@@ -83,7 +83,7 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
output = mock_stdout.getvalue() output = mock_stdout.getvalue()
self.assertIn('\nregistered_flag value for port registered_flag : 22\n', output) self.assertIn('\nflag value for port flag : 22\n', output)
@patch("builtins.input", side_effect=["test -h", "q"]) @patch("builtins.input", side_effect=["test -h", "q"])
@@ -94,7 +94,7 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
@router.command(Command('test', flags=flag)) @router.command(Command('test', flags=flag))
def test(args: dict): def test(args: dict):
print(f'help for {args['h']['name']} registered_flag') print(f'help for {args[0].get_name()} flag')
app = App() app = App()
app.include_router(router) app.include_router(router)
@@ -102,7 +102,7 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
output = mock_stdout.getvalue() output = mock_stdout.getvalue()
self.assertIn('\nhelp for h registered_flag\n', output) self.assertIn('\nhelp for h flag\n', output)
@patch("builtins.input", side_effect=["test --info", "q"]) @patch("builtins.input", side_effect=["test --info", "q"])
@@ -112,8 +112,8 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
flag = DefaultFlags.INFO flag = DefaultFlags.INFO
@router.command(Command('test', flags=flag)) @router.command(Command('test', flags=flag))
def test(args: dict): def test(args: InputFlags):
if args.get('info'): if args.get_flag('info'):
print('info about test command') print('info about test command')
app = App() app = App()
@@ -132,8 +132,8 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
flag = DefaultFlags.HOST flag = DefaultFlags.HOST
@router.command(Command('test', flags=flag)) @router.command(Command('test', flags=flag))
def test(args: dict): def test(args: InputFlags):
print(f'connecting to host {args["host"]["value"]}') print(f'connecting to host {args[0].get_value()}')
app = App() app = App()
app.include_router(router) app.include_router(router)
@@ -148,11 +148,11 @@ class TestSystemHandlerNormalWork(unittest.TestCase):
@patch("sys.stdout", new_callable=io.StringIO) @patch("sys.stdout", new_callable=io.StringIO)
def test_input_correct_command_with_two_flags(self, mock_stdout: _io.StringIO, magick_mock: MagicMock): def test_input_correct_command_with_two_flags(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
router = Router() router = Router()
flags = FlagsGroup(DefaultFlags.HOST, DefaultFlags.PORT) flags = Flags(DefaultFlags.HOST, DefaultFlags.PORT)
@router.command(Command('test', flags=flags)) @router.command(Command('test', flags=flags))
def test(args: dict): def test(args: InputFlags):
print(f'connecting to host {args["host"]["value"]} and port {args["port"]["value"]}') print(f'connecting to host {args[0].get_value()} and port {args[1].get_value()}')
app = App() app = App()
app.include_router(router) app.include_router(router)
+6 -9
View File
@@ -1,4 +1,4 @@
from argenta.command import Command from argenta.command.models import InputCommand
from argenta.command.exceptions import (UnprocessedInputFlagException, from argenta.command.exceptions import (UnprocessedInputFlagException,
RepeatedInputFlagsException, RepeatedInputFlagsException,
EmptyInputCommandException) EmptyInputCommandException)
@@ -6,22 +6,19 @@ from argenta.command.exceptions import (UnprocessedInputFlagException,
import unittest import unittest
class TestCommand(unittest.TestCase): class TestInputCommand(unittest.TestCase):
def test_parse_correct_raw_command(self): def test_parse_correct_raw_command(self):
self.assertEqual(Command.parse_input_command('ssh --host 192.168.0.3').get_trigger(), 'ssh') self.assertEqual(InputCommand.parse_input_command('ssh --host 192.168.0.3').get_trigger(), 'ssh')
def test_parse_raw_command_without_flag_name_with_value(self): def test_parse_raw_command_without_flag_name_with_value(self):
with self.assertRaises(UnprocessedInputFlagException): with self.assertRaises(UnprocessedInputFlagException):
Command.parse_input_command('ssh 192.168.0.3') InputCommand.parse_input_command('ssh 192.168.0.3')
def test_parse_raw_command_with_repeated_flag_name(self): def test_parse_raw_command_with_repeated_flag_name(self):
with self.assertRaises(RepeatedInputFlagsException): with self.assertRaises(RepeatedInputFlagsException):
Command.parse_input_command('ssh --host 192.168.0.3 --host 172.198.0.43') InputCommand.parse_input_command('ssh --host 192.168.0.3 --host 172.198.0.43')
def test_parse_empty_raw_command(self): def test_parse_empty_raw_command(self):
with self.assertRaises(EmptyInputCommandException): with self.assertRaises(EmptyInputCommandException):
Command.parse_input_command('') InputCommand.parse_input_command('')
def test_get_command_description(self):
self.assertEqual(Command(trigger='test', description='test description').get_description(), 'test description')
+18 -18
View File
@@ -1,4 +1,4 @@
from argenta.command.flag.registered_flag import Flag from argenta.command.flag.models import Flag, InputFlag
import unittest import unittest
import re import re
@@ -6,66 +6,66 @@ import re
class TestFlag(unittest.TestCase): class TestFlag(unittest.TestCase):
def test_get_string_entity(self): def test_get_string_entity(self):
self.assertEqual(Flag(flag_name='test').get_string_entity(), self.assertEqual(Flag(name='test').get_string_entity(),
'--test') '--test')
def test_get_string_entity2(self): def test_get_string_entity2(self):
self.assertEqual(Flag(flag_name='test', self.assertEqual(Flag(name='test',
flag_prefix='---').get_string_entity(), prefix='---').get_string_entity(),
'---test') '---test')
def test_get_flag_name(self): def test_get_flag_name(self):
self.assertEqual(Flag(flag_name='test').get_flag_name(), self.assertEqual(Flag(name='test').get_name(),
'test') 'test')
def test_get_flag_prefix(self): def test_get_flag_prefix(self):
self.assertEqual(Flag(flag_name='test').get_flag_prefix(), self.assertEqual(Flag(name='test').get_prefix(),
'--') '--')
def test_get_flag_prefix2(self): def test_get_flag_prefix2(self):
self.assertEqual(Flag(flag_name='test', self.assertEqual(Flag(name='test',
flag_prefix='--').get_flag_prefix(), prefix='--').get_prefix(),
'--') '--')
def test_get_flag_value_without_set(self): def test_get_flag_value_without_set(self):
self.assertEqual(Flag(flag_name='test').get_value(), self.assertEqual(InputFlag(name='test').get_value(),
None) None)
def test_get_flag_value_with_set(self): def test_get_flag_value_with_set(self):
flag = Flag(flag_name='test') flag = InputFlag(name='test')
flag.set_value('example') flag.set_value('example')
self.assertEqual(flag.get_value(), 'example') self.assertEqual(flag.get_value(), 'example')
def test_validate_incorrect_flag_value_with_list_of_possible_flag_values(self): def test_validate_incorrect_flag_value_with_list_of_possible_flag_values(self):
flag = Flag(flag_name='test', possible_flag_values=['1', '2', '3']) flag = Flag(name='test', possible_values=['1', '2', '3'])
self.assertEqual(flag.validate_input_flag_value('bad value'), False) self.assertEqual(flag.validate_input_flag_value('bad value'), False)
def test_validate_correct_flag_value_with_list_of_possible_flag_values(self): def test_validate_correct_flag_value_with_list_of_possible_flag_values(self):
flag = Flag(flag_name='test', possible_flag_values=['1', '2', '3']) flag = Flag(name='test', possible_values=['1', '2', '3'])
self.assertEqual(flag.validate_input_flag_value('1'), True) self.assertEqual(flag.validate_input_flag_value('1'), True)
def test_validate_incorrect_flag_value_with_pattern_of_possible_flag_values(self): def test_validate_incorrect_flag_value_with_pattern_of_possible_flag_values(self):
flag = Flag(flag_name='test', possible_flag_values=re.compile(r'192.168.\d+.\d+')) flag = Flag(name='test', possible_values=re.compile(r'192.168.\d+.\d+'))
self.assertEqual(flag.validate_input_flag_value('152.123.9.8'), False) self.assertEqual(flag.validate_input_flag_value('152.123.9.8'), False)
def test_validate_correct_flag_value_with_pattern_of_possible_flag_values(self): def test_validate_correct_flag_value_with_pattern_of_possible_flag_values(self):
flag = Flag(flag_name='test', possible_flag_values=re.compile(r'192.168.\d+.\d+')) flag = Flag(name='test', possible_values=re.compile(r'192.168.\d+.\d+'))
self.assertEqual(flag.validate_input_flag_value('192.168.9.8'), True) self.assertEqual(flag.validate_input_flag_value('192.168.9.8'), True)
def test_validate_correct_empty_flag_value_without_possible_flag_values(self): def test_validate_correct_empty_flag_value_without_possible_flag_values(self):
flag = Flag(flag_name='test', possible_flag_values=False) flag = Flag(name='test', possible_values=False)
self.assertEqual(flag.validate_input_flag_value(None), True) self.assertEqual(flag.validate_input_flag_value(None), True)
def test_validate_correct_empty_flag_value_with_possible_flag_values(self): def test_validate_correct_empty_flag_value_with_possible_flag_values(self):
flag = Flag(flag_name='test', possible_flag_values=True) flag = Flag(name='test', possible_values=True)
self.assertEqual(flag.validate_input_flag_value(None), True) self.assertEqual(flag.validate_input_flag_value(None), True)
def test_validate_incorrect_random_flag_value_without_possible_flag_values(self): def test_validate_incorrect_random_flag_value_without_possible_flag_values(self):
flag = Flag(flag_name='test', possible_flag_values=False) flag = Flag(name='test', possible_values=False)
self.assertEqual(flag.validate_input_flag_value('random value'), False) self.assertEqual(flag.validate_input_flag_value('random value'), False)
def test_validate_correct_random_flag_value_with_possible_flag_values(self): def test_validate_correct_random_flag_value_with_possible_flag_values(self):
flag = Flag(flag_name='test', possible_flag_values=True) flag = Flag(name='test', possible_values=True)
self.assertEqual(flag.validate_input_flag_value('random value'), True) self.assertEqual(flag.validate_input_flag_value('random value'), True)
+5 -28
View File
@@ -1,11 +1,11 @@
from argenta.command.flag.registered_flag import Flag, FlagsGroup from argenta.command.flag.models import Flag, Flags
import unittest import unittest
class TestFlagsGroup(unittest.TestCase): class TestFlags(unittest.TestCase):
def test_get_flags(self): def test_get_flags(self):
flags = FlagsGroup() flags = Flags()
list_of_flags = [ list_of_flags = [
Flag('test1'), Flag('test1'),
Flag('test2'), Flag('test2'),
@@ -16,34 +16,11 @@ class TestFlagsGroup(unittest.TestCase):
list_of_flags) list_of_flags)
def test_add_flag(self): def test_add_flag(self):
flags = FlagsGroup() flags = Flags()
flags.add_flag(Flag('test')) flags.add_flag(Flag('test'))
self.assertEqual(len(flags.get_flags()), 1) self.assertEqual(len(flags.get_flags()), 1)
def test_add_flags(self): def test_add_flags(self):
flags = FlagsGroup() flags = Flags()
flags.add_flags([Flag('test'), Flag('test2')]) flags.add_flags([Flag('test'), Flag('test2')])
self.assertEqual(len(flags.get_flags()), 2) self.assertEqual(len(flags.get_flags()), 2)
def test_unparse_flags_to_dict(self):
list_of_flags = [
Flag('test1'),
Flag('test2'),
Flag('test3'),
]
flags = FlagsGroup(*list_of_flags)
serialized_flags = flags.unparse_to_dict()
needed_result = {'test1': {'name': 'test1',
'prefix': '--',
'string_entity': '--test1',
'value': None},
'test2': {'name': 'test2',
'prefix': '--',
'string_entity': '--test2',
'value': None},
'test3': {'name': 'test3',
'prefix': '--',
'string_entity': '--test3',
'value': None}}
self.assertDictEqual(serialized_flags, needed_result)