mirror of
https://github.com/koloideal/Argenta.git
synced 2026-06-10 18:15:28 +03:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 956febc757 | |||
| beafdd0afd | |||
| b172e2cdc3 | |||
| baaf0e25f3 | |||
| 09c40978a1 | |||
| 0f4f48555e | |||
| d30515c1a2 | |||
| 5a6fc1d8ca |
@@ -56,16 +56,15 @@ if __name__ == '__main__':
|
||||
import re
|
||||
from argenta.router import Router
|
||||
from argenta.command import Command
|
||||
from argenta.command.params.flag import FlagsGroup, Flag
|
||||
from argenta.command.flag import FlagsGroup, Flag
|
||||
|
||||
router = Router()
|
||||
|
||||
registered_flags = FlagsGroup([
|
||||
registered_flags = FlagsGroup(
|
||||
Flag(flag_name='host',
|
||||
flag_prefix='--',
|
||||
possible_flag_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')),
|
||||
Flag('port', '---', re.compile(r'^[0-9]{1,4}$'))
|
||||
])
|
||||
Flag('port', '--', re.compile(r'^[0-9]{1,4}$')))
|
||||
|
||||
|
||||
@router.command(Command("hello"))
|
||||
@@ -365,8 +364,7 @@ Command(trigger: str,
|
||||
```python
|
||||
Flag(flag_name: str,
|
||||
flag_prefix: typing.Literal['-', '--', '---'] = '-',
|
||||
ignore_flag_value_register: bool = False,
|
||||
possible_flag_values: list[str] | typing.Pattern[str] = False)
|
||||
possible_flag_values: list[str] | typing.Pattern[str] | False = True)
|
||||
```
|
||||
|
||||
---
|
||||
@@ -375,9 +373,10 @@ Flag(flag_name: str,
|
||||
- **name : mean**
|
||||
- `flag_name` (`str`): Имя флага
|
||||
- `flag_prefix` (`Literal['-', '--', '---']`): Префикс команды, допустимым значением является от одного до трёх минусов
|
||||
- `ignore_flag_value_register` (`bool`): Будет ли игнорироваться регистр значения введённого флага
|
||||
- `possible_flag_values` (`list[str] | Pattern[str]`): Множество допустимых значений флага, может быть задано
|
||||
списком с допустимыми значениями или регулярным выражением (рекомендуется `re.compile(r'example exspression')`)
|
||||
- `possible_flag_values` (`list[str] | Pattern[str] | bool`): Множество допустимых значений флага, может быть задано
|
||||
списком с допустимыми значениями или регулярным выражением (рекомендуется `re.compile(r'example exspression')`), при значении
|
||||
аргумента `False` у введённого флага не может быть значения, иначе будет вызвано исключение и обработано соответствующим
|
||||
еррор-хэндлером
|
||||
|
||||
---
|
||||
|
||||
@@ -410,14 +409,14 @@ Flag(flag_name: str,
|
||||
|
||||
### Конструктор
|
||||
```python
|
||||
FlagsGroup(flags: list[Flag] = None)
|
||||
FlagsGroup(*flagы: Flag)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Аргументы:**
|
||||
- **name : mean**
|
||||
- `flags` (`list[Flag]`): Список флагов, которые будут объединены в одну группу
|
||||
- `*flags` (`Flag`): Неограниченное количество передаваемых флагов
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class App:
|
||||
self._invalid_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'Incorrect flag syntax: "{raw_command}"')
|
||||
self._repeated_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'Repeated input flags: "{raw_command}"')
|
||||
self._empty_input_command_handler: Callable[[], None] = lambda: print_func(f'Empty input command')
|
||||
self._unknown_command_handler: Callable[[Command], None] = lambda command: print_func(f"Unknown command: {command.get_string_entity()}")
|
||||
self._unknown_command_handler: Callable[[Command], None] = lambda command: print_func(f"Unknown command: {command.get_trigger()}")
|
||||
|
||||
|
||||
def start_polling(self) -> None:
|
||||
@@ -100,7 +100,9 @@ class App:
|
||||
self.print_func(self.prompt)
|
||||
continue
|
||||
|
||||
self._check_command_for_exit_command(input_command.get_trigger())
|
||||
is_exit = self._is_exit_command(input_command.get_trigger())
|
||||
if is_exit:
|
||||
return
|
||||
|
||||
self.print_func(self.line_separate)
|
||||
is_unknown_command: bool = self._check_is_command_unknown(input_command)
|
||||
@@ -212,15 +214,16 @@ class App:
|
||||
raise RepeatedCommandInDifferentRoutersException()
|
||||
|
||||
|
||||
def _check_command_for_exit_command(self, command: str):
|
||||
def _is_exit_command(self, command: str):
|
||||
if command.lower() == self.exit_command.lower():
|
||||
if self.ignore_exit_command_register:
|
||||
self.print_func(self.farewell_message)
|
||||
exit(0)
|
||||
return True
|
||||
else:
|
||||
if command == self.exit_command:
|
||||
self.print_func(self.farewell_message)
|
||||
exit(0)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _check_is_command_unknown(self, command: Command):
|
||||
|
||||
+13
-11
@@ -1,23 +1,22 @@
|
||||
from .params.flag.entity import Flag
|
||||
from .params.flag.flags_group.entity import FlagsGroup
|
||||
from argenta.command.flag.entity import Flag
|
||||
from argenta.command.flag.flags_group import FlagsGroup
|
||||
from .exceptions import (UnprocessedInputFlagException,
|
||||
RepeatedInputFlagsException,
|
||||
EmptyInputCommandException)
|
||||
|
||||
from typing import Generic, TypeVar
|
||||
from typing import Generic, TypeVar, cast, Literal
|
||||
|
||||
|
||||
T = TypeVar('T')
|
||||
CommandType = TypeVar('CommandType')
|
||||
|
||||
|
||||
class Command(Generic[T]):
|
||||
class Command(Generic[CommandType]):
|
||||
def __init__(self, trigger: str,
|
||||
description: str = None,
|
||||
flags: Flag | FlagsGroup = None):
|
||||
self._trigger = trigger
|
||||
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._registered_flags: FlagsGroup | None = flags if isinstance(flags, FlagsGroup) else FlagsGroup(flags) if isinstance(flags, Flag) else flags
|
||||
self._input_flags: FlagsGroup | None = None
|
||||
|
||||
|
||||
@@ -57,7 +56,7 @@ class Command(Generic[T]):
|
||||
return self._input_flags
|
||||
|
||||
@staticmethod
|
||||
def parse_input_command(raw_command: str) -> 'Command[T]':
|
||||
def parse_input_command(raw_command: str) -> CommandType:
|
||||
if not raw_command:
|
||||
raise EmptyInputCommandException()
|
||||
list_of_tokens = raw_command.split()
|
||||
@@ -67,7 +66,7 @@ class Command(Generic[T]):
|
||||
flags: FlagsGroup = FlagsGroup()
|
||||
current_flag_name = None
|
||||
current_flag_value = None
|
||||
for _ in list_of_tokens:
|
||||
for k, _ in enumerate(list_of_tokens):
|
||||
if _.startswith('-'):
|
||||
flag_prefix_last_symbol_index = _.rfind('-')
|
||||
if current_flag_name or len(_) < 2 or len(_[:flag_prefix_last_symbol_index]) > 3:
|
||||
@@ -79,12 +78,15 @@ class Command(Generic[T]):
|
||||
raise UnprocessedInputFlagException()
|
||||
else:
|
||||
current_flag_value = _
|
||||
if current_flag_name and current_flag_value:
|
||||
if current_flag_name:
|
||||
if not len(list_of_tokens) == k+1:
|
||||
if not list_of_tokens[k+1].startswith('-'):
|
||||
continue
|
||||
flag_prefix_last_symbol_index = current_flag_name.rfind('-')
|
||||
flag_prefix = current_flag_name[:flag_prefix_last_symbol_index+1]
|
||||
flag_name = current_flag_name[flag_prefix_last_symbol_index+1:]
|
||||
input_flag = Flag(flag_name=flag_name,
|
||||
flag_prefix=flag_prefix)
|
||||
flag_prefix=cast(Literal['-', '--', '---'], flag_prefix))
|
||||
input_flag.set_value(current_flag_value)
|
||||
|
||||
all_flags = [x.get_string_entity() for x in flags.get_flags()]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from .params.flag.entity import Flag
|
||||
from argenta.command.flag.entity import Flag
|
||||
|
||||
|
||||
class UnprocessedInputFlagException(Exception):
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
from dataclasses import dataclass
|
||||
from argenta.command.flag import Flag
|
||||
import re
|
||||
|
||||
|
||||
@dataclass
|
||||
class DefaultFlags:
|
||||
help_flag = Flag(flag_name='help', possible_flag_values=False)
|
||||
short_help_flag = Flag(flag_name='h', flag_prefix='-', possible_flag_values=False)
|
||||
|
||||
info_flag = Flag(flag_name='info', possible_flag_values=False)
|
||||
short_info_flag = Flag(flag_name='i', flag_prefix='-', possible_flag_values=False)
|
||||
|
||||
all_flag = Flag(flag_name='all', possible_flag_values=False)
|
||||
short_all_flag = Flag(flag_name='a', flag_prefix='-', possible_flag_values=False)
|
||||
|
||||
host_flag = 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(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(flag_name='port', possible_flag_values=re.compile(r'^\d{1,5}$'))
|
||||
short_port_flag = Flag(flag_name='p', flag_prefix='-', possible_flag_values=re.compile(r'^\d{1,5}$'))
|
||||
@@ -4,12 +4,10 @@ from typing import Literal, Pattern
|
||||
class Flag:
|
||||
def __init__(self, flag_name: str,
|
||||
flag_prefix: Literal['-', '--', '---'] = '--',
|
||||
ignore_flag_value_register: bool = False,
|
||||
possible_flag_values: list[str] | Pattern[str] = False):
|
||||
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
|
||||
self.ignore_flag_value_register = ignore_flag_value_register
|
||||
|
||||
self._flag_value = None
|
||||
|
||||
@@ -29,23 +27,23 @@ class Flag:
|
||||
def set_value(self, value):
|
||||
self._flag_value = value
|
||||
|
||||
def validate_input_flag_value(self, input_flag_value: str):
|
||||
if isinstance(self.possible_flag_values, Pattern):
|
||||
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
|
||||
|
||||
if isinstance(self.possible_flag_values, list):
|
||||
if self.ignore_flag_value_register:
|
||||
if input_flag_value.lower() in [x.lower() for x in self.possible_flag_values]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
elif isinstance(self.possible_flag_values, list):
|
||||
if input_flag_value in self.possible_flag_values:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
@@ -0,0 +1 @@
|
||||
from .entity import FlagsGroup
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
from argenta.command.params.flag.entity import Flag
|
||||
from argenta.command.flag import Flag
|
||||
|
||||
|
||||
class FlagsGroup:
|
||||
def __init__(self, flags: list[Flag] = None):
|
||||
def __init__(self, *flags: Flag):
|
||||
self._flags: list[Flag] = [] if not flags else flags
|
||||
|
||||
def get_flags(self) -> list[Flag]:
|
||||
@@ -2,8 +2,8 @@ from typing import Callable, Any
|
||||
from inspect import getfullargspec
|
||||
|
||||
from ..command.entity import Command
|
||||
from ..command.params.flag.entity import Flag
|
||||
from ..command.params.flag.flags_group.entity import FlagsGroup
|
||||
from argenta.command.flag.entity import Flag
|
||||
from argenta.command.flag.flags_group import FlagsGroup
|
||||
from ..router.exceptions import (RepeatedCommandException,
|
||||
RepeatedFlagNameException,
|
||||
TooManyTransferredArgsException,
|
||||
@@ -23,7 +23,7 @@ class Router:
|
||||
self._command_entities: list[dict[str, Callable[[], None] | Command]] = []
|
||||
self._ignore_command_register: bool = False
|
||||
|
||||
self._not_valid_flag_handler: Callable[[Flag], None] = lambda flag: print(f"Undefined or incorrect input flag: '{flag.get_string_entity()} {flag.get_value()}'")
|
||||
self._not_valid_flag_handler: Callable[[Flag], None] = lambda flag: print(f"Undefined or incorrect input flag: {flag.get_string_entity()}{(' '+flag.get_value()) if flag.get_value() else ''}")
|
||||
|
||||
|
||||
def command(self, command: Command) -> Callable[[Any], Any]:
|
||||
|
||||
+3
-7
@@ -1,11 +1,7 @@
|
||||
import re
|
||||
|
||||
|
||||
def set_description_message_pattern(pattern: str) -> None:
|
||||
first_check = re.match(r'.*command.*', pattern)
|
||||
second_check = re.match(r'.*{description}.*', pattern)
|
||||
if bool(first_check) and bool(second_check):
|
||||
print('Success')
|
||||
def test(string):
|
||||
return bool(re.match(r'\ntest command\n(.|\s)*\nsome command\n', string))
|
||||
|
||||
|
||||
set_description_message_pattern('Invalid des{ommand}cription pattern')
|
||||
print(test('test command tpgm4tigm4tigmt\n i0hhmi6h some command'))
|
||||
|
||||
@@ -2,15 +2,15 @@ import re
|
||||
from pprint import pprint
|
||||
from rich.console import Console
|
||||
|
||||
from argenta.command.entity import Command
|
||||
from argenta.command.params.flag.entity import Flag
|
||||
from argenta.command.params.flag.flags_group.entity import FlagsGroup
|
||||
from argenta.command import Command
|
||||
from argenta.command.flag import Flag, FlagsGroup
|
||||
from argenta.command.flag.defaults import DefaultFlags
|
||||
from argenta.router import Router
|
||||
from .handlers_implementation.help_command import help_command
|
||||
|
||||
|
||||
work_router: Router = Router(title='Work nts:')
|
||||
work_router.set_invalid_input_flag_handler(lambda flag: print(f'Invalid input flag: "{flag.get_string_entity()} {flag.get_value()}"'))
|
||||
work_router.set_invalid_input_flag_handler(lambda flag: print(f'Invalid input flag: {flag.get_string_entity()} {flag.get_value() if flag.get_value() else ''}'))
|
||||
|
||||
settings_router: Router = Router(title='Settings points:')
|
||||
|
||||
@@ -18,21 +18,12 @@ settings_router: Router = Router(title='Settings points:')
|
||||
console = Console()
|
||||
|
||||
|
||||
flags = FlagsGroup(flags=[
|
||||
Flag(flag_name='host',
|
||||
flag_prefix='--',
|
||||
possible_flag_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')),
|
||||
Flag(flag_name='port',
|
||||
flag_prefix='--', )
|
||||
])
|
||||
|
||||
|
||||
@work_router.command(Command(trigger='0', description='Get Help'))
|
||||
def command_help():
|
||||
help_command()
|
||||
|
||||
|
||||
@work_router.command(Command(trigger='--gbP', description='Start Solving', flags=flags))
|
||||
@work_router.command(Command(trigger='P', description='Start Solving', flags=FlagsGroup(DefaultFlags.host_flag, DefaultFlags.port_flag)))
|
||||
def command_start_solving(args: dict):
|
||||
print('Solving...')
|
||||
pprint(args)
|
||||
|
||||
@@ -3,16 +3,13 @@ from art import text2art
|
||||
from rich.console import Console
|
||||
|
||||
from argenta.app import App
|
||||
from argenta.router import Router
|
||||
from argenta.command import Command
|
||||
from argenta.command.params.flag import Flag, FlagsGroup
|
||||
|
||||
|
||||
app: App = App(prompt='[italic white bold]What do you want to do(enter number of action)?',
|
||||
line_separate=f'\n{"[bold green]-[/bold green][bold red]-[/bold red]"*25}\n',
|
||||
print_func=Console().print,
|
||||
command_group_description_separate='',
|
||||
repeat_command_groups=True)
|
||||
repeat_command_groups=True,
|
||||
ignore_exit_command_register=False)
|
||||
|
||||
|
||||
def main():
|
||||
@@ -29,7 +26,7 @@ def main():
|
||||
app.set_farewell_message(goodbye_message)
|
||||
|
||||
app.set_invalid_input_flags_handler(lambda raw_command: print(f"Invalid input flags: {raw_command}"))
|
||||
app.set_unknown_command_handler(lambda command: print(f"Unknown command: {command.get_string_entity()}"))
|
||||
app.set_unknown_command_handler(lambda command: print(f"Unknown command: {command.get_trigger()}"))
|
||||
app.set_repeated_input_flags_handler(lambda raw_command: print(f"Repeated input flags: {raw_command}"))
|
||||
|
||||
app.set_description_message_pattern('[bold red][{command}][/bold red] [blue]*=*=*[/blue] [bold yellow italic]{description}')
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "argenta"
|
||||
version = "0.3.8"
|
||||
version = "0.4.0"
|
||||
description = "python library for creating custom shells"
|
||||
authors = [
|
||||
{name = "kolo", email = "kolo.is.main@gmail.com"}
|
||||
@@ -33,4 +33,5 @@ numpy = "^2.2.2"
|
||||
word2number = "^1.1"
|
||||
numexpr = "^2.10.2"
|
||||
requests = "^2.32.3"
|
||||
pyreadline3 = "^3.5.4"
|
||||
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
import _io
|
||||
from unittest.mock import patch, MagicMock
|
||||
import unittest
|
||||
import io
|
||||
import re
|
||||
|
||||
from argenta.app import App
|
||||
from argenta.command import Command
|
||||
from argenta.router import Router
|
||||
from argenta.command.flag import Flag, FlagsGroup
|
||||
from argenta.command.flag.defaults import DefaultFlags
|
||||
|
||||
|
||||
|
||||
class TestSystemHandlerNormalWork(unittest.TestCase):
|
||||
@patch("builtins.input", side_effect=["help", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_incorrect_command(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test'))
|
||||
def test():
|
||||
print('test command')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn("\nUnknown command: help\n", output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["TeSt", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_incorrect_command2(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test'))
|
||||
def test():
|
||||
print('test command')
|
||||
|
||||
app = App(ignore_command_register=False)
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn('\nUnknown command: TeSt\n', output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test --help", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_correct_command_with_unregistered_flag(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test'))
|
||||
def test():
|
||||
print(f'test command')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn('\nUndefined or incorrect input flag: --help\n', output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test --port 22", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_correct_command_with_unregistered_flag2(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test'))
|
||||
def test():
|
||||
print('test command')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
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("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):
|
||||
router = Router()
|
||||
flags = FlagsGroup(DefaultFlags.host_flag)
|
||||
|
||||
@router.command(Command('test', flags=flags))
|
||||
def test(args: dict):
|
||||
print(f'connecting to host {args["host"]["value"]}')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn('\nUndefined or incorrect input flag: --port 132\n', output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test", "some", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_one_correct_command_and_one_incorrect_command(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test'))
|
||||
def test():
|
||||
print(f'test command')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertRegex(output, re.compile(r'\ntest command\n(.|\n)*\nUnknown command: some\n'))
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test", "some", "more", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_two_correct_commands_and_one_incorrect_command(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test'))
|
||||
def test():
|
||||
print(f'test command')
|
||||
|
||||
@router.command(Command('more'))
|
||||
def test():
|
||||
print(f'more command')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertRegex(output, re.compile(r'\ntest command\n(.|\n)*\nUnknown command: some\n(.|\n)*\nmore command'))
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test 535 --port", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_correct_command_with_incorrect_flag(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test'))
|
||||
def test():
|
||||
print(f'test command')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn("\nIncorrect flag syntax: \"test 535 --port\"\n", output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_empty_command(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test'))
|
||||
def test():
|
||||
print(f'test command')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn("\nEmpty input command\n", output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test --port 22 --port 33", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_correct_command_with_repeated_flags(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test', flags=DefaultFlags.port_flag))
|
||||
def test(args):
|
||||
print('test command')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn("\nRepeated input flags: \"test --port 22 --port 33\"", output)
|
||||
@@ -0,0 +1,211 @@
|
||||
import _io
|
||||
from unittest.mock import patch, MagicMock
|
||||
import unittest
|
||||
import io
|
||||
import re
|
||||
|
||||
from argenta.app import App
|
||||
from argenta.command import Command
|
||||
from argenta.router import Router
|
||||
from argenta.command.flag import Flag, FlagsGroup
|
||||
from argenta.command.flag.defaults import DefaultFlags
|
||||
|
||||
|
||||
|
||||
class TestSystemHandlerNormalWork(unittest.TestCase):
|
||||
@patch("builtins.input", side_effect=["test", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_correct_command(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test'))
|
||||
def test():
|
||||
print('test command')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn('\ntest command\n', output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["TeSt", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_correct_command2(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test'))
|
||||
def test():
|
||||
print('test command')
|
||||
|
||||
app = App(ignore_command_register=True)
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn('\ntest command\n', output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test --help", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_correct_command_with_custom_flag(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
flag = Flag('help', '--', False)
|
||||
|
||||
@router.command(Command('test', flags=flag))
|
||||
def test(args: dict):
|
||||
print(f'\nhelp for {args['help']['name']} flag\n')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn('\nhelp for help flag\n', output)
|
||||
|
||||
@patch("builtins.input", side_effect=["test --port 22", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_correct_command_with_custom_flag2(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
flag = Flag('port', '--', re.compile(r'^\d{1,5}$'))
|
||||
|
||||
@router.command(Command('test', flags=flag))
|
||||
def test(args: dict):
|
||||
print(f'flag value for {args['port']['name']} flag : {args["port"]["value"]}')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn('\nflag value for port flag : 22\n', output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test -h", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_correct_command_with_default_flag(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
flag = DefaultFlags.short_help_flag
|
||||
|
||||
@router.command(Command('test', flags=flag))
|
||||
def test(args: dict):
|
||||
print(f'help for {args['h']['name']} flag')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn('\nhelp for h flag\n', output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test --info", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_correct_command_with_default_flag2(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
flag = DefaultFlags.info_flag
|
||||
|
||||
@router.command(Command('test', flags=flag))
|
||||
def test(args: dict):
|
||||
if args.get('info'):
|
||||
print('info about test command')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn('\ninfo about test command\n', output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test --host 192.168.0.1", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_correct_command_with_default_flag3(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
flag = DefaultFlags.host_flag
|
||||
|
||||
@router.command(Command('test', flags=flag))
|
||||
def test(args: dict):
|
||||
print(f'connecting to host {args["host"]["value"]}')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn('\nconnecting to host 192.168.0.1\n', output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test --host 192.168.32.1 --port 132", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_correct_command_with_two_flags(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
flags = FlagsGroup(DefaultFlags.host_flag, DefaultFlags.port_flag)
|
||||
|
||||
@router.command(Command('test', flags=flags))
|
||||
def test(args: dict):
|
||||
print(f'connecting to host {args["host"]["value"]} and port {args["port"]["value"]}')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertIn('\nconnecting to host 192.168.32.1 and port 132\n', output)
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test", "some", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_two_correct_command(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test'))
|
||||
def test():
|
||||
print(f'test command')
|
||||
|
||||
@router.command(Command('some'))
|
||||
def test():
|
||||
print(f'some command')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertRegex(output, re.compile(r'\ntest command\n(.|\n)*\nsome command\n'))
|
||||
|
||||
|
||||
@patch("builtins.input", side_effect=["test", "some", "more", "q"])
|
||||
@patch("sys.stdout", new_callable=io.StringIO)
|
||||
def test_input_three_correct_command(self, mock_stdout: _io.StringIO, magick_mock: MagicMock):
|
||||
router = Router()
|
||||
|
||||
@router.command(Command('test'))
|
||||
def test():
|
||||
print(f'test command')
|
||||
|
||||
@router.command(Command('some'))
|
||||
def test():
|
||||
print(f'some command')
|
||||
|
||||
@router.command(Command('more'))
|
||||
def test():
|
||||
print(f'more command')
|
||||
|
||||
app = App()
|
||||
app.include_router(router)
|
||||
app.start_polling()
|
||||
|
||||
output = mock_stdout.getvalue()
|
||||
|
||||
self.assertRegex(output, re.compile(r'\ntest command\n(.|\n)*\nsome command\n(.|\n)*\nmore command'))
|
||||
@@ -10,10 +10,6 @@ class TestCommand(unittest.TestCase):
|
||||
def test_parse_correct_raw_command(self):
|
||||
self.assertEqual(Command.parse_input_command('ssh --host 192.168.0.3').get_trigger(), 'ssh')
|
||||
|
||||
def test_parse_raw_command_with_flag_name_without_value(self):
|
||||
with self.assertRaises(UnprocessedInputFlagException):
|
||||
Command.parse_input_command('ssh --host')
|
||||
|
||||
def test_parse_raw_command_without_flag_name_with_value(self):
|
||||
with self.assertRaises(UnprocessedInputFlagException):
|
||||
Command.parse_input_command('ssh 192.168.0.3')
|
||||
@@ -1,4 +1,4 @@
|
||||
from argenta.command.params.flag import Flag
|
||||
from argenta.command.flag import Flag
|
||||
|
||||
import unittest
|
||||
import re
|
||||
@@ -52,6 +52,22 @@ class TestFlag(unittest.TestCase):
|
||||
flag = Flag(flag_name='test', possible_flag_values=re.compile(r'192.168.\d+.\d+'))
|
||||
self.assertEqual(flag.validate_input_flag_value('192.168.9.8'), True)
|
||||
|
||||
def test_validate_correct_empty_flag_value_without_possible_flag_values(self):
|
||||
flag = Flag(flag_name='test', possible_flag_values=False)
|
||||
self.assertEqual(flag.validate_input_flag_value(None), True)
|
||||
|
||||
def test_validate_correct_empty_flag_value_with_possible_flag_values(self):
|
||||
flag = Flag(flag_name='test', possible_flag_values=True)
|
||||
self.assertEqual(flag.validate_input_flag_value(None), True)
|
||||
|
||||
def test_validate_incorrect_random_flag_value_without_possible_flag_values(self):
|
||||
flag = Flag(flag_name='test', possible_flag_values=False)
|
||||
self.assertEqual(flag.validate_input_flag_value('random value'), False)
|
||||
|
||||
def test_validate_correct_random_flag_value_with_possible_flag_values(self):
|
||||
flag = Flag(flag_name='test', possible_flag_values=True)
|
||||
self.assertEqual(flag.validate_input_flag_value('random value'), True)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from argenta.command.params.flag import Flag, FlagsGroup
|
||||
from argenta.command.flag import Flag, FlagsGroup
|
||||
|
||||
import unittest
|
||||
|
||||
@@ -31,7 +31,7 @@ class TestFlagsGroup(unittest.TestCase):
|
||||
Flag('test2'),
|
||||
Flag('test3'),
|
||||
]
|
||||
flags = FlagsGroup(list_of_flags)
|
||||
flags = FlagsGroup(*list_of_flags)
|
||||
serialized_flags = flags.unparse_to_dict()
|
||||
needed_result = {'test1': {'name': 'test1',
|
||||
'prefix': '--',
|
||||
@@ -1,4 +1,4 @@
|
||||
from argenta.command.params.flag import FlagsGroup, Flag
|
||||
from argenta.command.flag import FlagsGroup, Flag
|
||||
from argenta.router import Router
|
||||
from argenta.command import Command
|
||||
from argenta.router.exceptions import RepeatedCommandException, TriggerCannotContainSpacesException
|
||||
Reference in New Issue
Block a user