Skip to content

Commit

Permalink
Merge pull request #12 from SwiftRex/MiddlewareIO
Browse files Browse the repository at this point in the history
Update SwiftRex to use Middleware IO
  • Loading branch information
luizmb authored Nov 30, 2021
2 parents 3c13c03 + c2e2678 commit e2822a4
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 83 deletions.
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"repositoryURL": "https://github.com/SwiftRex/SwiftRex.git",
"state": {
"branch": null,
"revision": "660ba8ec5a79bc30f152955f9d8ea0b69ba6b466",
"version": "0.8.6"
"revision": "c51328031f943d8f055dbcb738bc66915825b8cc",
"version": "0.8.8"
}
}
]
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ let package = Package(
.library(name: "LoggerMiddleware", targets: ["LoggerMiddleware"])
],
dependencies: [
.package(url: "https://github.com/SwiftRex/SwiftRex.git", .upToNextMajor(from: "0.8.6"))
.package(url: "https://github.com/SwiftRex/SwiftRex.git", .upToNextMajor(from: "0.8.8"))
],
targets: [
.target(
Expand Down
52 changes: 20 additions & 32 deletions Sources/LoggerMiddleware/LoggerMiddleware.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,31 @@ import Foundation
import os.log
import SwiftRex

extension Middleware where StateType: Equatable {
extension MiddlewareProtocol where StateType: Equatable {
public func logger(
actionTransform: LoggerMiddleware<Self>.ActionTransform = .default(),
actionPrinter: LoggerMiddleware<Self>.ActionLogger = .osLog,
actionTransform: LoggerMiddleware<InputActionType, StateType>.ActionTransform = .default(),
actionPrinter: LoggerMiddleware<InputActionType, StateType>.ActionLogger = .osLog,
actionFilter: @escaping (InputActionType) -> Bool = { _ in true },
stateDiffTransform: LoggerMiddleware<Self>.StateDiffTransform = .diff(),
stateDiffPrinter: LoggerMiddleware<Self>.StateLogger = .osLog,
stateDiffTransform: LoggerMiddleware<InputActionType, StateType>.StateDiffTransform = .diff(),
stateDiffPrinter: LoggerMiddleware<InputActionType, StateType>.StateLogger = .osLog,
queue: DispatchQueue = .main
) -> LoggerMiddleware<Self> {
) -> ComposedMiddleware<InputActionType, OutputActionType, StateType> {
LoggerMiddleware(
self,
actionTransform: actionTransform,
actionPrinter: actionPrinter,
actionFilter: actionFilter,
stateDiffTransform: stateDiffTransform,
stateDiffPrinter: stateDiffPrinter,
queue: queue
)
).lift(outputAction: { (_: Never) -> OutputActionType in }) <> self
}
}

public final class LoggerMiddleware<M: Middleware>: Middleware where M.StateType: Equatable {
public typealias InputActionType = M.InputActionType
public typealias OutputActionType = M.OutputActionType
public typealias StateType = M.StateType
private let middleware: M
public final class LoggerMiddleware<Action, State: Equatable>: MiddlewareProtocol {
public typealias InputActionType = Action
public typealias OutputActionType = Never
public typealias StateType = State

private let queue: DispatchQueue
private var getState: GetState<StateType>?
private let actionTransform: ActionTransform
Expand All @@ -37,15 +36,13 @@ public final class LoggerMiddleware<M: Middleware>: Middleware where M.StateType
private let stateDiffPrinter: StateLogger

init(
_ middleware: M,
actionTransform: ActionTransform,
actionPrinter: ActionLogger,
actionFilter: @escaping (InputActionType) -> Bool = { _ in true },
stateDiffTransform: StateDiffTransform,
stateDiffPrinter: StateLogger,
queue: DispatchQueue
) {
self.middleware = middleware
self.actionTransform = actionTransform
self.actionPrinter = actionPrinter
self.actionFilter = actionFilter
Expand All @@ -54,19 +51,11 @@ public final class LoggerMiddleware<M: Middleware>: Middleware where M.StateType
self.queue = queue
}

public func receiveContext(getState: @escaping GetState<StateType>, output: AnyActionHandler<OutputActionType>) {
self.getState = getState
middleware.receiveContext(getState: getState, output: output)
}

public func handle(action: InputActionType, from dispatcher: ActionSource, afterReducer: inout AfterReducer) {
guard actionFilter(action) else { return }
public func handle(action: Action, from dispatcher: ActionSource, state: @escaping GetState<State>) -> IO<Never> {
guard actionFilter(action) else { return .pure() }
let stateBefore = getState?()
var innerAfterReducer = AfterReducer.doNothing()

middleware.handle(action: action, from: dispatcher, afterReducer: &innerAfterReducer)

afterReducer = innerAfterReducer <> .do { [weak self] in
return IO { [weak self] _ in
guard let self = self,
let stateAfter = self.getState?() else { return }

Expand All @@ -83,15 +72,14 @@ public final class LoggerMiddleware<M: Middleware>: Middleware where M.StateType

extension LoggerMiddleware {
public static func `default`(
actionTransform: LoggerMiddleware<IdentityMiddleware<InputActionType, OutputActionType, StateType>>.ActionTransform = .default(),
actionPrinter: LoggerMiddleware<IdentityMiddleware<InputActionType, OutputActionType, StateType>>.ActionLogger = .osLog,
actionTransform: LoggerMiddleware<InputActionType, StateType>.ActionTransform = .default(),
actionPrinter: LoggerMiddleware<InputActionType, StateType>.ActionLogger = .osLog,
actionFilter: @escaping (InputActionType) -> Bool = { _ in true },
stateDiffTransform: LoggerMiddleware<IdentityMiddleware<InputActionType, OutputActionType, StateType>>.StateDiffTransform = .diff(),
stateDiffPrinter: LoggerMiddleware<IdentityMiddleware<InputActionType, OutputActionType, StateType>>.StateLogger = .osLog,
stateDiffTransform: LoggerMiddleware<InputActionType, StateType>.StateDiffTransform = .diff(),
stateDiffPrinter: LoggerMiddleware<InputActionType, StateType>.StateLogger = .osLog,
queue: DispatchQueue = .main
) -> LoggerMiddleware<IdentityMiddleware<InputActionType, OutputActionType, StateType>> {
) -> LoggerMiddleware<InputActionType, StateType> {
.init(
IdentityMiddleware(),
actionTransform: actionTransform,
actionPrinter: actionPrinter,
actionFilter: actionFilter,
Expand Down
95 changes: 47 additions & 48 deletions Tests/LoggerMiddlewareTests/LoggerMiddlewareTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,41 @@ struct Substate: Equatable {
public let z: Bool
}

struct TestMiddleware: Middleware {
func receiveContext(getState: @escaping GetState<TestState>, output: AnyActionHandler<Int>) {
struct TestMiddleware: MiddlewareProtocol {

func handle(action: Int, from dispatcher: ActionSource, state: @escaping GetState<TestState>) -> IO<Int> {
.pure()
}

func handle(action: Int, from dispatcher: ActionSource, afterReducer: inout AfterReducer) {
}


typealias InputActionType = Int
typealias OutputActionType = Int
typealias StateType = TestState
}

final class LoggerMiddlewareTests: XCTestCase {

func testStateDiff() {
// given
let beforeState: LoggerMiddleware<TestMiddleware>.StateType = TestState(a: Substate(x: ["SetB", "SetA"],
y1: ["one": 1, "eleven": 11],
y2: ["one": 1, "eleven": 11, "zapp": 42],
z: true),
b: [0, 1],
c: "Foo",
d: "",
e: nil)
let afterState: LoggerMiddleware<TestMiddleware>.StateType = TestState(a: Substate(x: ["SetB", "SetC"],
y1: ["one": 1, "twelve": 12],
y2: ["one": 1, "twelve": 12, "zapp": nil],
z: false),
b: [0],
c: "Bar",
d: nil,
e: "🥚")

let beforeState = TestState(a: Substate(x: ["SetB", "SetA"],
y1: ["one": 1, "eleven": 11],
y2: ["one": 1, "eleven": 11, "zapp": 42],
z: true),
b: [0, 1],
c: "Foo",
d: "",
e: nil)
let afterState = TestState(a: Substate(x: ["SetB", "SetC"],
y1: ["one": 1, "twelve": 12],
y2: ["one": 1, "twelve": 12, "zapp": nil],
z: false),
b: [0],
c: "Bar",
d: nil,
e: "🥚")
// when
let result: String? = LoggerMiddleware<TestMiddleware>.recursiveDiff(prefixLines: "🏛", stateName: "TestState", before: beforeState, after: afterState)

let result: String? = LoggerMiddleware<Int, TestState>.recursiveDiff(prefixLines: "🏛", stateName: "TestState", before: beforeState, after: afterState)
// then
let expected = """
🏛 TestState.a.x: 📦 <SetA, SetB> → <SetB, SetC>
Expand All @@ -66,37 +65,37 @@ final class LoggerMiddlewareTests: XCTestCase {
"""
XCTAssertEqual(result, expected)
}


func testStateDiffWithFilters() {
// given
let beforeState: LoggerMiddleware<TestMiddleware>.StateType = TestState(a: Substate(x: ["SetB", "SetA"],
y1: ["one": 1, "eleven": 11],
y2: ["one": 1, "eleven": 11, "zapp": 42],
z: true),
b: [0, 1],
c: "Foo",
d: "",
e: nil)
let afterState: LoggerMiddleware<TestMiddleware>.StateType = TestState(a: Substate(x: ["SetB", "SetC"],
y1: ["one": 1, "twelve": 12],
y2: ["one": 1, "twelve": 12, "zapp": nil],
z: false),
b: [0],
c: "Bar",
d: nil,
e: "🥚")

let beforeState = TestState(a: Substate(x: ["SetB", "SetA"],
y1: ["one": 1, "eleven": 11],
y2: ["one": 1, "eleven": 11, "zapp": 42],
z: true),
b: [0, 1],
c: "Foo",
d: "",
e: nil)
let afterState = TestState(a: Substate(x: ["SetB", "SetC"],
y1: ["one": 1, "twelve": 12],
y2: ["one": 1, "twelve": 12, "zapp": nil],
z: false),
b: [0],
c: "Bar",
d: nil,
e: "🥚")
// when
let result: String? = LoggerMiddleware<TestMiddleware>.recursiveDiff(prefixLines: "🏛",
let result: String? = LoggerMiddleware<Int, TestState>.recursiveDiff(prefixLines: "🏛",
stateName: "TestState",
filters: [
" TestState.a.y2",
" TestState.b.#"
],
before: beforeState,
after: afterState)

// then
let expected = """
🏛 TestState.a.x: 📦 <SetA, SetB> → <SetB, SetC>
Expand All @@ -108,7 +107,7 @@ final class LoggerMiddlewareTests: XCTestCase {
"""
XCTAssertEqual(result, expected)
}

static var allTests = [
("testStateDiff", testStateDiff),
]
Expand Down

0 comments on commit e2822a4

Please sign in to comment.