diff --git a/Sources/OpenSwiftUICore/Data/Environment/EnvironmentKeyTransformModifier.swift b/Sources/OpenSwiftUICore/Data/Environment/EnvironmentKeyTransformModifier.swift index 29df6407b..dfdbd69db 100644 --- a/Sources/OpenSwiftUICore/Data/Environment/EnvironmentKeyTransformModifier.swift +++ b/Sources/OpenSwiftUICore/Data/Environment/EnvironmentKeyTransformModifier.swift @@ -96,14 +96,16 @@ private struct ChildEnvironment: StatefulRule, AsyncAttribute, CustomStri } } let valueChanged = if !environmentChanged { - // FIXME: The map logic is buggy - oldValue.map{ compareValues($0, newValue, mode: .equatableUnlessPOD) } ?? true + // SwiftUI implementation: + // oldValue.map { compareValues($0, newValue, mode: .equatableUnlessPOD) } ?? true + oldValue.map{ !compareValues($0, newValue, mode: .equatableUnlessPOD) } ?? true } else { true } let keyPathChanged = if !valueChanged { - // FIXME: The map logic is buggy - oldKeyPath.map({ $0 == newKeyPath }) ?? true + // SwiftUI implementation: + // oldKeyPath.map { $0 === newKeyPath } ?? true + oldKeyPath.map{ $0 !== newKeyPath } ?? true } else { true } diff --git a/Tests/OpenSwiftUICompatibilityTests/Data/Environment/EnvironmentKeyTransformModifierCompatibilityTests.swift b/Tests/OpenSwiftUICompatibilityTests/Data/Environment/EnvironmentKeyTransformModifierCompatibilityTests.swift index 1f1714957..baf3b1e0f 100644 --- a/Tests/OpenSwiftUICompatibilityTests/Data/Environment/EnvironmentKeyTransformModifierCompatibilityTests.swift +++ b/Tests/OpenSwiftUICompatibilityTests/Data/Environment/EnvironmentKeyTransformModifierCompatibilityTests.swift @@ -7,6 +7,12 @@ import Testing extension EnvironmentValues { @Entry fileprivate var customValue = 0 + @Entry fileprivate var customValue2 = 0 +} + +@Observable +private final class Model { + var value = 0 } @MainActor @@ -36,4 +42,67 @@ struct EnvironmentKeyTransformModifierCompatibilityTests { ) } } + + @Test + func environmentKeyTransformDifferentKeyPath() async throws { + @MainActor + enum Count { + static var contentBody: Int = 0 + static var subviewBody: Int = 0 + } + + struct ContentView: View { + @State private var model = Model() + + var body: some View { + let _ = { + Count.contentBody += 1 + }() + Subview() + .transformEnvironment(model.value == 0 ? \.customValue : \.customValue2) { + $0 = model.value + } + .onAppear { + model.value = 2 + } + } + } + + struct Subview: View { + @Environment(\.customValue) private var value + @Environment(\.customValue2) private var value2 + + var body: some View { + let _ = { + Count.subviewBody += 1 + switch Count.subviewBody { + case 1: + #expect(value == 0) + #expect(value2 == 0) + case 2: + #expect(value == 0) + #if OPENSWIFTUI + #expect(value2 == 2) + #else + // SwiftUI known implementation issue + withKnownIssue { + #expect(value2 == 2) + } + #expect(value2 == 0) + #endif + default: + Issue.record() + } + }() + Color.red + } + } + try await triggerLayoutWithWindow(expectedCount: 0) { _ in + PlatformHostingController( + rootView: ContentView() + ) + } + #expect(Count.contentBody == 2) + #expect(Count.subviewBody == 2) + } }