aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_integration.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_integration.py
parentd70a199a72bf9a69eb4a3fcf166b0435918b2e33 (diff)
downloadselectui-main.tar.gz
selectui-main.zip
Add tests and justfileHEADmain
Diffstat (limited to 'tests/test_integration.py')
-rw-r--r--tests/test_integration.py286
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)