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_integration.py | |
| parent | d70a199a72bf9a69eb4a3fcf166b0435918b2e33 (diff) | |
| download | selectui-main.tar.gz selectui-main.zip | |
Diffstat (limited to 'tests/test_integration.py')
| -rw-r--r-- | tests/test_integration.py | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/tests/test_integration.py b/tests/test_integration.py new file mode 100644 index 0000000..bf6beca --- /dev/null +++ b/tests/test_integration.py @@ -0,0 +1,286 @@ +from selectui import SelectItem, SelectUI + + +class TestPydanticIntegration: + """Integration tests for Pydantic SelectItem with SelectUI.""" + + def test_selectui_with_selectitems(self): + """Test SelectUI works with SelectItem instances.""" + items = [ + SelectItem(title="Python", subtitle="Language", info="1991"), + SelectItem(title="Rust", subtitle="Systems", info="2010"), + ] + + app = SelectUI(items=items, oneshot=True) + + assert len(app.items) == 2 + assert app.items[0]["title"] == "Python" + assert app.items[1]["title"] == "Rust" + + def test_selectui_preserves_selectitem_data(self): + """Test that SelectUI preserves SelectItem data field.""" + items = [ + SelectItem( + title="Python", + subtitle="Language", + data={"website": "python.org", "typing": "dynamic"} + ), + ] + + app = SelectUI(items=items) + + assert app.items[0]["website"] == "python.org" + assert app.items[0]["typing"] == "dynamic" + + def test_mixed_items_not_allowed(self): + """Test that items list should be homogeneous.""" + # Note: Current implementation assumes all items are same type + # This test documents the behavior + items = [SelectItem(title="A")] + app = SelectUI(items=items) + + # Should convert to dicts + assert isinstance(app.items[0], dict) + + +class TestDictToPydanticConversion: + """Test converting dict items to Pydantic and back.""" + + def test_from_dict_to_selectui(self, custom_key_items): + """Test converting custom dict items to SelectItem then to SelectUI.""" + items = [ + SelectItem.from_dict( + item, + title_key="name", + subtitle_key="role", + info_key="team" + ) + for item in custom_key_items + ] + + app = SelectUI(items=items, oneshot=True) + + assert len(app.items) == 3 + assert app.items[0]["title"] == "Alice" + + def test_json_to_selectitem_to_selectui(self): + """Test full pipeline: JSON -> SelectItem -> SelectUI.""" + json_data = [ + {"product": "Laptop", "price": "$1299", "stock": 45}, + {"product": "Mouse", "price": "$29", "stock": 200}, + ] + + items = [ + SelectItem.from_dict( + item, + title_key="product", + subtitle_key=None, + info_key="price" + ) + for item in json_data + ] + + app = SelectUI(items=items) + + assert len(app.items) == 2 + assert app.items[0]["title"] == "Laptop" + assert app.items[0]["info"] == "$1299" + assert app.items[0]["stock"] == 45 + + +class TestCustomKeyMappings: + """Integration tests for custom key mappings.""" + + def test_selectui_with_custom_keys_dict(self, custom_key_items): + """Test SelectUI with dict items and custom keys.""" + app = SelectUI( + items=custom_key_items, + title_key="name", + subtitle_key="role", + info_key="team" + ) + + assert app.title_key == "name" + assert app.subtitle_key == "role" + assert app.info_key == "team" + + def test_selectui_with_custom_keys_pydantic(self): + """Test SelectUI with SelectItem and custom keys.""" + 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" + + +class TestRealWorldScenarios: + """Test real-world usage scenarios.""" + + def test_github_api_response_format(self): + """Test handling GitHub-style API response.""" + repos = [ + { + "full_name": "python/cpython", + "description": "The Python programming language", + "stargazers_count": 50000, + "html_url": "https://github.com/python/cpython" + }, + { + "full_name": "rust-lang/rust", + "description": "Empowering everyone to build reliable software", + "stargazers_count": 80000, + "html_url": "https://github.com/rust-lang/rust" + }, + ] + + items = [ + SelectItem.from_dict( + repo, + title_key="full_name", + subtitle_key="description", + info_key="stargazers_count" + ) + for repo in repos + ] + + app = SelectUI(items=items, oneshot=True) + + assert len(app.items) == 2 + assert app.items[0]["html_url"] == "https://github.com/python/cpython" + + def test_database_query_results(self): + """Test handling database query results.""" + users = [ + {"id": 1, "username": "alice", "email": "alice@example.com", "role": "admin"}, + {"id": 2, "username": "bob", "email": "bob@example.com", "role": "user"}, + ] + + items = [ + SelectItem.from_dict( + user, + title_key="username", + subtitle_key="email", + info_key="role" + ) + for user in users + ] + + app = SelectUI(items=items) + + assert len(app.items) == 2 + assert app.items[0]["id"] == 1 + assert app.items[0]["title"] == "alice" + + def test_file_listing_scenario(self): + """Test file listing scenario.""" + files = [ + {"filename": "config.json", "size": 1024, "modified": "2024-01-15"}, + {"filename": "data.csv", "size": 4096, "modified": "2024-01-14"}, + ] + + items = [ + SelectItem.from_dict( + file, + title_key="filename", + subtitle_key=None, + info_key="size" + ) + for file in files + ] + + app = SelectUI(items=items, oneshot=True) + + assert len(app.items) == 2 + assert app.items[0]["modified"] == "2024-01-15" + + +class TestEdgeCasesIntegration: + """Integration tests for edge cases.""" + + def test_empty_items_to_selectui(self): + """Test SelectUI with empty items list.""" + items = [] + app = SelectUI(items=items) + + assert app.items == [] + assert app.filtered_items == [] + + def test_single_item(self): + """Test SelectUI with single item.""" + items = [SelectItem(title="Only Item")] + app = SelectUI(items=items) + + assert len(app.items) == 1 + + def test_large_number_of_items(self): + """Test SelectUI with many items.""" + items = [ + SelectItem(title=f"Item {i}", subtitle=f"Subtitle {i}") + for i in range(1000) + ] + + app = SelectUI(items=items) + + assert len(app.items) == 1000 + + def test_items_with_unicode(self): + """Test SelectUI with Unicode characters.""" + items = [ + SelectItem(title="Python 🐍", subtitle="Programming"), + SelectItem(title="Rust 🦀", subtitle="Systems"), + SelectItem(title="日本語", subtitle="Japanese"), + ] + + app = SelectUI(items=items) + + assert len(app.items) == 3 + assert app.items[0]["title"] == "Python 🐍" + assert app.items[2]["title"] == "日本語" + + def test_items_with_special_chars(self): + """Test SelectUI with special characters.""" + items = [ + SelectItem(title="test@example.com", subtitle="Email"), + SelectItem(title="user-name_123", subtitle="Username"), + SelectItem(title="$100.00", subtitle="Price"), + ] + + app = SelectUI(items=items) + + assert len(app.items) == 3 + assert "@" in app.items[0]["title"] + assert "$" in app.items[2]["title"] + + +class TestBackwardCompatibility: + """Test backward compatibility with plain dicts.""" + + def test_plain_dicts_still_work(self, sample_items): + """Test that plain dict items still work.""" + app = SelectUI(items=sample_items, oneshot=True) + + assert len(app.items) == 4 + assert isinstance(app.items[0], dict) + + def test_mixed_usage_patterns(self): + """Test that both dict and Pydantic patterns work.""" + # Pattern 1: Plain dicts + app1 = SelectUI(items=[{"title": "A"}]) + assert app1.items[0]["title"] == "A" + + # Pattern 2: Pydantic models + app2 = SelectUI(items=[SelectItem(title="B")]) + assert app2.items[0]["title"] == "B" + + # Both should work identically + assert isinstance(app1.items[0], dict) + assert isinstance(app2.items[0], dict) |
