@@ -67,7 +67,56 @@ import Testing
6767 let greaterThanOrEqual = try FetchRequest . Predicate ( #Predicate< PersonModel> { $0. age >= 20 } )
6868 #expect( greaterThanOrEqual == . comparison( . init( left: . keyPath( " age " ) , right: . attribute( . int64( 20 ) ) , type: . greaterThanOrEqualTo) ) )
6969 #expect( Self . people. filtered ( by: greaterThanOrEqual) . map ( \. id. rawValue) == [ " Alice " , " Alina " ] )
70+
71+ let lessThanOrEqual = try FetchRequest . Predicate ( #Predicate< PersonModel> { $0. age <= 20 } )
72+ #expect( lessThanOrEqual == . comparison( . init( left: . keyPath( " age " ) , right: . attribute( . int64( 20 ) ) , type: . lessThanOrEqualTo) ) )
73+ #expect( Self . people. filtered ( by: lessThanOrEqual) . map ( \. id. rawValue) == [ " Bob " , " Alina " ] )
74+
75+ let greaterThan = try FetchRequest . Predicate ( #Predicate< PersonModel> { $0. age > 20 } )
76+ #expect( greaterThan == . comparison( . init( left: . keyPath( " age " ) , right: . attribute( . int64( 20 ) ) , type: . greaterThan) ) )
77+ #expect( Self . people. filtered ( by: greaterThan) . map ( \. id. rawValue) == [ " Alice " ] )
78+ }
79+
80+ @available ( macOS 14 . 0 , iOS 17 . 0 , tvOS 17 . 0 , watchOS 10 . 0 , * )
81+ @Test func sequenceContains( ) throws {
82+
83+ // an element tested against a collection property
84+ let predicate = try FetchRequest . Predicate ( #Predicate< PersonModel> { $0. scores. contains ( 10 ) } )
85+ #expect( predicate == . comparison( . init(
86+ left: . keyPath( " scores " ) ,
87+ right: . attribute( . int64( 10 ) ) ,
88+ type: . contains
89+ ) ) )
90+ }
91+
92+ #if canImport(Darwin)
93+ @available ( macOS 14 . 0 , iOS 17 . 0 , tvOS 17 . 0 , watchOS 10 . 0 , * )
94+ @Test func localizedStandardContains( ) throws {
95+
96+ // maps to a case- and diacritic-insensitive CONTAINS
97+ let predicate = try FetchRequest . Predicate ( #Predicate< PersonModel> { $0. name. localizedStandardContains ( " ali " ) } )
98+ #expect( predicate == . comparison( . init(
99+ left: . keyPath( " name " ) ,
100+ right: . attribute( . string( " ali " ) ) ,
101+ type: . contains,
102+ options: [ . caseInsensitive, . diacriticInsensitive]
103+ ) ) )
104+ // the case-insensitive option applies when evaluating in memory
105+ #expect( Self . people. filtered ( by: predicate) . map ( \. id. rawValue) == [ " Alice " , " Alina " ] )
106+ }
107+
108+ @available ( macOS 14 . 0 , iOS 17 . 0 , tvOS 17 . 0 , watchOS 10 . 0 , * )
109+ @Test func objectKeyPath( ) throws {
110+
111+ // an @objc root resolves its key paths through Key-Value Coding
112+ let predicate = try FetchRequest . Predicate ( #Predicate< EventObject> { $0. name == " Event 1 " } )
113+ #expect( predicate == . comparison( . init(
114+ left: . keyPath( " name " ) ,
115+ right: . attribute( . string( " Event 1 " ) ) ,
116+ type: . equalTo
117+ ) ) )
70118 }
119+ #endif
71120
72121 @available ( macOS 14 . 0 , iOS 17 . 0 , tvOS 17 . 0 , watchOS 10 . 0 , * )
73122 @Test func compound( ) throws {
0 commit comments