feat(core): clone commands and actions when binding runtimes
Add clone support across Action types and Command so commands can be safely registered or runner-bound without mutating the original instances. - clone BaseAction implementations across simple, composite, IO, prompt, file, HTTP, process, and signal actions - bind cloned commands in Falyx.add_command_from_command() and CommandRunner - preserve local never_prompt settings when cloning actions - rename shared runtime state from options to options_manager for consistency - seed root and execution option namespaces consistently - apply scoped root and namespace option overrides during routing and dispatch - improve namespace completion by delegating option suggestions to FalyxParser - enrich missing-value errors and error hints
This commit is contained in:
68
tests/test_falyx/test_exceptions.py
Normal file
68
tests/test_falyx/test_exceptions.py
Normal file
@@ -0,0 +1,68 @@
|
||||
import pytest
|
||||
|
||||
from falyx.console import print_error
|
||||
from falyx.exceptions import CommandArgumentError, MissingValueError
|
||||
from falyx.parser import CommandArgumentParser
|
||||
|
||||
|
||||
async def test_missing_value_error_has_user_facing_message():
|
||||
parser = CommandArgumentParser()
|
||||
parser.add_argument("--pair", type=int, nargs=2)
|
||||
|
||||
with pytest.raises(MissingValueError) as exc:
|
||||
await parser.parse_args(["--pair", "1"])
|
||||
|
||||
assert "pair" in str(exc.value)
|
||||
assert "expected" in str(exc.value).lower()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_missing_value_error_for_fixed_nargs_has_message_and_hint():
|
||||
parser = CommandArgumentParser()
|
||||
parser.add_argument("--pair", type=int, nargs=2)
|
||||
|
||||
with pytest.raises(MissingValueError) as exc:
|
||||
await parser.parse_args(["--pair", "1"])
|
||||
|
||||
error = exc.value
|
||||
|
||||
assert str(error) == "missing values for '--pair': expected 2, got 1"
|
||||
assert error.hint == "provide 2 values for '--pair'."
|
||||
assert error.show_short_usage is True
|
||||
assert error.dest == "pair"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_missing_value_error_for_plus_nargs_has_message_and_hint():
|
||||
parser = CommandArgumentParser()
|
||||
parser.add_argument("--items", nargs="+")
|
||||
|
||||
with pytest.raises(MissingValueError) as exc:
|
||||
await parser.parse_args(["--items"])
|
||||
|
||||
error = exc.value
|
||||
|
||||
assert str(error) == "missing value for '--items'"
|
||||
assert error.hint == "provide one or more values for '--items'."
|
||||
|
||||
|
||||
def test_print_error_uses_exception_hint(monkeypatch) -> None:
|
||||
printed: list[str] = []
|
||||
|
||||
class FakeConsole:
|
||||
def print(self, value):
|
||||
printed.append(value)
|
||||
|
||||
monkeypatch.setattr("falyx.console.error_console", FakeConsole())
|
||||
|
||||
error = CommandArgumentError(
|
||||
"invalid command argument",
|
||||
hint="use --help to see available options",
|
||||
)
|
||||
|
||||
print_error(error)
|
||||
|
||||
assert any("error:" in line for line in printed)
|
||||
assert any("invalid command argument" in line for line in printed)
|
||||
assert any("hint:" in line for line in printed)
|
||||
assert any("use --help to see available options" in line for line in printed)
|
||||
Reference in New Issue
Block a user