123 lines
4 KiB
Python
123 lines
4 KiB
Python
import re
|
|
import time
|
|
import pytest
|
|
from unittest.mock import patch
|
|
|
|
from iredis.utils import timer, strip_quote_args
|
|
from iredis.commands import split_command_args, split_unknown_args
|
|
from iredis.utils import command_syntax
|
|
from iredis.style import STYLE
|
|
from iredis.exceptions import InvalidArguments, AmbiguousCommand
|
|
from iredis.commands import commands_summary
|
|
from prompt_toolkit import print_formatted_text
|
|
|
|
|
|
def test_timer():
|
|
with patch("iredis.utils.logger") as mock_logger:
|
|
timer("foo")
|
|
time.sleep(0.1)
|
|
timer("bar")
|
|
mock_logger.debug.assert_called()
|
|
args, kwargs = mock_logger.debug.call_args
|
|
matched = re.match(r"\[timer (\d)\] (0\.\d+) -> bar", args[0])
|
|
|
|
assert matched.group(1) == str(3)
|
|
assert 0.1 <= float(matched.group(2)) <= 0.2
|
|
|
|
# --- test again ---
|
|
timer("foo")
|
|
time.sleep(0.2)
|
|
timer("bar")
|
|
mock_logger.debug.assert_called()
|
|
args, kwargs = mock_logger.debug.call_args
|
|
matched = re.match(r"\[timer (\d)\] (0\.\d+) -> bar", args[0])
|
|
|
|
assert matched.group(1) == str(5)
|
|
assert 0.2 <= float(matched.group(2)) <= 0.3
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"test_input,expected",
|
|
[
|
|
("hello world", ["hello", "world"]),
|
|
("'hello world'", ["hello world"]),
|
|
('''hello"world"''', ["helloworld"]),
|
|
(r'''hello\"world"''', [r"hello\world"]),
|
|
(r'"\\"', [r"\\"]),
|
|
(r"\\", [r"\\"]),
|
|
(r"\abcd ef", [r"\abcd", "ef"]),
|
|
# quotes in quotes
|
|
(r""" 'hello"world' """, ['hello"world']),
|
|
(r""" "hello'world" """, ["hello'world"]),
|
|
(r""" 'hello\'world'""", ["hello'world"]),
|
|
(r""" "hello\"world" """, ['hello"world']),
|
|
(r"''", [""]), # set foo "" is a legal command
|
|
(r'""', [""]), # set foo "" is a legal command
|
|
(r"\\", ["\\\\"]), # backslash are legal
|
|
("\\hello\\", ["\\hello\\"]), # backslash are legal
|
|
('foo "bar\\n1"', ["foo", "bar\n1"]),
|
|
],
|
|
)
|
|
def test_stripe_quote_escape_in_quote(test_input, expected):
|
|
assert list(strip_quote_args(test_input)) == expected
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"command,expected,args",
|
|
[
|
|
("GET a", "GET", ["a"]),
|
|
("cluster info", "cluster info", []),
|
|
("getbit foo 17", "getbit", ["foo", "17"]),
|
|
("command ", "command", []),
|
|
(" command count ", "command count", []),
|
|
(" command count ", "command count", []), # command with multi space
|
|
(" command count ' hello world'", "command count", [" hello world"]),
|
|
("set foo 'hello world'", "set", ["foo", "hello world"]),
|
|
],
|
|
)
|
|
def test_split_commands(command, expected, args):
|
|
parsed_command, parsed_args = split_command_args(command)
|
|
assert expected == parsed_command
|
|
assert args == parsed_args
|
|
|
|
|
|
def test_split_commands_fail_on_unknown_command():
|
|
with pytest.raises(InvalidArguments):
|
|
split_command_args("FOO BAR")
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"command",
|
|
["command in", "command in", "Command in", "COMMAND in"],
|
|
)
|
|
def test_split_commands_fail_on_partially_input(command):
|
|
with pytest.raises(AmbiguousCommand):
|
|
split_command_args(command)
|
|
|
|
|
|
def test_split_commands_fail_on_unfinished_command():
|
|
with pytest.raises(InvalidArguments):
|
|
split_command_args("setn")
|
|
|
|
|
|
def test_render_bottom_with_command_json():
|
|
for command, info in commands_summary.items():
|
|
print_formatted_text(command_syntax(command, info), style=STYLE)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"raw,command,args",
|
|
[
|
|
("abc 123", "abc", ["123"]),
|
|
("abc", "abc", []),
|
|
("abc foo bar", "abc", ["foo", "bar"]),
|
|
("abc 'foo bar'", "abc", ["foo bar"]),
|
|
('abc "foo bar"', "abc", ["foo bar"]),
|
|
('abc "foo bar" 3 hello', "abc", ["foo bar", "3", "hello"]),
|
|
('abc "foo \nbar"', "abc", ["foo \nbar"]),
|
|
],
|
|
)
|
|
def test_split_unknown_commands(raw, command, args):
|
|
parsed_command, parsed_args = split_unknown_args(raw)
|
|
assert command == parsed_command
|
|
assert args == parsed_args
|