Skip to content

Commit 5eeec4f

Browse files
authored
Fix Xcode15.3 (Swift5.10) warning/Swift 6 error: Main actor-isolated class 'XXXTests' has different actor isolation from nonisolated superclass 'XCTestCase'; this is an error in Swift 6 (#97)
* Move MainActor attribute from subclass of XCTestCase to each function because different actor isolation from nonisolated superclass will be compiler error in Swift6 * Move MainActor attribute from class to func on Exmaple/Tests * Fix sample code of testing on README.md
1 parent 7dd0846 commit 5eeec4f

32 files changed

+126
-33
lines changed

Examples/Packages/CrossPlatform/Tests/ExampleCounterTests/ExampleCounterTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import XCTest
33

44
@testable import ExampleCounter
55

6-
@MainActor
76
final class ExampleCounterTests: XCTestCase {
7+
@MainActor
88
func testCounterAtom() {
99
let context = AtomTestContext()
1010
let atom = CounterAtom()

Examples/Packages/CrossPlatform/Tests/ExampleTodoTests/ExampleTodoTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import XCTest
33

44
@testable import ExampleTodo
55

6-
@MainActor
76
final class ExampleTodoTests: XCTestCase {
87
let completedTodos = [
98
Todo(
@@ -30,6 +29,7 @@ final class ExampleTodoTests: XCTestCase {
3029
completedTodos + uncompleteTodos
3130
}
3231

32+
@MainActor
3333
func testFilteredTodosAtom() {
3434
let context = AtomTestContext()
3535
let atom = FilteredTodosAtom()
@@ -53,6 +53,7 @@ final class ExampleTodoTests: XCTestCase {
5353
XCTAssertEqual(context.watch(atom), uncompleteTodos)
5454
}
5555

56+
@MainActor
5657
func testStatsAtom() {
5758
let context = AtomTestContext()
5859
let atom = StatsAtom()

Examples/Packages/iOS/Tests/ExampleMapTests/ExampleMapTests.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import XCTest
44

55
@testable import ExampleMap
66

7-
@MainActor
87
final class ExampleMapTests: XCTestCase {
8+
@MainActor
99
func testLocationObserverAtom() {
1010
let atom = LocationObserverAtom()
1111
let context = AtomTestContext()
@@ -25,6 +25,7 @@ final class ExampleMapTests: XCTestCase {
2525
XCTAssertFalse(manager.isUpdatingLocation)
2626
}
2727

28+
@MainActor
2829
func testCoordinateAtom() {
2930
let atom = CoordinateAtom()
3031
let context = AtomTestContext()
@@ -40,6 +41,7 @@ final class ExampleMapTests: XCTestCase {
4041
XCTAssertEqual(context.watch(atom)?.longitude, 2)
4142
}
4243

44+
@MainActor
4345
func testAuthorizationStatusAtom() async {
4446
let atom = AuthorizationStatusAtom()
4547
let manager = MockLocationManager()

Examples/Packages/iOS/Tests/ExampleMovieDBTests/ExampleMovieDBTests.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import XCTest
33

44
@testable import ExampleMovieDB
55

6-
@MainActor
76
final class ExampleMovieDBTests: XCTestCase {
7+
@MainActor
88
func testImageAtom() async {
99
let apiClient = MockAPIClient()
1010
let atom = ImageAtom(path: "", size: .original)
@@ -29,6 +29,7 @@ final class ExampleMovieDBTests: XCTestCase {
2929
XCTAssertEqual(failurePhase.error as? URLError, error)
3030
}
3131

32+
@MainActor
3233
func testMovieLoader() async {
3334
let apiClient = MockAPIClient()
3435
let atom = MovieLoaderAtom()
@@ -61,6 +62,7 @@ final class ExampleMovieDBTests: XCTestCase {
6162
}
6263
}
6364

65+
@MainActor
6466
func testMyListAtom() {
6567
let atom = MyListAtom()
6668
let context = AtomTestContext()
@@ -80,6 +82,7 @@ final class ExampleMovieDBTests: XCTestCase {
8082
XCTAssertEqual(context.watch(atom).movies, [.stub(id: 1)])
8183
}
8284

85+
@MainActor
8386
func testIsInMyListAtom() {
8487
let context = AtomTestContext()
8588

@@ -89,6 +92,7 @@ final class ExampleMovieDBTests: XCTestCase {
8992
XCTAssertFalse(context.watch(IsInMyListAtom(movie: .stub(id: 1))))
9093
}
9194

95+
@MainActor
9296
func testCastsAtom() async {
9397
let apiClient = MockAPIClient()
9498
let atom = CastsAtom(movieID: 0)
@@ -113,6 +117,7 @@ final class ExampleMovieDBTests: XCTestCase {
113117
XCTAssertEqual(failurePhase.error as? URLError, error)
114118
}
115119

120+
@MainActor
116121
func testSearchMoviesAtom() async throws {
117122
let apiClient = MockAPIClient()
118123
let atom = SearchMoviesAtom()

Examples/Packages/iOS/Tests/ExampleTimeTravelTests/ExampleTimeTravelTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import XCTest
33

44
@testable import ExampleTimeTravel
55

6-
@MainActor
76
final class ExampleTimeTravelTests: XCTestCase {
7+
@MainActor
88
func testTextAtom() {
99
let context = AtomTestContext()
1010
let atom = InputStateAtom()

Examples/Packages/iOS/Tests/ExampleVoiceMemoTests/ExampleVoiceMemoTests.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import XCTest
55

66
@testable import ExampleVoiceMemo
77

8-
@MainActor
98
final class ExampleVoiceMemoTests: XCTestCase {
9+
@MainActor
1010
func testIsRecordingAtom() {
1111
let context = AtomTestContext()
1212
let atom = IsRecordingAtom()
@@ -18,6 +18,7 @@ final class ExampleVoiceMemoTests: XCTestCase {
1818
XCTAssertTrue(context.read(atom))
1919
}
2020

21+
@MainActor
2122
func testRecordingDataAtom() {
2223
let context = AtomTestContext()
2324
let atom = RecordingDataAtom()
@@ -55,6 +56,7 @@ final class ExampleVoiceMemoTests: XCTestCase {
5556
XCTAssertTrue(context.watch(IsRecordingFailedAtom()))
5657
}
5758

59+
@MainActor
5860
func testRecordingElapsedTimeAtom() async {
5961
let context = AtomTestContext()
6062
let atom = RecordingElapsedTimeAtom()
@@ -79,6 +81,7 @@ final class ExampleVoiceMemoTests: XCTestCase {
7981
XCTAssertEqual(context.watch(atom), .success(10))
8082
}
8183

84+
@MainActor
8285
func testToggleRecording() {
8386
let context = AtomTestContext()
8487
let actions = VoiceMemoActions(context: context)
@@ -125,6 +128,7 @@ final class ExampleVoiceMemoTests: XCTestCase {
125128
XCTAssertNil(context.watch(RecordingDataAtom()))
126129
}
127130

131+
@MainActor
128132
func testDelete() {
129133
let context = AtomTestContext()
130134
let actions = VoiceMemoActions(context: context)
@@ -142,6 +146,7 @@ final class ExampleVoiceMemoTests: XCTestCase {
142146
XCTAssertFalse(context.watch(IsPlayingAtom(voiceMemo: voiceMemo)))
143147
}
144148

149+
@MainActor
145150
func testIsPlayingAtom() {
146151
let context = AtomTestContext()
147152
let audioPlayer = MockAudioPlayer()
@@ -167,6 +172,7 @@ final class ExampleVoiceMemoTests: XCTestCase {
167172
XCTAssertTrue(context.watch(IsPlaybackFailedAtom()))
168173
}
169174

175+
@MainActor
170176
func testPlayingElapsedTimeAtom() async {
171177
let context = AtomTestContext()
172178
let voiceMemo = VoiceMemo.stub()

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ In order to fully test your app, this library guarantees the following principle
12401240

12411241
In the test case, you first create an `AtomTestContext` instance that behaves similarly to other context types. The context allows for flexible reproduction of expected scenarios for testing using the control functions described in the [Context](#context) section.
12421242
In addition, it's able to replace the atom value with test-friendly dependencies with `override` function. It helps you to write a reproducible & stable testing.
1243-
Since atom needs to be used from the main actor to guarantee thread-safety, `XCTestCase` class that tests atoms should have `@MainActor` attribute.
1243+
Since atom needs to be used from the main actor to guarantee thread-safety, functions that tests atoms should have `@MainActor` attribute.
12441244

12451245
<details><summary>Click to expand the classes to be tested</summary>
12461246

@@ -1293,8 +1293,8 @@ struct FetchBookAtom: ThrowingTaskAtom, Hashable {
12931293

12941294
```swift
12951295

1296-
@MainActor
12971296
class FetchBookTests: XCTestCase {
1297+
@MainActor
12981298
func testFetch() async throws {
12991299
let context = AtomTestContext()
13001300
let api = MockAPIClient()

Tests/AtomsTests/Atom/AsyncSequenceAtomTests.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import XCTest
22

33
@testable import Atoms
44

5-
@MainActor
65
final class AsyncSequenceAtomTests: XCTestCase {
6+
@MainActor
77
func testValue() async {
88
let pipe = AsyncThrowingStreamPipe<Int>()
99
let atom = TestAsyncSequenceAtom { pipe.stream }
@@ -67,6 +67,7 @@ final class AsyncSequenceAtomTests: XCTestCase {
6767
}
6868
}
6969

70+
@MainActor
7071
func testRefresh() async {
7172
let pipe = AsyncThrowingStreamPipe<Int>()
7273
let atom = TestAsyncSequenceAtom { pipe.stream }
@@ -130,6 +131,7 @@ final class AsyncSequenceAtomTests: XCTestCase {
130131
}
131132
}
132133

134+
@MainActor
133135
func testUpdated() async {
134136
let pipe = AsyncThrowingStreamPipe<Int>()
135137
var updatedValues = [Pair<Int?>]()

Tests/AtomsTests/Atom/ModifiedAtomTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import XCTest
22

33
@testable import Atoms
44

5-
@MainActor
65
final class ModifiedAtomTests: XCTestCase {
6+
@MainActor
77
func testKey() {
88
let base = TestAtom(value: 0)
99
let modifier = SelectModifier<Int, String>(keyPath: \.description)
@@ -17,6 +17,7 @@ final class ModifiedAtomTests: XCTestCase {
1717
XCTAssertNotEqual(AnyHashable(atom.key).hashValue, AnyHashable(base.key).hashValue)
1818
}
1919

20+
@MainActor
2021
func testValue() async {
2122
let base = TestStateAtom(defaultValue: "test")
2223
let modifier = SelectModifier<String, Int>(keyPath: \.count)

Tests/AtomsTests/Atom/ObservableObjectAtomTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import XCTest
22

33
@testable import Atoms
44

5-
@MainActor
65
final class ObservableObjectAtomTests: XCTestCase {
76
@MainActor
87
final class TestObject: ObservableObject {
@@ -30,6 +29,7 @@ final class ObservableObjectAtomTests: XCTestCase {
3029
}
3130
}
3231

32+
@MainActor
3333
func test() async {
3434
let atom = TestAtom()
3535
let context = AtomTestContext()
@@ -112,6 +112,7 @@ final class ObservableObjectAtomTests: XCTestCase {
112112
}
113113
}
114114

115+
@MainActor
115116
func testUpdated() async {
116117
var updatedObjects = [TestObject]()
117118
let atom = TestAtom { object, _ in

0 commit comments

Comments
 (0)