Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import XCTest

@testable import ExampleCounter

@MainActor
final class ExampleCounterTests: XCTestCase {
@MainActor
func testCounterAtom() {
let context = AtomTestContext()
let atom = CounterAtom()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import XCTest

@testable import ExampleTodo

@MainActor
final class ExampleTodoTests: XCTestCase {
let completedTodos = [
Todo(
Expand All @@ -30,6 +29,7 @@ final class ExampleTodoTests: XCTestCase {
completedTodos + uncompleteTodos
}

@MainActor
func testFilteredTodosAtom() {
let context = AtomTestContext()
let atom = FilteredTodosAtom()
Expand All @@ -53,6 +53,7 @@ final class ExampleTodoTests: XCTestCase {
XCTAssertEqual(context.watch(atom), uncompleteTodos)
}

@MainActor
func testStatsAtom() {
let context = AtomTestContext()
let atom = StatsAtom()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import XCTest

@testable import ExampleMap

@MainActor
final class ExampleMapTests: XCTestCase {
@MainActor
func testLocationObserverAtom() {
let atom = LocationObserverAtom()
let context = AtomTestContext()
Expand All @@ -25,6 +25,7 @@ final class ExampleMapTests: XCTestCase {
XCTAssertFalse(manager.isUpdatingLocation)
}

@MainActor
func testCoordinateAtom() {
let atom = CoordinateAtom()
let context = AtomTestContext()
Expand All @@ -40,6 +41,7 @@ final class ExampleMapTests: XCTestCase {
XCTAssertEqual(context.watch(atom)?.longitude, 2)
}

@MainActor
func testAuthorizationStatusAtom() async {
let atom = AuthorizationStatusAtom()
let manager = MockLocationManager()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import XCTest

@testable import ExampleMovieDB

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

@MainActor
func testMovieLoader() async {
let apiClient = MockAPIClient()
let atom = MovieLoaderAtom()
Expand Down Expand Up @@ -61,6 +62,7 @@ final class ExampleMovieDBTests: XCTestCase {
}
}

@MainActor
func testMyListAtom() {
let atom = MyListAtom()
let context = AtomTestContext()
Expand All @@ -80,6 +82,7 @@ final class ExampleMovieDBTests: XCTestCase {
XCTAssertEqual(context.watch(atom).movies, [.stub(id: 1)])
}

@MainActor
func testIsInMyListAtom() {
let context = AtomTestContext()

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

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

@MainActor
func testSearchMoviesAtom() async throws {
let apiClient = MockAPIClient()
let atom = SearchMoviesAtom()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import XCTest

@testable import ExampleTimeTravel

@MainActor
final class ExampleTimeTravelTests: XCTestCase {
@MainActor
func testTextAtom() {
let context = AtomTestContext()
let atom = InputStateAtom()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import XCTest

@testable import ExampleVoiceMemo

@MainActor
final class ExampleVoiceMemoTests: XCTestCase {
@MainActor
func testIsRecordingAtom() {
let context = AtomTestContext()
let atom = IsRecordingAtom()
Expand All @@ -18,6 +18,7 @@ final class ExampleVoiceMemoTests: XCTestCase {
XCTAssertTrue(context.read(atom))
}

@MainActor
func testRecordingDataAtom() {
let context = AtomTestContext()
let atom = RecordingDataAtom()
Expand Down Expand Up @@ -55,6 +56,7 @@ final class ExampleVoiceMemoTests: XCTestCase {
XCTAssertTrue(context.watch(IsRecordingFailedAtom()))
}

@MainActor
func testRecordingElapsedTimeAtom() async {
let context = AtomTestContext()
let atom = RecordingElapsedTimeAtom()
Expand All @@ -79,6 +81,7 @@ final class ExampleVoiceMemoTests: XCTestCase {
XCTAssertEqual(context.watch(atom), .success(10))
}

@MainActor
func testToggleRecording() {
let context = AtomTestContext()
let actions = VoiceMemoActions(context: context)
Expand Down Expand Up @@ -125,6 +128,7 @@ final class ExampleVoiceMemoTests: XCTestCase {
XCTAssertNil(context.watch(RecordingDataAtom()))
}

@MainActor
func testDelete() {
let context = AtomTestContext()
let actions = VoiceMemoActions(context: context)
Expand All @@ -142,6 +146,7 @@ final class ExampleVoiceMemoTests: XCTestCase {
XCTAssertFalse(context.watch(IsPlayingAtom(voiceMemo: voiceMemo)))
}

@MainActor
func testIsPlayingAtom() {
let context = AtomTestContext()
let audioPlayer = MockAudioPlayer()
Expand All @@ -167,6 +172,7 @@ final class ExampleVoiceMemoTests: XCTestCase {
XCTAssertTrue(context.watch(IsPlaybackFailedAtom()))
}

@MainActor
func testPlayingElapsedTimeAtom() async {
let context = AtomTestContext()
let voiceMemo = VoiceMemo.stub()
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,7 @@ In order to fully test your app, this library guarantees the following principle

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.
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.
Since atom needs to be used from the main actor to guarantee thread-safety, `XCTestCase` class that tests atoms should have `@MainActor` attribute.
Since atom needs to be used from the main actor to guarantee thread-safety, functions that tests atoms should have `@MainActor` attribute.

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

Expand Down Expand Up @@ -1293,8 +1293,8 @@ struct FetchBookAtom: ThrowingTaskAtom, Hashable {

```swift

@MainActor
class FetchBookTests: XCTestCase {
@MainActor
func testFetch() async throws {
let context = AtomTestContext()
let api = MockAPIClient()
Expand Down
4 changes: 3 additions & 1 deletion Tests/AtomsTests/Atom/AsyncSequenceAtomTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import XCTest

@testable import Atoms

@MainActor
final class AsyncSequenceAtomTests: XCTestCase {
@MainActor
func testValue() async {
let pipe = AsyncThrowingStreamPipe<Int>()
let atom = TestAsyncSequenceAtom { pipe.stream }
Expand Down Expand Up @@ -67,6 +67,7 @@ final class AsyncSequenceAtomTests: XCTestCase {
}
}

@MainActor
func testRefresh() async {
let pipe = AsyncThrowingStreamPipe<Int>()
let atom = TestAsyncSequenceAtom { pipe.stream }
Expand Down Expand Up @@ -130,6 +131,7 @@ final class AsyncSequenceAtomTests: XCTestCase {
}
}

@MainActor
func testUpdated() async {
let pipe = AsyncThrowingStreamPipe<Int>()
var updatedValues = [Pair<Int?>]()
Expand Down
3 changes: 2 additions & 1 deletion Tests/AtomsTests/Atom/ModifiedAtomTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import XCTest

@testable import Atoms

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

@MainActor
func testValue() async {
let base = TestStateAtom(defaultValue: "test")
let modifier = SelectModifier<String, Int>(keyPath: \.count)
Expand Down
3 changes: 2 additions & 1 deletion Tests/AtomsTests/Atom/ObservableObjectAtomTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import XCTest

@testable import Atoms

@MainActor
final class ObservableObjectAtomTests: XCTestCase {
@MainActor
final class TestObject: ObservableObject {
Expand Down Expand Up @@ -30,6 +29,7 @@ final class ObservableObjectAtomTests: XCTestCase {
}
}

@MainActor
func test() async {
let atom = TestAtom()
let context = AtomTestContext()
Expand Down Expand Up @@ -112,6 +112,7 @@ final class ObservableObjectAtomTests: XCTestCase {
}
}

@MainActor
func testUpdated() async {
var updatedObjects = [TestObject]()
let atom = TestAtom { object, _ in
Expand Down
4 changes: 3 additions & 1 deletion Tests/AtomsTests/Atom/PublisherAtomTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import XCTest

@testable import Atoms

@MainActor
final class PublisherAtomTests: XCTestCase {
@MainActor
func testValue() async {
let subject = ResettableSubject<Int, URLError>()
let atom = TestPublisherAtom { subject }
Expand Down Expand Up @@ -66,6 +66,7 @@ final class PublisherAtomTests: XCTestCase {
}
}

@MainActor
func testRefresh() async {
let subject = ResettableSubject<Int, URLError>()
let atom = TestPublisherAtom { subject }
Expand Down Expand Up @@ -129,6 +130,7 @@ final class PublisherAtomTests: XCTestCase {
}
}

@MainActor
func testUpdated() async {
let subject = ResettableSubject<Int, URLError>()
var updatedValues = [Pair<Int?>]()
Expand Down
6 changes: 5 additions & 1 deletion Tests/AtomsTests/Atom/StateAtomTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import XCTest

@testable import Atoms

@MainActor
final class StateAtomTests: XCTestCase {
@MainActor
func testValue() {
let atom = TestStateAtom(defaultValue: 0)
let context = AtomTestContext()
Expand All @@ -22,6 +22,7 @@ final class StateAtomTests: XCTestCase {
}
}

@MainActor
func testSet() {
let atom = TestStateAtom(defaultValue: 0)
let context = AtomTestContext()
Expand All @@ -33,6 +34,7 @@ final class StateAtomTests: XCTestCase {
XCTAssertEqual(context.watch(atom), 100)
}

@MainActor
func testSetOverride() {
let atom = TestStateAtom(defaultValue: 0)
let context = AtomTestContext()
Expand All @@ -46,6 +48,7 @@ final class StateAtomTests: XCTestCase {
XCTAssertEqual(context.watch(atom), 100)
}

@MainActor
func testDependency() async {
struct Dependency1Atom: StateAtom, Hashable {
func defaultValue(context: Context) -> Int {
Expand Down Expand Up @@ -81,6 +84,7 @@ final class StateAtomTests: XCTestCase {
XCTAssertEqual(value2, 0)
}

@MainActor
func testUpdated() {
var updatedValues = [Pair<Int>]()
let atom = TestStateAtom(defaultValue: 0) { new, old in
Expand Down
5 changes: 4 additions & 1 deletion Tests/AtomsTests/Atom/TaskAtomTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import XCTest

@testable import Atoms

@MainActor
final class TaskAtomTests: XCTestCase {
@MainActor
func testValue() async {
let atom = TestTaskAtom(value: 0)
let context = AtomTestContext()
Expand Down Expand Up @@ -41,6 +41,7 @@ final class TaskAtomTests: XCTestCase {
}
}

@MainActor
func testRefresh() async {
var value = 0
let atom = TestTaskAtom<Int> { value }
Expand Down Expand Up @@ -108,6 +109,7 @@ final class TaskAtomTests: XCTestCase {
}
}

@MainActor
func testReleaseDependencies() async {
struct DependencyAtom: StateAtom, Hashable {
func defaultValue(context: Context) -> Int {
Expand Down Expand Up @@ -142,6 +144,7 @@ final class TaskAtomTests: XCTestCase {
XCTAssertEqual(dependencyValue, 0)
}

@MainActor
func testUpdated() {
var updatedTaskHashValues = [Int]()
let atom = TestTaskAtom {
Expand Down
Loading