Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

Commit

Permalink
Merge branch 'release/0.6.0' into versions
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeehut committed Sep 30, 2021
2 parents 8609a78 + 7f62f46 commit 3cbfb67
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 50 deletions.
16 changes: 0 additions & 16 deletions .sourcery/LinuxMain.stencil

This file was deleted.

4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
### Security
- None.

## [0.6.0] - 2021-09-30
### Added
- New async `response` method based on the new concurrency features available in Swift 5.5.

## [0.5.0] - 2021-09-28
### Added
- New `mockingBehavior` parameter on `ApiProvider` for testing purposes. Specify one with `delay` and `scheduler`, e.g. `.seconds(0.5)` and `DispatchQueue.main.eraseToAnyScheduler()`. Provides `nil` by default to make actual requests.
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
alt="codebeat badge">
</a>
<a href="https://github.com/Flinesoft/HandySwift/releases">
<img src="https://img.shields.io/badge/Version-0.5.0-blue.svg"
alt="Version: 0.5.0">
<img src="https://img.shields.io/badge/Version-0.6.0-blue.svg"
alt="Version: 0.6.0">
<img src="https://img.shields.io/badge/Swift-5.3-FFAC45.svg"
alt="Swift: 5.3">
<img src="https://img.shields.io/badge/Platforms-Apple%20%7C%20Linux-FF69B4.svg"
Expand Down Expand Up @@ -157,7 +157,7 @@ extension MicrosoftTranslatorEndpoint: Endpoint {

return queryParameters
}

var mockedResponse: MockedResponse? {
switch self {
case .languages:
Expand Down
62 changes: 62 additions & 0 deletions Sources/Microya/Core/ApiProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,68 @@ open class ApiProvider<EndpointType: Endpoint> {
}
}

@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
public func response(on endpoint: EndpointType) async -> TypedResult<EmptyBodyResponse> {
await self.response(on: endpoint, decodeBodyTo: EmptyBodyResponse.self)
}

@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
public func response<ResultType: Decodable>(
on endpoint: EndpointType,
decodeBodyTo: ResultType.Type
) async -> TypedResult<ResultType> {
var request: URLRequest = endpoint.buildRequest(baseUrl: baseUrl)

for plugin in plugins {
plugin.modifyRequest(&request, endpoint: endpoint)
}

for plugin in plugins {
plugin.willPerformRequest(request, endpoint: endpoint)
}

func handleResponse(data: Data?, response: URLResponse?, error: Error?) -> TypedResult<ResultType> {
let urlSessionResult: URLSessionResult = (data: data, response: response, error: error)
let typedResult: TypedResult<ResultType> = self.decodeBody(from: urlSessionResult, endpoint: endpoint)

for plugin in self.plugins {
plugin.didPerformRequest(urlSessionResult: urlSessionResult, typedResult: typedResult, endpoint: endpoint)
}

return typedResult
}

if let mockingBehavior = mockingBehavior {
let baseUrl = self.baseUrl

var schedulerFired: Bool = false
mockingBehavior.scheduler.schedule(after: mockingBehavior.scheduler.now.advanced(by: mockingBehavior.delay)) {
schedulerFired = true
}
while !schedulerFired { /* wait for scheduler to schedule */ }

guard let mockedResponse = mockingBehavior.mockedResponseProvider(endpoint) else {
return .failure(.emptyMockedResponse)
}

return handleResponse(
data: mockedResponse.bodyData,
response: mockedResponse.httpUrlResponse(baseUrl: baseUrl),
error: nil
)
}
else {
// this is the main logic, making the actual call
do {
let (data, response) = try await URLSession.shared.data(for: request)
return handleResponse(data: data, response: response, error: nil)
}
catch {
return handleResponse(data: nil, response: nil, error: error)
}
}
}

/// Performs the asynchronous request for the chosen write-only endpoint and calls the completion closure with the result.
/// Returns a `EmptyBodyResponse` on success.
///
Expand Down
30 changes: 0 additions & 30 deletions Tests/LinuxMain.swift

This file was deleted.

124 changes: 124 additions & 0 deletions Tests/MicroyaTests/MicroyaIntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -466,4 +466,128 @@ class MicroyaIntegrationTests: XCTestCase {
wait(for: [expectation], timeout: 10)
#endif
}

@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testIndexAsync() async throws {
let typedResponseBody =
try await sampleApiProvider.response(
on: .index(sortedBy: "updatedAt"),
decodeBodyTo: PostmanEchoResponse.self
)
.get()

XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Content-Type"], "application/json")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Accept"], "application/json")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Accept-Language"], "en")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Authorization"], "Basic abc123")

XCTAssertEqual(TestDataStore.request?.httpMethod, "GET")
XCTAssertEqual(TestDataStore.request?.url?.path, "/get")
XCTAssertEqual(TestDataStore.request?.url?.query, "sortedBy=updatedAt")

