WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 556e32b

Browse files
committed
Swap ranges upper and lower
We seem to be passing upper to lower and lower to upper when converting. That does not seem right.
1 parent b0d9eb4 commit 556e32b

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

Sources/FoundationEssentials/Predicate/NSPredicateConversion.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,11 +374,11 @@ extension PredicateExpressions.RangeExpressionContains : ConvertibleExpression {
374374
} else if let rangeValue = (range as? _RangeValue)?._anyRange {
375375
// Otherwise, if the range is a captured value then convert it to appropriate comparison expressions based on the range type
376376
switch rangeValue {
377-
case let .range(upper, lower):
377+
case let .range(lower, upper):
378378
let lowerBoundCondition = _comparison(elementExpr, try _expressionForBound(lower), type: .greaterThanOrEqualTo)
379379
let upperBoundCondition = _comparison(elementExpr, try _expressionForBound(upper), type: .lessThan)
380380
return .predicate(NSCompoundPredicate(andPredicateWithSubpredicates: [lowerBoundCondition, upperBoundCondition]))
381-
case let .closed(upper, lower):
381+
case let .closed(lower, upper):
382382
let lowerValue = try _expressionCompatibleValue(for: lower)
383383
let upperValue = try _expressionCompatibleValue(for: upper)
384384
return .predicate(NSComparisonPredicate(

Tests/FoundationEssentialsTests/PredicateConversionTests.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)