Skip to content

Commit cd96220

Browse files
authored
Update CompareValuesCompatibilityTests (#186)
1 parent 6f398f0 commit cd96220

File tree

1 file changed

+197
-1
lines changed

1 file changed

+197
-1
lines changed

Tests/OpenAttributeGraphCompatibilityTests/CompareValuesCompatibilityTests.swift

Lines changed: 197 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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,200 @@ struct CompareValuesCompatibilityTests {
5959
}
6060
}
6161
}
62+
63+
64+
// Below is the graph to show the expected behavior of compareValues with different modes and types
65+
// ┌──────────────────┬────────────────────┬──────────────────┬──────────────────┐
66+
// │ │ mode │ Layout not ready │ Layout ready │
67+
// ├──────────────────┼────────────────────┼──────────────────┼──────────────────┤
68+
// │ │ bitwise │ bitwise │ bitwise │
69+
// │ PODEquatable │ equatableUnlessPOD │ bitwise │ bitwise │
70+
// │ │ equatableAlways │ bitwise │ equatable │
71+
// ├──────────────────┼────────────────────┼──────────────────┼──────────────────┤
72+
// │ │ bitwise │ bitwise │ bitwise │
73+
// │ NonPODEquatable │ equatableUnlessPOD │ bitwise │ equatable │
74+
// │ │ equatableAlways │ bitwise │ equatable │
75+
// └──────────────────┴────────────────────┴──────────────────┴──────────────────┘
76+
77+
struct POD {
78+
var id: Int
79+
}
80+
81+
struct PODEquatable: Equatable {
82+
var id: Int
83+
var v1: Int
84+
85+
static func == (lhs: Self, rhs: Self) -> Bool {
86+
lhs.id == rhs.id && (lhs.v1 - rhs.v1) % 2 == 0
87+
}
88+
}
89+
90+
struct PODEquatableTrue: Equatable {
91+
var id: Int
92+
93+
static func == (lhs: Self, rhs: Self) -> Bool {
94+
true
95+
}
96+
}
97+
98+
struct PODEquatableFalse: Equatable {
99+
var id: Int
100+
101+
static func == (lhs: Self, rhs: Self) -> Bool {
102+
false
103+
}
104+
}
105+
106+
struct NonPODEquatable: Equatable {
107+
init(id: Int, v1: Int) {
108+
self.id = id
109+
self.wrapper = Wrapper(v: v1)
110+
}
111+
112+
var id: Int
113+
var v1: Int { wrapper.v }
114+
115+
class Wrapper: Equatable {
116+
var v: Int
117+
init(v: Int) { self.v = v }
118+
119+
static func == (lhs: Wrapper, rhs: Wrapper) -> Bool {
120+
lhs.v == rhs.v
121+
}
122+
}
123+
private var wrapper: Wrapper
124+
125+
static func == (lhs: NonPODEquatable, rhs: NonPODEquatable) -> Bool {
126+
lhs.id == rhs.id && (lhs.v1 - rhs.v1) % 2 == 0
127+
}
128+
}
129+
130+
struct NonPODEquatableTrue: Equatable {
131+
init() {
132+
self.wrapper = Wrapper()
133+
}
134+
135+
private var wrapper: Wrapper
136+
137+
class Wrapper {}
138+
139+
static func == (lhs: NonPODEquatableTrue, rhs: NonPODEquatableTrue) -> Bool {
140+
true
141+
}
142+
}
143+
144+
struct NonPODEquatableFalse: Equatable {
145+
init() {
146+
self.wrapper = Wrapper.shared
147+
}
148+
149+
private var wrapper: Wrapper
150+
151+
class Wrapper {
152+
static let shared = Wrapper()
153+
}
154+
155+
static func == (lhs: NonPODEquatableFalse, rhs: NonPODEquatableFalse) -> Bool {
156+
false
157+
}
158+
}
159+
160+
@Test
161+
func bitwizeMode() async throws {
162+
let mode = ComparisonMode.bitwise
163+
#expect(compareValues(POD(id: 1), POD(id: 1), mode: mode) == true)
164+
#expect(compareValues(POD(id: 1), POD(id: 2), mode: mode) == false)
165+
#expect(compareValues(POD(id: 1), POD(id: 3), mode: mode) == false)
166+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 2), mode: mode) == true)
167+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 3), mode: mode) == false)
168+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 4), mode: mode) == false)
169+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 1), mode: mode) == true)
170+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 2), mode: mode) == false)
171+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 1), mode: mode) == true)
172+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 2), mode: mode) == false)
173+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 2), mode: mode) == false, "bitwize compare will fail since M is a class")
174+
}
175+
176+
@Test
177+
func equatableUnlessPODMode() async throws {
178+
let mode = ComparisonMode.equatableUnlessPOD
179+
// layout is not ready, use bitwise copmare
180+
#expect(compareValues(POD(id: 1), POD(id: 1), mode: mode) == true)
181+
#expect(compareValues(POD(id: 1), POD(id: 2), mode: mode) == false)
182+
#expect(compareValues(POD(id: 1), POD(id: 3), mode: mode) == false)
183+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 2), mode: mode) == true)
184+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 3), mode: mode) == false)
185+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 4), mode: mode) == false)
186+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 1), mode: mode) == true)
187+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 2), mode: mode) == false)
188+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 1), mode: mode) == true)
189+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 2), mode: mode) == false)
190+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 2), mode: mode) == false)
191+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 3), mode: mode) == false)
192+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 4), mode: mode) == false)
193+
#expect(compareValues(NonPODEquatableTrue(), NonPODEquatableTrue(), mode: mode) == false)
194+
#expect(compareValues(NonPODEquatableFalse(), NonPODEquatableFalse(), mode: mode) == true)
195+
196+
try await Task.sleep(nanoseconds: 1_000_000_000)
197+
198+
// layout is ready, use Equatable copmare only for non POD type when avaiable
199+
#expect(compareValues(POD(id: 1), POD(id: 1), mode: mode) == true)
200+
#expect(compareValues(POD(id: 1), POD(id: 2), mode: mode) == false)
201+
#expect(compareValues(POD(id: 1), POD(id: 3), mode: mode) == false)
202+
203+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 2), mode: mode) == true)
204+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 3), mode: mode) == false)
205+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 4), mode: mode) == false, "POD type, use bitwise compare")
206+
207+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 1), mode: mode) == true)
208+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 2), mode: mode) == false, "POD type, use bitwise compare")
209+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 1), mode: mode) == true, "POD type, use bitwise compare")
210+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 2), mode: mode) == false)
211+
212+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 2), mode: mode) == true, "Non POD type, use Equatable compare")
213+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 3), mode: mode) == false)
214+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 4), mode: mode) == true, "Non POD type, use Equatable compare")
215+
216+
#expect(compareValues(NonPODEquatableTrue(), NonPODEquatableTrue(), mode: mode) == true)
217+
#expect(compareValues(NonPODEquatableFalse(), NonPODEquatableFalse(), mode: mode) == false)
218+
}
219+
220+
@Test
221+
func equatableAlwaysMode() async throws {
222+
let mode = ComparisonMode.equatableAlways
223+
// When layout is not ready, the same as bitwize
224+
#expect(compareValues(POD(id: 1), POD(id: 1), mode: mode) == true)
225+
#expect(compareValues(POD(id: 1), POD(id: 2), mode: mode) == false)
226+
#expect(compareValues(POD(id: 1), POD(id: 3), mode: mode) == false)
227+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 2), mode: mode) == true)
228+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 3), mode: mode) == false)
229+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 4), mode: mode) == false)
230+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 1), mode: mode) == true)
231+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 2), mode: mode) == false)
232+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 1), mode: mode) == true)
233+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 2), mode: mode) == false)
234+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 2), mode: mode) == false)
235+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 3), mode: mode) == false)
236+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 4), mode: mode) == false)
237+
238+
try await Task.sleep(nanoseconds: 1_000_000_000)
239+
240+
// layout is ready, Equatable is used when avaiable
241+
#expect(compareValues(POD(id: 1), POD(id: 1), mode: mode) == true)
242+
#expect(compareValues(POD(id: 1), POD(id: 2), mode: mode) == false)
243+
#expect(compareValues(POD(id: 1), POD(id: 3), mode: mode) == false)
244+
245+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 2), mode: mode) == true)
246+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 3), mode: mode) == false)
247+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 4), mode: mode) == true, "use Equatable compare")
248+
249+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 1), mode: mode) == true)
250+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 2), mode: mode) == true, "use Equatable compare")
251+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 1), mode: mode) == false, "use Equatable compare")
252+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 2), mode: mode) == false)
253+
254+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 2), mode: mode) == true, "use Equatable compare")
255+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 3), mode: mode) == false)
256+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 4), mode: mode) == true, "use Equatable compare")
257+
}
62258
}

0 commit comments

Comments
 (0)