Skip to content

Commit f15306d

Browse files
Make the Store able to subscribe to Action publishers (#85)
1 parent c88d666 commit f15306d

File tree

2 files changed

+33
-14
lines changed

2 files changed

+33
-14
lines changed

Sources/Fluxor/Store.swift

+21-3
Original file line numberDiff line numberDiff line change
@@ -203,16 +203,34 @@ public extension Store where Environment == Void {
203203
}
204204
}
205205

206+
// MARK: - Subscriptions
207+
208+
extension Store: Subscriber {
209+
public typealias Input = Action
210+
public typealias Failure = Never
211+
212+
public func receive(subscription: Subscription) {
213+
subscription.request(.unlimited)
214+
}
215+
216+
public func receive(_ input: Action) -> Subscribers.Demand {
217+
dispatch(action: input)
218+
return .unlimited
219+
}
220+
221+
public func receive(completion: Subscribers.Completion<Never>) {}
222+
}
223+
206224
// MARK: - Private
207225

208-
extension Store {
226+
private extension Store {
209227
/**
210228
Creates `Cancellable`s for the given `Effect`s.
211229

212230
- Parameter effects: The `Effect`s to create `Cancellable`s for
213231
- Returns: The `Cancellable`s for the given `Effect`s
214232
*/
215-
private func createCancellables(for effects: [Effect<Environment>]) -> [AnyCancellable] {
233+
func createCancellables(for effects: [Effect<Environment>]) -> [AnyCancellable] {
216234
return effects.map(createCancellable(for:))
217235
}
218236

@@ -222,7 +240,7 @@ extension Store {
222240
- Parameter effect: The `Effect` to create `Cancellable` for
223241
- Returns: The `Cancellable` for the given `Effect`
224242
*/
225-
private func createCancellable(for effect: Effect<Environment>) -> AnyCancellable {
243+
func createCancellable(for effect: Effect<Environment>) -> AnyCancellable {
226244
switch effect {
227245
case .dispatchingOne(let effectCreator):
228246
return effectCreator(actions.eraseToAnyPublisher(), environment)

Tests/FluxorTests/StoreTests.swift

+12-11
Original file line numberDiff line numberDiff line change
@@ -236,21 +236,22 @@ class StoreTests: XCTestCase {
236236
wait(for: [VoidTestEffects.expectation], timeout: 5)
237237
}
238238

239-
/// Can we get all state changes in a `MockStore`?
240-
func testMockStoreStateChanges() {
239+
/// Does the `Store` dispatch actions when it subscribes to a `Publisher`?
240+
func testSubscribing() {
241241
// Given
242-
let mockStore = MockStore(initialState: TestState(type: .initial, lastAction: nil))
242+
let subject = PassthroughSubject<Action, Never>()
243+
let interceptor = TestInterceptor<TestState>()
244+
let store = Store(initialState: TestState(type: .initial))
245+
store.register(interceptor: interceptor)
246+
subject.subscribe(store)
247+
XCTAssertEqual(interceptor.stateChanges.count, 0)
243248
let action = TestAction()
244-
let modifiedState = TestState(type: .modified, lastAction: "Set State")
245249
// When
246-
mockStore.dispatch(action: action)
247-
mockStore.setState(newState: modifiedState)
250+
subject.send(action)
251+
subject.send(completion: .finished)
248252
// Then
249-
XCTAssertEqual(mockStore.stateChanges.count, 2)
250-
XCTAssertEqual(mockStore.stateChanges[0].action as! TestAction, action)
251-
let setStateAction = mockStore.stateChanges[1].action as! AnonymousAction<TestState>
252-
XCTAssertEqual(setStateAction.id, "Set State")
253-
XCTAssertEqual(mockStore.stateChanges[1].newState, modifiedState)
253+
XCTAssertEqual(interceptor.stateChanges.count, 1)
254+
XCTAssertEqual(interceptor.stateChanges[0].action as! TestAction, action)
254255
}
255256
}
256257

0 commit comments

Comments
 (0)