import pytest from pydantic import ValidationError from selectui import SelectItem class TestSelectItemCreation: """Test SelectItem model creation.""" def test_create_with_all_fields(self): """Test creating SelectItem with all fields.""" item = SelectItem( title="Python", subtitle="Programming language", info="1991", data={"website": "python.org", "typing": "dynamic"} ) assert item.title == "Python" assert item.subtitle == "Programming language" assert item.info == "1991" assert item.data["website"] == "python.org" assert item.data["typing"] == "dynamic" def test_create_with_required_only(self): """Test creating SelectItem with only required fields.""" item = SelectItem(title="Minimal") assert item.title == "Minimal" assert item.subtitle is None assert item.info is None assert item.data == {} def test_create_with_optional_fields(self): """Test creating SelectItem with some optional fields.""" item = SelectItem(title="Python", subtitle="Language") assert item.title == "Python" assert item.subtitle == "Language" assert item.info is None assert item.data == {} class TestSelectItemValidation: """Test SelectItem validation.""" def test_empty_title_fails(self): """Test that empty title raises validation error.""" with pytest.raises(ValidationError) as exc_info: SelectItem(title="") error_msg = str(exc_info.value).lower() assert "string should have at least 1 character" in error_msg or "title cannot be empty" in error_msg def test_whitespace_title_fails(self): """Test that whitespace-only title raises validation error.""" with pytest.raises(ValidationError) as exc_info: SelectItem(title=" ") assert "title cannot be empty" in str(exc_info.value).lower() def test_title_with_spaces_succeeds(self): """Test that title with spaces (but not only spaces) is valid.""" item = SelectItem(title="Hello World") assert item.title == "Hello World" def test_missing_title_fails(self): """Test that missing title raises validation error.""" with pytest.raises((ValidationError, TypeError)): SelectItem() # type: ignore class TestSelectItemToDict: """Test SelectItem.to_dict() method.""" def test_to_dict_all_fields(self): """Test converting SelectItem with all fields to dict.""" item = SelectItem( title="Python", subtitle="Language", info="1991", data={"extra": "field"} ) result = item.to_dict() assert result["title"] == "Python" assert result["subtitle"] == "Language" assert result["info"] == "1991" assert result["extra"] == "field" def test_to_dict_minimal(self): """Test converting minimal SelectItem to dict.""" item = SelectItem(title="Test") result = item.to_dict() assert result["title"] == "Test" assert "subtitle" not in result assert "info" not in result def test_to_dict_with_custom_data(self): """Test that custom data is preserved in to_dict.""" item = SelectItem( title="Item", data={"custom1": "value1", "custom2": "value2"} ) result = item.to_dict() assert result["custom1"] == "value1" assert result["custom2"] == "value2" class TestSelectItemFromDict: """Test SelectItem.from_dict() method.""" def test_from_dict_standard_keys(self): """Test from_dict with standard keys.""" data = { "title": "Python", "subtitle": "Language", "info": "1991", "extra": "data" } item = SelectItem.from_dict(data) assert item.title == "Python" assert item.subtitle == "Language" assert item.info == "1991" assert item.data["extra"] == "data" def test_from_dict_custom_keys(self): """Test from_dict with custom key mappings.""" data = { "name": "Alice", "role": "Engineer", "team": "Backend", "level": "Senior" } item = SelectItem.from_dict( data, title_key="name", subtitle_key="role", info_key="team" ) assert item.title == "Alice" assert item.subtitle == "Engineer" assert item.info == "Backend" assert item.data["level"] == "Senior" def test_from_dict_missing_optional_keys(self): """Test from_dict when optional keys are missing.""" data = {"title": "Only Title"} item = SelectItem.from_dict(data) assert item.title == "Only Title" assert item.subtitle is None assert item.info is None def test_from_dict_no_subtitle(self): """Test from_dict with subtitle_key=None.""" data = {"filename": "test.py", "size": 1024} item = SelectItem.from_dict( data, title_key="filename", subtitle_key=None, info_key="size" ) assert item.title == "test.py" assert item.subtitle is None assert item.info == "1024" def test_from_dict_preserves_all_data(self): """Test that from_dict preserves all original data.""" data = { "name": "Alice", "role": "Engineer", "extra1": "value1", "extra2": "value2" } item = SelectItem.from_dict(data, title_key="name", subtitle_key="role") assert item.data["name"] == "Alice" assert item.data["role"] == "Engineer" assert item.data["extra1"] == "value1" assert item.data["extra2"] == "value2" def test_from_dict_type_conversion(self): """Test that from_dict converts values to strings.""" data = { "title": 123, "subtitle": True, "info": 456.78 } item = SelectItem.from_dict(data) assert item.title == "123" assert item.subtitle == "True" assert item.info == "456.78" class TestSelectItemRoundTrip: """Test SelectItem conversion round trips.""" def test_roundtrip_standard_keys(self): """Test SelectItem -> dict -> SelectItem with standard keys.""" original = SelectItem( title="Test", subtitle="Subtitle", info="Info", data={"custom": "field"} ) # Convert to dict and back data = original.to_dict() restored = SelectItem.from_dict(data) assert restored.title == original.title assert restored.subtitle == original.subtitle assert restored.info == original.info assert restored.data["custom"] == original.data["custom"] def test_roundtrip_minimal(self): """Test round trip with minimal SelectItem.""" original = SelectItem(title="Minimal") data = original.to_dict() restored = SelectItem.from_dict(data) assert restored.title == original.title assert restored.subtitle == original.subtitle assert restored.info == original.info