@@ -1177,5 +1177,107 @@ class Config:
11771177 validate ({"value" : MISSING }, Config , allow_missing = True )
11781178
11791179
1180+ class TestAnyTypeValidation :
1181+ """Test validation with Any type."""
1182+
1183+ def test_any_type_accepts_any_value (self ):
1184+ """Test that Any type accepts any value."""
1185+ from typing import Any
1186+
1187+ @dataclass
1188+ class Config :
1189+ value : Any
1190+
1191+ # Should accept any type
1192+ validate ({"value" : 42 }, Config )
1193+ validate ({"value" : "string" }, Config )
1194+ validate ({"value" : [1 , 2 , 3 ]}, Config )
1195+ validate ({"value" : {"nested" : "dict" }}, Config )
1196+ validate ({"value" : None }, Config )
1197+
1198+
1199+ class TestValidatorExceptionHandling :
1200+ """Test validator exception handling."""
1201+
1202+ def test_validator_with_bad_init (self ):
1203+ """Test validator when dataclass __init__ raises exception."""
1204+ from sparkwheel .schema import validator
1205+
1206+ @dataclass
1207+ class Config :
1208+ value : int
1209+
1210+ def __post_init__ (self ):
1211+ # This will raise during validation
1212+ if self .value < 0 :
1213+ raise ValueError ("Value must be positive" )
1214+
1215+ @validator
1216+ def check_value (self ):
1217+ # This validator won't run if __init__ fails
1218+ assert self .value > 0
1219+
1220+ # Should still validate the types even if instance creation fails
1221+ validate ({"value" : - 5 }, Config )
1222+
1223+
1224+ class TestUnionValidationSuccess :
1225+ """Test union validation success path."""
1226+
1227+ def test_union_first_type_succeeds (self ):
1228+ """Test union validation when first type succeeds."""
1229+
1230+ @dataclass
1231+ class Config :
1232+ value : int | str
1233+
1234+ # First type (int) should succeed
1235+ validate ({"value" : 42 }, Config )
1236+
1237+ def test_union_second_type_succeeds (self ):
1238+ """Test union validation when second type succeeds."""
1239+
1240+ @dataclass
1241+ class Config :
1242+ value : int | str
1243+
1244+ # Second type (str) should succeed
1245+ validate ({"value" : "hello" }, Config )
1246+
1247+
1248+ class TestMetadataExceptionHandling :
1249+ """Test metadata source location exception handling."""
1250+
1251+ def test_metadata_get_raises_exception (self ):
1252+ """Test _get_source_location when metadata.get raises."""
1253+
1254+ class BadMetadata :
1255+ def get (self , key ):
1256+ raise RuntimeError ("Bad metadata" )
1257+
1258+ @dataclass
1259+ class Config :
1260+ value : int
1261+
1262+ # Should handle exception gracefully
1263+ with pytest .raises (ValidationError , match = "Missing required field" ):
1264+ validate ({}, Config , metadata = BadMetadata ())
1265+
1266+ def test_metadata_returns_non_source_location (self ):
1267+ """Test _get_source_location when metadata returns wrong type."""
1268+
1269+ class BadMetadata :
1270+ def get (self , key ):
1271+ return "not a source location"
1272+
1273+ @dataclass
1274+ class Config :
1275+ value : int
1276+
1277+ # Should handle gracefully
1278+ with pytest .raises (ValidationError , match = "Missing required field" ):
1279+ validate ({}, Config , metadata = BadMetadata ())
1280+
1281+
11801282if __name__ == "__main__" :
11811283 pytest .main ([__file__ , "-v" ])
0 commit comments