Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
getzze committed Dec 4, 2024
1 parent 14324e9 commit 7d379aa
Showing 1 changed file with 121 additions and 31 deletions.
152 changes: 121 additions & 31 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,44 @@
from rexi.cli import app, is_stdin_a_tty


@pytest.mark.parametrize("input_value", [True, False])
def test_is_stdin_a_tty(monkeypatch: MonkeyPatch, input_value: bool) -> None:
isatty_mock = Mock()
with monkeypatch.context():
isatty_mock.return_value = input_value
monkeypatch.setattr("rexi.cli.sys.stdin.isatty", isatty_mock)
assert is_stdin_a_tty() == input_value


def test_no_args(monkeypatch: MonkeyPatch) -> None:
runner = CliRunner()
class_mock = Mock()
instance_mock = Mock()
with monkeypatch.context():
class_mock.return_value = instance_mock
monkeypatch.setattr("rexi.cli.RexiApp", class_mock)
result = runner.invoke(app)

assert result.exit_code == 0
class_mock.assert_called_once_with("", initial_mode=None, initial_pattern=None)


def test_string_input(monkeypatch: MonkeyPatch) -> None:
runner = CliRunner()
text = "This iS! aTe xt2 F0r T3sT!ng"
class_mock = Mock()
instance_mock = Mock()
with monkeypatch.context():
class_mock.return_value = instance_mock
monkeypatch.setattr("rexi.cli.is_stdin_a_tty", lambda: True)
monkeypatch.setattr("rexi.cli.RexiApp", class_mock)
result = runner.invoke(app, args=[text])

assert result.exit_code == 0
class_mock.assert_called_once_with(text, initial_mode=None, initial_pattern=None)


def test_stdin_input(monkeypatch: MonkeyPatch) -> None:
"""
Couldn't find a better way to test the CLI without patching everything :(
"""
Expand All @@ -21,19 +58,19 @@ def test_no_args(monkeypatch: MonkeyPatch) -> None:
instance_mock = Mock()
open_mock = Mock()
read_mock = Mock()
isatty_mock = Mock()

with monkeypatch.context():
read_mock.return_value = ""
class_mock.return_value = instance_mock
isatty_mock.return_value = False
monkeypatch.setattr("rexi.cli.is_stdin_a_tty", isatty_mock)
monkeypatch.setattr("rexi.cli.is_stdin_a_tty", lambda: False)
monkeypatch.setattr("rexi.cli.RexiApp", class_mock)
monkeypatch.setattr("builtins.open", open_mock)
runner.invoke(app, input=a)
result = runner.invoke(app, input=a)
open_mock.assert_called_once_with(
"con:" if os.name == "nt" else "/dev/tty", "rb"
)

assert result.exit_code == 0
class_mock.assert_called_once_with(
text.decode(), initial_mode=None, initial_pattern=None
)
Expand All @@ -49,53 +86,106 @@ def test_file_input(monkeypatch: MonkeyPatch, tmp_path: Path) -> None:
with monkeypatch.context():
class_mock.return_value = instance_mock
monkeypatch.setattr("rexi.cli.RexiApp", class_mock)
runner.invoke(app, args=["-i", str(tmp_path / "text_file")])
monkeypatch.setattr("rexi.cli.is_stdin_a_tty", lambda: True)
result = runner.invoke(app, args=["-i", str(tmp_path / "text_file")])

assert result.exit_code == 0
class_mock.assert_called_once_with(text, initial_mode=None, initial_pattern=None)


@pytest.mark.parametrize("use_stdin", [False, True])
@pytest.mark.parametrize("use_input", [False, True])
@pytest.mark.parametrize("use_string", [False, True])
def test_argument_conflicts(
monkeypatch: MonkeyPatch,
tmp_path: Path,
use_stdin: bool,
use_input: bool,
use_string: bool,
) -> None:
"""
Couldn't find a better way to test the CLI without patching everything :(
"""
# Text stdin
text_stdin = "stdin: This iS! aTe xt2 F0r T3sT!ng"
a = BytesIO(text_stdin.encode())
# Text string
text_string = "string: ThaT iS! éhé"
# Text input file
text_input = "input: This iS! aTe xt2 F0r T3sT!ng"
tmp_file = (tmp_path / "text_file")
tmp_file.write_text(text_input)

