Skip to content

Commit

Permalink
Map by keyPath (#1118)
Browse files Browse the repository at this point in the history
* Added func map<U>(_ keyPath: KeyPath<T, U>)

* Added swift version

* Added func map<U>(_ keyPath: KeyPath<T, U>)

* testMap

* testMap for Guarantee

* Added missing __allTests__GuaranteeTests

* Added all missing tests

* Removed #if swift

* Tests ordering

* Fixed tests
  • Loading branch information
RomanPodymov authored and mxcl committed Jan 7, 2020
1 parent 8b97eb2 commit f8a593a
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Sources/Guarantee.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ public extension Guarantee {
return rg
}

#if swift(>=4)
func map<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ keyPath: KeyPath<T, U>) -> Guarantee<U> {
let rg = Guarantee<U>(.pending)
pipe { value in
on.async(flags: flags) {
rg.box.seal(value[keyPath: keyPath])
}
}
return rg
}
#endif

@discardableResult
func then<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(T) -> Guarantee<U>) -> Guarantee<U> {
let rg = Guarantee<U>(.pending)
Expand Down
24 changes: 24 additions & 0 deletions Sources/Thenable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,30 @@ public extension Thenable {
return rp
}

#if swift(>=4)
/**
Similar to func `map<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T) throws -> U) -> Promise<U>`, but accepts a key path instead of a closure.
- Parameter on: The queue to which the provided key path for value dispatches.
- Parameter keyPath: The key path to the value that is using when this Promise is fulfilled.
- Returns: A new promise that is fulfilled with the value for the provided key path.
*/
func map<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ keyPath: KeyPath<T, U>) -> Promise<U> {
let rp = Promise<U>(.pending)
pipe {
switch $0 {
case .fulfilled(let value):
on.async(flags: flags) {
rp.box.seal(.fulfilled(value[keyPath: keyPath]))
}
case .rejected(let error):
rp.box.seal(.rejected(error))
}
}
return rp
}
#endif

/**
The provided closure is executed when this promise is fulfilled.
Expand Down
26 changes: 26 additions & 0 deletions Tests/CorePromise/GuaranteeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,32 @@ class GuaranteeTests: XCTestCase {
wait(for: [ex], timeout: 10)
}

func testMap() {
let ex = expectation(description: "")

Guarantee.value(1).map {
$0 * 2
}.done {
XCTAssertEqual(2, $0)
ex.fulfill()
}

wait(for: [ex], timeout: 10)
}

#if swift(>=4)
func testMapByKeyPath() {
let ex = expectation(description: "")

Guarantee.value("Hello world").map(\.count).done {
XCTAssertEqual(11, $0)
ex.fulfill()
}

wait(for: [ex], timeout: 10)
}
#endif

func testWait() {
XCTAssertEqual(after(.milliseconds(100)).map(on: nil){ 1 }.wait(), 1)
}
Expand Down
22 changes: 22 additions & 0 deletions Tests/CorePromise/ThenableTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,28 @@ class ThenableTests: XCTestCase {
wait(for: [ex1, ex2], timeout: 10)
}

func testMap() {
let ex = expectation(description: "")
Promise.value(1).map {
$0 * 2
}.done {
XCTAssertEqual($0, 2)
ex.fulfill()
}.silenceWarning()
wait(for: [ex], timeout: 10)
}

#if swift(>=4)
func testMapByKeyPath() {
let ex = expectation(description: "")
Promise.value("Hello world").map(\.count).done {
XCTAssertEqual($0, 11)
ex.fulfill()
}.silenceWarning()
wait(for: [ex], timeout: 10)
}
#endif

func testCompactMap() {
let ex = expectation(description: "")
Promise.value(1.0).compactMap {
Expand Down
4 changes: 4 additions & 0 deletions Tests/CorePromise/XCTestManifests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ extension GuaranteeTests {
("testFilterValues", testFilterValues),
("testFlatMapValues", testFlatMapValues),
("testInit", testInit),
("testMap", testMap),
("testMapByKeyPath", testMapByKeyPath),
("testMapValues", testMapValues),
("testNoAmbiguityForValue", testNoAmbiguityForValue),
("testSorted", testSorted),
Expand Down Expand Up @@ -192,6 +194,8 @@ extension ThenableTests {
("testFirstValueForEmpty", testFirstValueForEmpty),
("testGet", testGet),
("testLastValueForEmpty", testLastValueForEmpty),
("testMap", testMap),
("testMapByKeyPath", testMapByKeyPath),
("testPMKErrorCompactMap", testPMKErrorCompactMap),
("testRejectedPromiseCompactMap", testRejectedPromiseCompactMap),
("testThenFlatMap", testThenFlatMap),
Expand Down

0 comments on commit f8a593a

Please sign in to comment.