diff --git a/.swift-format b/.swift-format index a7faa61..9a5cde0 100644 --- a/.swift-format +++ b/.swift-format @@ -1,6 +1,6 @@ { "version": 1, - "lineLength": 120, + "lineLength": 100000, "indentation": { "spaces": 4 }, diff --git a/Sources/Networking/CacheStore.swift b/Sources/Networking/CacheStore.swift index 3b394f3..f4a9346 100644 --- a/Sources/Networking/CacheStore.swift +++ b/Sources/Networking/CacheStore.swift @@ -37,9 +37,7 @@ final class CacheStore: @unchecked Sendable { let folderPath = "\(folderName)/\(Self.shardName(for: component))" let finalPath = "\(folderPath)/\(component)" - guard let url = URL(string: finalPath), - let cachesURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first - else { + guard let url = URL(string: finalPath), let cachesURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else { throw NSError( domain: folderName, code: 9999, @@ -126,8 +124,7 @@ final class CacheStore: @unchecked Sendable { memory.setObject(returnedObject as AnyObject, forKey: key as AnyObject) // Re-warm: bump the file's mtime so an entry in active use never expires. Only happens // on a memory miss, so it's ~once per entry per launch — no explicit debounce needed. - try? FileManager.default.setAttributes( - [.modificationDate: Date()], ofItemAtPath: destinationURL.path) + try? FileManager.default.setAttributes([.modificationDate: Date()], ofItemAtPath: destinationURL.path) } return returnedObject diff --git a/Sources/Networking/FakeRequest.swift b/Sources/Networking/FakeRequest.swift index 0b33d39..0879166 100644 --- a/Sources/Networking/FakeRequest.swift +++ b/Sources/Networking/FakeRequest.swift @@ -39,9 +39,7 @@ struct FakeRequest { let lookupPathParts = evaluatedPath.components(separatedBy: "/") for (originalFakedPath, fakeRequest) in requests { - guard let replacedValues = captures(from: originalFakedPath, matching: lookupPathParts), - originalFakedPath.replacing(replacedValues) == path - else { continue } + guard let replacedValues = captures(from: originalFakedPath, matching: lookupPathParts), originalFakedPath.replacing(replacedValues) == path else { continue } guard case .data(let data) = fakeRequest.payload, let responseString = String(data: data, encoding: .utf8) else { continue } diff --git a/Sources/Networking/HTTPInterceptor.swift b/Sources/Networking/HTTPInterceptor.swift index f9caea3..1c80a7b 100644 --- a/Sources/Networking/HTTPInterceptor.swift +++ b/Sources/Networking/HTTPInterceptor.swift @@ -15,10 +15,7 @@ public struct HTTPExchange: Sendable { /// A composable hook wrapping every verb request. `next` runs the rest of the chain (innermost is the real /// network call); calling it again replays the request — the basis for retry and auth-refresh. public protocol HTTPInterceptor: Sendable { - func intercept( - _ request: URLRequest, - next: @Sendable (URLRequest) async throws -> HTTPExchange - ) async throws + func intercept(_ request: URLRequest, next: @Sendable (URLRequest) async throws -> HTTPExchange) async throws -> HTTPExchange } @@ -40,10 +37,7 @@ public struct AuthRefreshInterceptor: HTTPInterceptor { self.coordinator = RefreshCoordinator(refresh) } - public func intercept( - _ request: URLRequest, - next: @Sendable (URLRequest) async throws -> HTTPExchange - ) async throws -> HTTPExchange { + public func intercept(_ request: URLRequest, next: @Sendable (URLRequest) async throws -> HTTPExchange) async throws -> HTTPExchange { let exchange = try await next(request) guard triggeringStatusCodes.contains(exchange.response.statusCode) else { return exchange } guard let refreshedValue = try await coordinator.refreshOnce() else { return exchange } @@ -81,10 +75,7 @@ public struct RetryInterceptor: HTTPInterceptor { self.retryableMethods = Set(retryableMethods.map { $0.uppercased() }) } - public func intercept( - _ request: URLRequest, - next: @Sendable (URLRequest) async throws -> HTTPExchange - ) async throws -> HTTPExchange { + public func intercept(_ request: URLRequest, next: @Sendable (URLRequest) async throws -> HTTPExchange) async throws -> HTTPExchange { let methodAllowsRetry = retryableMethods.contains((request.httpMethod ?? "GET").uppercased()) var attempt = 1 while true { @@ -115,9 +106,7 @@ public struct RetryInterceptor: HTTPInterceptor { // Retry-After is either a count of seconds or an HTTP-date (RFC 9110). static func retryAfterDelay(from response: HTTPURLResponse) -> Duration? { - guard let value = response.value(forHTTPHeaderField: "Retry-After")?.trimmingCharacters(in: .whitespaces), - !value.isEmpty - else { return nil } + guard let value = response.value(forHTTPHeaderField: "Retry-After")?.trimmingCharacters(in: .whitespaces), !value.isEmpty else { return nil } if let seconds = Int(value) { return .seconds(max(0, seconds)) } @@ -145,18 +134,14 @@ public struct ResponseValidatorInterceptor: HTTPInterceptor { self.validate = validate } - public func intercept( - _ request: URLRequest, - next: @Sendable (URLRequest) async throws -> HTTPExchange - ) async throws -> HTTPExchange { + public func intercept(_ request: URLRequest, next: @Sendable (URLRequest) async throws -> HTTPExchange) async throws -> HTTPExchange { let exchange = try await next(request) guard (200..<300).contains(exchange.response.statusCode) else { return exchange } switch validate(exchange) { case .valid: return exchange case .invalid(let reason): - throw NetworkingError.validation( - reason: reason, ResponseMetadata(response: exchange.response, body: exchange.data)) + throw NetworkingError.validation(reason: reason, ResponseMetadata(response: exchange.response, body: exchange.data)) } } } diff --git a/Sources/Networking/Helpers.swift b/Sources/Networking/Helpers.swift index d2bbad6..30702c7 100644 --- a/Sources/Networking/Helpers.swift +++ b/Sources/Networking/Helpers.swift @@ -25,9 +25,7 @@ extension Dictionary where Key: ExpressibleByStringLiteral { public func urlEncodedString() throws -> String { let pairs = try reduce([]) { current, keyValuePair -> [String] in - if let encodedValue = "\(keyValuePair.value)".addingPercentEncoding( - withAllowedCharacters: .urlQueryParametersAllowed) - { + if let encodedValue = "\(keyValuePair.value)".addingPercentEncoding(withAllowedCharacters: .urlQueryParametersAllowed) { return current + ["\(keyValuePair.key)=\(encodedValue)"] } else { throw NSError( diff --git a/Sources/Networking/JSONResponse.swift b/Sources/Networking/JSONResponse.swift index 9fb8dd5..8914a3b 100644 --- a/Sources/Networking/JSONResponse.swift +++ b/Sources/Networking/JSONResponse.swift @@ -33,8 +33,7 @@ public struct AnyCodable: Decodable, @unchecked Sendable { } else if let value = try? container.decode([AnyCodable].self) { self.value = value } else { - throw DecodingError.dataCorruptedError( - in: container, debugDescription: "The container contains nothing serializable") + throw DecodingError.dataCorruptedError(in: container, debugDescription: "The container contains nothing serializable") } } diff --git a/Sources/Networking/Networking+New.swift b/Sources/Networking/Networking+New.swift index fd567de..d1c9304 100644 --- a/Sources/Networking/Networking+New.swift +++ b/Sources/Networking/Networking+New.swift @@ -98,8 +98,7 @@ extension Networking { ) { // Run the cache hit back out through the interceptor chain so validators apply to it too. - let exchange = try await perform( - request, cached: HTTPExchange(data: cached.body, response: cachedResponse)) + let exchange = try await perform(request, cached: HTTPExchange(data: cached.body, response: cachedResponse)) result = handleResponse( responseData: exchange.data, response: exchange.response, @@ -490,8 +489,7 @@ extension Networking { case .cancelled: return .failure(.cancelled) case .redirection, .clientError, .serverError, .unknown: - let error = HTTPError( - statusCode: statusCode, metadata: ResponseMetadata(response: httpResponse, body: responseData)) + let error = HTTPError(statusCode: statusCode, metadata: ResponseMetadata(response: httpResponse, body: responseData)) return .failure(.http(error)) } } diff --git a/Sources/Networking/Networking.swift b/Sources/Networking/Networking.swift index c2646cb..99301bf 100644 --- a/Sources/Networking/Networking.swift +++ b/Sources/Networking/Networking.swift @@ -73,8 +73,7 @@ public actor Networking { /// A stream of observability events — one `.started` then one `.completed` per request. Each call /// returns its own multicast stream; the buffer keeps the newest 256 events for a slow consumer. public func events() -> AsyncStream { - let (stream, continuation) = AsyncStream.makeStream( - of: NetworkingEvent.self, bufferingPolicy: .bufferingNewest(256)) + let (stream, continuation) = AsyncStream.makeStream(of: NetworkingEvent.self, bufferingPolicy: .bufferingNewest(256)) let id = UUID() streamContinuations[id] = continuation continuation.onTermination = { [weak self] _ in @@ -208,8 +207,7 @@ public actor Networking { folderName: Networking.domain ) self.logger = logger ?? Networking.defaultLogger - self.logFileURL = ProcessInfo.processInfo.environment["NETWORKING_LOG_FILE"].flatMap( - Networking.resolveLogFileURL) + self.logFileURL = ProcessInfo.processInfo.environment["NETWORKING_LOG_FILE"].flatMap(Networking.resolveLogFileURL) // Sweep aged-out files off the request path so the disk cache can't grow without bound (one shard // per launch — see `CacheStore.sweepExpired`). let store = self.cacheStore diff --git a/Tests/NetworkingTests/CacheStoreTests.swift b/Tests/NetworkingTests/CacheStoreTests.swift index 576049b..6e8c0d6 100644 --- a/Tests/NetworkingTests/CacheStoreTests.swift +++ b/Tests/NetworkingTests/CacheStoreTests.swift @@ -63,8 +63,7 @@ final class CacheStoreTests: XCTestCase { let url = try store.destinationURL(forResource: resource) memory.removeObject(forKey: url.absoluteString as AnyObject) // force the disk path - try FileManager.default.setAttributes( - [.modificationDate: Date(timeIntervalSinceNow: -120)], ofItemAtPath: url.path) + try FileManager.default.setAttributes([.modificationDate: Date(timeIntervalSinceNow: -120)], ofItemAtPath: url.path) XCTAssertNil( try store.object( @@ -88,8 +87,7 @@ final class CacheStoreTests: XCTestCase { let url = try store.destinationURL(forResource: resource) memory.removeObject(forKey: url.absoluteString as AnyObject) // force the disk path - try FileManager.default.setAttributes( - [.modificationDate: Date(timeIntervalSinceNow: -30)], ofItemAtPath: url.path) + try FileManager.default.setAttributes([.modificationDate: Date(timeIntervalSinceNow: -30)], ofItemAtPath: url.path) XCTAssertNotNil( try store.object( diff --git a/Tests/NetworkingTests/CacheWriteAndDataBodyRegressionTests.swift b/Tests/NetworkingTests/CacheWriteAndDataBodyRegressionTests.swift index e9baf14..fdbe32d 100644 --- a/Tests/NetworkingTests/CacheWriteAndDataBodyRegressionTests.swift +++ b/Tests/NetworkingTests/CacheWriteAndDataBodyRegressionTests.swift @@ -29,9 +29,7 @@ final class CacheWriteAndDataBodyRegressionTests: XCTestCase { guard case .success = result else { return XCTFail("expected a successful download, got \(result)") } let orphanURL = try networking.destinationURL(for: path, cacheName: nil) - XCTAssertFalse( - FileManager.default.exists(at: orphanURL), - "downloadData wrote a stray cache file under the path key that no read path uses") + XCTAssertFalse(FileManager.default.exists(at: orphanURL), "downloadData wrote a stray cache file under the path key that no read path uses") } // The `.memory`/`.none` pure-read contracts (a read must not destroy a durable `.memoryAndFile` copy) diff --git a/Tests/NetworkingTests/DELETEIntegrationTests.swift b/Tests/NetworkingTests/DELETEIntegrationTests.swift index 742210f..ad3e1fc 100644 --- a/Tests/NetworkingTests/DELETEIntegrationTests.swift +++ b/Tests/NetworkingTests/DELETEIntegrationTests.swift @@ -46,8 +46,7 @@ final class DELETEIntegrationTests: XCTestCase { func testDELETEWithURLEncodedParameters() async throws { let networking = Networking(baseURL: baseURL) - let result: Result = await networking.delete( - "/delete", query: [URLQueryItem(name: "userId", value: "25")]) + let result: Result = await networking.delete("/delete", query: [URLQueryItem(name: "userId", value: "25")]) switch result { case .success(let response): XCTAssertEqual(response.body.string(for: "url"), "\(TestConfig.httpbinBaseURL)/delete?userId=25") diff --git a/Tests/NetworkingTests/DownloadEventsIntegrationTests.swift b/Tests/NetworkingTests/DownloadEventsIntegrationTests.swift index 0611ed4..85f29d5 100644 --- a/Tests/NetworkingTests/DownloadEventsIntegrationTests.swift +++ b/Tests/NetworkingTests/DownloadEventsIntegrationTests.swift @@ -21,9 +21,7 @@ final class DownloadEventsIntegrationTests: XCTestCase { 2, "downloadImage should emit .started and .completed; got \(events)" ) - guard case .started(let startContext) = events.first, - case .completed(let endContext, let outcome, _, _) = events.last - else { + guard case .started(let startContext) = events.first, case .completed(let endContext, let outcome, _, _) = events.last else { return XCTFail("expected .started then .completed, got \(events)") } XCTAssertEqual(startContext.id, endContext.id) diff --git a/Tests/NetworkingTests/DownloadInterceptorIntegrationTests.swift b/Tests/NetworkingTests/DownloadInterceptorIntegrationTests.swift index e20871b..c025a90 100644 --- a/Tests/NetworkingTests/DownloadInterceptorIntegrationTests.swift +++ b/Tests/NetworkingTests/DownloadInterceptorIntegrationTests.swift @@ -17,10 +17,7 @@ final class DownloadInterceptorIntegrationTests: XCTestCase { private struct CountingPassthroughInterceptor: HTTPInterceptor { let counter: Counter - func intercept( - _ request: URLRequest, - next: @Sendable (URLRequest) async throws -> HTTPExchange - ) async throws -> HTTPExchange { + func intercept(_ request: URLRequest, next: @Sendable (URLRequest) async throws -> HTTPExchange) async throws -> HTTPExchange { await counter.tick() return try await next(request) } diff --git a/Tests/NetworkingTests/FakeRequestTests.swift b/Tests/NetworkingTests/FakeRequestTests.swift index 83a5087..227d0e7 100644 --- a/Tests/NetworkingTests/FakeRequestTests.swift +++ b/Tests/NetworkingTests/FakeRequestTests.swift @@ -446,8 +446,7 @@ extension FakeRequestTests { await networking.fakePOST("/story", response: [["name": "Elvis"]]) - let result: Result<[[String: AnyCodable]], NetworkingError> = await networking.post( - "/story", body: ["username": "jameson", "password": "secret"]) + let result: Result<[[String: AnyCodable]], NetworkingError> = await networking.post("/story", body: ["username": "jameson", "password": "secret"]) switch result { case .success(let stories): XCTAssertEqual(stories.first?.string(for: "name"), "Elvis") @@ -536,8 +535,7 @@ extension FakeRequestTests { await networking.fakePUT("/story", response: [["name": "Elvis"]]) - let result: Result<[[String: AnyCodable]], NetworkingError> = await networking.put( - "/story", body: ["username": "jameson", "password": "secret"]) + let result: Result<[[String: AnyCodable]], NetworkingError> = await networking.put("/story", body: ["username": "jameson", "password": "secret"]) switch result { case .success(let stories): XCTAssertEqual(stories.first?.string(for: "name"), "Elvis") @@ -603,8 +601,7 @@ extension FakeRequestTests { await networking.fakePATCH("/story", response: [["name": "Elvis"]]) - let result: Result<[[String: AnyCodable]], NetworkingError> = await networking.patch( - "/story", body: ["username": "jameson", "password": "secret"]) + let result: Result<[[String: AnyCodable]], NetworkingError> = await networking.patch("/story", body: ["username": "jameson", "password": "secret"]) switch result { case .success(let stories): XCTAssertEqual(stories.first?.string(for: "name"), "Elvis") @@ -856,8 +853,7 @@ extension FakeRequestTests { "confirmation_code": "confirmationCode" ] - let result: Result = await networking.post( - "/auth/verify_confirmation_code", body: parameters) + let result: Result = await networking.post("/auth/verify_confirmation_code", body: parameters) switch result { case .success(let response): let headers = response.headers diff --git a/Tests/NetworkingTests/FileLoggingIntegrationTests.swift b/Tests/NetworkingTests/FileLoggingIntegrationTests.swift index 8006829..e0dbc22 100644 --- a/Tests/NetworkingTests/FileLoggingIntegrationTests.swift +++ b/Tests/NetworkingTests/FileLoggingIntegrationTests.swift @@ -7,8 +7,7 @@ final class FileLoggingIntegrationTests: XCTestCase { // The diagnostics file sink lets a CLI / headless / agent run read what happened, since os.Logger // isn't visible in stdout. (The NETWORKING_LOG_FILE env var sets the same `logFileURL` at init.) func testDiagnosticsAreWrittenToConfiguredFile() async throws { - let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent( - "networking-\(UUID().uuidString).log") + let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("networking-\(UUID().uuidString).log") defer { try? FileManager.default.removeItem(at: url) } let networking = Networking(baseURL: TestConfig.httpbinBaseURL) @@ -20,18 +19,14 @@ final class FileLoggingIntegrationTests: XCTestCase { let contents = (try? String(contentsOf: url, encoding: .utf8)) ?? "" XCTAssertFalse(contents.contains("/get "), "successful requests must not be logged; got:\n\(contents)") XCTAssertTrue(contents.contains("✗ GET"), "expected a failure line; got:\n\(contents)") - XCTAssertTrue( - contents.contains("failed: The server returned status 404"), - "expected the failure detail; got:\n\(contents)") + XCTAssertTrue(contents.contains("failed: The server returned status 404"), "expected the failure detail; got:\n\(contents)") } // NETWORKING_LOG_FILE resolution: a bare name lands in Caches (sandbox-safe for an app); a path is used as-is. func testLogFileEnvValueResolution() { let bare = Networking.resolveLogFileURL("networking.log") XCTAssertEqual(bare?.lastPathComponent, "networking.log") - XCTAssertTrue( - bare?.path.contains("Caches") ?? false, - "a bare name should resolve under Caches; got \(String(describing: bare?.path))") + XCTAssertTrue(bare?.path.contains("Caches") ?? false, "a bare name should resolve under Caches; got \(String(describing: bare?.path))") XCTAssertEqual(Networking.resolveLogFileURL("/tmp/explicit.log")?.path, "/tmp/explicit.log") XCTAssertNil(Networking.resolveLogFileURL("")) diff --git a/Tests/NetworkingTests/GETIntegrationTests.swift b/Tests/NetworkingTests/GETIntegrationTests.swift index bbc518c..ef10788 100644 --- a/Tests/NetworkingTests/GETIntegrationTests.swift +++ b/Tests/NetworkingTests/GETIntegrationTests.swift @@ -82,8 +82,7 @@ final class GETIntegrationTests: XCTestCase { func testGETWithURLEncodedParameters() async throws { let networking = Networking(baseURL: baseURL) - let result: Result = await networking.get( - "/get", query: [URLQueryItem(name: "count", value: "25")]) + let result: Result = await networking.get("/get", query: [URLQueryItem(name: "count", value: "25")]) switch result { case .success(let response): XCTAssertEqual(response.body.string(for: "url"), "\(TestConfig.httpbinBaseURL)/get?count=25") @@ -94,8 +93,7 @@ final class GETIntegrationTests: XCTestCase { func testGETWithURLEncodedParametersWithExistingQuery() async throws { let networking = Networking(baseURL: baseURL) - let result: Result = await networking.get( - "/get?accountId=123", query: [URLQueryItem(name: "userId", value: "5")]) + let result: Result = await networking.get("/get?accountId=123", query: [URLQueryItem(name: "userId", value: "5")]) switch result { case .success(let response): XCTAssertEqual(response.body.string(for: "url"), "\(TestConfig.httpbinBaseURL)/get?accountId=123&userId=5") @@ -106,8 +104,7 @@ final class GETIntegrationTests: XCTestCase { func testGETWithURLEncodedParametersWithPercentEncoding() async throws { let networking = Networking(baseURL: baseURL) - let result: Result = await networking.get( - "/get", query: [URLQueryItem(name: "name", value: "Elvis Nuñez")]) + let result: Result = await networking.get("/get", query: [URLQueryItem(name: "name", value: "Elvis Nuñez")]) switch result { case .success(let response): XCTAssertEqual(response.body.string(for: "url"), "\(TestConfig.httpbinBaseURL)/get?name=Elvis%20Nu%C3%B1ez") @@ -146,8 +143,7 @@ final class GETIntegrationTests: XCTestCase { let primed: Result = await networking.get("/uuid", cachingLevel: .memoryAndFile) let _: Result = await networking.get("/uuid", cachingLevel: .none) - let afterwards: Result = await networking.get( - "/uuid", cachingLevel: .memoryAndFile) + let afterwards: Result = await networking.get("/uuid", cachingLevel: .memoryAndFile) guard case .success(let primedResponse) = primed, case .success(let afterwardsResponse) = afterwards else { return XCTFail("expected both cached requests to succeed") @@ -206,9 +202,7 @@ final class GETIntegrationTests: XCTestCase { } let url = secondResponse.body.string(for: "url") ?? "" XCTAssertFalse(url.contains("%26"), "the second request must not be served the first request's cached body") - XCTAssertTrue( - url.contains("a=1") && url.contains("b=2"), - "the second request must reflect its own parameters, got: \(url)") + XCTAssertTrue(url.contains("a=1") && url.contains("b=2"), "the second request must reflect its own parameters, got: \(url)") } // Full-URL GETs to different hosts but the same path must not collide. A key built from only @@ -237,9 +231,7 @@ final class GETIntegrationTests: XCTestCase { return XCTFail("expected the second request to succeed") } let url = secondResponse.body.string(for: "url") ?? "" - XCTAssertTrue( - url.contains(aliasHost), - "a request to a different host must not receive the first host's cached body, got: \(url)") + XCTAssertTrue(url.contains(aliasHost), "a request to a different host must not receive the first host's cached body, got: \(url)") } // A cache hit must carry the original response's status code and headers, not fabricated ones. diff --git a/Tests/NetworkingTests/GETTests.swift b/Tests/NetworkingTests/GETTests.swift index cc26629..67ba746 100644 --- a/Tests/NetworkingTests/GETTests.swift +++ b/Tests/NetworkingTests/GETTests.swift @@ -46,8 +46,7 @@ final class GETTests: XCTestCase { cache: cache ) await networking.fakeGET("/get", response: ["key": "value1"]) - let firstResult: Result = await networking.get( - "/get", cachingLevel: .memoryAndFile) + let firstResult: Result = await networking.get("/get", cachingLevel: .memoryAndFile) switch firstResult { case .success(let response): XCTAssertEqual(response.body.string(for: "key"), "value1") @@ -56,8 +55,7 @@ final class GETTests: XCTestCase { } await networking.fakeGET("/get", response: ["key": "value2"]) - let secondResult: Result = await networking.get( - "/get", cachingLevel: .memoryAndFile) + let secondResult: Result = await networking.get("/get", cachingLevel: .memoryAndFile) switch secondResult { case .success(let response): XCTAssertEqual(response.body.string(for: "key"), "value2") diff --git a/Tests/NetworkingTests/LogLevelIntegrationTests.swift b/Tests/NetworkingTests/LogLevelIntegrationTests.swift index 31910d1..98940f9 100644 --- a/Tests/NetworkingTests/LogLevelIntegrationTests.swift +++ b/Tests/NetworkingTests/LogLevelIntegrationTests.swift @@ -9,8 +9,7 @@ final class LogLevelIntegrationTests: XCTestCase { let baseURL = TestConfig.httpbinBaseURL private func log(level: Networking.LogLevel, _ body: (Networking) async -> Void) async -> String { - let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent( - "networking-\(UUID().uuidString).log") + let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("networking-\(UUID().uuidString).log") defer { try? FileManager.default.removeItem(at: url) } let networking = Networking(baseURL: baseURL) await networking.setLogFileURL(url) @@ -28,13 +27,11 @@ final class LogLevelIntegrationTests: XCTestCase { func testFailuresLevelLogsFailureWithFullDetail() async { let contents = await log(level: .failures) { networking in - let _: Result = await networking.post( - "/status/400", body: ["shape": "wrong"]) + let _: Result = await networking.post("/status/400", body: ["shape": "wrong"]) } XCTAssertTrue(contents.contains("✗ POST"), "expected the failure line; got:\n\(contents)") XCTAssertTrue(contents.contains("→ Content-Type"), "expected request headers; got:\n\(contents)") - XCTAssertTrue( - contents.contains("→ body:") && contents.contains("shape"), "expected the request body; got:\n\(contents)") + XCTAssertTrue(contents.contains("→ body:") && contents.contains("shape"), "expected the request body; got:\n\(contents)") XCTAssertTrue(contents.contains("← Content-Type"), "expected response headers; got:\n\(contents)") } @@ -43,8 +40,7 @@ final class LogLevelIntegrationTests: XCTestCase { let _: Result = await networking.post("/post", body: ["shape": "right"]) } XCTAssertTrue(contents.contains("✓ POST"), "expected a success line at .all; got:\n\(contents)") - XCTAssertTrue( - contents.contains("→ body:") && contents.contains("shape"), "expected the request body; got:\n\(contents)") + XCTAssertTrue(contents.contains("→ body:") && contents.contains("shape"), "expected the request body; got:\n\(contents)") XCTAssertTrue(contents.contains("← body:"), "expected the response body; got:\n\(contents)") } @@ -52,8 +48,7 @@ final class LogLevelIntegrationTests: XCTestCase { // the line still logs, but the payload and Authorization/Cookie values are replaced with so // they can't leak to prod logs. func testBodiesAndHeadersRedactedWhenEnabled() async { - let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent( - "networking-\(UUID().uuidString).log") + let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("networking-\(UUID().uuidString).log") defer { try? FileManager.default.removeItem(at: url) } let networking = Networking(baseURL: baseURL) await networking.setLogFileURL(url) @@ -61,14 +56,12 @@ final class LogLevelIntegrationTests: XCTestCase { await networking.setRedactsLogs(true) await networking.setAuthorizationHeader(token: "supersecret") - let _: Result = await networking.post( - "/status/400", body: ["shape": "secret-value"]) + let _: Result = await networking.post("/status/400", body: ["shape": "secret-value"]) let contents = (try? String(contentsOf: url, encoding: .utf8)) ?? "" XCTAssertTrue(contents.contains("✗ POST"), "the failure line should still log; got:\n\(contents)") XCTAssertTrue(contents.contains("→ body: "), "the request body should be redacted; got:\n\(contents)") - XCTAssertTrue( - contents.contains("→ Authorization: "), "the auth header should be redacted; got:\n\(contents)") + XCTAssertTrue(contents.contains("→ Authorization: "), "the auth header should be redacted; got:\n\(contents)") XCTAssertFalse(contents.contains("secret-value"), "the body contents must not leak; got:\n\(contents)") XCTAssertFalse(contents.contains("supersecret"), "the auth token must not leak; got:\n\(contents)") } @@ -80,9 +73,7 @@ final class LogLevelIntegrationTests: XCTestCase { await networking.setAuthorizationHeader(token: "supersecret") let _: Result = await networking.get("/status/401") } - XCTAssertTrue( - contents.contains("→ Authorization: Bearer supersecret"), - "debug logs should show the real header; got:\n\(contents)") + XCTAssertTrue(contents.contains("→ Authorization: Bearer supersecret"), "debug logs should show the real header; got:\n\(contents)") } func testNoneSilencesEvenFailures() async { diff --git a/Tests/NetworkingTests/NetworkingTests.swift b/Tests/NetworkingTests/NetworkingTests.swift index a39060c..02a3a4f 100644 --- a/Tests/NetworkingTests/NetworkingTests.swift +++ b/Tests/NetworkingTests/NetworkingTests.swift @@ -119,14 +119,11 @@ final class NetworkingTests: XCTestCase { } func testSplitBaseURLAndRelativePath() throws { - let (baseURL1, relativePath1) = try XCTUnwrap( - Networking.splitBaseURLAndRelativePath( - for: "https://rescuejuice.com/wp-content/uploads/2015/11/døgnvillburgere.jpg")) + let (baseURL1, relativePath1) = try XCTUnwrap(Networking.splitBaseURLAndRelativePath(for: "https://rescuejuice.com/wp-content/uploads/2015/11/døgnvillburgere.jpg")) XCTAssertEqual(baseURL1, "https://rescuejuice.com") XCTAssertEqual(relativePath1, "/wp-content/uploads/2015/11/døgnvillburgere.jpg") - let (baseURL2, relativePath2) = try XCTUnwrap( - Networking.splitBaseURLAndRelativePath(for: "http://example.com/basic-auth/user/passwd")) + let (baseURL2, relativePath2) = try XCTUnwrap(Networking.splitBaseURLAndRelativePath(for: "http://example.com/basic-auth/user/passwd")) XCTAssertEqual(baseURL2, "http://example.com") XCTAssertEqual(relativePath2, "/basic-auth/user/passwd") } diff --git a/Tests/NetworkingTests/ObservabilityIntegrationTests.swift b/Tests/NetworkingTests/ObservabilityIntegrationTests.swift index 29c9c5a..88ef440 100644 --- a/Tests/NetworkingTests/ObservabilityIntegrationTests.swift +++ b/Tests/NetworkingTests/ObservabilityIntegrationTests.swift @@ -18,9 +18,7 @@ final class ObservabilityIntegrationTests: XCTestCase { 2, "expected a .started and a .completed event" ) - guard case .started(let startContext) = events.first, - case .completed(let endContext, let outcome, let duration, let metrics) = events.last - else { + guard case .started(let startContext) = events.first, case .completed(let endContext, let outcome, let duration, let metrics) = events.last else { return XCTFail("expected .started then .completed, got \(events)") } XCTAssertEqual( @@ -92,9 +90,7 @@ final class ObservabilityIntegrationTests: XCTestCase { 2, "an encode failure must still emit .started and .completed; got \(events)" ) - guard case .started(let startContext) = events.first, - case .completed(let endContext, let outcome, _, _) = events.last - else { + guard case .started(let startContext) = events.first, case .completed(let endContext, let outcome, _, _) = events.last else { return XCTFail("expected .started then .completed, got \(events)") } XCTAssertEqual( diff --git a/Tests/NetworkingTests/PATCHIntegrationTests.swift b/Tests/NetworkingTests/PATCHIntegrationTests.swift index 5f84839..cb2df41 100644 --- a/Tests/NetworkingTests/PATCHIntegrationTests.swift +++ b/Tests/NetworkingTests/PATCHIntegrationTests.swift @@ -8,8 +8,7 @@ final class PATCHIntegrationTests: XCTestCase { func testPATCH() async throws { let networking = Networking(baseURL: baseURL) - let result: Result = await networking.patch( - "/patch", body: ["username": "jameson", "password": "secret"]) + let result: Result = await networking.patch("/patch", body: ["username": "jameson", "password": "secret"]) switch result { case .success(let response): let json = httpbinEchoedMap(response, "json") @@ -37,8 +36,7 @@ final class PATCHIntegrationTests: XCTestCase { func testPATCHWithIvalidPath() async throws { let networking = Networking(baseURL: baseURL) - let result: Result = await networking.patch( - "/posdddddt", body: ["username": "jameson", "password": "secret"]) + let result: Result = await networking.patch("/posdddddt", body: ["username": "jameson", "password": "secret"]) switch result { case .success: XCTFail("a PATCH to a path that does not exist must fail") diff --git a/Tests/NetworkingTests/POSTIntegrationTests.swift b/Tests/NetworkingTests/POSTIntegrationTests.swift index 8053f2a..7f0ea65 100644 --- a/Tests/NetworkingTests/POSTIntegrationTests.swift +++ b/Tests/NetworkingTests/POSTIntegrationTests.swift @@ -213,8 +213,7 @@ final class POSTIntegrationTests: XCTestCase { func testPOSTWithIvalidPath() async throws { let networking = Networking(baseURL: baseURL) - let result: Result = await networking.post( - "/posdddddt", body: ["username": "jameson", "password": "secret"]) + let result: Result = await networking.post("/posdddddt", body: ["username": "jameson", "password": "secret"]) switch result { case .success: XCTFail("a POST to a path that does not exist must fail") diff --git a/Tests/NetworkingTests/PUTIntegrationTests.swift b/Tests/NetworkingTests/PUTIntegrationTests.swift index 8110f7a..440e2d4 100644 --- a/Tests/NetworkingTests/PUTIntegrationTests.swift +++ b/Tests/NetworkingTests/PUTIntegrationTests.swift @@ -8,8 +8,7 @@ final class PUTIntegrationTests: XCTestCase { func testPUT() async throws { let networking = Networking(baseURL: baseURL) - let result: Result = await networking.put( - "/put", body: ["username": "jameson", "password": "secret"]) + let result: Result = await networking.put("/put", body: ["username": "jameson", "password": "secret"]) switch result { case .success(let response): let json = httpbinEchoedMap(response, "json") @@ -37,8 +36,7 @@ final class PUTIntegrationTests: XCTestCase { func testPUTWithIvalidPath() async throws { let networking = Networking(baseURL: baseURL) - let result: Result = await networking.put( - "/posdddddt", body: ["username": "jameson", "password": "secret"]) + let result: Result = await networking.put("/posdddddt", body: ["username": "jameson", "password": "secret"]) switch result { case .success: XCTFail("a PUT to a path that does not exist must fail") diff --git a/Tests/NetworkingTests/RetryInterceptorTests.swift b/Tests/NetworkingTests/RetryInterceptorTests.swift index 1d62d8b..0efd84a 100644 --- a/Tests/NetworkingTests/RetryInterceptorTests.swift +++ b/Tests/NetworkingTests/RetryInterceptorTests.swift @@ -27,10 +27,7 @@ final class RetryInterceptorTests: XCTestCase { let counter: CallCounter let outcomeForAttempt: @Sendable (Int) -> ScriptedOutcome - func intercept( - _ request: URLRequest, - next: @Sendable (URLRequest) async throws -> HTTPExchange - ) async throws -> HTTPExchange { + func intercept(_ request: URLRequest, next: @Sendable (URLRequest) async throws -> HTTPExchange) async throws -> HTTPExchange { let attempt = await counter.tick() switch outcomeForAttempt(attempt) { case .status(let code, let headers):