mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
* A few different types of validation * Rename * Fix test * Updating validation framework * Update lockfile * Ensure validators can be None * Reworking the API a little * Convert Input.Changed to dataclass * Add utility for getting failures as strings * Update an example in Validator docstring * Remove some redundant `pass`es * Renaming variables * Validating Input on submit, attaching result to Submitted event * Testing various validation features * Update snapshots and deps * Styling unfocused -invalid Input differently * Add snapshot test around input validation and associated styles * Validation docs * Tidying validation docs in Input widget reference * Fix mypy issues * Remove __bool__ from Failure, make validator field required * Code review changes * Improving error messages in Validators
80 lines
2.4 KiB
Python
80 lines
2.4 KiB
Python
from textual import on
|
|
from textual.app import App, ComposeResult
|
|
from textual.validation import Number, ValidationResult
|
|
from textual.widgets import Input
|
|
|
|
|
|
class InputApp(App):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.messages = []
|
|
self.validator = Number(minimum=1, maximum=5)
|
|
|
|
def compose(self) -> ComposeResult:
|
|
yield Input(
|
|
validators=self.validator,
|
|
)
|
|
|
|
@on(Input.Changed)
|
|
@on(Input.Submitted)
|
|
def on_changed_or_submitted(self, event):
|
|
self.messages.append(event)
|
|
|
|
|
|
async def test_input_changed_message_validation_failure():
|
|
app = InputApp()
|
|
async with app.run_test() as pilot:
|
|
input = app.query_one(Input)
|
|
input.value = "8"
|
|
await pilot.pause()
|
|
assert len(app.messages) == 1
|
|
assert app.messages[0].validation_result == ValidationResult.failure(
|
|
failures=[
|
|
Number.NotInRange(
|
|
value="8",
|
|
validator=app.validator,
|
|
description="Must be between 1 and 5.",
|
|
)
|
|
],
|
|
)
|
|
|
|
|
|
async def test_input_changed_message_validation_success():
|
|
app = InputApp()
|
|
async with app.run_test() as pilot:
|
|
input = app.query_one(Input)
|
|
input.value = "3"
|
|
await pilot.pause()
|
|
assert len(app.messages) == 1
|
|
assert app.messages[0].validation_result == ValidationResult.success()
|
|
|
|
|
|
async def test_input_submitted_message_validation_failure():
|
|
app = InputApp()
|
|
async with app.run_test() as pilot:
|
|
input = app.query_one(Input)
|
|
input.value = "8"
|
|
await input.action_submit()
|
|
await pilot.pause()
|
|
assert len(app.messages) == 2
|
|
assert app.messages[1].validation_result == ValidationResult.failure(
|
|
failures=[
|
|
Number.NotInRange(
|
|
value="8",
|
|
validator=app.validator,
|
|
description="Must be between 1 and 5.",
|
|
)
|
|
],
|
|
)
|
|
|
|
|
|
async def test_input_submitted_message_validation_success():
|
|
app = InputApp()
|
|
async with app.run_test() as pilot:
|
|
input = app.query_one(Input)
|
|
input.value = "3"
|
|
await input.action_submit()
|
|
await pilot.pause()
|
|
assert len(app.messages) == 2
|
|
assert app.messages[1].validation_result == ValidationResult.success()
|