- Refactored `FalyxCompleter` to support longest common prefix (LCP) completions by default. - Added `_ensure_quote` helper to auto-quote completions containing spaces/tabs. - Integrated `_yield_lcp_completions` for consistent completion insertion logic. - Added `_suggest_paths()` helper to dynamically suggest filesystem paths for arguments of type `Path`. - Integrated path completion into `suggest_next()` for both positional and flagged arguments. - Updated `argument_examples.py` to include a `--path` argument (`Path | None`), demonstrating file path completion. - Enabled `CompleteStyle.COLUMN` for tab-completion menu formatting in interactive sessions. - Improved bottom bar docstring formatting with fenced code block examples. - Added safeguard to `word_validator` to reject `"N"` since it’s reserved for `yes_no_validator`. - Improved help panel rendering for commands (using `Padding` + `Panel`). - Added full test coverage for: - `FalyxCompleter` and LCP behavior (`tests/test_completer/`) - All validators (`tests/test_validators/`) - Bumped version to 0.1.80.
106 lines
3.0 KiB
Python
106 lines
3.0 KiB
Python
import pytest
|
|
from prompt_toolkit.document import Document
|
|
from prompt_toolkit.validation import ValidationError
|
|
|
|
from falyx.validators import MultiKeyValidator
|
|
|
|
|
|
def test_multi_key_validator_accepts_valid_keys():
|
|
validator = MultiKeyValidator(
|
|
["A", "B", "C"],
|
|
number_selections=2,
|
|
separator=",",
|
|
allow_duplicates=False,
|
|
cancel_key="X",
|
|
)
|
|
for valid in ["A,B", "B,C", "A,C"]:
|
|
validator.validate(Document(valid))
|
|
|
|
|
|
def test_multi_key_validator_rejects_invalid_keys():
|
|
validator = MultiKeyValidator(
|
|
["A", "B", "C"],
|
|
number_selections=2,
|
|
separator=",",
|
|
allow_duplicates=False,
|
|
cancel_key="X",
|
|
)
|
|
with pytest.raises(ValidationError):
|
|
validator.validate(Document("D,E,F"))
|
|
with pytest.raises(ValidationError):
|
|
validator.validate(Document("A,B,A"))
|
|
with pytest.raises(ValidationError):
|
|
validator.validate(Document("A,B,C,D"))
|
|
|
|
|
|
def test_multi_key_validator_rejects_invalid_number_of_selections():
|
|
validator = MultiKeyValidator(
|
|
["A", "B", "C"],
|
|
number_selections=2,
|
|
separator=",",
|
|
allow_duplicates=False,
|
|
cancel_key="X",
|
|
)
|
|
with pytest.raises(ValidationError):
|
|
validator.validate(Document("A")) # Not enough selections
|
|
with pytest.raises(ValidationError):
|
|
validator.validate(Document("A,B,C")) # Too many selections
|
|
validator = MultiKeyValidator(
|
|
["A", "B", "C"],
|
|
number_selections=1,
|
|
separator=",",
|
|
allow_duplicates=False,
|
|
cancel_key="X",
|
|
)
|
|
validator.validate(Document("A")) # Exactly one selection is valid
|
|
with pytest.raises(ValidationError):
|
|
validator.validate(Document("B,C")) # Too many selections
|
|
|
|
|
|
def test_multi_key_validator_cancel_key():
|
|
validator = MultiKeyValidator(
|
|
["A", "B", "C"],
|
|
number_selections=2,
|
|
separator=",",
|
|
allow_duplicates=False,
|
|
cancel_key="X",
|
|
)
|
|
validator.validate(Document("X"))
|
|
|
|
|
|
def test_multi_key_validator_cancel_alone():
|
|
validator = MultiKeyValidator(
|
|
["A", "B", "C"],
|
|
number_selections=2,
|
|
separator=",",
|
|
allow_duplicates=False,
|
|
cancel_key="X",
|
|
)
|
|
with pytest.raises(ValidationError):
|
|
validator.validate(Document("A,X"))
|
|
|
|
|
|
def test_multi_key_validator_empty_input():
|
|
validator = MultiKeyValidator(
|
|
["A", "B", "C"],
|
|
number_selections=2,
|
|
separator=",",
|
|
allow_duplicates=False,
|
|
cancel_key="X",
|
|
)
|
|
with pytest.raises(ValidationError):
|
|
validator.validate(Document(""))
|
|
|
|
|
|
def test_multi_key_validator_error_message_for_duplicates():
|
|
validator = MultiKeyValidator(
|
|
["A", "B", "C"],
|
|
number_selections=2,
|
|
separator=",",
|
|
allow_duplicates=False,
|
|
cancel_key="X",
|
|
)
|
|
with pytest.raises(ValidationError) as e:
|
|
validator.validate(Document("A,A,B"))
|
|
assert "Duplicate selection" in str(e.value)
|