@@ -177,6 +177,32 @@ private struct NSPredicateConversionTests {
177177 #expect( !converted. evaluate ( with: ObjCObject ( ) ) )
178178 }
179179
180+ @Test func rangesDistinctBounds( ) throws {
181+ // Test that captured ranges have correct bounds order in NSPredicate conversion
182+ // This tests the _RangeValue branch in RangeExpressionContains.convert
183+ let lowerDate = Date ( timeIntervalSinceReferenceDate: 100 )
184+ let upperDate = Date ( timeIntervalSinceReferenceDate: 200 )
185+ let range = lowerDate ..< upperDate
186+
187+ let predicate = #Predicate< ObjCObject> {
188+ range. contains ( $0. i)
189+ }
190+ let converted = try #require( convert ( predicate) )
191+
192+ // Verify the bounds are in the correct order (lower, upper)
193+ #expect( converted == NSPredicate ( format: " i >= %@ AND i < %@ " , lowerDate as NSDate , upperDate as NSDate ) )
194+
195+ // Create an object with a date in the range
196+ let objInRange = ObjCObject ( )
197+ objInRange. i = Date ( timeIntervalSinceReferenceDate: 150 )
198+ #expect( converted. evaluate ( with: objInRange) , " Date in range should match " )
199+
200+ // Create an object with a date outside the range
201+ let objOutOfRange = ObjCObject ( )
202+ objOutOfRange. i = Date ( timeIntervalSinceReferenceDate: 250 )
203+ #expect( !converted. evaluate ( with: objOutOfRange) , " Date outside range should not match " )
204+ }
205+
180206 @Test func nonObjC( ) throws {
181207 let predicate = #Predicate< ObjCObject> {
182208 $0. nonObjCKeypath == 2
0 commit comments