XCTAssertNotNil(TestDataStore.urlSessionResult?.data)
XCTAssertNil(TestDataStore.urlSessionResult?.error)
XCTAssertNotNil(TestDataStore.urlSessionResult?.response)

XCTAssertEqual(typedResponseBody.args, ["sortedBy": "updatedAt"])
XCTAssertEqual(typedResponseBody.headers["content-type"], "application/json")
XCTAssertEqual(typedResponseBody.headers["accept"], "application/json")
XCTAssertEqual(typedResponseBody.headers["accept-language"], "en")
XCTAssertEqual(typedResponseBody.url, "https://postman-echo.com/get?sortedBy=updatedAt")
}

@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testPostAsync() async throws {
let typedResponseBody =
try await sampleApiProvider.response(
on: .post(fooBar: FooBar(foo: "Lorem", bar: "Ipsum")),
decodeBodyTo: PostmanEchoResponse.self
)
.get()

XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Content-Type"], "application/json")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Accept"], "application/json")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Accept-Language"], "en")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Authorization"], "Basic abc123")

XCTAssertEqual(TestDataStore.request?.httpMethod, "POST")
XCTAssertEqual(TestDataStore.request?.url?.path, "/post")
XCTAssertNil(TestDataStore.request?.url?.query)

XCTAssertNotNil(TestDataStore.urlSessionResult?.data)
XCTAssertNil(TestDataStore.urlSessionResult?.error)
XCTAssertNotNil(TestDataStore.urlSessionResult?.response)

XCTAssertEqual(typedResponseBody.args, [:])
XCTAssertEqual(typedResponseBody.headers["content-type"], "application/json")
XCTAssertEqual(typedResponseBody.headers["accept"], "application/json")
XCTAssertEqual(typedResponseBody.headers["accept-language"], "en")
XCTAssertEqual(typedResponseBody.url, "https://postman-echo.com/post")
}

@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testGetAsync() async {
let response = await sampleApiProvider.response(
on: .get(fooBarID: fooBarID),
decodeBodyTo: PostmanEchoResponse.self
)
XCTAssertThrowsError(try response.get())

XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Content-Type"], "application/json")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Accept"], "application/json")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Accept-Language"], "en")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Authorization"], "Basic abc123")

XCTAssertEqual(TestDataStore.request?.httpMethod, "GET")
XCTAssertEqual(TestDataStore.request?.url?.path, "/get/\(fooBarID)")
XCTAssertNil(TestDataStore.request?.url?.query)
}

@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testPatchAsync() async throws {
let response = await sampleApiProvider.response(
on: .patch(fooBarID: fooBarID, fooBar: FooBar(foo: "Dolor", bar: "Amet")),
decodeBodyTo: PostmanEchoResponse.self
)
XCTAssertThrowsError(try response.get())

XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Content-Type"], "application/json")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Accept"], "application/json")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Accept-Language"], "en")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Authorization"], "Basic abc123")

XCTAssertEqual(TestDataStore.request?.httpMethod, "PATCH")
XCTAssertEqual(TestDataStore.request?.url?.path, "/patch/\(fooBarID)")
XCTAssertNil(TestDataStore.request?.url?.query)

XCTAssertNotNil(TestDataStore.urlSessionResult?.data)
XCTAssertNil(TestDataStore.urlSessionResult?.error)
XCTAssertNotNil(TestDataStore.urlSessionResult?.response)
}

@available(iOS 15, tvOS 15, macOS 12, watchOS 8, *)
func testDeleteAsync() async throws {
let result = await sampleApiProvider.response(on: .delete)

switch result {
case .success:
break

default:
XCTFail("Expected request to succeed.")
}

XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Content-Type"], "application/json")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Accept"], "application/json")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Accept-Language"], "en")
XCTAssertEqual(TestDataStore.request?.allHTTPHeaderFields?["Authorization"], "Basic abc123")

XCTAssertEqual(TestDataStore.request?.httpMethod, "DELETE")
XCTAssertEqual(TestDataStore.request?.url?.path, "/delete")
XCTAssertNil(TestDataStore.request?.url?.query)

XCTAssertNotNil(TestDataStore.urlSessionResult?.data)
XCTAssertNil(TestDataStore.urlSessionResult?.error)
XCTAssertNotNil(TestDataStore.urlSessionResult?.response)
}
}
1 change: 0 additions & 1 deletion build-script.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/bin/bash
set -euxo pipefail

sourcery --sources Tests/MicroyaTests --templates .sourcery/LinuxMain.stencil --output Tests/LinuxMain.swift
swift-format --recursive Sources/Microya Tests --in-place
swift-format lint --recursive Sources/Microya Tests

0 comments on commit 3cbfb67

Please sign in to comment.