@@ -61,5 +61,124 @@ import Testing
6161 #expect( sortedEvents. map ( \. id) == [ 1 , 2 , 3 ] )
6262 #expect( sortDescriptor == FetchRequest . SortDescriptor ( sort) )
6363 }
64+
65+ @Test func foundationConversion( ) throws {
66+
67+ let sortDescriptor = FetchRequest . SortDescriptor (
68+ property: PropertyKey ( EventObject . CodingKeys. id) ,
69+ ascending: false
70+ )
71+ let foundationSort = try #require( sortDescriptor. toFoundation ( comparing: EventObject . self) )
72+ #expect( FetchRequest . SortDescriptor ( foundationSort) == sortDescriptor)
73+
74+ let events = [
75+ EventObject ( id: 1 , name: " Event 1 " , start: Date ( timeIntervalSince1970: 0 ) , speakers: [ ] ) ,
76+ EventObject ( id: 3 , name: " Event 3 " , start: Date ( timeIntervalSince1970: 60 ) , speakers: [ ] ) ,
77+ EventObject ( id: 2 , name: " Event 2 " , start: Date ( timeIntervalSince1970: 30 ) , speakers: [ ] )
78+ ]
79+ let sortedEvents = events. sorted ( using: foundationSort)
80+ #expect( sortedEvents. map ( \. id) == [ 3 , 2 , 1 ] )
81+ }
82+
83+ @Test func nsSortDescriptor( ) throws {
84+
85+ let sortDescriptor = FetchRequest . SortDescriptor (
86+ property: PropertyKey ( EventObject . CodingKeys. name) ,
87+ ascending: true
88+ )
89+ let nsSortDescriptor = try #require( sortDescriptor. toFoundation ( ) )
90+ #expect( nsSortDescriptor. key == " name " )
91+ #expect( nsSortDescriptor. ascending)
92+ #expect( FetchRequest . SortDescriptor ( nsSortDescriptor) == sortDescriptor)
93+
94+ // sort descriptors without a key path cannot be converted
95+ let comparatorSortDescriptor = NSSortDescriptor ( key: nil , ascending: true )
96+ #expect( FetchRequest . SortDescriptor ( comparatorSortDescriptor) == nil )
97+ }
98+
99+ @Test func functionSortTerm( ) {
100+
101+ // function-based sort terms have no Foundation equivalent
102+ let sortDescriptor = FetchRequest . SortDescriptor (
103+ term: . function( . init( name: " custom " , arguments: [ . keyPath( " name " ) ] ) ) ,
104+ ascending: true
105+ )
106+ #expect( sortDescriptor. toFoundation ( ) == nil )
107+ #expect( sortDescriptor. toFoundation ( comparing: EventObject . self) == nil )
108+ }
109+
110+ @Test func fetchRequest( ) {
111+
112+ let fetchRequest = FetchRequest (
113+ entity: " Event " ,
114+ sortDescriptors: [
115+ SortDescriptor ( \EventObject . start, order: . forward) ,
116+ SortDescriptor ( \EventObject . id, order: . reverse)
117+ ]
118+ )
119+ #expect( fetchRequest. sortDescriptors == [
120+ FetchRequest . SortDescriptor ( property: PropertyKey ( EventObject . CodingKeys. start) , ascending: true ) ,
121+ FetchRequest . SortDescriptor ( property: PropertyKey ( EventObject . CodingKeys. id) , ascending: false )
122+ ] )
123+ }
124+ }
125+ #endif
126+
127+ #if !canImport(Darwin)
128+ #if canImport(FoundationEssentials)
129+ import FoundationEssentials
130+ #elseif canImport(Foundation)
131+ import Foundation
132+ #endif
133+ import Testing
134+ @testable import CoreModel
135+ #endif
136+
137+ #if canImport(FoundationEssentials) || canImport(Foundation)
138+ @Suite struct SortComparatorTests {
139+
140+ static var events : [ ModelData ] {
141+ [ 1 , 3 , 2 ] . map { id in
142+ ModelData (
143+ entity: " Event " ,
144+ id: ObjectID ( rawValue: id. description) ,
145+ attributes: [
146+ " id " : . int64( numericCast ( id) ) ,
147+ " name " : . string( " Event \( id) " )
148+ ]
149+ )
150+ }
151+ }
152+
153+ @Test func sortOrder( ) {
154+
155+ var sortDescriptor = FetchRequest . SortDescriptor ( property: " id " , order: . forward)
156+ #expect( sortDescriptor. ascending)
157+ #expect( sortDescriptor. order == . forward)
158+ sortDescriptor. order = . reverse
159+ #expect( sortDescriptor. ascending == false )
160+ #expect( sortDescriptor == FetchRequest . SortDescriptor ( term: . property( " id " ) , order: . reverse) )
161+ }
162+
163+ @Test func sortComparator( ) {
164+
165+ let events = Self . events
166+ let forward = FetchRequest . SortDescriptor ( property: " id " , order: . forward)
167+ #expect( events. sorted ( using: forward) . map ( \. id. rawValue) == [ " 1 " , " 2 " , " 3 " ] )
168+ let reverse = FetchRequest . SortDescriptor ( property: " id " , order: . reverse)
169+ #expect( events. sorted ( using: reverse) . map ( \. id. rawValue) == [ " 3 " , " 2 " , " 1 " ] )
170+
171+ let lhs = events [ 0 ]
172+ #expect( forward. compare ( lhs, lhs) == . orderedSame)
173+ #expect( forward. compare ( events [ 1 ] , events [ 2 ] ) == . orderedDescending)
174+ #expect( reverse. compare ( events [ 1 ] , events [ 2 ] ) == . orderedAscending)
175+
176+ // function-based sort terms compare as equal without registered functions
177+ let function = FetchRequest . SortDescriptor (
178+ term: . function( . init( name: " custom " , arguments: [ . keyPath( " name " ) ] ) ) ,
179+ order: . forward
180+ )
181+ #expect( function. compare ( events [ 0 ] , events [ 1 ] ) == . orderedSame)
182+ }
64183}
65184#endif
0 commit comments