@@ -33,7 +33,7 @@ struct CompareValuesCompatibilityTests {
3333 }
3434
3535 @Test
36- func testStructCompare ( ) throws {
36+ func structCompare ( ) throws {
3737 struct A1 {
3838 var a : Int
3939 var b : Bool
@@ -59,4 +59,151 @@ struct CompareValuesCompatibilityTests {
5959 }
6060 }
6161 }
62+
63+ struct POD {
64+ var id : Int
65+ }
66+
67+ struct PODEquatable : Equatable {
68+ var id : Int
69+ var v1 : Int
70+
71+ static func == ( lhs: Self , rhs: Self ) -> Bool {
72+ lhs. id == rhs. id && ( lhs. v1 - rhs. v1) % 2 == 0
73+ }
74+ }
75+
76+ struct PODEquatableTrue : Equatable {
77+ var id : Int
78+
79+ static func == ( lhs: Self , rhs: Self ) -> Bool {
80+ true
81+ }
82+ }
83+
84+ struct PODEquatableFalse : Equatable {
85+ var id : Int
86+
87+ static func == ( lhs: Self , rhs: Self ) -> Bool {
88+ false
89+ }
90+ }
91+
92+ struct NonPODEquatable : Equatable {
93+ init ( id: Int , v1: Int ) {
94+ self . id = id
95+ self . m = M ( v: v1)
96+ }
97+
98+ var id : Int
99+ var v1 : Int { m. v }
100+
101+ class M : Equatable {
102+ var v : Int
103+ init ( v: Int ) { self . v = v }
104+
105+ static func == ( lhs: M , rhs: M ) -> Bool {
106+ lhs. v == rhs. v
107+ }
108+ }
109+ var m : M
110+
111+ static func == ( lhs: NonPODEquatable , rhs: NonPODEquatable ) -> Bool {
112+ lhs. id == rhs. id && ( lhs. v1 - rhs. v1) % 2 == 0
113+ }
114+ }
115+
116+ @Test
117+ func bitwizeMode( ) async throws {
118+ let mode = ComparisonMode . bitwise
119+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 1 ) , mode: mode) == true )
120+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 2 ) , mode: mode) == false )
121+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 3 ) , mode: mode) == false )
122+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 2 ) , mode: mode) == true )
123+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 3 ) , mode: mode) == false )
124+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 4 ) , mode: mode) == false )
125+ #expect( compareValues ( PODEquatableTrue ( id: 1 ) , PODEquatableTrue ( id: 1 ) , mode: mode) == true )
126+ #expect( compareValues ( PODEquatableTrue ( id: 1 ) , PODEquatableTrue ( id: 2 ) , mode: mode) == false )
127+ #expect( compareValues ( PODEquatableFalse ( id: 1 ) , PODEquatableFalse ( id: 1 ) , mode: mode) == true )
128+ #expect( compareValues ( PODEquatableFalse ( id: 1 ) , PODEquatableFalse ( id: 2 ) , mode: mode) == false )
129+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 2 ) , mode: mode) == false , " bitwize compare will fail since M is a class " )
130+ }
131+
132+ @Test
133+ func equatableUnlessPODMode( ) async throws {
134+ let mode = ComparisonMode . equatableUnlessPOD
135+ // layout is not ready, use bitwise copmare
136+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 1 ) , mode: mode) == true )
137+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 2 ) , mode: mode) == false )
138+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 3 ) , mode: mode) == false )
139+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 2 ) , mode: mode) == true )
140+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 3 ) , mode: mode) == false )
141+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 4 ) , mode: mode) == false )
142+ #expect( compareValues ( PODEquatableTrue ( id: 1 ) , PODEquatableTrue ( id: 1 ) , mode: mode) == true )
143+ #expect( compareValues ( PODEquatableTrue ( id: 1 ) , PODEquatableTrue ( id: 2 ) , mode: mode) == false )
144+ #expect( compareValues ( PODEquatableFalse ( id: 1 ) , PODEquatableFalse ( id: 1 ) , mode: mode) == true )
145+ #expect( compareValues ( PODEquatableFalse ( id: 1 ) , PODEquatableFalse ( id: 2 ) , mode: mode) == false )
146+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 2 ) , mode: mode) == false )
147+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 3 ) , mode: mode) == false )
148+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 4 ) , mode: mode) == false )
149+
150+ try await Task . sleep ( for: . seconds( 1 ) )
151+
152+ // layout is ready, use Equatable copmare only for non POD type when avaiable
153+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 1 ) , mode: mode) == true )
154+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 2 ) , mode: mode) == false )
155+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 3 ) , mode: mode) == false )
156+
157+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 2 ) , mode: mode) == true )
158+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 3 ) , mode: mode) == false )
159+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 4 ) , mode: mode) == false , " POD type, use bitwise compare " )
160+
161+ #expect( compareValues ( PODEquatableTrue ( id: 1 ) , PODEquatableTrue ( id: 1 ) , mode: mode) == true )
162+ #expect( compareValues ( PODEquatableTrue ( id: 1 ) , PODEquatableTrue ( id: 2 ) , mode: mode) == false , " POD type, use bitwise compare " )
163+ #expect( compareValues ( PODEquatableFalse ( id: 1 ) , PODEquatableFalse ( id: 1 ) , mode: mode) == true , " POD type, use bitwise compare " )
164+ #expect( compareValues ( PODEquatableFalse ( id: 1 ) , PODEquatableFalse ( id: 2 ) , mode: mode) == false )
165+
166+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 2 ) , mode: mode) == true , " Non POD type, use Equatable compare " )
167+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 3 ) , mode: mode) == false )
168+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 4 ) , mode: mode) == true , " Non POD type, use Equatable compare " )
169+ }
170+
171+ @Test
172+ func equatableAlwaysMode( ) async throws {
173+ let mode = ComparisonMode . equatableAlways
174+ // When layout is not ready, the same as bitwize
175+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 1 ) , mode: mode) == true )
176+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 2 ) , mode: mode) == false )
177+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 3 ) , mode: mode) == false )
178+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 2 ) , mode: mode) == true )
179+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 3 ) , mode: mode) == false )
180+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 4 ) , mode: mode) == false )
181+ #expect( compareValues ( PODEquatableTrue ( id: 1 ) , PODEquatableTrue ( id: 1 ) , mode: mode) == true )
182+ #expect( compareValues ( PODEquatableTrue ( id: 1 ) , PODEquatableTrue ( id: 2 ) , mode: mode) == false )
183+ #expect( compareValues ( PODEquatableFalse ( id: 1 ) , PODEquatableFalse ( id: 1 ) , mode: mode) == true )
184+ #expect( compareValues ( PODEquatableFalse ( id: 1 ) , PODEquatableFalse ( id: 2 ) , mode: mode) == false )
185+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 2 ) , mode: mode) == false )
186+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 3 ) , mode: mode) == false )
187+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 4 ) , mode: mode) == false )
188+
189+ try await Task . sleep ( for: . seconds( 1 ) )
190+
191+ // layout is ready, Equatable is used when avaiable
192+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 1 ) , mode: mode) == true )
193+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 2 ) , mode: mode) == false )
194+ #expect( compareValues ( POD ( id: 1 ) , POD ( id: 3 ) , mode: mode) == false )
195+
196+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 2 ) , mode: mode) == true )
197+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 3 ) , mode: mode) == false )
198+ #expect( compareValues ( PODEquatable ( id: 1 , v1: 2 ) , PODEquatable ( id: 1 , v1: 4 ) , mode: mode) == true , " use Equatable compare " )
199+
200+ #expect( compareValues ( PODEquatableTrue ( id: 1 ) , PODEquatableTrue ( id: 1 ) , mode: mode) == true )
201+ #expect( compareValues ( PODEquatableTrue ( id: 1 ) , PODEquatableTrue ( id: 2 ) , mode: mode) == true , " use Equatable compare " )
202+ #expect( compareValues ( PODEquatableFalse ( id: 1 ) , PODEquatableFalse ( id: 1 ) , mode: mode) == false , " use Equatable compare " )
203+ #expect( compareValues ( PODEquatableFalse ( id: 1 ) , PODEquatableFalse ( id: 2 ) , mode: mode) == false )
204+
205+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 2 ) , mode: mode) == true , " use Equatable compare " )
206+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 3 ) , mode: mode) == false )
207+ #expect( compareValues ( NonPODEquatable ( id: 1 , v1: 2 ) , NonPODEquatable ( id: 1 , v1: 4 ) , mode: mode) == true , " use Equatable compare " )
208+ }
62209}
0 commit comments