aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_selectui.py
diff options
context:
space:
mode:
authorLouis Burda <dev@sinitax.com>2026-02-28 18:54:19 +0100
committerLouis Burda <dev@sinitax.com>2026-02-28 18:54:19 +0100
commitbe1dd21f8e4fbd5361531b4d8727a0d0d243e8ec (patch)
treee7b540012e0510d1304d2dac8e137545ae103f75 /tests/test_selectui.py
parentd70a199a72bf9a69eb4a3fcf166b0435918b2e33 (diff)
downloadselectui-main.tar.gz
selectui-main.zip
Add tests and justfileHEADmain
Diffstat (limited to 'tests/test_selectui.py')
-rw-r--r--tests/test_selectui.py272
1 files changed, 272 insertions, 0 deletions
diff --git a/tests/test_selectui.py b/tests/test_selectui.py
new file mode 100644
index 0000000..991a065
--- /dev/null
+++ b/tests/test_selectui.py
@@ -0,0 +1,272 @@
+from selectui import SelectItem, SelectUI
+
+
+class TestSelectUIInitialization:
+ """Test SelectUI initialization."""
+
+ def test_init_with_dict_items(self, sample_items):
+ """Test initialization with dictionary items."""
+ app = SelectUI(items=sample_items)
+
+ assert len(app.items) == 4
+ assert app.items[0]["title"] == "Python"
+ assert app.oneshot is False
+ assert app.fuzzy_search is False
+ assert app.case_sensitive is False
+
+ def test_init_with_pydantic_items(self):
+ """Test initialization with SelectItem instances."""
+ items = [
+ SelectItem(title="Python", subtitle="Language"),
+ SelectItem(title="Rust", subtitle="Systems"),
+ ]
+
+ app = SelectUI(items=items)
+
+ assert len(app.items) == 2
+ assert app.items[0]["title"] == "Python"
+
+ def test_init_empty(self):
+ """Test initialization with no items."""
+ app = SelectUI()
+
+ assert app.items == []
+ assert app.filtered_items == []
+
+ def test_init_with_oneshot(self, sample_items):
+ """Test initialization with oneshot mode."""
+ app = SelectUI(items=sample_items, oneshot=True)
+
+ assert app.oneshot is True
+
+ def test_init_with_custom_keys(self, sample_items):
+ """Test initialization with custom key configuration."""
+ app = SelectUI(
+ items=sample_items,
+ title_key="name",
+ subtitle_key="desc",
+ info_key="year"
+ )
+
+ assert app.title_key == "name"
+ assert app.subtitle_key == "desc"
+ assert app.info_key == "year"
+
+ def test_init_with_events_mode(self, sample_items):
+ """Test initialization with events mode."""
+ app = SelectUI(items=sample_items, events_mode=True)
+
+ assert app.events_mode is True
+
+ def test_init_with_command_template(self):
+ """Test initialization with command template."""
+ app = SelectUI(command_template="echo {}")
+
+ assert app.command_template == "echo {}"
+ assert app.input_mode is True
+
+
+class TestSelectUIFiltering:
+ """Test SelectUI filtering functionality."""
+
+ def test_filter_items_exact_match(self, sample_items):
+ """Test exact string filtering."""
+ app = SelectUI(items=sample_items)
+ app.fuzzy_search = False
+ app.case_sensitive = False
+
+ # Simulate filtering for "python"
+ filtered = []
+ query = "python"
+ for item in app.items:
+ title = str(item.get("title", "")).lower()
+ subtitle = str(item.get("subtitle", "")).lower()
+ if query in title or query in subtitle:
+ filtered.append(item)
+
+ assert len(filtered) == 1
+ assert filtered[0]["title"] == "Python"
+
+ def test_filter_items_case_sensitive(self, sample_items):
+ """Test case-sensitive filtering."""
+ app = SelectUI(items=sample_items)
+
+ # Lowercase query should not match "Python" in case-sensitive mode
+ filtered = []
+ query = "python"
+ for item in app.items:
+ title = str(item.get("title", ""))
+ subtitle = str(item.get("subtitle", ""))
+ if query in title or query in subtitle:
+ filtered.append(item)
+
+ assert len(filtered) == 0
+
+ # Correct case should match
+ filtered = []
+ query = "Python"
+ for item in app.items:
+ title = str(item.get("title", ""))
+ subtitle = str(item.get("subtitle", ""))
+ if query in title or query in subtitle:
+ filtered.append(item)
+
+ assert len(filtered) == 1
+
+ def test_filter_by_subtitle(self, sample_items):
+ """Test filtering by subtitle."""
+ app = SelectUI(items=sample_items)
+
+ filtered = []
+ query = "language"
+ for item in app.items:
+ title = str(item.get("title", "")).lower()
+ subtitle = str(item.get("subtitle", "")).lower()
+ if query in title or query in subtitle:
+ filtered.append(item)
+
+ assert len(filtered) == 4 # All items have "language" in subtitle
+
+
+class TestSelectUINormalization:
+ """Test item normalization in SelectUI."""
+
+ def test_normalize_dict_items(self, sample_items):
+ """Test that dict items are normalized correctly."""
+ app = SelectUI(items=sample_items)
+
+ assert isinstance(app.items, list)
+ assert all(isinstance(item, dict) for item in app.items)
+
+ def test_normalize_pydantic_items(self):
+ """Test that Pydantic items are converted to dicts."""
+ items = [
+ SelectItem(title="Python", subtitle="Language", info="1991"),
+ SelectItem(title="Rust", subtitle="Systems", info="2010"),
+ ]
+
+ app = SelectUI(items=items)
+
+ assert isinstance(app.items, list)
+ assert all(isinstance(item, dict) for item in app.items)
+ assert app.items[0]["title"] == "Python"
+ assert app.items[1]["title"] == "Rust"
+
+ def test_normalize_with_custom_keys(self):
+ """Test normalization preserves custom key mappings."""
+ items = [
+ SelectItem(title="Alice", subtitle="Engineer", info="Backend"),
+ ]
+
+ app = SelectUI(
+ items=items,
+ title_key="name",
+ subtitle_key="role",
+ info_key="team"
+ )
+
+ # Should have both standard and custom keys
+ assert app.items[0]["title"] == "Alice"
+ assert app.items[0]["name"] == "Alice"
+ assert app.items[0]["subtitle"] == "Engineer"
+ assert app.items[0]["role"] == "Engineer"
+
+
+class TestSelectUIState:
+ """Test SelectUI state management."""
+
+ def test_initial_state(self, sample_items):
+ """Test initial state after initialization."""
+ app = SelectUI(items=sample_items)
+
+ assert app.selected_item is None
+ assert app.fuzzy_search is False
+ assert app.case_sensitive is False
+ assert app._stream_complete is False
+ assert app._refresh_timer_running is False
+
+ def test_filtered_items_initial(self, sample_items):
+ """Test that filtered_items initially equals items."""
+ app = SelectUI(items=sample_items)
+
+ assert app.filtered_items == app.items
+
+ def test_command_mode_state(self):
+ """Test state in command mode."""
+ app = SelectUI(command_template="echo {}")
+
+ assert app.input_mode is True
+ assert app.command_template == "echo {}"
+ assert app._command_running is False
+
+ def test_stdin_mode_state(self):
+ """Test state when stdin_fd is not provided."""
+ app = SelectUI()
+
+ assert app.stdin_fd is None
+ assert app._stream_complete is False
+
+
+class TestSelectUIEdgeCases:
+ """Test edge cases and error handling."""
+
+ def test_empty_items_list(self):
+ """Test with empty items list."""
+ app = SelectUI(items=[])
+
+ assert app.items == []
+ assert app.filtered_items == []
+
+ def test_none_items(self):
+ """Test with None items."""
+ app = SelectUI(items=None)
+
+ assert app.items == []
+ assert app.filtered_items == []
+
+ def test_items_without_required_keys(self):
+ """Test items missing title key."""
+ items = [{"name": "Test"}] # Missing 'title' key
+
+ app = SelectUI(items=items, title_key="name")
+
+ assert len(app.items) == 1
+
+ def test_mixed_item_types(self):
+ """Test that dict items work after Pydantic items."""
+ pydantic_items = [SelectItem(title="A")]
+ dict_items = [{"title": "B"}]
+
+ app1 = SelectUI(items=pydantic_items)
+ app2 = SelectUI(items=dict_items)
+
+ assert app1.items[0]["title"] == "A"
+ assert app2.items[0]["title"] == "B"
+
+
+class TestSelectUICustomKeys:
+ """Test custom key configuration."""
+
+ def test_custom_title_key(self, custom_key_items):
+ """Test using custom title key."""
+ app = SelectUI(items=custom_key_items, title_key="name")
+
+ assert app.title_key == "name"
+
+ def test_custom_subtitle_key(self, custom_key_items):
+ """Test using custom subtitle key."""
+ app = SelectUI(items=custom_key_items, subtitle_key="role")
+
+ assert app.subtitle_key == "role"
+
+ def test_custom_info_key(self, custom_key_items):
+ """Test using custom info key."""
+ app = SelectUI(items=custom_key_items, info_key="team")
+
+ assert app.info_key == "team"
+
+ def test_no_subtitle_key(self, single_line_items):
+ """Test with subtitle_key=None for single-line display."""
+ app = SelectUI(items=single_line_items, subtitle_key=None)
+
+ assert app.subtitle_key is None