Skip to content

Commit f495cd5

Browse files
authored
Remove the package access modifier and update the store's interface (#101)
1 parent f9b9211 commit f495cd5

File tree

7 files changed

+63
-195
lines changed

7 files changed

+63
-195
lines changed

Sources/OneWay/OneWay.docc/Articles/Testing.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@ Before using the `expect` function, make sure to import the **OneWayTesting** mo
1212
import OneWayTesting
1313
```
1414

15+
When testing a reducer, you need to use `Store` instead of `ViewStore` for the `expect` function to be available.
16+
17+
```swift
18+
let sut = Store(
19+
reducer: TestReducer(),
20+
state: TestReducer.State(count: 0)
21+
)
22+
await sut.send(.increment)
23+
await sut.expect(\.count, 1)
24+
```
25+
26+
The completion of `send`'s `await` literally means that `send` has finished. It does not mean that the state has fully changed. The state change always happpens asynchronously. Therefore, tests should be written using the `expect` function.
27+
1528
#### When using Testing
1629

1730
You can use the `expect` function to easily check the state value.
@@ -35,7 +48,7 @@ func test_incrementTwice() async {
3548
await sut.send(.increment)
3649
await sut.send(.increment)
3750

38-
await sut.xctExpect(\.count, 2)
51+
await sut.expect(\.count, 2)
3952
}
4053
```
4154

Sources/OneWay/Store.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ where R.Action: Sendable, R.State: Sendable & Equatable {
4040
/// state changes.
4141
public var states: AsyncStream<State>
4242

43-
package var isIdle: Bool { !isProcessing && tasks.isEmpty }
43+
/// Returns `true` if the store is idle, meaning it's not processing and there are no pending
44+
/// tasks for side effects.
45+
public var isIdle: Bool {
46+
!isProcessing && tasks.isEmpty
47+
}
48+
4449
private let reducer: any Reducer<Action, State>
4550
private let continuation: AsyncStream<State>.Continuation
4651
private var isProcessing: Bool = false

Sources/OneWay/ViewStore.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ where R.Action: Sendable, R.State: Sendable & Equatable {
4141
/// state changes
4242
public let states: AsyncViewStateSequence<State>
4343

44-
package let store: Store<R>
44+
private let store: Store<R>
4545
private let continuation: AsyncStream<State>.Continuation
4646
private var task: Task<Void, Never>?
4747

Sources/OneWayTesting/ViewStore+Testing.swift

Lines changed: 0 additions & 162 deletions
This file was deleted.

Tests/OneWayTestingTests/TestingTests.swift

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
// Copyright (c) 2022-2024 SeungYeop Yeom ( https://github.com/DevYeom ).
66
//
77

8-
#if canImport(Testing)
8+
#if canImport(Testing) && canImport(Darwin)
9+
import Darwin
910
import Testing
1011
import OneWay
1112

@@ -38,33 +39,28 @@ struct TestingTests {
3839
await store.expect(\.nested.doubleNested.value, 1.23)
3940
}
4041

41-
#if !os(Linux)
4242
@Test
43-
func viewStoreExpect() async {
44-
let store = await ViewStore(
43+
func storeExpectWithManyActions() async {
44+
let store = Store(
4545
reducer: TestReducer(),
4646
state: TestReducer.State(count: 0)
4747
)
4848
await store.expect(\.count, 0)
4949

50-
await store.send(.increment)
51-
await store.expect(\.count, 1)
52-
53-
await store.send(.increment)
54-
await store.expect(\.count, 2)
55-
56-
await store.send(.setName("hello"))
57-
await store.expect(\.nested.name, "hello")
50+
for _ in 0..<10_000 {
51+
await store.send(.increment)
52+
}
53+
await store.expect(\.count, 10_000)
5854

59-
await store.send(.setValue(1.23))
60-
await store.expect(\.nested.doubleNested.value, 1.23)
55+
await store.send(.delayedIncrement)
56+
await store.expect(\.count, 10_001)
6157
}
62-
#endif
6358
}
6459

6560
private struct TestReducer: Reducer {
6661
enum Action: Sendable {
6762
case increment
63+
case delayedIncrement
6864
case setName(String)
6965
case setValue(Double)
7066
}
@@ -86,6 +82,11 @@ private struct TestReducer: Reducer {
8682
case .increment:
8783
state.count += 1
8884
return .none
85+
case .delayedIncrement:
86+
return .single {
87+
try! await Task.sleep(nanoseconds: NSEC_PER_MSEC * 100)
88+
return .increment
89+
}
8990
case let .setName(name):
9091
state.nested.name = name
9192
return .none

Tests/OneWayTestingTests/XCTestTests.swift

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// Copyright (c) 2022-2024 SeungYeop Yeom ( https://github.com/DevYeom ).
66
//
77

8+
#if canImport(XCTest) && canImport(Darwin)
9+
import Darwin
810
import XCTest
911
import OneWay
1012

@@ -35,32 +37,27 @@ final class XCTestTests: XCTestCase {
3537
await store.expect(\.nested.doubleNested.value, 1.23)
3638
}
3739

38-
#if !os(Linux)
39-
func test_viewStoreExpect() async {
40-
let store = await ViewStore(
40+
func test_storeExpectWithManyActions() async {
41+
let store = Store(
4142
reducer: TestReducer(),
4243
state: TestReducer.State(count: 0)
4344
)
4445
await store.expect(\.count, 0)
4546

46-
await store.send(.increment)
47-
await store.expect(\.count, 1)
48-
49-
await store.send(.increment)
50-
await store.expect(\.count, 2)
51-
52-
await store.send(.setName("hello"))
53-
await store.expect(\.nested.name, "hello")
47+
for _ in 0..<10_000 {
48+
await store.send(.increment)
49+
}
50+
await store.expect(\.count, 10_000)
5451

55-
await store.send(.setValue(1.23))
56-
await store.expect(\.nested.doubleNested.value, 1.23)
52+
await store.send(.delayedIncrement)
53+
await store.expect(\.count, 10_001)
5754
}
58-
#endif
5955
}
6056

6157
private struct TestReducer: Reducer {
6258
enum Action: Sendable {
6359
case increment
60+
case delayedIncrement
6461
case setName(String)
6562
case setValue(Double)
6663
}
@@ -82,6 +79,11 @@ private struct TestReducer: Reducer {
8279
case .increment:
8380
state.count += 1
8481
return .none
82+
case .delayedIncrement:
83+
return .single {
84+
try! await Task.sleep(nanoseconds: NSEC_PER_MSEC * 100)
85+
return .increment
86+
}
8587
case let .setName(name):
8688
state.nested.name = name
8789
return .none
@@ -91,3 +93,4 @@ private struct TestReducer: Reducer {
9193
}
9294
}
9395
}
96+
#endif

Tests/OneWayTests/ViewStoreTests.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,15 @@ final class ViewStoreTests: XCTestCase {
4444
sut.send(.increment)
4545
sut.send(.twice)
4646

47-
await sut.expect(\.count, 4)
47+
var result: [Int] = []
48+
for await state in sut.states {
49+
result.append(state.count)
50+
if result.count > 4 {
51+
break
52+
}
53+
}
54+
55+
XCTAssertEqual(result, [0, 1, 2, 3, 4])
4856
}
4957

5058
@MainActor

0 commit comments

Comments
 (0)