pointfreeco / swift-case-paths

🧰 Case paths extends the key path hierarchy to enum cases.
https://www.pointfree.co/collections/enums-and-structs/case-paths
MIT License
904 stars 105 forks source link

Tests fail to build in Xcode 16 beta #167

Closed bdbergeron closed 3 months ago

bdbergeron commented 3 months ago

Describe the bug I'm using this library as part of a feature that uses TCA, and I believe that it's the CasePaths library specifically that's causing my test suite to fail to build. The app itself builds and runs as expected.

To Reproduce I have two tests that cover both the success and failure cases of an Action that has an associated value of Result<Void, Error> type, used within a feature annotated with the @Reducer macro:

@Reducer
struct MyFeature {
  enum Action: Sendable {
    case didFinishLoading(Result<Void, Error>)
    ...
  }
  ...
}

My test cases look like this:

final class MyFeatureTests: XCTestCase {
  @MainActor
  func test_fetch_success() async {
    let store = TestStore(initialState: MyFeature.State()) {
        MyFeature()
    }
    await store.send(.fetch) {
      $0.isFetching = true
    }
    await store.receive(\.setFetchingFinished.success) {
      $0.isFetching = false
    }
  }

  @MainActor
  func test_fetch_failure() async {
    let store = TestStore(initialState: MyFeature.State()) {
      MyFeature()
    } withDependencies: {
      $0.fetchAction = {
        throw TestError.expected
      }
    }
    await store.send(.fetch) {
      $0.isFetching = true
    }
    await store.receive(\.setFetchingFinished.failure) {
      $0.isFetching = false
      $0.navigationDestination = .alert(AlertState { TextState("Expected error.") })
    }
  }
}

private enum TestError: LocalizedError {
  case expected

  var errorDescription: String? {
    switch self {
    case .expected:
      "Expected error."
    }
  }
}

Expected behavior The test suite should build without error.

Environment

Additional context Changing the Void success type to some other concrete type such as Bool results in the tests building successfully. Also removing the .success and .failure from the case path in the .receive() calls results in the tests building successfully.

I use the Void type in this instance because I have an external (non-TCA) object that handles the loading and data management that the .fetch action triggers.

stephencelis commented 3 months ago

@bdbergeron Can you zip up and share a project that reproduces the issue? The code snippet above unfortunately isn't enough to debug things.

bdbergeron commented 3 months ago

@stephencelis sure thing, here y'a go: TCATestIssueRepro.zip

stephencelis commented 3 months ago

@bdbergeron As far as I can tell this is a Swift bug/regression that affects all the way back to swift-case-paths 1.1, where the macros were first introduced, and I haven't been able to figure out a workaround in the library itself to support the preexisting types.

Can you file a bug with apple/swift and report back here? I'll try to spend some time reducing the problem tomorrow, but it'd be good to flag the regression with Apple.

Since this is an Apple bug that we can't do much about, I'm going to convert to a discussion, but hopefully it gets fixed soon.