Skip to content

Commit

Permalink
Fix unit tests for Xcode 16 and older iOS destinations (#3537)
Browse files Browse the repository at this point in the history
* Limit test case availability when using TestClock

* Use withLock with shared state

* Fix unit tests on iOS 16 and earlier

* Fix DEBUG-mode perception check test to cover iOS 17+

* Run iOS & macOS unit tests on Xcode 16.0
  • Loading branch information
pyrtsa authored Jan 7, 2025
1 parent 642af1d commit a7da60e
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
runs-on: macos-15
strategy:
matrix:
command: ['']
command: [test, '']
platform: [IOS, MACOS]
xcode: ['16.0']
steps:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ final class OnChangeReducerTests: BaseTCATestCase {
Reduce { state, action in
switch action {
case .incrementButtonTapped:
state.count.value += 1
state.$count.withLock { $0.value += 1 }
return .none
}
}
Expand All @@ -222,11 +222,11 @@ final class OnChangeReducerTests: BaseTCATestCase {
}
let store = await TestStore(initialState: Feature.State()) { Feature() }
await store.send(.incrementButtonTapped) {
$0.count.value = 1
$0.$count.withLock { $0.value = 1 }
$0.description = "old: 0, new: 1"
}
await store.send(.incrementButtonTapped) {
$0.count.value = 2
$0.$count.withLock { $0.value = 2 }
$0.description = "old: 1, new: 2"
}
}
Expand Down
48 changes: 32 additions & 16 deletions Tests/ComposableArchitectureTests/StorePerceptionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import XCTest

@available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
final class StorePerceptionTests: BaseTCATestCase {
override func setUpWithError() throws {
try checkAvailability()
}

@MainActor
func testPerceptionCheck_SkipWhenOutsideView() {
let store = Store(initialState: Feature.State()) {
Expand All @@ -29,25 +33,30 @@ final class StorePerceptionTests: BaseTCATestCase {

@MainActor
func testPerceptionCheck_AccessStateWithoutTracking() {
if #unavailable(iOS 17, macOS 14, tvOS 17, watchOS 10) {
@MainActor
struct FeatureView: View {
let store = Store(initialState: Feature.State()) {
Feature()
}
var body: some View {
Text(store.count.description)
}
@MainActor
struct FeatureView: View {
let store = Store(initialState: Feature.State()) {
Feature()
}
XCTExpectFailure {
render(FeatureView())
} issueMatcher: {
$0.compactDescription == """
Perceptible state was accessed but is not being tracked. Track changes to state by \
wrapping your view in a 'WithPerceptionTracking' view.
"""
var body: some View {
Text(store.count.description)
}
}
#if DEBUG && !os(visionOS)
let previous = Perception.isPerceptionCheckingEnabled
Perception.isPerceptionCheckingEnabled = true
defer { Perception.isPerceptionCheckingEnabled = previous }
XCTExpectFailure {
render(FeatureView())
} issueMatcher: {
$0.compactDescription == """
failed - Perceptible state was accessed but is not being tracked. Track changes to state by \
wrapping your view in a 'WithPerceptionTracking' view. This must also be done for any \
escaping, trailing closures, such as 'GeometryReader', `LazyVStack` (and all lazy \
views), navigation APIs ('sheet', 'popover', 'fullScreenCover', etc.), and others.
"""
}
#endif
}

@MainActor
Expand Down Expand Up @@ -87,3 +96,10 @@ private struct Feature {
}
}
}

// NB: Workaround to XCTest ignoring `@available(...)` attributes.
private func checkAvailability() throws {
guard #available(iOS 16, macOS 13, tvOS 16, watchOS 9, *) else {
throw XCTSkip("Requires iOS 16, macOS 13, tvOS 16, or watchOS 9")
}
}
2 changes: 2 additions & 0 deletions Tests/ComposableArchitectureTests/StoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,7 @@ final class StoreTests: BaseTCATestCase {
#if canImport(Testing)
@Suite
struct ModernStoreTests {
@available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
@Reducer
fileprivate struct TaskTreeFeature {
let clock: TestClock<Duration>
Expand Down Expand Up @@ -1206,6 +1207,7 @@ final class StoreTests: BaseTCATestCase {
}
}

@available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
@MainActor
@Test
func cancellation() async throws {
Expand Down

0 comments on commit a7da60e

Please sign in to comment.