Skip to content

Commit 45315ca

Browse files
committed
Update CompareValuesCompatibilityTests
1 parent 6f398f0 commit 45315ca

File tree

1 file changed

+162
-1
lines changed

1 file changed

+162
-1
lines changed

Tests/OpenAttributeGraphCompatibilityTests/CompareValuesCompatibilityTests.swift

Lines changed: 162 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,165 @@ 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.m = M(v: v1)
110+
}
111+
112+
var id: Int
113+
var v1: Int { m.v }
114+
115+
class M: Equatable {
116+
var v: Int
117+
init(v: Int) { self.v = v }
118+
119+
static func == (lhs: M, rhs: M) -> Bool {
120+
lhs.v == rhs.v
121+
}
122+
}
123+
var m: M
124+
125+
static func == (lhs: NonPODEquatable, rhs: NonPODEquatable) -> Bool {
126+
lhs.id == rhs.id && (lhs.v1 - rhs.v1) % 2 == 0
127+
}
128+
}
129+
130+
@Test
131+
func bitwizeMode() async throws {
132+
let mode = ComparisonMode.bitwise
133+
#expect(compareValues(POD(id: 1), POD(id: 1), mode: mode) == true)
134+
#expect(compareValues(POD(id: 1), POD(id: 2), mode: mode) == false)
135+
#expect(compareValues(POD(id: 1), POD(id: 3), mode: mode) == false)
136+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 2), mode: mode) == true)
137+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 3), mode: mode) == false)
138+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 4), mode: mode) == false)
139+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 1), mode: mode) == true)
140+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 2), mode: mode) == false)
141+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 1), mode: mode) == true)
142+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 2), mode: mode) == false)
143+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 2), mode: mode) == false, "bitwize compare will fail since M is a class")
144+
}
145+
146+
@Test
147+
func equatableUnlessPODMode() async throws {
148+
let mode = ComparisonMode.equatableUnlessPOD
149+
// layout is not ready, use bitwise copmare
150+
#expect(compareValues(POD(id: 1), POD(id: 1), mode: mode) == true)
151+
#expect(compareValues(POD(id: 1), POD(id: 2), mode: mode) == false)
152+
#expect(compareValues(POD(id: 1), POD(id: 3), mode: mode) == false)
153+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 2), mode: mode) == true)
154+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 3), mode: mode) == false)
155+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 4), mode: mode) == false)
156+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 1), mode: mode) == true)
157+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 2), mode: mode) == false)
158+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 1), mode: mode) == true)
159+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 2), mode: mode) == false)
160+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 2), mode: mode) == false)
161+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 3), mode: mode) == false)
162+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 4), mode: mode) == false)
163+
164+
try await Task.sleep(for: .seconds(1))
165+
166+
// layout is ready, use Equatable copmare only for non POD type when avaiable
167+
#expect(compareValues(POD(id: 1), POD(id: 1), mode: mode) == true)
168+
#expect(compareValues(POD(id: 1), POD(id: 2), mode: mode) == false)
169+
#expect(compareValues(POD(id: 1), POD(id: 3), mode: mode) == false)
170+
171+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 2), mode: mode) == true)
172+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 3), mode: mode) == false)
173+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 4), mode: mode) == false, "POD type, use bitwise compare")
174+
175+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 1), mode: mode) == true)
176+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 2), mode: mode) == false, "POD type, use bitwise compare")
177+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 1), mode: mode) == true, "POD type, use bitwise compare")
178+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 2), mode: mode) == false)
179+
180+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 2), mode: mode) == true, "Non POD type, use Equatable compare")
181+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 3), mode: mode) == false)
182+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 4), mode: mode) == true, "Non POD type, use Equatable compare")
183+
}
184+
185+
@Test
186+
func equatableAlwaysMode() async throws {
187+
let mode = ComparisonMode.equatableAlways
188+
// When layout is not ready, the same as bitwize
189+
#expect(compareValues(POD(id: 1), POD(id: 1), mode: mode) == true)
190+
#expect(compareValues(POD(id: 1), POD(id: 2), mode: mode) == false)
191+
#expect(compareValues(POD(id: 1), POD(id: 3), mode: mode) == false)
192+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 2), mode: mode) == true)
193+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 3), mode: mode) == false)
194+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 4), mode: mode) == false)
195+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 1), mode: mode) == true)
196+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 2), mode: mode) == false)
197+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 1), mode: mode) == true)
198+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 2), mode: mode) == false)
199+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 2), mode: mode) == false)
200+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 3), mode: mode) == false)
201+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 4), mode: mode) == false)
202+
203+
try await Task.sleep(for: .seconds(1))
204+
205+
// layout is ready, Equatable is used when avaiable
206+
#expect(compareValues(POD(id: 1), POD(id: 1), mode: mode) == true)
207+
#expect(compareValues(POD(id: 1), POD(id: 2), mode: mode) == false)
208+
#expect(compareValues(POD(id: 1), POD(id: 3), mode: mode) == false)
209+
210+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 2), mode: mode) == true)
211+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 3), mode: mode) == false)
212+
#expect(compareValues(PODEquatable(id: 1, v1: 2), PODEquatable(id: 1, v1: 4), mode: mode) == true, "use Equatable compare")
213+
214+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 1), mode: mode) == true)
215+
#expect(compareValues(PODEquatableTrue(id: 1), PODEquatableTrue(id: 2), mode: mode) == true, "use Equatable compare")
216+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 1), mode: mode) == false, "use Equatable compare")
217+
#expect(compareValues(PODEquatableFalse(id: 1), PODEquatableFalse(id: 2), mode: mode) == false)
218+
219+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 2), mode: mode) == true, "use Equatable compare")
220+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 3), mode: mode) == false)
221+
#expect(compareValues(NonPODEquatable(id: 1, v1: 2), NonPODEquatable(id: 1, v1: 4), mode: mode) == true, "use Equatable compare")
222+
}
62223
}

0 commit comments

Comments
 (0)