1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
from textwrap import dedent
from typing import Tuple
import pytest
from cyclopts import CycloptsError
from cyclopts.exceptions import InvalidCommandError, MissingArgumentError
@pytest.fixture
def mock_get_function_info(mocker):
mocker.patch("cyclopts.exceptions._get_function_info", return_value=("FILENAME", 100))
def test_runtime_exception_not_enough_tokens(app, console, mock_get_function_info):
@app.default
def foo(a: Tuple[int, int, int]):
pass
with console.capture() as capture, pytest.raises(CycloptsError):
app(["1", "2"], exit_on_error=False, console=console)
actual = capture.get()
assert actual == (
"╭─ Error ────────────────────────────────────────────────────────────╮\n"
'│ Parameter "--a" requires 3 positional arguments. Only got 2. │\n'
"╰────────────────────────────────────────────────────────────────────╯\n"
)
with console.capture() as capture, pytest.raises(CycloptsError):
app(["1", "2"], exit_on_error=False, console=console, verbose=True)
actual = capture.get()
assert actual == dedent(
"""\
╭─ Error ────────────────────────────────────────────────────────────╮
│ MissingArgumentError │
│ Function defined in file "FILENAME", line 100: │
│ foo(a: Tuple[int, int, int]) │
│ Root Input Tokens: ['1', '2'] │
│ Parameter "--a" requires 3 positional arguments. Only got 2. │
│ Parsed: ['1', '2']. │
╰────────────────────────────────────────────────────────────────────╯
"""
)
def test_runtime_exception_missing_parameter(app, console):
@app.default
def foo(a, b, c):
pass
with console.capture() as capture, pytest.raises(CycloptsError):
app(["1", "2"], exit_on_error=False, console=console)
actual = capture.get()
assert actual == (
"╭─ Error ────────────────────────────────────────────────────────────╮\n"
'│ Parameter "--c" requires an argument. │\n'
"╰────────────────────────────────────────────────────────────────────╯\n"
)
def test_runtime_exception_bad_command(app, console):
with console.capture() as capture, pytest.raises(InvalidCommandError):
app(["bad-command", "123"], exit_on_error=False, console=console)
actual = capture.get()
assert actual == (
"╭─ Error ────────────────────────────────────────────────────────────╮\n"
'│ Unknown command "bad-command". │\n'
"╰────────────────────────────────────────────────────────────────────╯\n"
)
def test_runtime_exception_bad_command_recommend(app, console):
@app.command
def mad_command():
pass
with console.capture() as capture, pytest.raises(InvalidCommandError):
app(["bad-command", "123"], exit_on_error=False, console=console)
actual = capture.get()
assert actual == dedent(
"""\
╭─ Error ────────────────────────────────────────────────────────────╮
│ Unknown command "bad-command". Did you mean "mad-command"? │
│ Available commands: mad-command. │
╰────────────────────────────────────────────────────────────────────╯
"""
)
def test_runtime_exception_bad_command_list_ellipsis(app, console):
def cmd():
pass
app.command(name="cmd1")(cmd)
app.command(name="cmd2")(cmd)
app.command(name="cmd3")(cmd)
app.command(name="cmd4")(cmd)
app.command(name="cmd5")(cmd)
app.command(name="cmd6")(cmd)
app.command(name="cmd7")(cmd)
app.command(name="cmd8")(cmd)
app.command(name="cmd9")(cmd)
with console.capture() as capture, pytest.raises(InvalidCommandError):
app(["cmd", "123"], exit_on_error=False, console=console)
actual = capture.get()
assert actual == dedent(
"""\
╭─ Error ────────────────────────────────────────────────────────────╮
│ Unknown command "cmd". Did you mean "cmd9"? Available commands: │
│ cmd1, cmd2, cmd3, cmd4, cmd5, cmd6, cmd7, cmd8, ... │
╰────────────────────────────────────────────────────────────────────╯
"""
)
def test_runtime_exception_bad_parameter_recommend(app, console):
@app.command
def some_command(*, foo: int):
pass
with console.capture() as capture, pytest.raises(MissingArgumentError):
app(["some-command", "--boo", "123"], exit_on_error=False, console=console)
actual = capture.get()
assert actual == dedent(
"""\
╭─ Error ────────────────────────────────────────────────────────────╮
│ Command "some-command" parameter "--foo" requires an argument. Did │
│ you mean "--foo" instead of "--boo"? │
╰────────────────────────────────────────────────────────────────────╯
"""
)
def test_runtime_exception_repeat_arguments(app, console):
@app.default
def foo(a):
pass
with console.capture() as capture, pytest.raises(CycloptsError):
app(["--a=1", "--a=2"], exit_on_error=False, console=console)
actual = capture.get()
assert actual == (
"╭─ Error ────────────────────────────────────────────────────────────╮\n"
"│ Parameter --a specified multiple times. │\n"
"╰────────────────────────────────────────────────────────────────────╯\n"
)
|