Skip to content

Commit

Permalink
feat: unite modified implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
danthorpe committed Aug 2, 2024
1 parent 242689e commit a1a4ef5
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 39 deletions.
58 changes: 21 additions & 37 deletions Sources/TestSupport/Mocked.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,40 @@ import Networking

extension NetworkingComponent {

public func mocked(
_ stub: StubbedResponseStream,
check: @escaping @Sendable (HTTPRequestData) -> Bool
) -> some NetworkingComponent {
mocked { check($0) ? stub : nil }
}

/// Mock a given request with a stub
public func mocked(
_ request: HTTPRequestData,
stub: StubbedResponseStream
) -> some NetworkingComponent {
mocked { $0 ~= request ? stub : nil }
mocked(stub) { $0 ~= request }
}

/// Mock the provided stub, after evaluating the request via the check
public func mocked(
_ stub: @escaping @Sendable (HTTPRequestData) -> StubbedResponseStream?
_ stub: StubbedResponseStream,
check: @escaping @Sendable (HTTPRequestData) -> Bool
) -> some NetworkingComponent {
modified(Mocked(mock: stub))
}
}

struct Mocked: NetworkingModifier {
let mock: @Sendable (HTTPRequestData) -> StubbedResponseStream?

@NetworkEnvironment(\.instrument) var instrument

init(mock: @escaping @Sendable (HTTPRequestData) -> StubbedResponseStream?) {
self.mock = mock
}

func resolve(upstream: some NetworkingComponent, request: HTTPRequestData) -> HTTPRequestData {
request // Note: We actually do not want to resolve the request to be mocked
mocked { check($0) ? stub : nil }
}

func send(upstream: some NetworkingComponent, request: HTTPRequestData) -> ResponseStream<
HTTPResponseData
> {
guard let stub = mock(request) else {
return upstream.send(request)
}
return ResponseStream { continuation in
Task {
await instrument?.measureElapsedTime("Mocked")
stub(request).redirect(into: continuation)
/// Evaluate the request, returning a stub to use for mocking, or nil to pass through without mocking
public func mocked(
_ mock: @escaping @Sendable (HTTPRequestData) -> StubbedResponseStream?
) -> some NetworkingComponent {
mocked { upstream, request in
ResponseStream { continuation in
Task {
if let stub = mock(request) {
stub(request).redirect(into: continuation)
} else {
upstream.send(request).redirect(into: continuation)
}
}
}
}
}
}

extension NetworkingComponent {
/// Create a fully custom mock, given the upstream component, and request, returning a response stream.
public func mocked(
_ block: @escaping @Sendable (NetworkingComponent, HTTPRequestData) async -> ResponseStream<
HTTPResponseData
Expand All @@ -61,7 +45,7 @@ extension NetworkingComponent {
}
}

struct CustomMocked: NetworkingModifier {
private struct CustomMocked: NetworkingModifier {
let block: @Sendable (NetworkingComponent, HTTPRequestData) async -> ResponseStream<HTTPResponseData>

func resolve(upstream: some NetworkingComponent, request: HTTPRequestData) -> HTTPRequestData {
Expand Down
4 changes: 2 additions & 2 deletions Tests/NetworkingTests/Components/MetricsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ final class MetricsTests: XCTestCase {
return
}

XCTAssertNoDifference(measurements.map(\.label), ["Delay", "Mocked"])
XCTAssertNoDifference(measurements.map(\.duration), [.zero, .seconds(3)])
XCTAssertNoDifference(measurements.map(\.label), ["Delay"])
XCTAssertNoDifference(measurements.map(\.duration), [.zero])
}
}
}

0 comments on commit a1a4ef5

Please sign in to comment.