# Initialize mocks
runner = CliRunner()
class_mock = Mock()
instance_mock = Mock()
read_mock = Mock()

with monkeypatch.context():
read_mock.return_value = ""
monkeypatch.setattr("rexi.cli.is_stdin_a_tty", lambda: not use_stdin)
monkeypatch.setattr("rexi.cli.RexiApp", class_mock)
class_mock.return_value = instance_mock

kwargs = {}
args = []
if use_stdin:
kwargs["input"] = a
if use_input:
args.extend(["-i", os.fspath(tmp_file)])
if use_string:
args.extend([text_string])
if args:
kwargs["args"] = args
# Call CLI
result = runner.invoke(app, **kwargs)

# Check result
has_conflict = int(use_stdin + use_string + use_input) > 1
if has_conflict:
assert result.exit_code > 0
assert "Invalid value" in result.output
return

expected_text = ""
if use_stdin:
expected_text = text_stdin
elif use_input:
expected_text = text_input
elif use_string:
expected_text = text_string

assert result.exit_code == 0
class_mock.assert_called_once_with(
expected_text,
initial_mode=None,
initial_pattern=None,
)
instance_mock.run.assert_called_once()


def test_initial_pattern(monkeypatch: MonkeyPatch, tmp_path: Path) -> None:
runner = CliRunner()
text = "This iS! aTe xt2 F0r T3sT!ng"
(tmp_path / "text_file").write_text(text)
class_mock = Mock()
instance_mock = Mock()
with monkeypatch.context():
class_mock.return_value = instance_mock
monkeypatch.setattr("rexi.cli.is_stdin_a_tty", lambda: True)
monkeypatch.setattr("rexi.cli.RexiApp", class_mock)
runner.invoke(app, args=["-i", str(tmp_path / "text_file"), "--pattern", "wtf"])
runner.invoke(app, args=[text, "--pattern", "wtf"])
class_mock.assert_called_once_with(text, initial_mode=None, initial_pattern="wtf")


def test_initial_mode(monkeypatch: MonkeyPatch, tmp_path: Path) -> None:
runner = CliRunner()
text = "This iS! aTe xt2 F0r T3sT!ng"
(tmp_path / "text_file").write_text(text)
class_mock = Mock()
instance_mock = Mock()
with monkeypatch.context():
class_mock.return_value = instance_mock
monkeypatch.setattr("rexi.cli.is_stdin_a_tty", lambda: True)
monkeypatch.setattr("rexi.cli.RexiApp", class_mock)
runner.invoke(app, args=["-i", str(tmp_path / "text_file"), "--mode", "match"])
runner.invoke(app, args=[text, "--mode", "match"])
class_mock.assert_called_once_with(text, initial_mode="match", initial_pattern=None)


def test_no_stdin_error(monkeypatch: MonkeyPatch) -> None:
"""
Couldn't find a better way to test the CLI without patching everything :(
"""
runner = CliRunner()
isatty_mock = Mock()
with monkeypatch.context():
isatty_mock.return_value = True
monkeypatch.setattr("rexi.cli.is_stdin_a_tty", isatty_mock)
result = runner.invoke(app)
assert "Invalid value" in result.output


@pytest.mark.parametrize("input_value", [True, False])
def test_is_stdin_a_tty(monkeypatch: MonkeyPatch, input_value: bool) -> None:
isatty_mock = Mock()
with monkeypatch.context():
isatty_mock.return_value = input_value
monkeypatch.setattr("rexi.cli.sys.stdin.isatty", isatty_mock)
assert is_stdin_a_tty() == input_value

0 comments on commit 7d379aa

Please sign in to comment.