@@ -2037,3 +2037,140 @@ def test_humanize_error_with_none_data():
20372037
20382038 error_message = humanize_error (data , ctx .value )
20392039 assert "expected a dictionary" in error_message
2040+
2041+
2042+ def test_required_complex_key_any ():
2043+ """Test Required with Any validator for multiple possible keys"""
2044+ schema = Schema (
2045+ {Required (Any ("color" , "temperature" , "brightness" )): str , "device_id" : str }
2046+ )
2047+
2048+ # Should pass - defines one of the required keys
2049+ result = schema ({"color" : "red" , "device_id" : "light1" })
2050+ assert result == {"color" : "red" , "device_id" : "light1" }
2051+
2052+ # Should pass - defines several of the required keys
2053+ result = schema ({"color" : "blue" , "brightness" : "50%" , "device_id" : "light1" })
2054+ assert result == {"color" : "blue" , "brightness" : "50%" , "device_id" : "light1" }
2055+
2056+ # Should fail - has none of the required keys
2057+ with pytest .raises (MultipleInvalid ) as ctx :
2058+ schema ({"device_id" : "light1" })
2059+
2060+ error_msg = str (ctx .value )
2061+ assert (
2062+ "at least one of ['color', 'temperature', 'brightness'] is required"
2063+ in error_msg
2064+ )
2065+
2066+
2067+ def test_required_complex_key_custom_message ():
2068+ """Test Required with Any validator and custom error message"""
2069+ schema = Schema (
2070+ {
2071+ Required (
2072+ Any ("color" , "temperature" , "brightness" ),
2073+ msg = "Please specify a lighting attribute" ,
2074+ ): str ,
2075+ "device_id" : str ,
2076+ }
2077+ )
2078+
2079+ # Should pass
2080+ schema ({"color" : "red" , "device_id" : "light1" })
2081+
2082+ # Should fail with custom message
2083+ with pytest .raises (MultipleInvalid ) as ctx :
2084+ schema ({"device_id" : "light1" })
2085+
2086+ error_msg = str (ctx .value )
2087+ assert "Please specify a lighting attribute" in error_msg
2088+
2089+
2090+ def test_required_complex_key_mixed_types ():
2091+ """Test Required with Any validator containing mixed key types"""
2092+ schema = Schema ({Required (Any ("string_key" , 123 , 45.6 )): str , "other" : int })
2093+
2094+ # Should work with string key
2095+ result = schema ({"string_key" : "value" , "other" : 1 })
2096+ assert result == {"string_key" : "value" , "other" : 1 }
2097+
2098+ # Should work with int key
2099+ result = schema ({123 : "value" , "other" : 1 })
2100+ assert result == {123 : "value" , "other" : 1 }
2101+
2102+ # Should work with float key
2103+ result = schema ({45.6 : "value" , "other" : 1 })
2104+ assert result == {45.6 : "value" , "other" : 1 }
2105+
2106+ # Should fail with none present
2107+ with pytest .raises (MultipleInvalid ) as ctx :
2108+ schema ({"other" : 1 })
2109+
2110+ error_msg = str (ctx .value )
2111+ assert "at least one of ['string_key', 123, 45.6] is required" in error_msg
2112+
2113+
2114+ def test_required_complex_key_multiple_complex_requirements ():
2115+ """Test multiple Required complex keys in same schema"""
2116+ schema = Schema (
2117+ {
2118+ Required (Any ("color" , "hue" )): str ,
2119+ Required (Any ("brightness" , "intensity" )): str ,
2120+ "device" : str ,
2121+ }
2122+ )
2123+
2124+ # Should pass with one from each group
2125+ result = schema ({"color" : "red" , "brightness" : "high" , "device" : "light" })
2126+ assert result == {"color" : "red" , "brightness" : "high" , "device" : "light" }
2127+
2128+ # Should fail if missing on any group
2129+ with pytest .raises (MultipleInvalid ) as ctx :
2130+ schema ({"brightness" : "high" , "device" : "light" })
2131+
2132+ error_msg = str (ctx .value )
2133+ assert "at least one of ['color', 'hue'] is required" in error_msg
2134+
2135+
2136+ def test_required_complex_key_value_validation ():
2137+ """Test that value validation still works with complex required keys"""
2138+ schema = Schema ({Required (Any ("color" , "temperature" )): str , "device" : str })
2139+
2140+ # Should pass with valid string value
2141+ result = schema ({"color" : "red" , "device" : "light" })
2142+ assert result == {"color" : "red" , "device" : "light" }
2143+
2144+ # Should fail with invalid value type
2145+ with pytest .raises (MultipleInvalid ) as ctx :
2146+ schema ({"color" : 123 , "device" : "light" }) # color should be str, not int
2147+
2148+ error_msg = str (ctx .value )
2149+ assert "expected str" in error_msg
2150+
2151+
2152+ def test_complex_required_keys_with_specific_value_validation ():
2153+ """Test complex required keys combined with specific value validation for brightness range."""
2154+ schema = Schema (
2155+ {
2156+ Required (Any ('color' , 'temperature' , 'brightness' )): object ,
2157+ 'brightness' : All (
2158+ Coerce (int ), Range (min = 0 , max = 100 )
2159+ ), # Additional validation for brightness specifically
2160+ 'device_id' : str ,
2161+ }
2162+ )
2163+
2164+ # Valid - color provided, no brightness validation needed
2165+ result = schema ({'color' : 'red' , 'device_id' : 'light1' })
2166+ assert result == {'color' : 'red' , 'device_id' : 'light1' }
2167+
2168+ # Invalid - brightness provided but out of range (255 > 100)
2169+ # Should NOT get "required field missing" error, but should get range error
2170+ with pytest .raises (MultipleInvalid ) as exc_info :
2171+ schema ({'brightness' : '255' , 'device_id' : 'light1' })
2172+
2173+ # Verify it's a range error, not a missing required field error
2174+ error_msg = str (exc_info .value )
2175+ assert "required" not in error_msg .lower () # No "required field missing" error
2176+ assert "value must be at most 100" in error_msg # Range validation error
0 commit comments