mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Validation (#2600)
* 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
This commit is contained in:
79
tests/input/test_input_validation.py
Normal file
79
tests/input/test_input_validation.py
Normal file
@@ -0,0 +1,79 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user