From 6990d5c2d52cd36d7c3c957d3d8f7eedcdde0212 Mon Sep 17 00:00:00 2001 From: Pierluigi Cifani Date: Thu, 10 Mar 2022 18:25:41 +0100 Subject: [PATCH 1/3] Remove Deferred --- Package.resolved | 9 - Package.swift | 4 +- .../Deferred/Deferred+Customizations.swift | 204 ------------------ .../APIClient/APIClientErrorTests.swift | 6 + .../APIClient/APIClientTests.swift | 54 ++--- .../Extensions/DeferredTests.swift | 12 -- .../Parsing/JSONParserTests.swift | 16 +- Tests/BSWFoundationTests/XCTestCase.swift | 34 --- 8 files changed, 28 insertions(+), 311 deletions(-) delete mode 100644 Sources/BSWFoundation/Deferred/Deferred+Customizations.swift delete mode 100644 Tests/BSWFoundationTests/Extensions/DeferredTests.swift delete mode 100644 Tests/BSWFoundationTests/XCTestCase.swift diff --git a/Package.resolved b/Package.resolved index a3c861d..344c54f 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,15 +1,6 @@ { "object": { "pins": [ - { - "package": "Deferred", - "repositoryURL": "https://github.com/theleftbit/Deferred.git", - "state": { - "branch": null, - "revision": "8d601f0597135179a4b2f72b99fd196e6067dabe", - "version": "4.2.1" - } - }, { "package": "KeychainAccess", "repositoryURL": "https://github.com/kishikawakatsumi/KeychainAccess.git", diff --git a/Package.swift b/Package.swift index 54f2750..5d5a8bb 100644 --- a/Package.swift +++ b/Package.swift @@ -14,18 +14,16 @@ let package = Package( products: [ .library( name: "BSWFoundation", - type: .dynamic, targets: ["BSWFoundation"] ), ], dependencies: [ - .package(url: "https://github.com/theleftbit/Deferred.git", from: "4.2.0"), .package(url: "https://github.com/kishikawakatsumi/KeychainAccess.git", from: "4.2.0"), ], targets: [ .target( name: "BSWFoundation", - dependencies: ["Deferred", "KeychainAccess"] + dependencies: ["KeychainAccess"] ), .testTarget( name: "BSWFoundationTests", diff --git a/Sources/BSWFoundation/Deferred/Deferred+Customizations.swift b/Sources/BSWFoundation/Deferred/Deferred+Customizations.swift deleted file mode 100644 index 1bf9abf..0000000 --- a/Sources/BSWFoundation/Deferred/Deferred+Customizations.swift +++ /dev/null @@ -1,204 +0,0 @@ -// -// Result+Deferred.swift -// Created by Pierluigi Cifani on 20/04/16. -// - -import Task; import Deferred -import Foundation - -//MARK: Legacy APIs using Deferred - -extension APIClient { - public func perform(_ request: Request) -> Task { - Task.fromSwiftConcurrency { try await self.perform(request) } - } - - public func performSimpleRequest(forEndpoint endpoint: Endpoint) -> Task { - Task.fromSwiftConcurrency { try await self.performSimpleRequest(forEndpoint: endpoint )} - } -} - -import CoreLocation - -public extension LocationFetcher { - func fetchCurrentLocation(_ useCachedLocationIfAvailable: Bool = true) -> Task { - Task.fromSwiftConcurrency { try await self.fetchCurrentLocation(useCachedLocationIfAvailable) } - } -} - -extension JSONParser { - public static func parseData(_ data: Data) -> Task { - Task.fromSwiftConcurrency { try self.parseData(data) } - } -} - -//MARK: Public - -public func both(first: Task, second: Task) -> Task<(T, U)> { - - let deferred = Deferred.Result>() - first.and(second).upon { (tuple) in - guard let firstValue = tuple.0.value else { - deferred.fill(with: .failure(tuple.0.error!)) - return - } - - guard let secondValue = tuple.1.value else { - deferred.fill(with: .failure(tuple.1.error!)) - return - } - - deferred.fill(with: .success((firstValue, secondValue))) - } - - return Task(Future(deferred)) -} - -public func bothSerially(first: Task, second: @escaping (T) -> Task) -> Task<(T, U)> { - - let deferred = Deferred.Result>() - - first.upon { (firstResult) in - guard let firstValue = firstResult.value else { - deferred.fill(with: .failure(firstResult.error!)) - return - } - - second(firstValue).upon { (secondResult) in - guard let secondValue = secondResult.value else { - deferred.fill(with: .failure(secondResult.error!)) - return - } - - deferred.fill(with: .success((firstValue, secondValue))) - } - } - return Task(Future(deferred)) -} - -extension Task { - - public func toSwiftConcurrency() async throws -> Success { - try await withCheckedThrowingContinuation { cont in - toObjectiveC { success, error in - if let error = error { - cont.resume(throwing: error) - } else { - cont.resume(returning: success!) - } - } - } - } - - public func toObjectiveC(completionHandler handler: @escaping (Success?, NSError?) -> Void) { - upon(.main) { (result) in - switch result { - case .success(let value): - handler(value, nil) - case .failure(let error): - handler(nil, error as NSError) - } - } - } - - public typealias SwiftConcurrencySignature = () async throws -> Success - - public static func fromSwiftConcurrency(_ closure: @escaping SwiftConcurrencySignature) -> Task { - let deferred = Deferred.Result>() - let swiftTask = _Concurrency.Task { - do { - let object: Success = try await closure() - deferred.fill(with: .success(object)) - } catch { - deferred.fill(with: .failure(error)) - } - } - return Task(deferred, uponCancel: { - swiftTask.cancel() - }) - } -} - -extension Future { - public typealias SwiftConcurrencySignature = () async -> Value? - public static func fromSwiftConcurrency(_ closure: @escaping SwiftConcurrencySignature) -> Future { - let deferred = Deferred() - _Concurrency.Task { - let object: Value? = await closure() - deferred.fill(with: object) - } - return Future(deferred) - } -} - -extension Task.Result { - public var value: Success? { - switch self { - case .success(let value): - return value - case .failure(_): - return nil - } - } - - public var error: Error? { - switch self { - case .success(_): - return nil - case .failure(let error): - return error - } - } - - /// Returns a new Result by mapping `Success`es’ values using `transform`, or re-wrapping `Failure`s’ errors. - public func map(_ transform: (Success) -> OtherValue) -> Task.Result { - return flatMap { .success(transform($0)) } - } - - /// Returns the result of applying `transform` to `Success`es’ values, or re-wrapping `Failure`’s errors. - public func flatMap(_ transform: (Success) -> Task.Result) -> Task.Result { - switch self { - case .failure(let error): - return .failure(error) - case .success(let value): - return transform(value) - } - } -} - -public extension Task.Result { - func extract() throws -> Success { - switch self { - case .success(let value): - return value - case .failure(let error): - throw error - } - } - - var swiftResult: Swift.Result { - switch self { - case .failure(let error): - return .failure(error) - case .success(let value): - return .success(value) - } - } -} - -#if os(iOS) - -import UIKit - -public extension UIApplication { - func keepAppAliveUntilTaskCompletes(_ task: Task) { - let backgroundTask = self.beginBackgroundTask { - task.cancel() - } - task.upon(.main) { (_) in - self.endBackgroundTask(backgroundTask) - } - } -} - -#endif diff --git a/Tests/BSWFoundationTests/APIClient/APIClientErrorTests.swift b/Tests/BSWFoundationTests/APIClient/APIClientErrorTests.swift index 7d4a44b..2ac3b45 100644 --- a/Tests/BSWFoundationTests/APIClient/APIClientErrorTests.swift +++ b/Tests/BSWFoundationTests/APIClient/APIClientErrorTests.swift @@ -3,6 +3,12 @@ import XCTest @testable import BSWFoundation class APIClientErrorTests: XCTestCase { + + override func setUp() async throws { + try await super.setUp() + Locale.current = .init(identifier: "en_US") + } + func testErrorPrinting_encodingRequestFailed() { let localizedDescription = APIClient.Error.encodingRequestFailed.localizedDescription XCTAssert(localizedDescription == "The operation couldn’t be completed. (BSWFoundation.APIClient.Error.encodingRequestFailed)") diff --git a/Tests/BSWFoundationTests/APIClient/APIClientTests.swift b/Tests/BSWFoundationTests/APIClient/APIClientTests.swift index 8517675..d31b122 100644 --- a/Tests/BSWFoundationTests/APIClient/APIClientTests.swift +++ b/Tests/BSWFoundationTests/APIClient/APIClientTests.swift @@ -13,16 +13,7 @@ class APIClientTests: XCTestCase { sut = APIClient(environment: HTTPBin.Hosts.production) } - func testGET() throws { - let ipRequest = BSWFoundation.Request( - endpoint: HTTPBin.API.ip - ) - - let getTask = sut.perform(ipRequest) - let _ = try self.waitAndExtractValue(getTask, timeout: 3) - } - - func testGET_async_await() async throws { + func testGET() async throws { let ipRequest = BSWFoundation.Request( endpoint: HTTPBin.API.ip ) @@ -30,7 +21,7 @@ class APIClientTests: XCTestCase { let _ = try await sut.perform(ipRequest) } - func testGETWithCustomValidation() throws { + func testGETWithCustomValidation() async throws { let ipRequest = BSWFoundation.Request( endpoint: HTTPBin.API.ip, @@ -40,20 +31,19 @@ class APIClientTests: XCTestCase { } }) - let getTask = sut.perform(ipRequest) - let _ = try self.waitAndExtractValue(getTask, timeout: 3) + let _ = try await sut.perform(ipRequest) } - func testGETCancel() throws { + func testGETCancel() async throws { let ipRequest = BSWFoundation.Request( endpoint: HTTPBin.API.ip ) - let getTask = sut.perform(ipRequest) + let getTask = Task { try await sut.perform(ipRequest) } getTask.cancel() do { - let _ = try self.waitAndExtractValue(getTask) + let _ = try await getTask.value XCTFail("This should fail here") } catch let error { if error is CancellationError { @@ -66,30 +56,24 @@ class APIClientTests: XCTestCase { } } - func testUpload() throws { + func testUpload() async throws { let uploadRequest = BSWFoundation.Request( endpoint: HTTPBin.API.upload(generateRandomData()) ) - let uploadTask = sut.perform(uploadRequest) - var progress: ProgressObserver! = ProgressObserver(progress: uploadTask.progress) { (progress) in - print(progress.fractionCompleted) - } - let _ = try self.waitAndExtractValue(uploadTask, timeout: 10) - if let _ = progress {} /// This if-let is to to shut up the compiler - progress = nil + let _ = try await sut.perform(uploadRequest) } - func testUploadCancel() { + func testUploadCancel() async throws { let uploadRequest = BSWFoundation.Request( endpoint: HTTPBin.API.upload(generateRandomData()) ) - let uploadTask = sut.perform(uploadRequest) + let uploadTask = Task { try await sut.perform(uploadRequest) } uploadTask.cancel() do { - let _ = try self.waitAndExtractValue(uploadTask) + let _ = try await uploadTask.value XCTFail("This should fail here") } catch let error { if error is CancellationError { @@ -102,7 +86,7 @@ class APIClientTests: XCTestCase { } } - func testUnauthorizedCallsRightMethod() throws { + func testUnauthorizedCallsRightMethod() async throws { let mockDelegate = MockAPIClientDelegate() sut = APIClient(environment: HTTPBin.Hosts.production, networkFetcher: Network401Fetcher()) sut.delegate = mockDelegate @@ -111,11 +95,11 @@ class APIClientTests: XCTestCase { endpoint: HTTPBin.API.ip ) // We don't care about the error here - let _ = try? waitAndExtractValue(sut.perform(ipRequest)) + let _ = try? await sut.perform(ipRequest) XCTAssert(mockDelegate.failedPath != nil) } - func testUnauthorizedRetriesAfterGeneratingNewCredentials() throws { + func testUnauthorizedRetriesAfterGeneratingNewCredentials() async throws { class MockAPIClientDelegateThatGeneratesNewSignature: APIClientDelegate { func apiClientDidReceiveUnauthorized(forRequest atPath: String, apiClient: APIClient) async throws -> Bool { @@ -151,10 +135,10 @@ class APIClientTests: XCTestCase { let ipRequest = BSWFoundation.Request( endpoint: HTTPBin.API.ip ) - let _ = try waitAndExtractValue(sut.perform(ipRequest)) + let _ = try await sut.perform(ipRequest) } - func testCustomizeRequests() throws { + func testCustomizeRequests() async throws { let mockNetworkFetcher = MockNetworkFetcher() mockNetworkFetcher.mockedData = Data() sut = APIClient(environment: HTTPBin.Hosts.production, networkFetcher: mockNetworkFetcher) @@ -168,7 +152,7 @@ class APIClientTests: XCTestCase { endpoint: HTTPBin.API.ip ) - let _ = try waitAndExtractValue(sut.perform(ipRequest)) + let _ = try await sut.perform(ipRequest) guard let capturedURLRequest = mockNetworkFetcher.capturedURLRequest else { throw ValidationError() @@ -176,7 +160,7 @@ class APIClientTests: XCTestCase { XCTAssert(capturedURLRequest.allHTTPHeaderFields?["Signature"] == "hello") } - func testCustomizeSimpleRequests() throws { + func testCustomizeSimpleRequests() async throws { let mockNetworkFetcher = MockNetworkFetcher() mockNetworkFetcher.mockedData = Data() sut = APIClient(environment: HTTPBin.Hosts.production, networkFetcher: mockNetworkFetcher) @@ -186,7 +170,7 @@ class APIClientTests: XCTestCase { return mutableURLRequest } - let _ = try waitAndExtractValue(sut.performSimpleRequest(forEndpoint: HTTPBin.API.ip)) + let _ = try await sut.performSimpleRequest(forEndpoint: HTTPBin.API.ip) guard let capturedURLRequest = mockNetworkFetcher.capturedURLRequest else { throw ValidationError() diff --git a/Tests/BSWFoundationTests/Extensions/DeferredTests.swift b/Tests/BSWFoundationTests/Extensions/DeferredTests.swift deleted file mode 100644 index d20df9c..0000000 --- a/Tests/BSWFoundationTests/Extensions/DeferredTests.swift +++ /dev/null @@ -1,12 +0,0 @@ - -import Task -import BSWFoundation -import XCTest - -class DeferredTests: XCTestCase { - func testMappingFromTaskToSwiftConcurrency() async throws { - let task: Task = JSONParser.parseData("29".data(using: .utf16)!) - let value = try await task.toSwiftConcurrency() - XCTAssert(value == 29) - } -} diff --git a/Tests/BSWFoundationTests/Parsing/JSONParserTests.swift b/Tests/BSWFoundationTests/Parsing/JSONParserTests.swift index e48eef5..c0e1d0f 100644 --- a/Tests/BSWFoundationTests/Parsing/JSONParserTests.swift +++ b/Tests/BSWFoundationTests/Parsing/JSONParserTests.swift @@ -4,7 +4,6 @@ import XCTest import BSWFoundation -import Task class JSONParserTests: XCTestCase { @@ -30,13 +29,6 @@ class JSONParserTests: XCTestCase { } } - func testParsing() throws { - let model = SampleModel(identity: "123456", name: "Hola", amount: 5678) - let jsonData = try JSONEncoder().encode(model) - let task: Task = JSONParser.parseData(jsonData) - let _ = try self.waitAndExtractValue(task) - } - func testParsing_forSwiftConcurency() async throws { let model = SampleModel(identity: "123456", name: "Hola", amount: 5678) let jsonData = try JSONEncoder().encode(model) @@ -60,8 +52,7 @@ class JSONParserTests: XCTestCase { let array = [model1, model2] let jsonData = try JSONEncoder().encode(array) - let task: Task<[SampleModel]> = JSONParser.parseData(jsonData) - let _ = try self.waitAndExtractValue(task) + let _: [SampleModel] = try JSONParser.parseData(jsonData) } func testParsePrettyPrinting() throws { @@ -80,10 +71,7 @@ class JSONParserTests: XCTestCase { func testEmptyResponseParsing() throws { let jsonData = """ """.data(using: .utf8)! - print(jsonData) - let task: Task = JSONParser.parseData(jsonData) - let value = try self.waitAndExtractValue(task) - print(value) + let _: VoidResponse = try JSONParser.parseData(jsonData) } } diff --git a/Tests/BSWFoundationTests/XCTestCase.swift b/Tests/BSWFoundationTests/XCTestCase.swift deleted file mode 100644 index 377c6eb..0000000 --- a/Tests/BSWFoundationTests/XCTestCase.swift +++ /dev/null @@ -1,34 +0,0 @@ - -#if canImport(XCTest) - -import Task -import XCTest - -public extension XCTestCase { - func waitAndExtractValue(_ task: Task, timeout: TimeInterval = 1) throws -> T { - var catchedValue: T! - var catchedError: Swift.Error! - let exp = self.expectation(description: "Extract from Future") - task.upon(.main) { (result) in - switch result { - case .failure(let error): - catchedError = error - case .success(let value): - catchedValue = value - } - exp.fulfill() - } - self.waitForExpectations(timeout: timeout) { (timeoutError) in - if let timeoutError = timeoutError { - catchedError = timeoutError - } - } - - if let error = catchedError { - throw error - } - return catchedValue - } -} - -#endif From c9e1841b461fd0f64e78a5dda5e2b0cfefc809c2 Mon Sep 17 00:00:00 2001 From: Pierluigi Cifani Date: Thu, 10 Mar 2022 18:44:31 +0100 Subject: [PATCH 2/3] Bump fastlane --- Gemfile.lock | 70 +++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2a8b4d8..add55d9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,30 +1,30 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.4) + CFPropertyList (3.0.5) rexml addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.2.0) - aws-partitions (1.514.0) - aws-sdk-core (3.121.1) + aws-partitions (1.565.0) + aws-sdk-core (3.129.0) aws-eventstream (~> 1, >= 1.0.2) - aws-partitions (~> 1, >= 1.239.0) + aws-partitions (~> 1, >= 1.525.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.49.0) - aws-sdk-core (~> 3, >= 3.120.0) + aws-sdk-kms (1.55.0) + aws-sdk-core (~> 3, >= 3.127.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.103.0) - aws-sdk-core (~> 3, >= 3.120.0) + aws-sdk-s3 (1.113.0) + aws-sdk-core (~> 3, >= 3.127.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) aws-sigv4 (1.4.0) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) - claide (1.0.3) + claide (1.1.0) colored (1.2) colored2 (3.1.2) commander (4.6.0) @@ -36,17 +36,18 @@ GEM unf (>= 0.0.5, < 1.0.0) dotenv (2.7.6) emoji_regex (3.2.3) - excon (0.87.0) - faraday (1.8.0) + excon (0.91.0) + faraday (1.10.0) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.1) + faraday-net_http_persistent (~> 1.0) faraday-patron (~> 1.0) faraday-rack (~> 1.0) - multipart-post (>= 1.2, < 3) + faraday-retry (~> 1.0) ruby2_keywords (>= 0.0.4) faraday-cookie_jar (0.0.7) faraday (>= 0.8.0) @@ -55,14 +56,17 @@ GEM faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) faraday-httpclient (1.0.1) + faraday-multipart (1.0.3) + multipart-post (>= 1.2, < 3) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) - faraday_middleware (1.1.0) + faraday-retry (1.0.3) + faraday_middleware (1.2.0) faraday (~> 1.0) - fastimage (2.2.5) - fastlane (2.195.0) + fastimage (2.2.6) + fastlane (2.204.3) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -102,9 +106,9 @@ GEM xcpretty (~> 0.3.0) xcpretty-travis-formatter (>= 0.0.3) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.12.0) + google-apis-androidpublisher_v3 (0.16.0) google-apis-core (>= 0.4, < 2.a) - google-apis-core (0.4.1) + google-apis-core (0.4.2) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) @@ -113,11 +117,11 @@ GEM retriable (>= 2.0, < 4.a) rexml webrick - google-apis-iamcredentials_v1 (0.7.0) + google-apis-iamcredentials_v1 (0.10.0) google-apis-core (>= 0.4, < 2.a) - google-apis-playcustomapp_v1 (0.5.0) + google-apis-playcustomapp_v1 (0.7.0) google-apis-core (>= 0.4, < 2.a) - google-apis-storage_v1 (0.8.0) + google-apis-storage_v1 (0.11.0) google-apis-core (>= 0.4, < 2.a) google-cloud-core (1.6.0) google-cloud-env (~> 1.0) @@ -125,16 +129,16 @@ GEM google-cloud-env (1.5.0) faraday (>= 0.17.3, < 2.0) google-cloud-errors (1.2.0) - google-cloud-storage (1.34.1) - addressable (~> 2.5) + google-cloud-storage (1.36.1) + addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) google-apis-storage_v1 (~> 0.1) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - googleauth (1.0.0) - faraday (>= 0.17.3, < 2.0) + googleauth (1.1.2) + faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) memoist (~> 0.16) multi_json (~> 1.11) @@ -144,8 +148,8 @@ GEM http-cookie (1.0.4) domain_name (~> 0.5) httpclient (2.8.3) - jmespath (1.4.0) - json (2.5.1) + jmespath (1.6.1) + json (2.6.1) jwt (2.3.0) memoist (0.16.2) mini_magick (4.11.0) @@ -155,7 +159,7 @@ GEM nanaimo (0.3.0) naturally (2.2.1) optparse (0.1.1) - os (1.1.1) + os (1.1.4) plist (3.6.0) public_suffix (4.0.6) rake (13.0.6) @@ -169,9 +173,9 @@ GEM ruby2_keywords (0.0.5) rubyzip (2.3.2) security (0.1.3) - signet (0.16.0) + signet (0.16.1) addressable (~> 2.8) - faraday (>= 0.17.3, < 2.0) + faraday (>= 0.17.5, < 3.0) jwt (>= 1.5, < 3.0) multi_json (~> 1.10) simctl (1.6.8) @@ -180,7 +184,7 @@ GEM terminal-notifier (2.0.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - trailblazer-option (0.1.1) + trailblazer-option (0.1.2) tty-cursor (0.7.1) tty-screen (0.8.1) tty-spinner (0.9.3) @@ -211,4 +215,4 @@ DEPENDENCIES fastlane BUNDLED WITH - 2.2.15 + 2.2.21 From 3cc8a1805820693a7942c590ce947b7d9de17834 Mon Sep 17 00:00:00 2001 From: Pierluigi Cifani Date: Thu, 10 Mar 2022 18:45:24 +0100 Subject: [PATCH 3/3] Oops --- Tests/BSWFoundationTests/APIClient/APIClientErrorTests.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Tests/BSWFoundationTests/APIClient/APIClientErrorTests.swift b/Tests/BSWFoundationTests/APIClient/APIClientErrorTests.swift index 2ac3b45..0a07e12 100644 --- a/Tests/BSWFoundationTests/APIClient/APIClientErrorTests.swift +++ b/Tests/BSWFoundationTests/APIClient/APIClientErrorTests.swift @@ -6,7 +6,6 @@ class APIClientErrorTests: XCTestCase { override func setUp() async throws { try await super.setUp() - Locale.current = .init(identifier: "en_US") } func testErrorPrinting_encodingRequestFailed() {