From c448fa1ea089e405b30702d8d761bfacc64988e8 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 23 May 2023 15:48:34 +0100 Subject: [PATCH] Add unit tests for selection list messages --- .../selection_list/test_selection_messages.py | 194 ++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 tests/selection_list/test_selection_messages.py diff --git a/tests/selection_list/test_selection_messages.py b/tests/selection_list/test_selection_messages.py new file mode 100644 index 000000000..3e6041200 --- /dev/null +++ b/tests/selection_list/test_selection_messages.py @@ -0,0 +1,194 @@ +"""Unit tests aimed at testing the selection list messages. + +Note that these tests only cover a subset of the public API of this widget. +The bulk of the API is inherited from OptionList, and as such there are +comprehensive tests for that. These tests simply cover the parts of the API +that have been modified by the child class. +""" + +from __future__ import annotations + +from textual import on +from textual.app import App, ComposeResult +from textual.messages import Message +from textual.widgets import SelectionList + + +class SelectionListApp(App[None]): + """Test selection list application.""" + + def __init__(self) -> None: + super().__init__() + self.messages: list[tuple[str, int | None]] = [] + + def compose(self) -> ComposeResult: + yield SelectionList[int](*[(str(n), n) for n in range(10)]) + + @on(SelectionList.SelectionHighlighted) + @on(SelectionList.SelectionToggled) + @on(SelectionList.SelectedChanged) + def _record(self, event: Message) -> None: + self.messages.append( + ( + event.__class__.__name__, + event.selection_index + if isinstance(event, SelectionList.SelectionMessage) + else None, + ) + ) + + +async def test_messages_on_startup() -> None: + """There should be a highlighted message when a non-empty selection list first starts up.""" + async with SelectionListApp().run_test() as pilot: + assert isinstance(pilot.app, SelectionListApp) + await pilot.pause() + assert pilot.app.messages == [("SelectionHighlighted", 0)] + + +async def test_new_highlight() -> None: + """Setting the highlight to a new option should result in a message.""" + async with SelectionListApp().run_test() as pilot: + assert isinstance(pilot.app, SelectionListApp) + await pilot.pause() + pilot.app.query_one(SelectionList).highlighted = 2 + await pilot.pause() + assert pilot.app.messages[1:] == [("SelectionHighlighted", 2)] + + +async def test_toggle() -> None: + """Toggling an option should result in messages.""" + async with SelectionListApp().run_test() as pilot: + assert isinstance(pilot.app, SelectionListApp) + await pilot.pause() + pilot.app.query_one(SelectionList).toggle(0) + await pilot.pause() + assert pilot.app.messages == [ + ("SelectionHighlighted", 0), + ("SelectedChanged", None), + ] + + +async def test_toggle_all() -> None: + """Toggling all options should result in messages.""" + async with SelectionListApp().run_test() as pilot: + assert isinstance(pilot.app, SelectionListApp) + await pilot.pause() + pilot.app.query_one(SelectionList).toggle_all() + await pilot.pause() + assert pilot.app.messages == [ + ("SelectionHighlighted", 0), + ("SelectedChanged", None), + ] + + +async def test_select() -> None: + """Selecting all an option should result in a message.""" + async with SelectionListApp().run_test() as pilot: + assert isinstance(pilot.app, SelectionListApp) + await pilot.pause() + pilot.app.query_one(SelectionList).select(1) + await pilot.pause() + assert pilot.app.messages == [ + ("SelectionHighlighted", 0), + ("SelectedChanged", None), + ] + + +async def test_select_selected() -> None: + """Selecting an option that is already selected should emit no extra message..""" + async with SelectionListApp().run_test() as pilot: + assert isinstance(pilot.app, SelectionListApp) + await pilot.pause() + pilot.app.query_one(SelectionList).select(0) + await pilot.pause() + pilot.app.query_one(SelectionList).select(0) + await pilot.pause() + assert pilot.app.messages == [ + ("SelectionHighlighted", 0), + ("SelectedChanged", None), + ] + + +async def test_select_all() -> None: + """Selecting all options should result in messages.""" + async with SelectionListApp().run_test() as pilot: + assert isinstance(pilot.app, SelectionListApp) + await pilot.pause() + pilot.app.query_one(SelectionList).select_all() + await pilot.pause() + assert pilot.app.messages == [ + ("SelectionHighlighted", 0), + ("SelectedChanged", None), + ] + + +async def test_select_all_selected() -> None: + """Selecting all when all are selected should result in no extra messages.""" + async with SelectionListApp().run_test() as pilot: + assert isinstance(pilot.app, SelectionListApp) + await pilot.pause() + pilot.app.query_one(SelectionList).select_all() + await pilot.pause() + pilot.app.query_one(SelectionList).select_all() + await pilot.pause() + assert pilot.app.messages == [ + ("SelectionHighlighted", 0), + ("SelectedChanged", None), + ] + + +async def test_deselect() -> None: + """Deselecting an option should result in a message.""" + async with SelectionListApp().run_test() as pilot: + assert isinstance(pilot.app, SelectionListApp) + await pilot.pause() + pilot.app.query_one(SelectionList).select(1) + await pilot.pause() + pilot.app.query_one(SelectionList).deselect(1) + await pilot.pause() + assert pilot.app.messages == [ + ("SelectionHighlighted", 0), + ("SelectedChanged", None), + ("SelectedChanged", None), + ] + + +async def test_deselect_deselected() -> None: + """Deselecting a deslected option should result in no extra messages.""" + async with SelectionListApp().run_test() as pilot: + assert isinstance(pilot.app, SelectionListApp) + await pilot.pause() + pilot.app.query_one(SelectionList).deselect(0) + await pilot.pause() + assert pilot.app.messages == [("SelectionHighlighted", 0)] + + +async def test_deselect_all() -> None: + """Deselecting all options should result in no additional.""" + async with SelectionListApp().run_test() as pilot: + assert isinstance(pilot.app, SelectionListApp) + await pilot.pause() + pilot.app.query_one(SelectionList).deselect_all() + await pilot.pause() + assert pilot.app.messages == [("SelectionHighlighted", 0)] + + +async def test_select_then_deselect_all() -> None: + """Selecting and then deselecting all options should result in messages.""" + async with SelectionListApp().run_test() as pilot: + assert isinstance(pilot.app, SelectionListApp) + await pilot.pause() + pilot.app.query_one(SelectionList).select_all() + await pilot.pause() + assert pilot.app.messages == [ + ("SelectionHighlighted", 0), + ("SelectedChanged", None), + ] + pilot.app.query_one(SelectionList).deselect_all() + await pilot.pause() + assert pilot.app.messages == [ + ("SelectionHighlighted", 0), + ("SelectedChanged", None), + ("SelectedChanged", None), + ]