Skip to content

Commit

Permalink
Merge pull request #1309 from RomanPodymov/v6
Browse files Browse the repository at this point in the history
Future extensions
  • Loading branch information
mxcl authored Mar 10, 2023
2 parents 87b5d53 + 589dc34 commit cbb41e9
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 0 deletions.
37 changes: 37 additions & 0 deletions Sources/Combine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,42 @@ public extension Promise {
}
}
}

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
public extension Future {
func promise() -> PromiseKit.Promise<Output> {
return .init { [weak self] resolver in
var cancellable: AnyCancellable?
cancellable = self?.sink(receiveCompletion: { completion in
cancellable?.cancel()
cancellable = nil
switch completion {
case .failure(let error):
resolver.reject(error)
case .finished:
break
}
}, receiveValue: { value in
cancellable?.cancel()
cancellable = nil
resolver.fulfill(value)
})
}
}
}

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
public extension Future where Failure == Never {
func guarantee() -> Guarantee<Output> {
return .init { [weak self] resolver in
var cancellable: AnyCancellable?
cancellable = self?.sink(receiveValue: { value in
cancellable?.cancel()
cancellable = nil
resolver(value)
})
}
}
}
#endif
#endif
119 changes: 119 additions & 0 deletions Tests/CorePromise/CombineTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,123 @@ class CombineTests: XCTestCase {

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

func testPromiseCombineValue() {
let ex = expectation(description: "")
#if swift(>=4.1)
#if canImport(Combine)
if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) {
let promise = Future<Int, Error> { resolver in
resolver(.success(1))
}.delay(for: 5, scheduler: RunLoop.main).future().promise()
promise.done {
XCTAssertEqual($0, 1)
ex.fulfill()
}.catch { _ in
XCTAssert(false)
ex.fulfill()
}
} else {
ex.fulfill()
}
#else
ex.fulfill()
#endif
#else
ex.fulfill()
#endif

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

func testGuaranteeCombineValue() {
let ex = expectation(description: "")
#if swift(>=4.1)
#if canImport(Combine)
if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) {
let guarantee = Future<Int, Never> { resolver in
resolver(.success(1))
}.delay(for: 5, scheduler: RunLoop.main).future().guarantee()
guarantee.done {
XCTAssertEqual($0, 1)
ex.fulfill()
}
} else {
ex.fulfill()
}
#else
ex.fulfill()
#endif
#else
ex.fulfill()
#endif

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

func testPromiseCombineThrows() {
let ex = expectation(description: "")
#if swift(>=4.1)
#if canImport(Combine)
if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) {
let promise = Future<Int, Error> { resolver in
resolver(.failure(.dummy))
}.delay(for: 5, scheduler: RunLoop.main).map { _ in
100
}.future().promise()
promise.done { _ in
XCTAssert(false)
ex.fulfill()
}.catch { error in
switch error as? Error {
case .dummy:
XCTAssert(true)
default:
XCTAssert(false)
}
ex.fulfill()
}
} else {
ex.fulfill()
}
#else
ex.fulfill()
#endif
#else
ex.fulfill()
#endif

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

#if swift(>=4.1)
#if canImport(Combine)
/// https://stackoverflow.com/a/60444607/2229783
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
private extension Publisher {
func future() -> Future<Output, Failure> {
return Future { promise in
var ticket: AnyCancellable? = nil
ticket = sink(
receiveCompletion: {
ticket?.cancel()
ticket = nil
switch $0 {
case .failure(let error):
promise(.failure(error))
case .finished:
break
}
},
receiveValue: {
ticket?.cancel()
ticket = nil
promise(.success($0))
}
)
}
}
}
#endif
#endif
3 changes: 3 additions & 0 deletions Tests/CorePromise/XCTestManifests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ extension CombineTests {
("testCombineGuaranteeValue", testCombineGuaranteeValue),
("testCombinePromiseThrow", testCombinePromiseThrow),
("testCombinePromiseValue", testCombinePromiseValue),
("testGuaranteeCombineValue", testGuaranteeCombineValue),
("testPromiseCombineThrows", testPromiseCombineThrows),
("testPromiseCombineValue", testPromiseCombineValue),
]
}

Expand Down

0 comments on commit cbb41e9

Please sign in to comment.