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_filtering.py | |
| parent | d70a199a72bf9a69eb4a3fcf166b0435918b2e33 (diff) | |
| download | selectui-main.tar.gz selectui-main.zip | |
Diffstat (limited to 'tests/test_filtering.py')
| -rw-r--r-- | tests/test_filtering.py | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/tests/test_filtering.py b/tests/test_filtering.py new file mode 100644 index 0000000..43a2e9b --- /dev/null +++ b/tests/test_filtering.py @@ -0,0 +1,318 @@ +from thefuzz import fuzz + + +class TestExactFiltering: + """Test exact string matching.""" + + def test_filter_by_title_case_insensitive(self, sample_items): + """Test filtering by title (case insensitive).""" + query = "python" + filtered = [] + + for item in sample_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_by_subtitle(self, sample_items): + """Test filtering by subtitle.""" + query = "web" + filtered = [] + + for item in sample_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"] == "JavaScript" + + def test_filter_no_matches(self, sample_items): + """Test filtering with no matches.""" + query = "nonexistent" + filtered = [] + + for item in sample_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) == 0 + + def test_filter_all_match(self, sample_items): + """Test filtering that matches all items.""" + query = "language" + filtered = [] + + for item in sample_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 + + def test_filter_partial_match(self, sample_items): + """Test partial string matching.""" + query = "rust" + filtered = [] + + for item in sample_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"] == "Rust" + + +class TestCaseSensitiveFiltering: + """Test case-sensitive filtering.""" + + def test_case_sensitive_title_match(self, sample_items): + """Test case-sensitive title matching.""" + query = "Python" + filtered = [] + + for item in sample_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 + assert filtered[0]["title"] == "Python" + + def test_case_sensitive_no_match(self, sample_items): + """Test case-sensitive no match.""" + query = "python" # lowercase + filtered = [] + + for item in sample_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 + + def test_case_sensitive_subtitle_match(self, sample_items): + """Test case-sensitive subtitle matching.""" + query = "Programming" + filtered = [] + + for item in sample_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 + + +class TestFuzzyFiltering: + """Test fuzzy search functionality.""" + + def test_fuzzy_match_with_typo(self, sample_items): + """Test fuzzy matching with a typo.""" + query = "Pythn" # Missing 'o' + filtered = [] + + for item in sample_items: + title = str(item.get("title", "")) + subtitle = str(item.get("subtitle", "")) + title_score = fuzz.partial_ratio(query, title) + subtitle_score = fuzz.partial_ratio(query, subtitle) + if title_score > 60 or subtitle_score > 60: + filtered.append(item) + + assert len(filtered) >= 1 + assert any(item["title"] == "Python" for item in filtered) + + def test_fuzzy_match_partial(self, sample_items): + """Test fuzzy partial matching.""" + query = "Jav" + filtered = [] + + for item in sample_items: + title = str(item.get("title", "")) + subtitle = str(item.get("subtitle", "")) + title_score = fuzz.partial_ratio(query, title) + subtitle_score = fuzz.partial_ratio(query, subtitle) + if title_score > 60 or subtitle_score > 60: + filtered.append(item) + + assert len(filtered) >= 1 + assert any(item["title"] == "JavaScript" for item in filtered) + + def test_fuzzy_match_transposition(self, sample_items): + """Test fuzzy match with character transposition.""" + query = "Rsut" # Characters swapped + filtered = [] + + for item in sample_items: + title = str(item.get("title", "")) + subtitle = str(item.get("subtitle", "")) + title_score = fuzz.partial_ratio(query, title) + subtitle_score = fuzz.partial_ratio(query, subtitle) + if title_score > 60 or subtitle_score > 60: + filtered.append(item) + + assert len(filtered) >= 1 + assert any(item["title"] == "Rust" for item in filtered) + + def test_fuzzy_no_match(self, sample_items): + """Test fuzzy search with no close matches.""" + query = "xyz123" + filtered = [] + + for item in sample_items: + title = str(item.get("title", "")) + subtitle = str(item.get("subtitle", "")) + title_score = fuzz.partial_ratio(query, title) + subtitle_score = fuzz.partial_ratio(query, subtitle) + if title_score > 60 or subtitle_score > 60: + filtered.append(item) + + assert len(filtered) == 0 + + +class TestFilteringWithCustomKeys: + """Test filtering with custom key configurations.""" + + def test_filter_custom_title_key(self, custom_key_items): + """Test filtering with custom title key.""" + query = "alice" + filtered = [] + title_key = "name" + subtitle_key = "role" + + for item in custom_key_items: + title = str(item.get(title_key, "")).lower() + subtitle = str(item.get(subtitle_key, "")).lower() + if query in title or query in subtitle: + filtered.append(item) + + assert len(filtered) == 1 + assert filtered[0]["name"] == "Alice" + + def test_filter_custom_subtitle_key(self, custom_key_items): + """Test filtering with custom subtitle key.""" + query = "engineer" + filtered = [] + title_key = "name" + subtitle_key = "role" + + for item in custom_key_items: + title = str(item.get(title_key, "")).lower() + subtitle = str(item.get(subtitle_key, "")).lower() + if query in title or query in subtitle: + filtered.append(item) + + assert len(filtered) == 1 + assert filtered[0]["role"] == "Engineer" + + def test_filter_no_subtitle_key(self, single_line_items): + """Test filtering when subtitle_key is None.""" + query = "config" + filtered = [] + title_key = "filename" + + for item in single_line_items: + title = str(item.get(title_key, "")).lower() + if query in title: + filtered.append(item) + + assert len(filtered) == 1 + assert filtered[0]["filename"] == "config.json" + + +class TestEmptyQueryFiltering: + """Test filtering with empty query.""" + + def test_empty_query_returns_all(self, sample_items): + """Test that empty query returns all items.""" + query = "" + filtered = sample_items.copy() if not query else [] + + assert len(filtered) == len(sample_items) + + def test_whitespace_query(self, sample_items): + """Test filtering with whitespace-only query.""" + query = " " + filtered = [] + + # Whitespace query should not match anything + for item in sample_items: + title = str(item.get("title", "")).lower() + subtitle = str(item.get("subtitle", "")).lower() + if query.strip() and (query.strip() in title or query.strip() in subtitle): + filtered.append(item) + + assert len(filtered) == 0 + + +class TestFilteringEdgeCases: + """Test edge cases in filtering.""" + + def test_filter_with_missing_fields(self): + """Test filtering when items are missing title/subtitle.""" + items = [ + {"other_field": "value"}, + {"title": "Has Title"}, + ] + + query = "title" + filtered = [] + + for item in 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 + + def test_filter_with_numeric_values(self): + """Test filtering with numeric values in fields.""" + items = [ + {"title": "Item 123", "subtitle": "Test"}, + {"title": "Item 456", "subtitle": "Test"}, + ] + + query = "123" + filtered = [] + + for item in 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 + + def test_filter_special_characters(self): + """Test filtering with special characters.""" + items = [ + {"title": "test@example.com", "subtitle": "Email"}, + {"title": "user-name", "subtitle": "Username"}, + ] + + query = "@" + filtered = [] + + for item in 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 "@" in filtered[0]["title"] |
