Skip to content

Commit

Permalink
Add Guarantees Support (#39)
Browse files Browse the repository at this point in the history
* Add Guarantees Support
  • Loading branch information
djtech42 authored and yannickl committed Mar 5, 2019
1 parent ce4fc4f commit ff456f4
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 3 deletions.
11 changes: 11 additions & 0 deletions Sources/AwaitKit/AwaitKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,14 @@ public func await<T>(_ body: @escaping () throws -> T) throws -> T {
public func await<T>(_ promise: Promise<T>) throws -> T {
return try Queue.await.ak.await(promise)
}

/**
Awaits that the given guarantee resolved and returns its value or throws an error if the current and target queues are the same.
- parameter guarantee: The guarantee to resolve.
- throws: when the queues are the same.
- returns: The value of the guarantee when it is resolved.
*/
@discardableResult
public func await<T>(_ guarantee: Guarantee<T>) throws -> T {
return try Queue.await.ak.await(guarantee)
}
34 changes: 34 additions & 0 deletions Sources/AwaitKit/DispatchQueue+Await.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,38 @@ extension Extension where Base: DispatchQueue {

return unwrappedResult
}

/**
Awaits that the given guarantee resolved on the receiver and returns its value or throws an error if the current and target queues are the same.

- parameter guarantee: The guarantee to resolve.
- throws: when the queues are the same.
- returns: The value of the guarantee when it is resolved.
*/
@discardableResult
public final func await<T>(_ guarantee: Guarantee<T>) throws -> T {
guard self.base.label != DispatchQueue.main.label else {
throw NSError(domain: "com.yannickloriot.awaitkit", code: 0, userInfo: [
NSLocalizedDescriptionKey: "Operation was aborted.",
NSLocalizedFailureReasonErrorKey: "The current and target queues are the same."
])
}

var result: T?

let semaphore = DispatchSemaphore(value: 0)

guarantee
.then(on: self.base) { value -> Guarantee<Void> in
result = value

semaphore.signal()

return Guarantee()
}

_ = semaphore.wait(timeout: .distantFuture)

return result!
}
}
22 changes: 22 additions & 0 deletions Tests/AwaitKitTests/AwaitKitAwaitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ class AwaitKitAwaitTests: XCTestCase {
XCTAssertEqual(name, "AwaitedPromiseKit")
}

func testSimpleAwaitGuarantee() {
let guarantee: Guarantee<String> = Guarantee { fulfill in
let deadlineTime = DispatchTime.now() + .seconds(1)

backgroundQueue.asyncAfter(deadline: deadlineTime, execute: {
fulfill("AwaitedPromiseKit")
})
}

let name = try! await(guarantee)

XCTAssertEqual(name, "AwaitedPromiseKit")
}

func testSimpleFailedAwaitPromise() {
let promise: Promise<String> = Promise { seal in
let deadlineTime = DispatchTime.now() + .seconds(1)
Expand All @@ -66,6 +80,14 @@ class AwaitKitAwaitTests: XCTestCase {
XCTAssertNotNil(promise.value)
}

func testNoValueAwaitGuarantee() {
let guarantee: Guarantee<Void> = Guarantee { fulfill in
fulfill(())
}

XCTAssertNotNil(guarantee.value)
}

func testAwaitBlock() {
var name: String = try! await {
return "AwaitedPromiseKit"
Expand Down
54 changes: 51 additions & 3 deletions Tests/AwaitKitTests/AwaitKitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,23 @@ import PromiseKit
import XCTest

class AwaitKitTests: XCTestCase {
func testExcludeSameQueue() {
func testExcludeSameQueuePromise() {
let promise = Promise<Void> { seal in
seal.fulfill(())
}

XCTAssertThrowsError(try DispatchQueue.main.ak.await(promise))
}

func testAsyncAndAwaitOnDifferentQueue() {
func testExcludeSameQueueGuarantee() {
let guarantee = Guarantee<Void> { fulfill in
fulfill(())
}

XCTAssertThrowsError(try DispatchQueue.main.ak.await(guarantee))
}

func testAsyncAndAwaitOnDifferentQueuePromise() {
let expect = expectation(description: "Async should fulfill")

let promise = Promise<Void> { seal in
Expand All @@ -57,7 +65,27 @@ class AwaitKitTests: XCTestCase {
waitForExpectations(timeout: 0.1, handler: nil)
}

func testImbricationQueue() {
func testAsyncAndAwaitOnDifferentQueueGuarantee() {
let expect = expectation(description: "Async should fulfill")

let guarantee = Guarantee<Void> { fulfill in
fulfill(())
}

let result: Promise<Void> = async {
try await(guarantee)
}

_ = result.then { _ -> Promise<Void> in
expect.fulfill()

return Promise()
}

waitForExpectations(timeout: 0.1, handler: nil)
}

func testImbricationQueuePromise() {
let expect = expectation(description: "Async should fulfill")

let promise = Promise<Void> { seal in
Expand All @@ -76,4 +104,24 @@ class AwaitKitTests: XCTestCase {

waitForExpectations(timeout: 0.1, handler: nil)
}

func testImbricationQueueGuarantee() {
let expect = expectation(description: "Async should fulfill")

let guarantee = Guarantee<Void> { fulfill in
fulfill(())
}

let result: Promise<Void> = async {
try await(async { try await(guarantee) })
}

_ = result.then { _ -> Promise<Void> in
expect.fulfill()

return Promise()
}

waitForExpectations(timeout: 0.1, handler: nil)
}
}

0 comments on commit ff456f4

Please sign in to comment.