Skip to content

Commit e861efc

Browse files
authored
Fix EnvironmentKeyTransformModifier implementation (#533)
1 parent cef2329 commit e861efc

File tree

2 files changed

+75
-4
lines changed

2 files changed

+75
-4
lines changed

Sources/OpenSwiftUICore/Data/Environment/EnvironmentKeyTransformModifier.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,16 @@ private struct ChildEnvironment<Value>: StatefulRule, AsyncAttribute, CustomStri
9696
}
9797
}
9898
let valueChanged = if !environmentChanged {
99-
// FIXME: The map logic is buggy
100-
oldValue.map{ compareValues($0, newValue, mode: .equatableUnlessPOD) } ?? true
99+
// SwiftUI implementation:
100+
// oldValue.map { compareValues($0, newValue, mode: .equatableUnlessPOD) } ?? true
101+
oldValue.map{ !compareValues($0, newValue, mode: .equatableUnlessPOD) } ?? true
101102
} else {
102103
true
103104
}
104105
let keyPathChanged = if !valueChanged {
105-
// FIXME: The map logic is buggy
106-
oldKeyPath.map({ $0 == newKeyPath }) ?? true
106+
// SwiftUI implementation:
107+
// oldKeyPath.map { $0 === newKeyPath } ?? true
108+
oldKeyPath.map{ $0 !== newKeyPath } ?? true
107109
} else {
108110
true
109111
}

Tests/OpenSwiftUICompatibilityTests/Data/Environment/EnvironmentKeyTransformModifierCompatibilityTests.swift

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ import Testing
77

88
extension EnvironmentValues {
99
@Entry fileprivate var customValue = 0
10+
@Entry fileprivate var customValue2 = 0
11+
}
12+
13+
@Observable
14+
private final class Model {
15+
var value = 0
1016
}
1117

1218
@MainActor
@@ -36,4 +42,67 @@ struct EnvironmentKeyTransformModifierCompatibilityTests {
3642
)
3743
}
3844
}
45+
46+
@Test
47+
func environmentKeyTransformDifferentKeyPath() async throws {
48+
@MainActor
49+
enum Count {
50+
static var contentBody: Int = 0
51+
static var subviewBody: Int = 0
52+
}
53+
54+
struct ContentView: View {
55+
@State private var model = Model()
56+
57+
var body: some View {
58+
let _ = {
59+
Count.contentBody += 1
60+
}()
61+
Subview()
62+
.transformEnvironment(model.value == 0 ? \.customValue : \.customValue2) {
63+
$0 = model.value
64+
}
65+
.onAppear {
66+
model.value = 2
67+
}
68+
}
69+
}
70+
71+
struct Subview: View {
72+
@Environment(\.customValue) private var value
73+
@Environment(\.customValue2) private var value2
74+
75+
var body: some View {
76+
let _ = {
77+
Count.subviewBody += 1
78+
switch Count.subviewBody {
79+
case 1:
80+
#expect(value == 0)
81+
#expect(value2 == 0)
82+
case 2:
83+
#expect(value == 0)
84+
#if OPENSWIFTUI
85+
#expect(value2 == 2)
86+
#else
87+
// SwiftUI known implementation issue
88+
withKnownIssue {
89+
#expect(value2 == 2)
90+
}
91+
#expect(value2 == 0)
92+
#endif
93+
default:
94+
Issue.record()
95+
}
96+
}()
97+
Color.red
98+
}
99+
}
100+
try await triggerLayoutWithWindow(expectedCount: 0) { _ in
101+
PlatformHostingController(
102+
rootView: ContentView()
103+
)
104+
}
105+
#expect(Count.contentBody == 2)
106+
#expect(Count.subviewBody == 2)
107+
}
39108
}

0 commit comments

Comments
 (0)