diff options
| author | Louis Burda <dev@sinitax.com> | 2026-02-28 18:54:19 +0100 |
|---|---|---|
| committer | Louis Burda <dev@sinitax.com> | 2026-02-28 18:54:19 +0100 |
| commit | be1dd21f8e4fbd5361531b4d8727a0d0d243e8ec (patch) | |
| tree | e7b540012e0510d1304d2dac8e137545ae103f75 /tests/test_selectui.py | |
| parent | d70a199a72bf9a69eb4a3fcf166b0435918b2e33 (diff) | |
| download | selectui-main.tar.gz selectui-main.zip | |
Diffstat (limited to 'tests/test_selectui.py')
| -rw-r--r-- | tests/test_selectui.py | 272 |
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 |
