Add PromiseKit dependency
- Added PromiseKit dependency
This commit is contained in:
185
Carthage/Checkouts/PromiseKit/Tests/A+/0.0.0.swift
vendored
Normal file
185
Carthage/Checkouts/PromiseKit/Tests/A+/0.0.0.swift
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
import PromiseKit
|
||||
import Dispatch
|
||||
import XCTest
|
||||
|
||||
enum Error: Swift.Error {
|
||||
case dummy // we reject with this when we don't intend to test against it
|
||||
case sentinel(UInt32)
|
||||
}
|
||||
|
||||
private let timeout: TimeInterval = 10
|
||||
|
||||
extension XCTestCase {
|
||||
func describe(_ description: String, file: StaticString = #file, line: UInt = #line, body: () throws -> Void) {
|
||||
|
||||
PromiseKit.conf.Q.map = .main
|
||||
|
||||
do {
|
||||
try body()
|
||||
} catch {
|
||||
XCTFail(description, file: file, line: line)
|
||||
}
|
||||
}
|
||||
|
||||
func specify(_ description: String, file: StaticString = #file, line: UInt = #line, body: ((promise: Promise<Void>, fulfill: () -> Void, reject: (Error) -> Void), XCTestExpectation) throws -> Void) {
|
||||
let expectation = self.expectation(description: description)
|
||||
let (pending, seal) = Promise<Void>.pending()
|
||||
|
||||
do {
|
||||
try body((pending, { seal.fulfill(()) }, seal.reject), expectation)
|
||||
waitForExpectations(timeout: timeout) { err in
|
||||
if let _ = err {
|
||||
XCTFail("wait failed: \(description)", file: file, line: line)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
XCTFail(description, file: file, line: line)
|
||||
}
|
||||
}
|
||||
|
||||
func testFulfilled(file: StaticString = #file, line: UInt = #line, body: @escaping (Promise<UInt32>, XCTestExpectation, UInt32) -> Void) {
|
||||
testFulfilled(withExpectationCount: 1, file: file, line: line) {
|
||||
body($0, $1.first!, $2)
|
||||
}
|
||||
}
|
||||
|
||||
func testRejected(file: StaticString = #file, line: UInt = #line, body: @escaping (Promise<UInt32>, XCTestExpectation, UInt32) -> Void) {
|
||||
testRejected(withExpectationCount: 1, file: file, line: line) {
|
||||
body($0, $1.first!, $2)
|
||||
}
|
||||
}
|
||||
|
||||
func testFulfilled(withExpectationCount: Int, file: StaticString = #file, line: UInt = #line, body: @escaping (Promise<UInt32>, [XCTestExpectation], UInt32) -> Void) {
|
||||
|
||||
let specify = mkspecify(withExpectationCount, file: file, line: line, body: body)
|
||||
|
||||
specify("already-fulfilled") { value in
|
||||
return (.value(value), {})
|
||||
}
|
||||
specify("immediately-fulfilled") { value in
|
||||
let (promise, seal) = Promise<UInt32>.pending()
|
||||
return (promise, {
|
||||
seal.fulfill(value)
|
||||
})
|
||||
}
|
||||
specify("eventually-fulfilled") { value in
|
||||
let (promise, seal) = Promise<UInt32>.pending()
|
||||
return (promise, {
|
||||
after(ticks: 5) {
|
||||
seal.fulfill(value)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testRejected(withExpectationCount: Int, file: StaticString = #file, line: UInt = #line, body: @escaping (Promise<UInt32>, [XCTestExpectation], UInt32) -> Void) {
|
||||
|
||||
let specify = mkspecify(withExpectationCount, file: file, line: line, body: body)
|
||||
|
||||
specify("already-rejected") { sentinel in
|
||||
return (Promise(error: Error.sentinel(sentinel)), {})
|
||||
}
|
||||
specify("immediately-rejected") { sentinel in
|
||||
let (promise, seal) = Promise<UInt32>.pending()
|
||||
return (promise, {
|
||||
seal.reject(Error.sentinel(sentinel))
|
||||
})
|
||||
}
|
||||
specify("eventually-rejected") { sentinel in
|
||||
let (promise, seal) = Promise<UInt32>.pending()
|
||||
return (promise, {
|
||||
after(ticks: 50) {
|
||||
seal.reject(Error.sentinel(sentinel))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private func mkspecify(_ numberOfExpectations: Int, file: StaticString, line: UInt, body: @escaping (Promise<UInt32>, [XCTestExpectation], UInt32) -> Void) -> (String, _ feed: (UInt32) -> (Promise<UInt32>, () -> Void)) -> Void {
|
||||
return { desc, feed in
|
||||
let value = arc4random()
|
||||
let (promise, executeAfter) = feed(value)
|
||||
let expectations = (1...numberOfExpectations).map {
|
||||
self.expectation(description: "\(desc) (\($0))")
|
||||
}
|
||||
body(promise, expectations, value)
|
||||
|
||||
executeAfter()
|
||||
|
||||
self.waitForExpectations(timeout: timeout) { err in
|
||||
if let _ = err {
|
||||
XCTFail("timed out: \(desc)", file: file, line: line)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mkex() -> XCTestExpectation {
|
||||
return expectation(description: "")
|
||||
}
|
||||
}
|
||||
|
||||
func after(ticks: Int, execute body: @escaping () -> Void) {
|
||||
precondition(ticks > 0)
|
||||
|
||||
var ticks = ticks
|
||||
func f() {
|
||||
DispatchQueue.main.async {
|
||||
ticks -= 1
|
||||
if ticks == 0 {
|
||||
body()
|
||||
} else {
|
||||
f()
|
||||
}
|
||||
}
|
||||
}
|
||||
f()
|
||||
}
|
||||
|
||||
extension Promise {
|
||||
func test(onFulfilled: @escaping () -> Void, onRejected: @escaping () -> Void) {
|
||||
tap { result in
|
||||
switch result {
|
||||
case .fulfilled:
|
||||
onFulfilled()
|
||||
case .rejected:
|
||||
onRejected()
|
||||
}
|
||||
}.silenceWarning()
|
||||
}
|
||||
}
|
||||
|
||||
prefix func ++(a: inout Int) -> Int {
|
||||
a += 1
|
||||
return a
|
||||
}
|
||||
|
||||
extension Promise {
|
||||
func silenceWarning() {}
|
||||
}
|
||||
|
||||
#if os(Linux)
|
||||
import func Glibc.random
|
||||
|
||||
func arc4random() -> UInt32 {
|
||||
return UInt32(random())
|
||||
}
|
||||
|
||||
extension XCTestExpectation {
|
||||
func fulfill() {
|
||||
fulfill(#file, line: #line)
|
||||
}
|
||||
}
|
||||
|
||||
extension XCTestCase {
|
||||
func wait(for: [XCTestExpectation], timeout: TimeInterval, file: StaticString = #file, line: UInt = #line) {
|
||||
#if !(swift(>=4.0) && !swift(>=4.1))
|
||||
let line = Int(line)
|
||||
#endif
|
||||
waitForExpectations(timeout: timeout, file: file, line: line)
|
||||
}
|
||||
}
|
||||
#endif
|
26
Carthage/Checkouts/PromiseKit/Tests/A+/2.1.2.swift
vendored
Normal file
26
Carthage/Checkouts/PromiseKit/Tests/A+/2.1.2.swift
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class Test212: XCTestCase {
|
||||
func test() {
|
||||
describe("2.1.2.1: When fulfilled, a promise: must not transition to any other state.") {
|
||||
testFulfilled { promise, expectation, _ in
|
||||
promise.test(onFulfilled: expectation.fulfill, onRejected: { XCTFail() })
|
||||
}
|
||||
|
||||
specify("trying to fulfill then immediately reject") { d, expectation in
|
||||
d.promise.test(onFulfilled: expectation.fulfill, onRejected: { XCTFail() })
|
||||
d.fulfill()
|
||||
d.reject(Error.dummy)
|
||||
}
|
||||
|
||||
specify("trying to fulfill then reject, delayed") { d, expectation in
|
||||
d.promise.test(onFulfilled: expectation.fulfill, onRejected: { XCTFail() })
|
||||
after(ticks: 1) {
|
||||
d.fulfill()
|
||||
d.reject(Error.dummy)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
34
Carthage/Checkouts/PromiseKit/Tests/A+/2.1.3.swift
vendored
Normal file
34
Carthage/Checkouts/PromiseKit/Tests/A+/2.1.3.swift
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class Test213: XCTestCase {
|
||||
func test() {
|
||||
describe("2.1.3.1: When rejected, a promise: must not transition to any other state.") {
|
||||
testRejected { promise, expectation, _ in
|
||||
promise.test(onFulfilled: { XCTFail() }, onRejected: expectation.fulfill)
|
||||
}
|
||||
|
||||
specify("trying to reject then immediately fulfill") { d, expectation in
|
||||
d.promise.test(onFulfilled: { XCTFail() }, onRejected: expectation.fulfill)
|
||||
d.reject(Error.dummy)
|
||||
d.fulfill()
|
||||
}
|
||||
|
||||
specify("trying to reject then fulfill, delayed") { d, expectation in
|
||||
d.promise.test(onFulfilled: { XCTFail() }, onRejected: expectation.fulfill)
|
||||
after(ticks: 1) {
|
||||
d.reject(Error.dummy)
|
||||
d.fulfill()
|
||||
}
|
||||
}
|
||||
|
||||
specify("trying to reject immediately then fulfill delayed") { d, expectation in
|
||||
d.promise.test(onFulfilled: { XCTFail() }, onRejected: expectation.fulfill)
|
||||
d.reject(Error.dummy)
|
||||
after(ticks: 1) {
|
||||
d.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
92
Carthage/Checkouts/PromiseKit/Tests/A+/2.2.2.swift
vendored
Normal file
92
Carthage/Checkouts/PromiseKit/Tests/A+/2.2.2.swift
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class Test222: XCTestCase {
|
||||
func test() {
|
||||
describe("2.2.2: If `onFulfilled` is a function,") {
|
||||
describe("2.2.2.1: it must be called after `promise` is fulfilled, with `promise`’s fulfillment value as its first argument.") {
|
||||
testFulfilled { promise, expectation, sentinel in
|
||||
promise.done {
|
||||
XCTAssertEqual(sentinel, $0)
|
||||
expectation.fulfill()
|
||||
}.silenceWarning()
|
||||
}
|
||||
}
|
||||
|
||||
describe("2.2.2.2: it must not be called before `promise` is fulfilled") {
|
||||
specify("fulfilled after a delay") { d, expectation in
|
||||
var called = false
|
||||
d.promise.done {
|
||||
called = true
|
||||
expectation.fulfill()
|
||||
}.silenceWarning()
|
||||
after(ticks: 5) {
|
||||
XCTAssertFalse(called)
|
||||
d.fulfill()
|
||||
}
|
||||
}
|
||||
specify("never fulfilled") { d, expectation in
|
||||
d.promise.done{ XCTFail() }.silenceWarning()
|
||||
after(ticks: 1000, execute: expectation.fulfill)
|
||||
}
|
||||
}
|
||||
|
||||
describe("2.2.2.3: it must not be called more than once.") {
|
||||
specify("already-fulfilled") { _, expectation in
|
||||
let ex = (expectation, mkex())
|
||||
Promise().done {
|
||||
ex.0.fulfill()
|
||||
}.silenceWarning()
|
||||
after(ticks: 1000) {
|
||||
ex.1.fulfill()
|
||||
}
|
||||
}
|
||||
specify("trying to fulfill a pending promise more than once, immediately") { d, expectation in
|
||||
d.promise.done(expectation.fulfill).silenceWarning()
|
||||
d.fulfill()
|
||||
d.fulfill()
|
||||
}
|
||||
specify("trying to fulfill a pending promise more than once, delayed") { d, expectation in
|
||||
d.promise.done(expectation.fulfill).silenceWarning()
|
||||
after(ticks: 5) {
|
||||
d.fulfill()
|
||||
d.fulfill()
|
||||
}
|
||||
}
|
||||
specify("trying to fulfill a pending promise more than once, immediately then delayed") { d, expectation in
|
||||
let ex = (expectation, mkex())
|
||||
d.promise.done(ex.0.fulfill).silenceWarning()
|
||||
d.fulfill()
|
||||
after(ticks: 5) {
|
||||
d.fulfill()
|
||||
}
|
||||
after(ticks: 10, execute: ex.1.fulfill)
|
||||
}
|
||||
specify("when multiple `then` calls are made, spaced apart in time") { d, expectation in
|
||||
let ex = (expectation, self.expectation(description: ""), self.expectation(description: ""), self.expectation(description: ""))
|
||||
|
||||
do {
|
||||
d.promise.done(ex.0.fulfill).silenceWarning()
|
||||
}
|
||||
after(ticks: 5) {
|
||||
d.promise.done(ex.1.fulfill).silenceWarning()
|
||||
}
|
||||
after(ticks: 10) {
|
||||
d.promise.done(ex.2.fulfill).silenceWarning()
|
||||
}
|
||||
after(ticks: 15) {
|
||||
d.fulfill()
|
||||
ex.3.fulfill()
|
||||
}
|
||||
}
|
||||
specify("when `then` is interleaved with fulfillment") { d, expectation in
|
||||
let ex = (expectation, self.expectation(description: ""), self)
|
||||
|
||||
d.promise.done(ex.0.fulfill).silenceWarning()
|
||||
d.fulfill()
|
||||
d.promise.done(ex.1.fulfill).silenceWarning()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
93
Carthage/Checkouts/PromiseKit/Tests/A+/2.2.3.swift
vendored
Normal file
93
Carthage/Checkouts/PromiseKit/Tests/A+/2.2.3.swift
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class Test223: XCTestCase {
|
||||
func test() {
|
||||
describe("2.2.3: If `onRejected` is a function,") {
|
||||
describe("2.2.3.1: it must be called after `promise` is rejected, with `promise`’s rejection reason as its first argument.") {
|
||||
testRejected { promise, expectation, sentinel in
|
||||
promise.catch { error in
|
||||
if case Error.sentinel(let value) = error {
|
||||
XCTAssertEqual(value, sentinel)
|
||||
} else {
|
||||
XCTFail()
|
||||
}
|
||||
expectation.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
describe("2.2.3.2: it must not be called before `promise` is rejected") {
|
||||
specify("rejected after a delay") { d, expectation in
|
||||
var called = false
|
||||
d.promise.catch { _ in
|
||||
called = true
|
||||
expectation.fulfill()
|
||||
}
|
||||
after(ticks: 1) {
|
||||
XCTAssertFalse(called)
|
||||
d.reject(Error.dummy)
|
||||
}
|
||||
}
|
||||
specify("never rejected") { d, expectation in
|
||||
d.promise.catch { _ in XCTFail() }
|
||||
after(ticks: 1, execute: expectation.fulfill)
|
||||
}
|
||||
}
|
||||
describe("2.2.3.3: it must not be called more than once.") {
|
||||
specify("already-rejected") { d, expectation in
|
||||
var timesCalled = 0
|
||||
Promise<Int>(error: Error.dummy).catch { _ in
|
||||
XCTAssertEqual(++timesCalled, 1)
|
||||
}
|
||||
after(ticks: 2) {
|
||||
XCTAssertEqual(timesCalled, 1)
|
||||
expectation.fulfill()
|
||||
}
|
||||
}
|
||||
specify("trying to reject a pending promise more than once, immediately") { d, expectation in
|
||||
d.promise.catch{_ in expectation.fulfill() }
|
||||
d.reject(Error.dummy)
|
||||
d.reject(Error.dummy)
|
||||
}
|
||||
specify("trying to reject a pending promise more than once, delayed") { d, expectation in
|
||||
d.promise.catch{_ in expectation.fulfill() }
|
||||
after(ticks: 1) {
|
||||
d.reject(Error.dummy)
|
||||
d.reject(Error.dummy)
|
||||
}
|
||||
}
|
||||
specify("trying to reject a pending promise more than once, immediately then delayed") { d, expectation in
|
||||
d.promise.catch{_ in expectation.fulfill() }
|
||||
d.reject(Error.dummy)
|
||||
after(ticks: 1) {
|
||||
d.reject(Error.dummy)
|
||||
}
|
||||
}
|
||||
specify("when multiple `then` calls are made, spaced apart in time") { d, expectation in
|
||||
let mk = { self.expectation(description: "") }
|
||||
let ex = (expectation, mk(), mk(), mk())
|
||||
|
||||
do {
|
||||
d.promise.catch{ _ in ex.0.fulfill() }
|
||||
}
|
||||
after(ticks: 1) {
|
||||
d.promise.catch{ _ in ex.1.fulfill() }
|
||||
}
|
||||
after(ticks: 2) {
|
||||
d.promise.catch{ _ in ex.2.fulfill() }
|
||||
}
|
||||
after(ticks: 3) {
|
||||
d.reject(Error.dummy)
|
||||
ex.3.fulfill()
|
||||
}
|
||||
}
|
||||
specify("when `then` is interleaved with rejection") { d, expectation in
|
||||
let ex = (expectation, self.expectation(description: ""))
|
||||
d.promise.catch{ _ in ex.0.fulfill() }
|
||||
d.reject(Error.dummy)
|
||||
d.promise.catch{ _ in ex.1.fulfill() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
146
Carthage/Checkouts/PromiseKit/Tests/A+/2.2.4.swift
vendored
Normal file
146
Carthage/Checkouts/PromiseKit/Tests/A+/2.2.4.swift
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class Test224: XCTestCase {
|
||||
func test() {
|
||||
describe("2.2.4: `onFulfilled` or `onRejected` must not be called until the execution context stack contains only platform code.") {
|
||||
|
||||
describe("`then` returns before the promise becomes fulfilled or rejected") {
|
||||
testFulfilled { promise, expectation, dummy in
|
||||
var thenHasReturned = false
|
||||
promise.done { _ in
|
||||
XCTAssert(thenHasReturned)
|
||||
expectation.fulfill()
|
||||
}.silenceWarning()
|
||||
thenHasReturned = true
|
||||
}
|
||||
testRejected { promise, expectation, memo in
|
||||
var catchHasReturned = false
|
||||
promise.catch { _->() in
|
||||
XCTAssert(catchHasReturned)
|
||||
expectation.fulfill()
|
||||
}
|
||||
catchHasReturned = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
describe("Clean-stack execution ordering tests (fulfillment case)") {
|
||||
specify("when `onFulfilled` is added immediately before the promise is fulfilled") { d, expectation in
|
||||
var onFulfilledCalled = false
|
||||
d.promise.done {
|
||||
onFulfilledCalled = true
|
||||
expectation.fulfill()
|
||||
}.silenceWarning()
|
||||
d.fulfill()
|
||||
XCTAssertFalse(onFulfilledCalled)
|
||||
}
|
||||
specify("when `onFulfilled` is added immediately after the promise is fulfilled") { d, expectation in
|
||||
var onFulfilledCalled = false
|
||||
d.fulfill()
|
||||
d.promise.done {
|
||||
onFulfilledCalled = true
|
||||
expectation.fulfill()
|
||||
}.silenceWarning()
|
||||
XCTAssertFalse(onFulfilledCalled)
|
||||
}
|
||||
specify("when one `onFulfilled` is added inside another `onFulfilled`") { _, expectation in
|
||||
var firstOnFulfilledFinished = false
|
||||
let promise = Promise()
|
||||
promise.done {
|
||||
promise.done {
|
||||
XCTAssertTrue(firstOnFulfilledFinished)
|
||||
expectation.fulfill()
|
||||
}.silenceWarning()
|
||||
firstOnFulfilledFinished = true
|
||||
}.silenceWarning()
|
||||
}
|
||||
|
||||
specify("when `onFulfilled` is added inside an `onRejected`") { _, expectation in
|
||||
let promise1 = Promise<Void>(error: Error.dummy)
|
||||
let promise2 = Promise()
|
||||
var firstOnRejectedFinished = false
|
||||
|
||||
promise1.catch { _ in
|
||||
promise2.done {
|
||||
XCTAssertTrue(firstOnRejectedFinished)
|
||||
expectation.fulfill()
|
||||
}.silenceWarning()
|
||||
firstOnRejectedFinished = true
|
||||
}
|
||||
}
|
||||
|
||||
specify("when the promise is fulfilled asynchronously") { d, expectation in
|
||||
var firstStackFinished = false
|
||||
|
||||
after(ticks: 1) {
|
||||
d.fulfill()
|
||||
firstStackFinished = true
|
||||
}
|
||||
|
||||
d.promise.done {
|
||||
XCTAssertTrue(firstStackFinished)
|
||||
expectation.fulfill()
|
||||
}.silenceWarning()
|
||||
}
|
||||
}
|
||||
|
||||
describe("Clean-stack execution ordering tests (rejection case)") {
|
||||
specify("when `onRejected` is added immediately before the promise is rejected") { d, expectation in
|
||||
var onRejectedCalled = false
|
||||
d.promise.catch { _ in
|
||||
onRejectedCalled = true
|
||||
expectation.fulfill()
|
||||
}
|
||||
d.reject(Error.dummy)
|
||||
XCTAssertFalse(onRejectedCalled)
|
||||
}
|
||||
specify("when `onRejected` is added immediately after the promise is rejected") { d, expectation in
|
||||
var onRejectedCalled = false
|
||||
d.reject(Error.dummy)
|
||||
d.promise.catch { _ in
|
||||
onRejectedCalled = true
|
||||
expectation.fulfill()
|
||||
}
|
||||
XCTAssertFalse(onRejectedCalled)
|
||||
}
|
||||
specify("when `onRejected` is added inside an `onFulfilled`") { d, expectation in
|
||||
let promise1 = Promise()
|
||||
let promise2 = Promise<Void>(error: Error.dummy)
|
||||
var firstOnFulfilledFinished = false
|
||||
|
||||
promise1.done { _ in
|
||||
promise2.catch { _ in
|
||||
XCTAssertTrue(firstOnFulfilledFinished)
|
||||
expectation.fulfill()
|
||||
}
|
||||
firstOnFulfilledFinished = true
|
||||
}.silenceWarning()
|
||||
}
|
||||
specify("when one `onRejected` is added inside another `onRejected`") { d, expectation in
|
||||
let promise = Promise<Void>(error: Error.dummy)
|
||||
var firstOnRejectedFinished = false;
|
||||
|
||||
promise.catch { _ in
|
||||
promise.catch { _ in
|
||||
XCTAssertTrue(firstOnRejectedFinished)
|
||||
expectation.fulfill()
|
||||
}
|
||||
firstOnRejectedFinished = true
|
||||
}
|
||||
}
|
||||
specify("when the promise is rejected asynchronously") { d, expectation in
|
||||
var firstStackFinished = false
|
||||
after(ticks: 1) {
|
||||
d.reject(Error.dummy)
|
||||
firstStackFinished = true
|
||||
}
|
||||
d.promise.catch { _ in
|
||||
XCTAssertTrue(firstStackFinished)
|
||||
expectation.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
275
Carthage/Checkouts/PromiseKit/Tests/A+/2.2.6.swift
vendored
Normal file
275
Carthage/Checkouts/PromiseKit/Tests/A+/2.2.6.swift
vendored
Normal file
@@ -0,0 +1,275 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class Test226: XCTestCase {
|
||||
func test() {
|
||||
describe("2.2.6: `then` may be called multiple times on the same promise.") {
|
||||
describe("2.2.6.1: If/when `promise` is fulfilled, all respective `onFulfilled` callbacks must execute in the order of their originating calls to `then`.") {
|
||||
describe("multiple boring fulfillment handlers") {
|
||||
testFulfilled(withExpectationCount: 4) { promise, exes, sentinel -> () in
|
||||
var orderValidator = 0
|
||||
promise.done {
|
||||
XCTAssertEqual($0, sentinel)
|
||||
XCTAssertEqual(++orderValidator, 1)
|
||||
exes[0].fulfill()
|
||||
}.silenceWarning()
|
||||
promise.catch { _ in XCTFail() }
|
||||
promise.done {
|
||||
XCTAssertEqual($0, sentinel)
|
||||
XCTAssertEqual(++orderValidator, 2)
|
||||
exes[1].fulfill()
|
||||
}.silenceWarning()
|
||||
promise.catch { _ in XCTFail() }
|
||||
promise.done {
|
||||
XCTAssertEqual($0, sentinel)
|
||||
XCTAssertEqual(++orderValidator, 3)
|
||||
exes[2].fulfill()
|
||||
}.silenceWarning()
|
||||
promise.catch { _ in XCTFail() }
|
||||
promise.done {
|
||||
XCTAssertEqual($0, sentinel)
|
||||
XCTAssertEqual(++orderValidator, 4)
|
||||
exes[3].fulfill()
|
||||
}.silenceWarning()
|
||||
}
|
||||
}
|
||||
describe("multiple fulfillment handlers, one of which throws") {
|
||||
testFulfilled(withExpectationCount: 4) { promise, exes, sentinel in
|
||||
var orderValidator = 0
|
||||
promise.done {
|
||||
XCTAssertEqual($0, sentinel)
|
||||
XCTAssertEqual(++orderValidator, 1)
|
||||
exes[0].fulfill()
|
||||
}.silenceWarning()
|
||||
promise.catch { _ in XCTFail() }
|
||||
promise.done {
|
||||
XCTAssertEqual($0, sentinel)
|
||||
XCTAssertEqual(++orderValidator, 2)
|
||||
exes[1].fulfill()
|
||||
}.silenceWarning()
|
||||
promise.catch { _ in XCTFail() }
|
||||
promise.done {
|
||||
XCTAssertEqual($0, sentinel)
|
||||
XCTAssertEqual(++orderValidator, 3)
|
||||
exes[2].fulfill()
|
||||
throw Error.dummy
|
||||
}.silenceWarning()
|
||||
promise.catch { value in XCTFail() }
|
||||
promise.done {
|
||||
XCTAssertEqual($0, sentinel)
|
||||
XCTAssertEqual(++orderValidator, 4)
|
||||
exes[3].fulfill()
|
||||
}.silenceWarning()
|
||||
}
|
||||
}
|
||||
describe("results in multiple branching chains with their own fulfillment values") {
|
||||
testFulfilled(withExpectationCount: 3) { promise, exes, memo in
|
||||
let sentinel1 = 671
|
||||
let sentinel2: UInt32 = 672
|
||||
let sentinel3 = 673
|
||||
|
||||
promise.map { _ in
|
||||
return sentinel1
|
||||
}.done { value in
|
||||
XCTAssertEqual(sentinel1, value)
|
||||
exes[0].fulfill()
|
||||
}.silenceWarning()
|
||||
|
||||
promise.done { _ in
|
||||
throw Error.sentinel(sentinel2)
|
||||
}.catch { err in
|
||||
switch err {
|
||||
case Error.sentinel(let err) where err == sentinel2:
|
||||
break
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
exes[1].fulfill()
|
||||
}
|
||||
|
||||
promise.map { _ in
|
||||
sentinel3
|
||||
}.done {
|
||||
XCTAssertEqual($0, sentinel3)
|
||||
exes[2].fulfill()
|
||||
}.silenceWarning()
|
||||
}
|
||||
}
|
||||
describe("`onFulfilled` handlers are called in the original order") {
|
||||
testFulfilled(withExpectationCount: 3) { promise, exes, memo in
|
||||
var orderValidator = 0
|
||||
|
||||
promise.done { _ in
|
||||
XCTAssertEqual(++orderValidator, 1)
|
||||
exes[0].fulfill()
|
||||
}.silenceWarning()
|
||||
promise.done { _ in
|
||||
XCTAssertEqual(++orderValidator, 2)
|
||||
exes[1].fulfill()
|
||||
}.silenceWarning()
|
||||
promise.done { _ in
|
||||
XCTAssertEqual(++orderValidator, 3)
|
||||
exes[2].fulfill()
|
||||
}.silenceWarning()
|
||||
}
|
||||
}
|
||||
describe("even when one handler is added inside another handler") {
|
||||
testFulfilled(withExpectationCount: 3) { promise, exes, memo in
|
||||
var x = 0
|
||||
promise.done { _ in
|
||||
XCTAssertEqual(x, 0)
|
||||
x += 1
|
||||
exes[0].fulfill()
|
||||
promise.done { _ in
|
||||
XCTAssertEqual(x, 2)
|
||||
x += 1
|
||||
exes[1].fulfill()
|
||||
}.silenceWarning()
|
||||
}.silenceWarning()
|
||||
promise.done { _ in
|
||||
XCTAssertEqual(x, 1)
|
||||
x += 1
|
||||
exes[2].fulfill()
|
||||
}.silenceWarning()
|
||||
}
|
||||
}
|
||||
}
|
||||
describe("2.2.6.2: If/when `promise` is rejected, all respective `onRejected` callbacks must execute in the order of their originating calls to `then`.") {
|
||||
describe("multiple boring rejection handlers") {
|
||||
testRejected(withExpectationCount: 4) { promise, exes, sentinel in
|
||||
var ticket = 0
|
||||
|
||||
promise.catch { err in
|
||||
guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }
|
||||
XCTAssertEqual(++ticket, 1)
|
||||
exes[0].fulfill()
|
||||
}
|
||||
promise.done { _ in XCTFail() }.silenceWarning()
|
||||
promise.catch { err in
|
||||
guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }
|
||||
XCTAssertEqual(++ticket, 2)
|
||||
exes[1].fulfill()
|
||||
}
|
||||
promise.done { _ in XCTFail() }.silenceWarning()
|
||||
promise.catch { err in
|
||||
guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }
|
||||
XCTAssertEqual(++ticket, 3)
|
||||
exes[2].fulfill()
|
||||
}
|
||||
promise.done { _ in XCTFail() }.silenceWarning()
|
||||
promise.catch { err in
|
||||
guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }
|
||||
XCTAssertEqual(++ticket, 4)
|
||||
exes[3].fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
describe("multiple rejection handlers, one of which throws") {
|
||||
testRejected(withExpectationCount: 4) { promise, exes, sentinel in
|
||||
var orderValidator = 0
|
||||
|
||||
promise.catch { err in
|
||||
guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }
|
||||
XCTAssertEqual(++orderValidator, 1)
|
||||
exes[0].fulfill()
|
||||
}
|
||||
promise.done { _ in XCTFail() }.silenceWarning()
|
||||
promise.catch { err in
|
||||
guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }
|
||||
XCTAssertEqual(++orderValidator, 2)
|
||||
exes[1].fulfill()
|
||||
}
|
||||
promise.done { _ in XCTFail() }.silenceWarning()
|
||||
promise.recover { err -> Promise<UInt32> in
|
||||
if case Error.sentinel(let x) = err {
|
||||
XCTAssertEqual(x, sentinel)
|
||||
} else {
|
||||
XCTFail()
|
||||
}
|
||||
XCTAssertEqual(++orderValidator, 3)
|
||||
exes[2].fulfill()
|
||||
throw Error.dummy
|
||||
}.silenceWarning()
|
||||
promise.done { _ in XCTFail() }.silenceWarning()
|
||||
promise.catch { err in
|
||||
guard case Error.sentinel(let x) = err, x == sentinel else { return XCTFail() }
|
||||
XCTAssertEqual(++orderValidator, 4)
|
||||
exes[3].fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
describe("results in multiple branching chains with their own fulfillment values") {
|
||||
testRejected(withExpectationCount: 3) { promise, exes, memo in
|
||||
let sentinel1 = arc4random()
|
||||
let sentinel2 = arc4random()
|
||||
let sentinel3 = arc4random()
|
||||
|
||||
promise.recover { _ in
|
||||
return .value(sentinel1)
|
||||
}.done { value in
|
||||
XCTAssertEqual(sentinel1, value)
|
||||
exes[0].fulfill()
|
||||
}
|
||||
|
||||
promise.recover { _ -> Promise<UInt32> in
|
||||
throw Error.sentinel(sentinel2)
|
||||
}.catch { err in
|
||||
if case Error.sentinel(let x) = err, x == sentinel2 {
|
||||
exes[1].fulfill()
|
||||
}
|
||||
}
|
||||
|
||||
promise.recover { _ in
|
||||
.value(sentinel3)
|
||||
}.done { value in
|
||||
XCTAssertEqual(value, sentinel3)
|
||||
exes[2].fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
describe("`onRejected` handlers are called in the original order") {
|
||||
testRejected(withExpectationCount: 3) { promise, exes, memo in
|
||||
var x = 0
|
||||
|
||||
promise.catch { _ in
|
||||
XCTAssertEqual(x, 0)
|
||||
x += 1
|
||||
exes[0].fulfill()
|
||||
}
|
||||
promise.catch { _ in
|
||||
XCTAssertEqual(x, 1)
|
||||
x += 1
|
||||
exes[1].fulfill()
|
||||
}
|
||||
promise.catch { _ in
|
||||
XCTAssertEqual(x, 2)
|
||||
x += 1
|
||||
exes[2].fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
describe("even when one handler is added inside another handler") {
|
||||
testRejected(withExpectationCount: 3) { promise, exes, memo in
|
||||
var x = 0
|
||||
|
||||
promise.catch { _ in
|
||||
XCTAssertEqual(x, 0)
|
||||
x += 1
|
||||
exes[0].fulfill()
|
||||
promise.catch { _ in
|
||||
XCTAssertEqual(x, 2)
|
||||
x += 1
|
||||
exes[1].fulfill()
|
||||
}
|
||||
}
|
||||
promise.catch { _ in
|
||||
XCTAssertEqual(x, 1)
|
||||
x += 1
|
||||
exes[2].fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
33
Carthage/Checkouts/PromiseKit/Tests/A+/2.2.7.swift
vendored
Normal file
33
Carthage/Checkouts/PromiseKit/Tests/A+/2.2.7.swift
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class Test227: XCTestCase {
|
||||
func test() {
|
||||
describe("2.2.7: `then` must return a promise: `promise2 = promise1.then(onFulfilled, onRejected)") {
|
||||
describe("2.2.7.2: If either `onFulfilled` or `onRejected` throws an exception `e`, `promise2` must be rejected with `e` as the reason.") {
|
||||
|
||||
testFulfilled { promise1, expectation, _ in
|
||||
let sentinel = arc4random()
|
||||
let promise2 = promise1.done { _ in throw Error.sentinel(sentinel) }
|
||||
|
||||
promise2.catch {
|
||||
if case Error.sentinel(let x) = $0, x == sentinel {
|
||||
expectation.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testRejected { promise1, expectation, _ in
|
||||
let sentinel = arc4random()
|
||||
let promise2 = promise1.recover { _ -> Promise<UInt32> in throw Error.sentinel(sentinel) }
|
||||
|
||||
promise2.catch { error in
|
||||
if case Error.sentinel(let x) = error, x == sentinel {
|
||||
expectation.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
31
Carthage/Checkouts/PromiseKit/Tests/A+/2.3.1.swift
vendored
Normal file
31
Carthage/Checkouts/PromiseKit/Tests/A+/2.3.1.swift
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class Test231: XCTestCase {
|
||||
func test() {
|
||||
describe("2.3.1: If `promise` and `x` refer to the same object, reject `promise` with a `TypeError' as the reason.") {
|
||||
specify("via return from a fulfilled promise") { d, expectation in
|
||||
var promise: Promise<Void>!
|
||||
promise = Promise().then { () -> Promise<Void> in
|
||||
return promise
|
||||
}
|
||||
promise.catch { err in
|
||||
if case PMKError.returnedSelf = err {
|
||||
expectation.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
specify("via return from a rejected promise") { d, expectation in
|
||||
var promise: Promise<Void>!
|
||||
promise = Promise<Void>(error: Error.dummy).recover { _ -> Promise<Void> in
|
||||
return promise
|
||||
}
|
||||
promise.catch { err in
|
||||
if case PMKError.returnedSelf = err {
|
||||
expectation.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
116
Carthage/Checkouts/PromiseKit/Tests/A+/2.3.2.swift
vendored
Normal file
116
Carthage/Checkouts/PromiseKit/Tests/A+/2.3.2.swift
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class Test232: XCTestCase {
|
||||
func test() {
|
||||
describe("2.3.2: If `x` is a promise, adopt its state") {
|
||||
describe("2.3.2.1: If `x` is pending, `promise` must remain pending until `x` is fulfilled or rejected.") {
|
||||
|
||||
func xFactory() -> Promise<UInt32> {
|
||||
return Promise.pending().promise
|
||||
}
|
||||
|
||||
testPromiseResolution(factory: xFactory) { promise, expectation in
|
||||
var wasFulfilled = false;
|
||||
var wasRejected = false;
|
||||
|
||||
promise.test(onFulfilled: { wasFulfilled = true }, onRejected: { wasRejected = true })
|
||||
|
||||
after(ticks: 4) {
|
||||
XCTAssertFalse(wasFulfilled)
|
||||
XCTAssertFalse(wasRejected)
|
||||
expectation.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe("2.3.2.2: If/when `x` is fulfilled, fulfill `promise` with the same value.") {
|
||||
describe("`x` is already-fulfilled") {
|
||||
let sentinel = arc4random()
|
||||
|
||||
func xFactory() -> Promise<UInt32> {
|
||||
return .value(sentinel)
|
||||
}
|
||||
|
||||
testPromiseResolution(factory: xFactory) { promise, expectation in
|
||||
promise.done {
|
||||
XCTAssertEqual($0, sentinel)
|
||||
expectation.fulfill()
|
||||
}.silenceWarning()
|
||||
}
|
||||
}
|
||||
describe("`x` is eventually-fulfilled") {
|
||||
let sentinel = arc4random()
|
||||
|
||||
func xFactory() -> Promise<UInt32> {
|
||||
return Promise { seal in
|
||||
after(ticks: 2) {
|
||||
seal.fulfill(sentinel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testPromiseResolution(factory: xFactory) { promise, expectation in
|
||||
promise.done {
|
||||
XCTAssertEqual($0, sentinel)
|
||||
expectation.fulfill()
|
||||
}.silenceWarning()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe("2.3.2.3: If/when `x` is rejected, reject `promise` with the same reason.") {
|
||||
describe("`x` is already-rejected") {
|
||||
let sentinel = arc4random()
|
||||
|
||||
func xFactory() -> Promise<UInt32> {
|
||||
return Promise(error: Error.sentinel(sentinel))
|
||||
}
|
||||
|
||||
testPromiseResolution(factory: xFactory) { promise, expectation in
|
||||
promise.catch { err in
|
||||
if case Error.sentinel(let value) = err, value == sentinel {
|
||||
expectation.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
describe("`x` is eventually-rejected") {
|
||||
let sentinel = arc4random()
|
||||
|
||||
func xFactory() -> Promise<UInt32> {
|
||||
return Promise { seal in
|
||||
after(ticks: 2) {
|
||||
seal.reject(Error.sentinel(sentinel))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testPromiseResolution(factory: xFactory) { promise, expectation in
|
||||
promise.catch { err in
|
||||
if case Error.sentinel(let value) = err, value == sentinel {
|
||||
expectation.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extension Test232 {
|
||||
fileprivate func testPromiseResolution(factory: @escaping () -> Promise<UInt32>, line: UInt = #line, test: (Promise<UInt32>, XCTestExpectation) -> Void) {
|
||||
specify("via return from a fulfilled promise", file: #file, line: line) { d, expectation in
|
||||
let promise = Promise.value(arc4random()).then { _ in factory() }
|
||||
test(promise, expectation)
|
||||
}
|
||||
specify("via return from a rejected promise", file: #file, line: line) { d, expectation in
|
||||
let promise: Promise<UInt32> = Promise(error: Error.dummy).recover { _ in factory() }
|
||||
test(promise, expectation)
|
||||
}
|
||||
}
|
||||
}
|
26
Carthage/Checkouts/PromiseKit/Tests/A+/2.3.4.swift
vendored
Normal file
26
Carthage/Checkouts/PromiseKit/Tests/A+/2.3.4.swift
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
|
||||
class Test234: XCTestCase {
|
||||
func test() {
|
||||
describe("2.3.4: If `x` is not an object or function, fulfill `promise` with `x`") {
|
||||
testFulfilled { promise, exception, _ in
|
||||
promise.map { value -> UInt32 in
|
||||
return 1
|
||||
}.done { value in
|
||||
XCTAssertEqual(value, 1)
|
||||
exception.fulfill()
|
||||
}.silenceWarning()
|
||||
}
|
||||
testRejected { promise, expectation, _ in
|
||||
promise.recover { _ -> Promise<UInt32> in
|
||||
return .value(UInt32(1))
|
||||
}.done { value in
|
||||
XCTAssertEqual(value, 1)
|
||||
expectation.fulfill()
|
||||
}.silenceWarning()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
Carthage/Checkouts/PromiseKit/Tests/A+/README.md
vendored
Normal file
13
Carthage/Checkouts/PromiseKit/Tests/A+/README.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
Resources
|
||||
=========
|
||||
* https://github.com/promises-aplus/promises-tests
|
||||
|
||||
|
||||
Skipped
|
||||
=======
|
||||
* 2.3.3: Otherwise, if x is an object or function.
|
||||
This spec is a NOOP for Swift:
|
||||
- We have decided not to interact with other Promises A+ implementations
|
||||
- functions cannot have properties
|
||||
* 2.3.3.4: If then is not a function, fulfill promise with x.
|
||||
- See: The 2.3.4 suite.
|
34
Carthage/Checkouts/PromiseKit/Tests/Bridging/BridgingTests.m
vendored
Normal file
34
Carthage/Checkouts/PromiseKit/Tests/Bridging/BridgingTests.m
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
@import PromiseKit;
|
||||
@import XCTest;
|
||||
#import "Infrastructure.h"
|
||||
|
||||
|
||||
@interface BridgingTests: XCTestCase @end @implementation BridgingTests
|
||||
|
||||
- (void)testChainAnyPromiseFromSwiftCode {
|
||||
XCTestExpectation *ex = [self expectationWithDescription:@""];
|
||||
AnyPromise *promise = PMKAfter(0.02);
|
||||
for (int x = 0; x < 100; ++x) {
|
||||
promise = promise.then(^{
|
||||
return [[[PromiseBridgeHelper alloc] init] bridge1];
|
||||
});
|
||||
}
|
||||
promise.then(^{
|
||||
[ex fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:20 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test626 {
|
||||
XCTestExpectation *ex = [self expectationWithDescription:@""];
|
||||
|
||||
testCase626().then(^{
|
||||
XCTFail();
|
||||
}).ensure(^{
|
||||
[ex fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:20 handler:nil];
|
||||
}
|
||||
|
||||
@end
|
280
Carthage/Checkouts/PromiseKit/Tests/Bridging/BridgingTests.swift
vendored
Normal file
280
Carthage/Checkouts/PromiseKit/Tests/Bridging/BridgingTests.swift
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
import Foundation
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class BridgingTests: XCTestCase {
|
||||
|
||||
func testCanBridgeAnyObject() {
|
||||
let sentinel = NSURLRequest()
|
||||
let p = Promise.value(sentinel)
|
||||
let ap = AnyPromise(p)
|
||||
|
||||
XCTAssertEqual(ap.value(forKey: "value") as? NSURLRequest, sentinel)
|
||||
}
|
||||
|
||||
func testCanBridgeOptional() {
|
||||
let sentinel: NSURLRequest? = NSURLRequest()
|
||||
let p = Promise.value(sentinel)
|
||||
let ap = AnyPromise(p)
|
||||
|
||||
XCTAssertEqual(ap.value(forKey: "value") as? NSURLRequest, sentinel)
|
||||
}
|
||||
|
||||
func testCanBridgeSwiftArray() {
|
||||
let sentinel = [NSString(), NSString(), NSString()]
|
||||
let p = Promise.value(sentinel)
|
||||
let ap = AnyPromise(p)
|
||||
|
||||
guard let foo = ap.value(forKey: "value") as? [NSString] else { return XCTFail() }
|
||||
XCTAssertEqual(foo, sentinel)
|
||||
}
|
||||
|
||||
func testCanBridgeSwiftDictionary() {
|
||||
let sentinel = [NSString(): NSString()]
|
||||
let p = Promise.value(sentinel)
|
||||
let ap = AnyPromise(p)
|
||||
|
||||
guard let foo = ap.value(forKey: "value") as? [NSString: NSString] else { return XCTFail() }
|
||||
XCTAssertEqual(foo, sentinel)
|
||||
}
|
||||
|
||||
func testCanBridgeInt() {
|
||||
let sentinel = 3
|
||||
let p = Promise.value(sentinel)
|
||||
let ap = AnyPromise(p)
|
||||
XCTAssertEqual(ap.value(forKey: "value") as? Int, sentinel)
|
||||
}
|
||||
|
||||
func testCanBridgeString() {
|
||||
let sentinel = "a"
|
||||
let p = Promise.value(sentinel)
|
||||
let ap = AnyPromise(p)
|
||||
XCTAssertEqual(ap.value(forKey: "value") as? String, sentinel)
|
||||
}
|
||||
|
||||
func testCanBridgeBool() {
|
||||
let sentinel = true
|
||||
let p = Promise.value(sentinel)
|
||||
let ap = AnyPromise(p)
|
||||
XCTAssertEqual(ap.value(forKey: "value") as? Bool, sentinel)
|
||||
}
|
||||
|
||||
func testCanChainOffAnyPromiseFromObjC() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
firstly {
|
||||
.value(1)
|
||||
}.then { _ -> AnyPromise in
|
||||
return PromiseBridgeHelper().value(forKey: "bridge2") as! AnyPromise
|
||||
}.done { value in
|
||||
XCTAssertEqual(123, value as? Int)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testCanThenOffAnyPromise() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
PMKDummyAnyPromise_YES().then { obj -> Promise<Void> in
|
||||
if let value = obj as? NSNumber {
|
||||
XCTAssertEqual(value, NSNumber(value: true))
|
||||
ex.fulfill()
|
||||
}
|
||||
return Promise()
|
||||
}.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testCanThenOffManifoldAnyPromise() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
PMKDummyAnyPromise_Manifold().then { obj -> Promise<Void> in
|
||||
defer { ex.fulfill() }
|
||||
XCTAssertEqual(obj as? NSNumber, NSNumber(value: true), "\(obj ?? "nil") is not @YES")
|
||||
return Promise()
|
||||
}.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testCanAlwaysOffAnyPromise() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
PMKDummyAnyPromise_YES().then { obj -> Promise<Void> in
|
||||
ex.fulfill()
|
||||
return Promise()
|
||||
}.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testCanCatchOffAnyPromise() {
|
||||
let ex = expectation(description: "")
|
||||
PMKDummyAnyPromise_Error().catch { err in
|
||||
ex.fulfill()
|
||||
}
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testAsPromise() {
|
||||
#if swift(>=3.1)
|
||||
XCTAssertTrue(Promise(PMKDummyAnyPromise_Error()).isRejected)
|
||||
XCTAssertEqual(Promise(PMKDummyAnyPromise_YES()).value as? NSNumber, NSNumber(value: true))
|
||||
#else
|
||||
XCTAssertTrue(PMKDummyAnyPromise_Error().asPromise().isRejected)
|
||||
XCTAssertEqual(PMKDummyAnyPromise_YES().asPromise().value as? NSNumber, NSNumber(value: true))
|
||||
#endif
|
||||
}
|
||||
|
||||
func testFirstlyReturningAnyPromiseSuccess() {
|
||||
let ex = expectation(description: "")
|
||||
firstly {
|
||||
PMKDummyAnyPromise_Error()
|
||||
}.catch { error in
|
||||
ex.fulfill()
|
||||
}
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testFirstlyReturningAnyPromiseError() {
|
||||
let ex = expectation(description: "")
|
||||
firstly {
|
||||
PMKDummyAnyPromise_YES()
|
||||
}.done { _ in
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func test1() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
// AnyPromise.then { return x }
|
||||
|
||||
let input = after(seconds: 0).map{ 1 }
|
||||
|
||||
AnyPromise(input).then { obj -> Promise<Int> in
|
||||
XCTAssertEqual(obj as? Int, 1)
|
||||
return .value(2)
|
||||
}.done { value in
|
||||
XCTAssertEqual(value, 2)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func test2() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
// AnyPromise.then { return AnyPromise }
|
||||
|
||||
let input = after(seconds: 0).map{ 1 }
|
||||
|
||||
AnyPromise(input).then { obj -> AnyPromise in
|
||||
XCTAssertEqual(obj as? Int, 1)
|
||||
return AnyPromise(after(seconds: 0).map{ 2 })
|
||||
}.done { obj in
|
||||
XCTAssertEqual(obj as? Int, 2)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func test3() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
// AnyPromise.then { return Promise<Int> }
|
||||
|
||||
let input = after(seconds: 0).map{ 1 }
|
||||
|
||||
AnyPromise(input).then { obj -> Promise<Int> in
|
||||
XCTAssertEqual(obj as? Int, 1)
|
||||
return after(seconds: 0).map{ 2 }
|
||||
}.done { value in
|
||||
XCTAssertEqual(value, 2)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
|
||||
// can return AnyPromise (that fulfills) in then handler
|
||||
func test4() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value(1).then { _ -> AnyPromise in
|
||||
return AnyPromise(after(seconds: 0).map{ 1 })
|
||||
}.done { x in
|
||||
XCTAssertEqual(x as? Int, 1)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
// can return AnyPromise (that rejects) in then handler
|
||||
func test5() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
Promise.value(1).then { _ -> AnyPromise in
|
||||
let promise = after(.milliseconds(100)).done{ throw Error.dummy }
|
||||
return AnyPromise(promise)
|
||||
}.catch { err in
|
||||
ex.fulfill()
|
||||
}
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testStandardSwiftBridgeIsUnambiguous() {
|
||||
let p = Promise.value(1)
|
||||
let q = Promise(p)
|
||||
|
||||
XCTAssertEqual(p.value, q.value)
|
||||
}
|
||||
|
||||
/// testing NSError to Error for cancelledError types
|
||||
func testErrorCancellationBridging() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
let p = Promise().done {
|
||||
throw LocalError.cancel as NSError
|
||||
}
|
||||
p.catch { _ in
|
||||
XCTFail()
|
||||
}
|
||||
p.catch(policy: .allErrors) {
|
||||
XCTAssertTrue($0.isCancelled)
|
||||
ex.fulfill()
|
||||
}
|
||||
waitForExpectations(timeout: 1)
|
||||
|
||||
// here we verify that Swift’s NSError bridging works as advertised
|
||||
|
||||
XCTAssertTrue(LocalError.cancel.isCancelled)
|
||||
XCTAssertTrue((LocalError.cancel as NSError).isCancelled)
|
||||
}
|
||||
}
|
||||
|
||||
private enum Error: Swift.Error {
|
||||
case dummy
|
||||
}
|
||||
|
||||
extension Promise {
|
||||
func silenceWarning() {}
|
||||
}
|
||||
|
||||
private enum LocalError: CancellableError {
|
||||
case notCancel
|
||||
case cancel
|
||||
|
||||
var isCancelled: Bool {
|
||||
switch self {
|
||||
case .notCancel: return false
|
||||
case .cancel: return true
|
||||
}
|
||||
}
|
||||
}
|
14
Carthage/Checkouts/PromiseKit/Tests/Bridging/Infrastructure.h
vendored
Normal file
14
Carthage/Checkouts/PromiseKit/Tests/Bridging/Infrastructure.h
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
@import Foundation;
|
||||
@class AnyPromise;
|
||||
|
||||
AnyPromise *PMKDummyAnyPromise_YES(void);
|
||||
AnyPromise *PMKDummyAnyPromise_Manifold(void);
|
||||
AnyPromise *PMKDummyAnyPromise_Error(void);
|
||||
|
||||
__attribute__((objc_runtime_name("PMKPromiseBridgeHelper")))
|
||||
__attribute__((objc_subclassing_restricted))
|
||||
@interface PromiseBridgeHelper: NSObject
|
||||
- (AnyPromise *)bridge1;
|
||||
@end
|
||||
|
||||
AnyPromise *testCase626(void);
|
38
Carthage/Checkouts/PromiseKit/Tests/Bridging/Infrastructure.m
vendored
Normal file
38
Carthage/Checkouts/PromiseKit/Tests/Bridging/Infrastructure.m
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
@import Foundation;
|
||||
@import PromiseKit;
|
||||
#import "Infrastructure.h"
|
||||
|
||||
AnyPromise *PMKDummyAnyPromise_YES() {
|
||||
return [AnyPromise promiseWithValue:@YES];
|
||||
}
|
||||
|
||||
AnyPromise *PMKDummyAnyPromise_Manifold() {
|
||||
return [AnyPromise promiseWithValue:PMKManifold(@YES, @NO, @NO)];
|
||||
}
|
||||
|
||||
AnyPromise *PMKDummyAnyPromise_Error() {
|
||||
return [AnyPromise promiseWithValue:[NSError errorWithDomain:@"a" code:1 userInfo:nil]];
|
||||
}
|
||||
|
||||
@implementation PromiseBridgeHelper (objc)
|
||||
|
||||
- (AnyPromise *)bridge2 {
|
||||
return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
resolve(@123);
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#import "PMKBridgeTests-Swift.h"
|
||||
|
||||
AnyPromise *testCase626() {
|
||||
return PMKWhen(@[[TestPromise626 promise], [TestPromise626 promise]]).then(^(id value){
|
||||
NSLog(@"Success: %@", value);
|
||||
}).catch(^(NSError *error) {
|
||||
NSLog(@"Error: %@", error);
|
||||
@throw error;
|
||||
});
|
||||
}
|
24
Carthage/Checkouts/PromiseKit/Tests/Bridging/Infrastructure.swift
vendored
Normal file
24
Carthage/Checkouts/PromiseKit/Tests/Bridging/Infrastructure.swift
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import PromiseKit
|
||||
|
||||
// for BridgingTests.m
|
||||
@objc(PMKPromiseBridgeHelper) class PromiseBridgeHelper: NSObject {
|
||||
@objc func bridge1() -> AnyPromise {
|
||||
let p = after(.milliseconds(10))
|
||||
return AnyPromise(p)
|
||||
}
|
||||
}
|
||||
|
||||
enum MyError: Error {
|
||||
case PromiseError
|
||||
}
|
||||
|
||||
@objc class TestPromise626: NSObject {
|
||||
|
||||
@objc class func promise() -> AnyPromise {
|
||||
let promise: Promise<String> = Promise { seal in
|
||||
seal.reject(MyError.PromiseError)
|
||||
}
|
||||
|
||||
return AnyPromise(promise)
|
||||
}
|
||||
}
|
896
Carthage/Checkouts/PromiseKit/Tests/CoreObjC/AnyPromiseTests.m
vendored
Normal file
896
Carthage/Checkouts/PromiseKit/Tests/CoreObjC/AnyPromiseTests.m
vendored
Normal file
@@ -0,0 +1,896 @@
|
||||
@import PromiseKit;
|
||||
@import XCTest;
|
||||
#import "Infrastructure.h"
|
||||
#define PMKTestErrorDomain @"PMKTestErrorDomain"
|
||||
|
||||
static inline NSError *dummyWithCode(NSInteger code) {
|
||||
return [NSError errorWithDomain:PMKTestErrorDomain code:rand() userInfo:@{NSLocalizedDescriptionKey: @(code).stringValue}];
|
||||
}
|
||||
|
||||
static inline NSError *dummy() {
|
||||
return dummyWithCode(rand());
|
||||
}
|
||||
|
||||
static inline AnyPromise *rejectLater() {
|
||||
return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
resolve(dummy());
|
||||
});
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
static inline AnyPromise *fulfillLater() {
|
||||
return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
dispatch_async(dispatch_get_global_queue(0, 0), ^{
|
||||
resolve(@1);
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@interface AnyPromiseTestSuite : XCTestCase @end @implementation AnyPromiseTestSuite
|
||||
|
||||
- (void)test_01_resolve {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@1);
|
||||
}];
|
||||
promise.then(^(NSNumber *o){
|
||||
[ex1 fulfill];
|
||||
XCTAssertEqual(o.intValue, 1);
|
||||
});
|
||||
promise.catch(^{
|
||||
XCTFail();
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_02_reject {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(dummyWithCode(2));
|
||||
}];
|
||||
promise.then(^{
|
||||
XCTFail();
|
||||
});
|
||||
promise.catch(^(NSError *error){
|
||||
XCTAssertEqualObjects(error.localizedDescription, @"2");
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_03_return_error {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@2);
|
||||
}];
|
||||
promise.then(^{
|
||||
return [NSError errorWithDomain:@"a" code:3 userInfo:nil];
|
||||
}).catch(^(NSError *e){
|
||||
[ex1 fulfill];
|
||||
XCTAssertEqual(3, e.code);
|
||||
});
|
||||
promise.catch(^{
|
||||
XCTFail();
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_04_return_error_doesnt_compromise_result {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@4);
|
||||
}].then(^{
|
||||
return dummy();
|
||||
});
|
||||
promise.then(^{
|
||||
XCTFail();
|
||||
});
|
||||
promise.catch(^{
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_05_throw_and_bubble {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@5);
|
||||
}].then(^(id ii){
|
||||
XCTAssertEqual(5, [ii intValue]);
|
||||
return [NSError errorWithDomain:@"a" code:[ii intValue] userInfo:nil];
|
||||
}).catch(^(NSError *e){
|
||||
XCTAssertEqual(e.code, 5);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_05_throw_and_bubble_more {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@5);
|
||||
}].then(^{
|
||||
return dummy();
|
||||
}).then(^{
|
||||
//NOOP
|
||||
}).catch(^(NSError *e){
|
||||
[ex1 fulfill];
|
||||
XCTAssertEqualObjects(e.domain, PMKTestErrorDomain);
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_06_return_error {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@5);
|
||||
}].then(^{
|
||||
return dummy();
|
||||
}).catch(^{
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_07_can_then_resolved {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@1);
|
||||
}].then(^(id o){
|
||||
[ex1 fulfill];
|
||||
XCTAssertEqualObjects(@1, o);
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_07a_can_fail_rejected {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(dummyWithCode(1));
|
||||
}].catch(^(NSError *e){
|
||||
[ex1 fulfill];
|
||||
XCTAssertEqualObjects(@"1", e.localizedDescription);
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_09_async {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
__block int x = 0;
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@1);
|
||||
}].then(^{
|
||||
XCTAssertEqual(x, 0);
|
||||
x++;
|
||||
}).then(^{
|
||||
XCTAssertEqual(x, 1);
|
||||
x++;
|
||||
}).then(^{
|
||||
XCTAssertEqual(x, 2);
|
||||
x++;
|
||||
}).then(^{
|
||||
XCTAssertEqual(x, 3);
|
||||
x++;
|
||||
}).then(^{
|
||||
XCTAssertEqual(x, 4);
|
||||
x++;
|
||||
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
|
||||
XCTAssertEqual(x, 5);
|
||||
}
|
||||
|
||||
- (void)test_10_then_returns_resolved_promise {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@10);
|
||||
}].then(^(id o){
|
||||
XCTAssertEqualObjects(@10, o);
|
||||
return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@100);
|
||||
}];
|
||||
}).then(^(id o){
|
||||
XCTAssertEqualObjects(@100, o);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_11_then_returns_pending_promise {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@1);
|
||||
}].then(^{
|
||||
return fulfillLater();
|
||||
}).then(^(id o){
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_12_then_returns_recursive_promises {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
id ex2 = [self expectationWithDescription:@""];
|
||||
|
||||
__block int x = 0;
|
||||
fulfillLater().then(^{
|
||||
NSLog(@"1");
|
||||
XCTAssertEqual(x++, 0);
|
||||
return fulfillLater().then(^{
|
||||
NSLog(@"2");
|
||||
XCTAssertEqual(x++, 1);
|
||||
return fulfillLater().then(^{
|
||||
NSLog(@"3");
|
||||
XCTAssertEqual(x++, 2);
|
||||
return fulfillLater().then(^{
|
||||
NSLog(@"4");
|
||||
XCTAssertEqual(x++, 3);
|
||||
[ex2 fulfill];
|
||||
return @"foo";
|
||||
});
|
||||
});
|
||||
});
|
||||
}).then(^(id o){
|
||||
NSLog(@"5");
|
||||
XCTAssertEqualObjects(@"foo", o);
|
||||
XCTAssertEqual(x++, 4);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
|
||||
XCTAssertEqual(x, 5);
|
||||
}
|
||||
|
||||
- (void)test_13_then_returns_recursive_promises_that_fails {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
id ex2 = [self expectationWithDescription:@""];
|
||||
|
||||
fulfillLater().then(^{
|
||||
return fulfillLater().then(^{
|
||||
return fulfillLater().then(^{
|
||||
return fulfillLater().then(^{
|
||||
[ex2 fulfill];
|
||||
return dummy();
|
||||
});
|
||||
});
|
||||
});
|
||||
}).then(^{
|
||||
XCTFail();
|
||||
}).catch(^(NSError *e){
|
||||
XCTAssertEqualObjects(e.domain, PMKTestErrorDomain);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_14_fail_returns_value {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@1);
|
||||
}].then(^{
|
||||
return [NSError errorWithDomain:@"a" code:1 userInfo:nil];
|
||||
}).catch(^(NSError *e){
|
||||
XCTAssertEqual(e.code, 1);
|
||||
return @2;
|
||||
}).then(^(id o){
|
||||
XCTAssertEqualObjects(o, @2);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_15_fail_returns_promise {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@1);
|
||||
}].then(^{
|
||||
return dummy();
|
||||
}).catch(^{
|
||||
return fulfillLater().then(^{
|
||||
return @123;
|
||||
});
|
||||
}).then(^(id o){
|
||||
XCTAssertEqualObjects(o, @123);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_23_add_another_fail_to_already_rejected {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
id ex2 = [self expectationWithDescription:@""];
|
||||
|
||||
PMKResolver resolve;
|
||||
AnyPromise *promise = [[AnyPromise alloc] initWithResolver:&resolve];
|
||||
|
||||
promise.then(^{
|
||||
XCTFail();
|
||||
}).catch(^(NSError *e){
|
||||
XCTAssertEqualObjects(e.localizedDescription, @"23");
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
resolve(dummyWithCode(23));
|
||||
|
||||
promise.then(^{
|
||||
XCTFail();
|
||||
}).catch(^(NSError *e){
|
||||
XCTAssertEqualObjects(e.localizedDescription, @"23");
|
||||
[ex2 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_25_then_plus_deferred_plus_GCD {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
id ex2 = [self expectationWithDescription:@""];
|
||||
id ex3 = [self expectationWithDescription:@""];
|
||||
|
||||
fulfillLater().then(^(id o){
|
||||
[ex1 fulfill];
|
||||
return fulfillLater().then(^{
|
||||
return @YES;
|
||||
});
|
||||
}).then(^(id o){
|
||||
XCTAssertEqualObjects(@YES, o);
|
||||
[ex2 fulfill];
|
||||
}).then(^(id o){
|
||||
XCTAssertNil(o);
|
||||
[ex3 fulfill];
|
||||
}).catch(^{
|
||||
XCTFail();
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_26_promise_then_promise_fail_promise_fail {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
fulfillLater().then(^{
|
||||
return fulfillLater().then(^{
|
||||
return dummy();
|
||||
}).catch(^{
|
||||
return fulfillLater().then(^{
|
||||
return dummy();
|
||||
});
|
||||
});
|
||||
}).then(^{
|
||||
XCTFail();
|
||||
}).catch(^{
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];}
|
||||
|
||||
- (void)test_27_eat_failure {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
fulfillLater().then(^{
|
||||
return dummy();
|
||||
}).catch(^{
|
||||
return @YES;
|
||||
}).then(^{
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_28_deferred_rejected_catch_promise {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
id ex2 = [self expectationWithDescription:@""];
|
||||
|
||||
rejectLater().catch(^{
|
||||
[ex1 fulfill];
|
||||
return fulfillLater();
|
||||
}).then(^(id o){
|
||||
[ex2 fulfill];
|
||||
}).catch(^{
|
||||
XCTFail();
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_29_deferred_rejected_catch_promise {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
id ex2 = [self expectationWithDescription:@""];
|
||||
|
||||
rejectLater().catch(^{
|
||||
[ex1 fulfill];
|
||||
return fulfillLater().then(^{
|
||||
return dummy();
|
||||
});
|
||||
}).then(^{
|
||||
XCTFail(@"1");
|
||||
}).catch(^(NSError *error){
|
||||
[ex2 fulfill];
|
||||
}).catch(^{
|
||||
XCTFail(@"2");
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_30_dispatch_returns_pending_promise {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
dispatch_promise(^{
|
||||
return fulfillLater();
|
||||
}).then(^{
|
||||
[ex1 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_31_dispatch_returns_promise {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
dispatch_promise(^{
|
||||
return [AnyPromise promiseWithValue:@1];
|
||||
}).then(^(id o){
|
||||
XCTAssertEqualObjects(o, @1);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_32_return_primitive {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
__block void (^fulfiller)(id) = nil;
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
fulfiller = resolve;
|
||||
}].then(^(id o){
|
||||
XCTAssertEqualObjects(o, @32);
|
||||
return 3;
|
||||
}).then(^(id o){
|
||||
XCTAssertEqualObjects(@3, o);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
fulfiller(@32);
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_33_return_nil {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
[AnyPromise promiseWithValue:@1].then(^(id o){
|
||||
XCTAssertEqualObjects(o, @1);
|
||||
return nil;
|
||||
}).then(^{
|
||||
return nil;
|
||||
}).then(^(id o){
|
||||
XCTAssertNil(o);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_33a_return_nil {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
id ex2 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithValue:@"HI"].then(^(id o){
|
||||
XCTAssertEqualObjects(o, @"HI");
|
||||
[ex1 fulfill];
|
||||
return nil;
|
||||
}).then(^{
|
||||
return nil;
|
||||
}).then(^{
|
||||
[ex2 fulfill];
|
||||
return nil;
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_36_promise_with_value_nil {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithValue:nil].then(^(id o){
|
||||
XCTAssertNil(o);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_42 {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithValue:@1].then(^{
|
||||
return fulfillLater();
|
||||
}).then(^{
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_43_return_promise_from_itself {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
AnyPromise *p = fulfillLater().then(^{ return @1; });
|
||||
p.then(^{
|
||||
return p;
|
||||
}).then(^{
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_44_reseal {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(@123);
|
||||
resolve(@234);
|
||||
}].then(^(id o){
|
||||
XCTAssertEqualObjects(o, @123);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_46_test_then_on {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
dispatch_queue_t q1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
|
||||
dispatch_queue_t q2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
[AnyPromise promiseWithValue:@1].thenOn(q1, ^{
|
||||
XCTAssertFalse([NSThread isMainThread]);
|
||||
return dispatch_get_current_queue();
|
||||
}).thenOn(q2, ^(id q){
|
||||
XCTAssertFalse([NSThread isMainThread]);
|
||||
XCTAssertNotEqualObjects(q, dispatch_get_current_queue());
|
||||
[ex1 fulfill];
|
||||
});
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_47_finally_plus {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithValue:@1].then(^{
|
||||
return @1;
|
||||
}).ensure(^{
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_48_finally_negative {
|
||||
@autoreleasepool {
|
||||
id ex1 = [self expectationWithDescription:@"always"];
|
||||
id ex2 = [self expectationWithDescription:@"errorUnhandler"];
|
||||
|
||||
[AnyPromise promiseWithValue:@1].then(^{
|
||||
return dummy();
|
||||
}).ensure(^{
|
||||
[ex1 fulfill];
|
||||
}).catch(^(NSError *err){
|
||||
XCTAssertEqualObjects(err.domain, PMKTestErrorDomain);
|
||||
[ex2 fulfill];
|
||||
});
|
||||
}
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_49_finally_negative_later {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
__block int x = 0;
|
||||
|
||||
[AnyPromise promiseWithValue:@1].then(^{
|
||||
XCTAssertEqual(++x, 1);
|
||||
return dummy();
|
||||
}).catch(^{
|
||||
XCTAssertEqual(++x, 2);
|
||||
}).then(^{
|
||||
XCTAssertEqual(++x, 3);
|
||||
}).ensure(^{
|
||||
XCTAssertEqual(++x, 4);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_50_fulfill_with_pending_promise {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(fulfillLater().then(^{ return @"HI"; }));
|
||||
}].then(^(id hi){
|
||||
XCTAssertEqualObjects(hi, @"HI");
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_51_fulfill_with_fulfilled_promise {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve([AnyPromise promiseWithValue:@1]);
|
||||
}].then(^(id o){
|
||||
XCTAssertEqualObjects(o, @1);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_52_fulfill_with_rejected_promise { //NEEDEDanypr
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
fulfillLater().then(^{
|
||||
return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve([AnyPromise promiseWithValue:dummy()]);
|
||||
}];
|
||||
}).catch(^(NSError *err){
|
||||
[ex1 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_53_return_rejected_promise {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
fulfillLater().then(^{
|
||||
return @1;
|
||||
}).then(^{
|
||||
return [AnyPromise promiseWithValue:dummy()];
|
||||
}).catch(^{
|
||||
[ex1 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_54_reject_with_rejected_promise {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
id err = [NSError errorWithDomain:@"a" code:123 userInfo:nil];
|
||||
resolve([AnyPromise promiseWithValue:err]);
|
||||
}].catch(^(NSError *err){
|
||||
XCTAssertEqual(err.code, 123);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_58_just_finally {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
AnyPromise *promise = fulfillLater().then(^{
|
||||
return nil;
|
||||
}).ensure(^{
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
|
||||
id ex2 = [self expectationWithDescription:@""];
|
||||
|
||||
promise.ensure(^{
|
||||
[ex2 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_59_catch_in_background {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
id err = [NSError errorWithDomain:@"a" code:123 userInfo:nil];
|
||||
resolve(err);
|
||||
}].catchInBackground(^(NSError *err){
|
||||
XCTAssertEqual(err.code, 123);
|
||||
XCTAssertFalse([NSThread isMainThread]);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_60_catch_on_specific_queue {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
NSString *expectedQueueName = @"specific queue 123";
|
||||
dispatch_queue_t q = dispatch_queue_create(expectedQueueName.UTF8String, DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
id err = [NSError errorWithDomain:@"a" code:123 userInfo:nil];
|
||||
resolve(err);
|
||||
}].catchOn(q, ^(NSError *err){
|
||||
XCTAssertEqual(err.code, 123);
|
||||
XCTAssertFalse([NSThread isMainThread]);
|
||||
NSString *currentQueueName = [NSString stringWithFormat:@"%s", dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
|
||||
XCTAssertEqualObjects(expectedQueueName, currentQueueName);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_properties {
|
||||
XCTAssertEqualObjects([AnyPromise promiseWithValue:@1].value, @1);
|
||||
XCTAssertEqualObjects([[AnyPromise promiseWithValue:dummyWithCode(2)].value localizedDescription], @"2");
|
||||
XCTAssertNil([AnyPromise promiseWithResolverBlock:^(id a){}].value);
|
||||
XCTAssertTrue([AnyPromise promiseWithResolverBlock:^(id a){}].pending);
|
||||
XCTAssertFalse([AnyPromise promiseWithValue:@1].pending);
|
||||
XCTAssertTrue([AnyPromise promiseWithValue:@1].fulfilled);
|
||||
XCTAssertFalse([AnyPromise promiseWithValue:@1].rejected);
|
||||
}
|
||||
|
||||
- (void)test_promiseWithValue {
|
||||
XCTAssertEqual([AnyPromise promiseWithValue:@1].value, @1);
|
||||
XCTAssertEqualObjects([[AnyPromise promiseWithValue:dummyWithCode(2)].value localizedDescription], @"2");
|
||||
XCTAssertEqual([AnyPromise promiseWithValue:[AnyPromise promiseWithValue:@1]].value, @1);
|
||||
}
|
||||
|
||||
- (void)test_race {
|
||||
id ex = [self expectationWithDescription:@""];
|
||||
id p = PMKAfter(0.1).then(^{ return @2; });
|
||||
PMKRace(@[PMKAfter(0.2), PMKAfter(0.5), p]).then(^(id obj){
|
||||
XCTAssertEqual(2, [obj integerValue]);
|
||||
[ex fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)testInBackground {
|
||||
id ex = [self expectationWithDescription:@""];
|
||||
PMKAfter(0.1).thenInBackground(^{ [ex fulfill]; });
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)testEnsureOn {
|
||||
id ex = [self expectationWithDescription:@""];
|
||||
PMKAfter(0.1).ensureOn(dispatch_get_global_queue(0, 0), ^{ [ex fulfill]; });
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)testAdapterBlock {
|
||||
void (^fetch)(PMKAdapter) = ^(PMKAdapter block){
|
||||
block(@1, nil);
|
||||
};
|
||||
id ex = [self expectationWithDescription:@""];
|
||||
[AnyPromise promiseWithAdapterBlock:fetch].then(^(id obj){
|
||||
XCTAssertEqualObjects(obj, @1);
|
||||
[ex fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)testIntegerAdapterBlock {
|
||||
void (^fetch)(PMKIntegerAdapter) = ^(PMKIntegerAdapter block){
|
||||
block(1, nil);
|
||||
};
|
||||
id ex = [self expectationWithDescription:@""];
|
||||
[AnyPromise promiseWithIntegerAdapterBlock:fetch].then(^(id obj){
|
||||
XCTAssertEqualObjects(obj, @1);
|
||||
[ex fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)testBooleanAdapterBlock {
|
||||
void (^fetch)(PMKBooleanAdapter) = ^(PMKBooleanAdapter block){
|
||||
block(YES, nil);
|
||||
};
|
||||
id ex = [self expectationWithDescription:@""];
|
||||
[AnyPromise promiseWithBooleanAdapterBlock:fetch].then(^(id obj){
|
||||
XCTAssertEqualObjects(obj, @YES);
|
||||
[ex fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
static NSHashTable *errorArray;
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
errorArray = [NSHashTable weakObjectsHashTable];
|
||||
}
|
||||
|
||||
- (void)testErrorLeaks {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
NSError *error = dummyWithCode(1001);
|
||||
[errorArray addObject:error];
|
||||
[AnyPromise promiseWithValue:error]
|
||||
.then(^{
|
||||
XCTFail();
|
||||
}).catch(^(NSError *e){
|
||||
XCTAssertEqual(e.localizedDescription.intValue, 1001);
|
||||
}).then(^{
|
||||
NSError *err = dummyWithCode(1002);
|
||||
[errorArray addObject:err];
|
||||
return err;
|
||||
}).catch(^(NSError *e){
|
||||
XCTAssertEqual(e.localizedDescription.intValue, 1002);
|
||||
}).then(^{
|
||||
NSError *err = dummyWithCode(1003);
|
||||
[errorArray addObject:err];
|
||||
return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve){
|
||||
resolve(err);
|
||||
}];
|
||||
}).catch(^(NSError *e){
|
||||
XCTAssertEqual(e.localizedDescription.intValue, 1003);
|
||||
NSError *err = dummyWithCode(1004);
|
||||
[errorArray addObject:err];
|
||||
return err;
|
||||
}).catch(^(NSError *e){
|
||||
XCTAssertEqual(e.localizedDescription.intValue, 1004);
|
||||
}).then(^{
|
||||
NSError *err = dummyWithCode(1005);
|
||||
[errorArray addObject:err];
|
||||
// throw will lead to leak, if not use complie flag with "-fobjc-arc-exceptions"
|
||||
@throw err;
|
||||
}).catch(^(NSError *e){
|
||||
XCTAssertEqual(e.localizedDescription.intValue, 1005);
|
||||
}).ensure(^{
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
XCTAssertEqual(errorArray.allObjects.count, 0);
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
//- (void)test_nil_block {
|
||||
// [AnyPromise promiseWithValue:@1].then(nil);
|
||||
// [AnyPromise promiseWithValue:@1].thenOn(nil, nil);
|
||||
// [AnyPromise promiseWithValue:@1].catch(nil);
|
||||
// [AnyPromise promiseWithValue:@1].always(nil);
|
||||
// [AnyPromise promiseWithValue:@1].alwaysOn(nil, nil);
|
||||
//}
|
||||
|
||||
@end
|
38
Carthage/Checkouts/PromiseKit/Tests/CoreObjC/AnyPromiseTests.swift
vendored
Normal file
38
Carthage/Checkouts/PromiseKit/Tests/CoreObjC/AnyPromiseTests.swift
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class AnyPromiseTests: XCTestCase {
|
||||
func testFulfilledResult() {
|
||||
switch AnyPromise(Promise.value(true)).result {
|
||||
case .fulfilled(let obj as Bool)? where obj:
|
||||
break
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
|
||||
func testRejectedResult() {
|
||||
switch AnyPromise(Promise<Int>(error: PMKError.badInput)).result {
|
||||
case .rejected(let err)?:
|
||||
print(err)
|
||||
break
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
|
||||
func testPendingResult() {
|
||||
switch AnyPromise(Promise<Int>.pending().promise).result {
|
||||
case nil:
|
||||
break
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
|
||||
func testCustomStringConvertible() {
|
||||
XCTAssertEqual("\(AnyPromise(Promise<Int>.pending().promise))", "AnyPromise(…)")
|
||||
XCTAssertEqual("\(AnyPromise(Promise.value(1)))", "AnyPromise(1)")
|
||||
XCTAssertEqual("\(AnyPromise(Promise<Int?>.value(nil)))", "AnyPromise(nil)")
|
||||
}
|
||||
}
|
13
Carthage/Checkouts/PromiseKit/Tests/CoreObjC/HangTests.m
vendored
Normal file
13
Carthage/Checkouts/PromiseKit/Tests/CoreObjC/HangTests.m
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
@import PromiseKit;
|
||||
@import XCTest;
|
||||
|
||||
@interface HangTests: XCTestCase @end @implementation HangTests
|
||||
|
||||
- (void)test {
|
||||
__block int x = 0;
|
||||
id value = PMKHang(PMKAfter(0.02).then(^{ x++; return 1; }));
|
||||
XCTAssertEqual(x, 1);
|
||||
XCTAssertEqualObjects(value, @1);
|
||||
}
|
||||
|
||||
@end
|
90
Carthage/Checkouts/PromiseKit/Tests/CoreObjC/JoinTests.m
vendored
Normal file
90
Carthage/Checkouts/PromiseKit/Tests/CoreObjC/JoinTests.m
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
@import Foundation;
|
||||
@import PromiseKit;
|
||||
@import XCTest;
|
||||
|
||||
|
||||
@interface JoinTests: XCTestCase @end @implementation JoinTests
|
||||
|
||||
- (void)test_73_join {
|
||||
XCTestExpectation *ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
__block void (^fulfiller)(id) = nil;
|
||||
AnyPromise *promise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
fulfiller = resolve;
|
||||
}];
|
||||
|
||||
PMKJoin(@[
|
||||
[AnyPromise promiseWithValue:[NSError errorWithDomain:@"dom" code:1 userInfo:nil]],
|
||||
promise,
|
||||
[AnyPromise promiseWithValue:[NSError errorWithDomain:@"dom" code:2 userInfo:nil]]
|
||||
]).then(^{
|
||||
XCTFail();
|
||||
}).catch(^(NSError *error){
|
||||
id promises = error.userInfo[PMKJoinPromisesKey];
|
||||
|
||||
int cume = 0, cumv = 0;
|
||||
|
||||
for (AnyPromise *promise in promises) {
|
||||
if ([promise.value isKindOfClass:[NSError class]]) {
|
||||
cume |= [promise.value code];
|
||||
} else {
|
||||
cumv |= [promise.value unsignedIntValue];
|
||||
}
|
||||
}
|
||||
|
||||
XCTAssertTrue(cumv == 4);
|
||||
XCTAssertTrue(cume == 3);
|
||||
|
||||
[ex1 fulfill];
|
||||
});
|
||||
fulfiller(@4);
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_74_join_no_errors {
|
||||
XCTestExpectation *ex1 = [self expectationWithDescription:@""];
|
||||
PMKJoin(@[
|
||||
[AnyPromise promiseWithValue:@1],
|
||||
[AnyPromise promiseWithValue:@2]
|
||||
]).then(^(NSArray *values, id errors) {
|
||||
XCTAssertEqualObjects(values, (@[@1, @2]));
|
||||
XCTAssertNil(errors);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void)test_75_join_no_success {
|
||||
XCTestExpectation *ex1 = [self expectationWithDescription:@""];
|
||||
PMKJoin(@[
|
||||
[AnyPromise promiseWithValue:[NSError errorWithDomain:@"dom" code:1 userInfo:nil]],
|
||||
[AnyPromise promiseWithValue:[NSError errorWithDomain:@"dom" code:2 userInfo:nil]],
|
||||
]).then(^{
|
||||
XCTFail();
|
||||
}).catch(^(NSError *error){
|
||||
XCTAssertNotNil(error.userInfo[PMKJoinPromisesKey]);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_76_join_fulfills_if_empty_input {
|
||||
XCTestExpectation *ex1 = [self expectationWithDescription:@""];
|
||||
PMKJoin(@[]).then(^(id a, id b, id c){
|
||||
XCTAssertEqualObjects(@[], a);
|
||||
XCTAssertNil(b);
|
||||
XCTAssertNil(c);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_join_nil {
|
||||
NSArray *foo = nil;
|
||||
NSError *err = PMKJoin(foo).value;
|
||||
XCTAssertEqual(err.domain, PMKErrorDomain);
|
||||
XCTAssertEqual(err.code, PMKInvalidUsageError);
|
||||
}
|
||||
|
||||
@end
|
83
Carthage/Checkouts/PromiseKit/Tests/CoreObjC/PMKManifoldTests.m
vendored
Normal file
83
Carthage/Checkouts/PromiseKit/Tests/CoreObjC/PMKManifoldTests.m
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
@import PromiseKit;
|
||||
@import XCTest;
|
||||
|
||||
@interface PMKManifoldTests: XCTestCase @end @implementation PMKManifoldTests
|
||||
|
||||
- (void)test_62_access_extra_elements {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
||||
resolve(PMKManifold(@1));
|
||||
}].then(^(id o, id m, id n){
|
||||
XCTAssertNil(m, @"Accessing extra elements should not crash");
|
||||
XCTAssertNil(n, @"Accessing extra elements should not crash");
|
||||
XCTAssertEqualObjects(o, @1);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_63_then_manifold {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithValue:@0].then(^{
|
||||
return PMKManifold(@1, @2, @3);
|
||||
}).then(^(id o1, id o2, id o3){
|
||||
XCTAssertEqualObjects(o1, @1);
|
||||
XCTAssertEqualObjects(o2, @2);
|
||||
XCTAssertEqualObjects(o3, @3);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_63_then_manifold_with_nil {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
[AnyPromise promiseWithValue:@0].then(^{
|
||||
return PMKManifold(@1, nil, @3);
|
||||
}).then(^(id o1, id o2, id o3){
|
||||
XCTAssertEqualObjects(o1, @1);
|
||||
XCTAssertEqualObjects(o2, nil);
|
||||
XCTAssertEqualObjects(o3, @3);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_65_manifold_fulfill_value {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
AnyPromise *promise = [AnyPromise promiseWithValue:@1].then(^{
|
||||
return PMKManifold(@123, @2);
|
||||
});
|
||||
|
||||
promise.then(^(id a, id b){
|
||||
XCTAssertNotNil(a);
|
||||
XCTAssertNotNil(b);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
|
||||
XCTAssertEqualObjects(promise.value, @123);
|
||||
}
|
||||
|
||||
- (void)test_37_PMKMany_2 {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
PMKAfter(0.02).then(^{
|
||||
return PMKManifold(@1, @2);
|
||||
}).then(^(id a, id b){
|
||||
XCTAssertEqualObjects(a, @1);
|
||||
XCTAssertEqualObjects(b, @2);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
@end
|
265
Carthage/Checkouts/PromiseKit/Tests/CoreObjC/WhenTests.m
vendored
Normal file
265
Carthage/Checkouts/PromiseKit/Tests/CoreObjC/WhenTests.m
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
@import Foundation;
|
||||
@import PromiseKit;
|
||||
@import XCTest;
|
||||
|
||||
|
||||
@interface WhenTests: XCTestCase @end @implementation WhenTests
|
||||
|
||||
- (void)testProgress {
|
||||
|
||||
id ex = [self expectationWithDescription:@""];
|
||||
|
||||
XCTAssertNil([NSProgress currentProgress]);
|
||||
|
||||
id p1 = PMKAfter(0.01);
|
||||
id p2 = PMKAfter(0.02);
|
||||
id p3 = PMKAfter(0.03);
|
||||
id p4 = PMKAfter(0.04);
|
||||
|
||||
NSProgress *progress = [NSProgress progressWithTotalUnitCount:1];
|
||||
[progress becomeCurrentWithPendingUnitCount:1];
|
||||
|
||||
PMKWhen(@[p1, p2, p3, p4]).then(^{
|
||||
XCTAssertEqual(progress.completedUnitCount, 1);
|
||||
[ex fulfill];
|
||||
});
|
||||
|
||||
[progress resignCurrent];
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)testProgressDoesNotExceed100Percent {
|
||||
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
id ex2 = [self expectationWithDescription:@""];
|
||||
|
||||
XCTAssertNil([NSProgress currentProgress]);
|
||||
|
||||
id p1 = PMKAfter(0.01);
|
||||
id p2 = PMKAfter(0.02).then(^{ return [NSError errorWithDomain:@"a" code:1 userInfo:nil]; });
|
||||
id p3 = PMKAfter(0.03);
|
||||
id p4 = PMKAfter(0.04);
|
||||
|
||||
id promises = @[p1, p2, p3, p4];
|
||||
|
||||
NSProgress *progress = [NSProgress progressWithTotalUnitCount:1];
|
||||
[progress becomeCurrentWithPendingUnitCount:1];
|
||||
|
||||
PMKWhen(promises).catch(^{
|
||||
[ex2 fulfill];
|
||||
});
|
||||
|
||||
[progress resignCurrent];
|
||||
|
||||
PMKJoin(promises).catch(^{
|
||||
XCTAssertLessThanOrEqual(1, progress.fractionCompleted);
|
||||
XCTAssertEqual(progress.completedUnitCount, 1);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)testWhenManifolds {
|
||||
id ex = [self expectationWithDescription:@""];
|
||||
id p1 = dispatch_promise(^{ return PMKManifold(@1, @2); });
|
||||
id p2 = dispatch_promise(^{});
|
||||
PMKWhen(@[p1, p2]).then(^(NSArray *results){
|
||||
XCTAssertEqualObjects(results[0], @1);
|
||||
XCTAssertEqualObjects(results[1], [NSNull null]);
|
||||
[ex fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_55_all_dictionary {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
id promises = @{
|
||||
@1: @2,
|
||||
@2: @"abc",
|
||||
@"a": PMKAfter(0.1).then(^{ return @"HI"; })
|
||||
};
|
||||
PMKWhen(promises).then(^(NSDictionary *dict){
|
||||
XCTAssertEqual(dict.count, 3ul);
|
||||
XCTAssertEqualObjects(dict[@1], @2);
|
||||
XCTAssertEqualObjects(dict[@2], @"abc");
|
||||
XCTAssertEqualObjects(dict[@"a"], @"HI");
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_56_empty_array_when {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
PMKWhen(@[]).then(^(NSArray *array){
|
||||
XCTAssertEqual(array.count, 0ul);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_57_empty_array_all {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
PMKWhen(@[]).then(^(NSArray *array){
|
||||
XCTAssertEqual(array.count, 0ul);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_18_when {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
id a = PMKAfter(0.02).then(^{ return @345; });
|
||||
id b = PMKAfter(0.03).then(^{ return @345; });
|
||||
PMKWhen(@[a, b]).then(^(NSArray *objs){
|
||||
XCTAssertEqual(objs.count, 2ul);
|
||||
XCTAssertEqualObjects(objs[0], objs[1]);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_21_recursive_when {
|
||||
id domain = @"sdjhfg";
|
||||
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
id a = PMKAfter(0.03).then(^{
|
||||
return [NSError errorWithDomain:domain code:123 userInfo:nil];
|
||||
});
|
||||
id b = PMKAfter(0.02);
|
||||
id c = PMKWhen(@[a, b]);
|
||||
PMKWhen(c).then(^{
|
||||
XCTFail();
|
||||
}).catch(^(NSError *e){
|
||||
XCTAssertEqualObjects(e.userInfo[PMKFailingPromiseIndexKey], @0);
|
||||
XCTAssertEqualObjects(e.domain, domain);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_22_already_resolved_and_bubble {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
id ex2 = [self expectationWithDescription:@""];
|
||||
|
||||
PMKResolver resolve;
|
||||
AnyPromise *promise = [[AnyPromise alloc] initWithResolver:&resolve];
|
||||
|
||||
promise.then(^{
|
||||
XCTFail();
|
||||
}).catch(^(NSError *e){
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
resolve([NSError errorWithDomain:@"a" code:1 userInfo:nil]);
|
||||
|
||||
PMKWhen(promise).then(^{
|
||||
XCTFail();
|
||||
}).catch(^{
|
||||
[ex2 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_24_some_edge_case {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
id a = PMKAfter(0.02).catch(^{});
|
||||
id b = PMKAfter(0.03);
|
||||
PMKWhen(@[a, b]).then(^(NSArray *objs){
|
||||
[ex1 fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_35_when_nil {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
AnyPromise *promise = [AnyPromise promiseWithValue:@"35"].then(^{ return nil; });
|
||||
PMKWhen(@[PMKAfter(0.02).then(^{ return @1; }), [AnyPromise promiseWithValue:nil], promise]).then(^(NSArray *results){
|
||||
XCTAssertEqual(results.count, 3ul);
|
||||
XCTAssertEqualObjects(results[1], [NSNull null]);
|
||||
[ex1 fulfill];
|
||||
}).catch(^(NSError *err){
|
||||
abort();
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void)test_39_when_with_some_values {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
id p = PMKAfter(0.02);
|
||||
id v = @1;
|
||||
PMKWhen(@[p, v]).then(^(NSArray *aa){
|
||||
XCTAssertEqual(aa.count, 2ul);
|
||||
XCTAssertEqualObjects(aa[1], @1);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_40_when_with_all_values {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
PMKWhen(@[@1, @2]).then(^(NSArray *aa){
|
||||
XCTAssertEqualObjects(aa[0], @1);
|
||||
XCTAssertEqualObjects(aa[1], @2);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_41_when_with_repeated_promises {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
id p = PMKAfter(0.02);
|
||||
id v = @1;
|
||||
PMKWhen(@[p, v, p, v]).then(^(NSArray *aa){
|
||||
XCTAssertEqual(aa.count, 4ul);
|
||||
XCTAssertEqualObjects(aa[1], @1);
|
||||
XCTAssertEqualObjects(aa[3], @1);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_45_when_which_returns_void {
|
||||
id ex1 = [self expectationWithDescription:@""];
|
||||
|
||||
AnyPromise *promise = [AnyPromise promiseWithValue:@1].then(^{});
|
||||
PMKWhen(@[promise, [AnyPromise promiseWithValue:@1]]).then(^(NSArray *stuff){
|
||||
XCTAssertEqual(stuff.count, 2ul);
|
||||
XCTAssertEqualObjects(stuff[0], [NSNull null]);
|
||||
[ex1 fulfill];
|
||||
});
|
||||
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_when_nil {
|
||||
NSArray *foo = nil;
|
||||
NSError *err = PMKWhen(foo).value;
|
||||
XCTAssertEqual(err.domain, PMKErrorDomain);
|
||||
XCTAssertEqual(err.code, PMKInvalidUsageError);
|
||||
}
|
||||
|
||||
|
||||
- (void)test_when_bad_input {
|
||||
id foo = @"a";
|
||||
XCTAssertEqual(PMKWhen(foo).value, foo);
|
||||
}
|
||||
|
||||
@end
|
52
Carthage/Checkouts/PromiseKit/Tests/CorePromise/AfterTests.swift
vendored
Normal file
52
Carthage/Checkouts/PromiseKit/Tests/CorePromise/AfterTests.swift
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class AfterTests: XCTestCase {
|
||||
func testZero() {
|
||||
let ex2 = expectation(description: "")
|
||||
after(seconds: 0).done(ex2.fulfill)
|
||||
waitForExpectations(timeout: 2, handler: nil)
|
||||
|
||||
let ex3 = expectation(description: "")
|
||||
after(.seconds(0)).done(ex3.fulfill)
|
||||
waitForExpectations(timeout: 2, handler: nil)
|
||||
|
||||
#if !SWIFT_PACKAGE
|
||||
let ex4 = expectation(description: "")
|
||||
__PMKAfter(0).done{ _ in ex4.fulfill() }.silenceWarning()
|
||||
waitForExpectations(timeout: 2, handler: nil)
|
||||
#endif
|
||||
}
|
||||
|
||||
func testNegative() {
|
||||
let ex2 = expectation(description: "")
|
||||
after(seconds: -1).done(ex2.fulfill)
|
||||
waitForExpectations(timeout: 2, handler: nil)
|
||||
|
||||
let ex3 = expectation(description: "")
|
||||
after(.seconds(-1)).done(ex3.fulfill)
|
||||
waitForExpectations(timeout: 2, handler: nil)
|
||||
|
||||
#if !SWIFT_PACKAGE
|
||||
let ex4 = expectation(description: "")
|
||||
__PMKAfter(-1).done{ _ in ex4.fulfill() }.silenceWarning()
|
||||
waitForExpectations(timeout: 2, handler: nil)
|
||||
#endif
|
||||
}
|
||||
|
||||
func testPositive() {
|
||||
let ex2 = expectation(description: "")
|
||||
after(seconds: 1).done(ex2.fulfill)
|
||||
waitForExpectations(timeout: 2, handler: nil)
|
||||
|
||||
let ex3 = expectation(description: "")
|
||||
after(.seconds(1)).done(ex3.fulfill)
|
||||
waitForExpectations(timeout: 2, handler: nil)
|
||||
|
||||
#if !SWIFT_PACKAGE
|
||||
let ex4 = expectation(description: "")
|
||||
__PMKAfter(1).done{ _ in ex4.fulfill() }.silenceWarning()
|
||||
waitForExpectations(timeout: 2, handler: nil)
|
||||
#endif
|
||||
}
|
||||
}
|
130
Carthage/Checkouts/PromiseKit/Tests/CorePromise/CancellableErrorTests.swift
vendored
Normal file
130
Carthage/Checkouts/PromiseKit/Tests/CorePromise/CancellableErrorTests.swift
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
import Foundation
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class CancellationTests: XCTestCase {
|
||||
func testCancellation() {
|
||||
let ex1 = expectation(description: "")
|
||||
|
||||
let p = after(seconds: 0).done { _ in
|
||||
throw LocalError.cancel
|
||||
}.done {
|
||||
XCTFail()
|
||||
}
|
||||
p.catch { _ in
|
||||
XCTFail()
|
||||
}
|
||||
p.catch(policy: .allErrors) {
|
||||
XCTAssertTrue($0.isCancelled)
|
||||
ex1.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 60)
|
||||
}
|
||||
|
||||
func testThrowCancellableErrorThatIsNotCancelled() {
|
||||
let expct = expectation(description: "")
|
||||
|
||||
after(seconds: 0).done { _ in
|
||||
throw LocalError.notCancel
|
||||
}.done {
|
||||
XCTFail()
|
||||
}.catch {
|
||||
XCTAssertFalse($0.isCancelled)
|
||||
expct.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testRecoverWithCancellation() {
|
||||
let ex1 = expectation(description: "")
|
||||
let ex2 = expectation(description: "")
|
||||
|
||||
let p = after(seconds: 0).done { _ in
|
||||
throw CocoaError.cancelled
|
||||
}.recover(policy: .allErrors) { err -> Promise<Void> in
|
||||
ex1.fulfill()
|
||||
XCTAssertTrue(err.isCancelled)
|
||||
throw err
|
||||
}.done { _ in
|
||||
XCTFail()
|
||||
}
|
||||
p.catch { _ in
|
||||
XCTFail()
|
||||
}
|
||||
p.catch(policy: .allErrors) {
|
||||
XCTAssertTrue($0.isCancelled)
|
||||
ex2.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testFoundationBridging1() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
let p = after(seconds: 0).done { _ in
|
||||
throw CocoaError.cancelled
|
||||
}
|
||||
p.catch { _ in
|
||||
XCTFail()
|
||||
}
|
||||
p.catch(policy: .allErrors) {
|
||||
XCTAssertTrue($0.isCancelled)
|
||||
ex.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testFoundationBridging2() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
let p = Promise().done {
|
||||
throw URLError.cancelled
|
||||
}
|
||||
p.catch { _ in
|
||||
XCTFail()
|
||||
}
|
||||
p.catch(policy: .allErrors) {
|
||||
XCTAssertTrue($0.isCancelled)
|
||||
ex.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
#if swift(>=3.2)
|
||||
func testIsCancelled() {
|
||||
XCTAssertTrue(PMKError.cancelled.isCancelled)
|
||||
XCTAssertTrue(URLError.cancelled.isCancelled)
|
||||
XCTAssertTrue(CocoaError.cancelled.isCancelled)
|
||||
XCTAssertFalse(CocoaError(_nsError: NSError(domain: NSCocoaErrorDomain, code: CocoaError.Code.coderInvalidValue.rawValue)).isCancelled)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private enum LocalError: CancellableError {
|
||||
case notCancel
|
||||
case cancel
|
||||
|
||||
var isCancelled: Bool {
|
||||
switch self {
|
||||
case .notCancel: return false
|
||||
case .cancel: return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension URLError {
|
||||
static var cancelled: URLError {
|
||||
return .init(_nsError: NSError(domain: NSURLErrorDomain, code: URLError.Code.cancelled.rawValue))
|
||||
}
|
||||
}
|
||||
|
||||
private extension CocoaError {
|
||||
static var cancelled: CocoaError {
|
||||
return .init(_nsError: NSError(domain: NSCocoaErrorDomain, code: CocoaError.Code.userCancelled.rawValue))
|
||||
}
|
||||
}
|
267
Carthage/Checkouts/PromiseKit/Tests/CorePromise/CatchableTests.swift
vendored
Normal file
267
Carthage/Checkouts/PromiseKit/Tests/CorePromise/CatchableTests.swift
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
import PromiseKit
|
||||
import Dispatch
|
||||
import XCTest
|
||||
|
||||
class CatchableTests: XCTestCase {
|
||||
|
||||
func testFinally() {
|
||||
let finallyQueue = DispatchQueue(label: "\(#file):\(#line)", attributes: .concurrent)
|
||||
|
||||
func helper(error: Error, on queue: DispatchQueue = .main, flags: DispatchWorkItemFlags? = nil) {
|
||||
let ex = (expectation(description: ""), expectation(description: ""))
|
||||
var x = 0
|
||||
Promise<Void>(error: error).catch(policy: .allErrors) { _ in
|
||||
XCTAssertEqual(x, 0)
|
||||
x += 1
|
||||
ex.0.fulfill()
|
||||
}.finally(on: queue, flags: flags) {
|
||||
if let flags = flags, flags.contains(.barrier) {
|
||||
dispatchPrecondition(condition: .onQueueAsBarrier(queue))
|
||||
} else {
|
||||
dispatchPrecondition(condition: .onQueue(queue))
|
||||
}
|
||||
XCTAssertEqual(x, 1)
|
||||
x += 1
|
||||
ex.1.fulfill()
|
||||
}
|
||||
wait(for: [ex.0, ex.1], timeout: 10)
|
||||
}
|
||||
|
||||
helper(error: Error.dummy)
|
||||
helper(error: Error.cancelled)
|
||||
helper(error: Error.dummy, on: finallyQueue)
|
||||
helper(error: Error.dummy, on: finallyQueue, flags: .barrier)
|
||||
}
|
||||
|
||||
func testCauterize() {
|
||||
let ex = expectation(description: "")
|
||||
let p = Promise<Void>(error: Error.dummy)
|
||||
|
||||
// cannot test specifically that this outputs to console,
|
||||
// but code-coverage will note that the line is run
|
||||
p.cauterize()
|
||||
|
||||
p.catch { _ in
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// `Promise<Void>.recover`
|
||||
extension CatchableTests {
|
||||
func test__void_specialized_full_recover() {
|
||||
|
||||
func helper(error: Swift.Error) {
|
||||
let ex = expectation(description: "")
|
||||
Promise<Void>(error: error).recover { _ in }.done(ex.fulfill)
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
helper(error: Error.dummy)
|
||||
helper(error: Error.cancelled)
|
||||
}
|
||||
|
||||
func test__void_specialized_full_recover__fulfilled_path() {
|
||||
let ex = expectation(description: "")
|
||||
Promise().recover { _ in XCTFail() }.done(ex.fulfill)
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func test__void_specialized_conditional_recover() {
|
||||
func helper(policy: CatchPolicy, error: Swift.Error, line: UInt = #line) {
|
||||
let ex = expectation(description: "")
|
||||
var x = 0
|
||||
Promise<Void>(error: error).recover(policy: policy) { err in
|
||||
guard x < 1 else { throw err }
|
||||
x += 1
|
||||
}.done(ex.fulfill).silenceWarning()
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
for error in [Error.dummy as Swift.Error, Error.cancelled] {
|
||||
helper(policy: .allErrors, error: error)
|
||||
}
|
||||
helper(policy: .allErrorsExceptCancellation, error: Error.dummy)
|
||||
}
|
||||
|
||||
func test__void_specialized_conditional_recover__no_recover() {
|
||||
|
||||
func helper(policy: CatchPolicy, error: Error, line: UInt = #line) {
|
||||
let ex = expectation(description: "")
|
||||
Promise<Void>(error: error).recover(policy: policy) { err in
|
||||
throw err
|
||||
}.catch(policy: .allErrors) {
|
||||
XCTAssertEqual(error, $0 as? Error)
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
for error in [Error.dummy, Error.cancelled] {
|
||||
helper(policy: .allErrors, error: error)
|
||||
}
|
||||
helper(policy: .allErrorsExceptCancellation, error: Error.dummy)
|
||||
}
|
||||
|
||||
func test__void_specialized_conditional_recover__ignores_cancellation_but_fed_cancellation() {
|
||||
let ex = expectation(description: "")
|
||||
Promise<Void>(error: Error.cancelled).recover(policy: .allErrorsExceptCancellation) { _ in
|
||||
XCTFail()
|
||||
}.catch(policy: .allErrors) {
|
||||
XCTAssertEqual(Error.cancelled, $0 as? Error)
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func test__void_specialized_conditional_recover__fulfilled_path() {
|
||||
let ex = expectation(description: "")
|
||||
Promise().recover { _ in
|
||||
XCTFail()
|
||||
}.catch { _ in
|
||||
XCTFail() // this `catch` to ensure we are calling the `recover` variant we think we are
|
||||
}.finally {
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// `Promise<T>.recover`
|
||||
extension CatchableTests {
|
||||
func test__full_recover() {
|
||||
|
||||
func helper(error: Swift.Error) {
|
||||
let ex = expectation(description: "")
|
||||
Promise<Int>(error: error).recover { _ in return .value(2) }.done {
|
||||
XCTAssertEqual($0, 2)
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
helper(error: Error.dummy)
|
||||
helper(error: Error.cancelled)
|
||||
}
|
||||
|
||||
func test__full_recover__fulfilled_path() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value(1).recover { _ in XCTFail(); return .value(2) }.done{
|
||||
XCTAssertEqual($0, 1)
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
|
||||
func test__conditional_recover() {
|
||||
func helper(policy: CatchPolicy, error: Swift.Error, line: UInt = #line) {
|
||||
let ex = expectation(description: "")
|
||||
var x = 0
|
||||
Promise<Int>(error: error).recover(policy: policy) { err -> Promise<Int> in
|
||||
guard x < 1 else { throw err }
|
||||
x += 1
|
||||
return .value(x)
|
||||
}.done {
|
||||
XCTAssertEqual($0, x)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
for error in [Error.dummy as Swift.Error, Error.cancelled] {
|
||||
helper(policy: .allErrors, error: error)
|
||||
}
|
||||
helper(policy: .allErrorsExceptCancellation, error: Error.dummy)
|
||||
}
|
||||
|
||||
func test__conditional_recover__no_recover() {
|
||||
|
||||
func helper(policy: CatchPolicy, error: Error, line: UInt = #line) {
|
||||
let ex = expectation(description: "")
|
||||
Promise<Int>(error: error).recover(policy: policy) { err -> Promise<Int> in
|
||||
throw err
|
||||
}.catch(policy: .allErrors) {
|
||||
XCTAssertEqual(error, $0 as? Error)
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
for error in [Error.dummy, Error.cancelled] {
|
||||
helper(policy: .allErrors, error: error)
|
||||
}
|
||||
helper(policy: .allErrorsExceptCancellation, error: Error.dummy)
|
||||
}
|
||||
|
||||
func test__conditional_recover__ignores_cancellation_but_fed_cancellation() {
|
||||
let ex = expectation(description: "")
|
||||
Promise<Int>(error: Error.cancelled).recover(policy: .allErrorsExceptCancellation) { _ -> Promise<Int> in
|
||||
XCTFail()
|
||||
return .value(1)
|
||||
}.catch(policy: .allErrors) {
|
||||
XCTAssertEqual(Error.cancelled, $0 as? Error)
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func test__conditional_recover__fulfilled_path() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value(1).recover { err -> Promise<Int> in
|
||||
XCTFail()
|
||||
throw err
|
||||
}.done {
|
||||
XCTAssertEqual($0, 1)
|
||||
ex.fulfill()
|
||||
}.catch { _ in
|
||||
XCTFail() // this `catch` to ensure we are calling the `recover` variant we think we are
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testEnsureThen_Error() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
Promise.value(1).done {
|
||||
XCTAssertEqual($0, 1)
|
||||
throw Error.dummy
|
||||
}.ensureThen {
|
||||
after(seconds: 0.01)
|
||||
}.catch {
|
||||
XCTAssertEqual(Error.dummy, $0 as? Error)
|
||||
}.finally {
|
||||
ex.fulfill()
|
||||
}
|
||||
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testEnsureThen_Value() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
Promise.value(1).ensureThen {
|
||||
after(seconds: 0.01)
|
||||
}.done {
|
||||
XCTAssertEqual($0, 1)
|
||||
}.catch { _ in
|
||||
XCTFail()
|
||||
}.finally {
|
||||
ex.fulfill()
|
||||
}
|
||||
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
}
|
||||
|
||||
private enum Error: CancellableError {
|
||||
case dummy
|
||||
case cancelled
|
||||
|
||||
var isCancelled: Bool {
|
||||
return self == Error.cancelled
|
||||
}
|
||||
}
|
70
Carthage/Checkouts/PromiseKit/Tests/CorePromise/DefaultDispatchQueueTests.swift
vendored
Normal file
70
Carthage/Checkouts/PromiseKit/Tests/CorePromise/DefaultDispatchQueueTests.swift
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// PMKDefaultDispatchQueue.test.swift
|
||||
// PromiseKit
|
||||
//
|
||||
// Created by David Rodriguez on 4/14/16.
|
||||
// Copyright © 2016 Max Howell. All rights reserved.
|
||||
//
|
||||
|
||||
import class Foundation.Thread
|
||||
import PromiseKit
|
||||
import Dispatch
|
||||
import XCTest
|
||||
|
||||
private enum Error: Swift.Error { case dummy }
|
||||
|
||||
|
||||
class PMKDefaultDispatchQueueTest: XCTestCase {
|
||||
|
||||
let myQueue = DispatchQueue(label: "myQueue")
|
||||
|
||||
override func setUp() {
|
||||
// can actually only set the default queue once
|
||||
// - See: PMKSetDefaultDispatchQueue
|
||||
conf.Q = (myQueue, myQueue)
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
conf.Q = (.main, .main)
|
||||
}
|
||||
|
||||
func testOverrodeDefaultThenQueue() {
|
||||
let ex = expectation(description: "resolving")
|
||||
|
||||
Promise.value(1).then { _ -> Promise<Void> in
|
||||
ex.fulfill()
|
||||
XCTAssertFalse(Thread.isMainThread)
|
||||
return Promise()
|
||||
}.silenceWarning()
|
||||
|
||||
XCTAssertTrue(Thread.isMainThread)
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testOverrodeDefaultCatchQueue() {
|
||||
let ex = expectation(description: "resolving")
|
||||
|
||||
Promise<Int>(error: Error.dummy).catch { _ in
|
||||
ex.fulfill()
|
||||
XCTAssertFalse(Thread.isMainThread)
|
||||
}
|
||||
|
||||
XCTAssertTrue(Thread.isMainThread)
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testOverrodeDefaultAlwaysQueue() {
|
||||
let ex = expectation(description: "resolving")
|
||||
|
||||
Promise.value(1).ensure {
|
||||
ex.fulfill()
|
||||
XCTAssertFalse(Thread.isMainThread)
|
||||
}.silenceWarning()
|
||||
|
||||
XCTAssertTrue(Thread.isMainThread)
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
}
|
22
Carthage/Checkouts/PromiseKit/Tests/CorePromise/ErrorTests.swift
vendored
Normal file
22
Carthage/Checkouts/PromiseKit/Tests/CorePromise/ErrorTests.swift
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class PMKErrorTests: XCTestCase {
|
||||
func testCustomStringConvertible() {
|
||||
XCTAssertNotNil(PMKError.invalidCallingConvention.errorDescription)
|
||||
XCTAssertNotNil(PMKError.returnedSelf.errorDescription)
|
||||
XCTAssertNotNil(PMKError.badInput.errorDescription)
|
||||
XCTAssertNotNil(PMKError.cancelled.errorDescription)
|
||||
XCTAssertNotNil(PMKError.compactMap(1, Int.self).errorDescription)
|
||||
XCTAssertNotNil(PMKError.emptySequence.errorDescription)
|
||||
}
|
||||
|
||||
func testCustomDebugStringConvertible() {
|
||||
XCTAssertFalse(PMKError.invalidCallingConvention.debugDescription.isEmpty)
|
||||
XCTAssertFalse(PMKError.returnedSelf.debugDescription.isEmpty)
|
||||
XCTAssertNotNil(PMKError.badInput.debugDescription.isEmpty)
|
||||
XCTAssertFalse(PMKError.cancelled.debugDescription.isEmpty)
|
||||
XCTAssertFalse(PMKError.compactMap(1, Int.self).debugDescription.isEmpty)
|
||||
XCTAssertFalse(PMKError.emptySequence.debugDescription.isEmpty)
|
||||
}
|
||||
}
|
33
Carthage/Checkouts/PromiseKit/Tests/CorePromise/GuaranteeTests.swift
vendored
Normal file
33
Carthage/Checkouts/PromiseKit/Tests/CorePromise/GuaranteeTests.swift
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class GuaranteeTests: XCTestCase {
|
||||
func testInit() {
|
||||
let ex = expectation(description: "")
|
||||
Guarantee { seal in
|
||||
seal(1)
|
||||
}.done {
|
||||
XCTAssertEqual(1, $0)
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testWait() {
|
||||
XCTAssertEqual(after(.milliseconds(100)).map(on: nil){ 1 }.wait(), 1)
|
||||
}
|
||||
|
||||
func testThenMap() {
|
||||
|
||||
let ex = expectation(description: "")
|
||||
|
||||
Guarantee.value([1, 2, 3])
|
||||
.thenMap { Guarantee.value($0 * 2) }
|
||||
.done { values in
|
||||
XCTAssertEqual([2, 4, 6], values)
|
||||
ex.fulfill()
|
||||
}
|
||||
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
}
|
38
Carthage/Checkouts/PromiseKit/Tests/CorePromise/HangTests.swift
vendored
Normal file
38
Carthage/Checkouts/PromiseKit/Tests/CorePromise/HangTests.swift
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class HangTests: XCTestCase {
|
||||
func test() {
|
||||
let ex = expectation(description: "block executed")
|
||||
do {
|
||||
let value = try hang(after(seconds: 0.02).then { _ -> Promise<Int> in
|
||||
ex.fulfill()
|
||||
return .value(1)
|
||||
})
|
||||
XCTAssertEqual(value, 1)
|
||||
} catch {
|
||||
XCTFail("Unexpected error")
|
||||
}
|
||||
waitForExpectations(timeout: 0)
|
||||
}
|
||||
|
||||
enum Error: Swift.Error {
|
||||
case test
|
||||
}
|
||||
|
||||
func testError() {
|
||||
var value = 0
|
||||
do {
|
||||
_ = try hang(after(seconds: 0.02).done {
|
||||
value = 1
|
||||
throw Error.test
|
||||
})
|
||||
XCTAssertEqual(value, 1)
|
||||
} catch Error.test {
|
||||
return
|
||||
} catch {
|
||||
XCTFail("Unexpected error (expected Error.test)")
|
||||
}
|
||||
XCTFail("Expected error but no error was thrown")
|
||||
}
|
||||
}
|
139
Carthage/Checkouts/PromiseKit/Tests/CorePromise/PromiseTests.swift
vendored
Normal file
139
Carthage/Checkouts/PromiseKit/Tests/CorePromise/PromiseTests.swift
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
import PromiseKit
|
||||
import Dispatch
|
||||
import XCTest
|
||||
|
||||
class PromiseTests: XCTestCase {
|
||||
func testIsPending() {
|
||||
XCTAssertTrue(Promise<Void>.pending().promise.isPending)
|
||||
XCTAssertFalse(Promise().isPending)
|
||||
XCTAssertFalse(Promise<Void>(error: Error.dummy).isPending)
|
||||
}
|
||||
|
||||
func testIsResolved() {
|
||||
XCTAssertFalse(Promise<Void>.pending().promise.isResolved)
|
||||
XCTAssertTrue(Promise().isResolved)
|
||||
XCTAssertTrue(Promise<Void>(error: Error.dummy).isResolved)
|
||||
}
|
||||
|
||||
func testIsFulfilled() {
|
||||
XCTAssertFalse(Promise<Void>.pending().promise.isFulfilled)
|
||||
XCTAssertTrue(Promise().isFulfilled)
|
||||
XCTAssertFalse(Promise<Void>(error: Error.dummy).isFulfilled)
|
||||
}
|
||||
|
||||
func testIsRejected() {
|
||||
XCTAssertFalse(Promise<Void>.pending().promise.isRejected)
|
||||
XCTAssertTrue(Promise<Void>(error: Error.dummy).isRejected)
|
||||
XCTAssertFalse(Promise().isRejected)
|
||||
}
|
||||
|
||||
@available(macOS 10.10, iOS 2.0, tvOS 10.0, watchOS 2.0, *)
|
||||
func testDispatchQueueAsyncExtensionReturnsPromise() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
DispatchQueue.global().async(.promise) { () -> Int in
|
||||
XCTAssertFalse(Thread.isMainThread)
|
||||
return 1
|
||||
}.done { one in
|
||||
XCTAssertEqual(one, 1)
|
||||
ex.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
@available(macOS 10.10, iOS 2.0, tvOS 10.0, watchOS 2.0, *)
|
||||
func testDispatchQueueAsyncExtensionCanThrowInBody() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
DispatchQueue.global().async(.promise) { () -> Int in
|
||||
throw Error.dummy
|
||||
}.done { _ in
|
||||
XCTFail()
|
||||
}.catch { _ in
|
||||
ex.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testCustomStringConvertible() {
|
||||
XCTAssertEqual(Promise<Int>.pending().promise.debugDescription, "Promise<Int>.pending(handlers: 0)")
|
||||
XCTAssertEqual(Promise().debugDescription, "Promise<()>.fulfilled(())")
|
||||
XCTAssertEqual(Promise<String>(error: Error.dummy).debugDescription, "Promise<String>.rejected(Error.dummy)")
|
||||
|
||||
XCTAssertEqual("\(Promise<Int>.pending().promise)", "Promise(…Int)")
|
||||
XCTAssertEqual("\(Promise.value(3))", "Promise(3)")
|
||||
XCTAssertEqual("\(Promise<Void>(error: Error.dummy))", "Promise(dummy)")
|
||||
}
|
||||
|
||||
func testCannotFulfillWithError() {
|
||||
|
||||
// sadly this test proves the opposite :(
|
||||
// left here so maybe one day we can prevent instantiation of `Promise<Error>`
|
||||
|
||||
_ = Promise { seal in
|
||||
seal.fulfill(Error.dummy)
|
||||
}
|
||||
|
||||
_ = Promise<Error>.pending()
|
||||
|
||||
_ = Promise.value(Error.dummy)
|
||||
|
||||
_ = Promise().map { Error.dummy }
|
||||
}
|
||||
|
||||
#if swift(>=3.1)
|
||||
func testCanMakeVoidPromise() {
|
||||
_ = Promise()
|
||||
_ = Guarantee()
|
||||
}
|
||||
#endif
|
||||
|
||||
enum Error: Swift.Error {
|
||||
case dummy
|
||||
}
|
||||
|
||||
func testThrowInInitializer() {
|
||||
let p = Promise<Void> { _ in
|
||||
throw Error.dummy
|
||||
}
|
||||
XCTAssertTrue(p.isRejected)
|
||||
guard let err = p.error, case Error.dummy = err else { return XCTFail() }
|
||||
}
|
||||
|
||||
func testThrowInFirstly() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
firstly { () -> Promise<Int> in
|
||||
throw Error.dummy
|
||||
}.catch {
|
||||
XCTAssertEqual($0 as? Error, Error.dummy)
|
||||
ex.fulfill()
|
||||
}
|
||||
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testWait() throws {
|
||||
let p = after(.milliseconds(100)).then(on: nil){ Promise.value(1) }
|
||||
XCTAssertEqual(try p.wait(), 1)
|
||||
|
||||
do {
|
||||
let p = after(.milliseconds(100)).map(on: nil){ throw Error.dummy }
|
||||
try p.wait()
|
||||
XCTFail()
|
||||
} catch {
|
||||
XCTAssertEqual(error as? Error, Error.dummy)
|
||||
}
|
||||
}
|
||||
|
||||
func testPipeForResolved() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value(1).done {
|
||||
XCTAssertEqual(1, $0)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
}
|
51
Carthage/Checkouts/PromiseKit/Tests/CorePromise/RaceTests.swift
vendored
Normal file
51
Carthage/Checkouts/PromiseKit/Tests/CorePromise/RaceTests.swift
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
import XCTest
|
||||
import PromiseKit
|
||||
|
||||
class RaceTests: XCTestCase {
|
||||
func test1() {
|
||||
let ex = expectation(description: "")
|
||||
race(after(.milliseconds(10)).then{ Promise.value(1) }, after(seconds: 1).map{ 2 }).done { index in
|
||||
XCTAssertEqual(index, 1)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func test2() {
|
||||
let ex = expectation(description: "")
|
||||
race(after(seconds: 1).map{ 1 }, after(.milliseconds(10)).map{ 2 }).done { index in
|
||||
XCTAssertEqual(index, 2)
|
||||
ex.fulfill()
|
||||
}
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func test1Array() {
|
||||
let ex = expectation(description: "")
|
||||
let promises = [after(.milliseconds(10)).map{ 1 }, after(seconds: 1).map{ 2 }]
|
||||
race(promises).done { index in
|
||||
XCTAssertEqual(index, 1)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func test2Array() {
|
||||
let ex = expectation(description: "")
|
||||
race(after(seconds: 1).map{ 1 }, after(.milliseconds(10)).map{ 2 }).done { index in
|
||||
XCTAssertEqual(index, 2)
|
||||
ex.fulfill()
|
||||
}
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testEmptyArray() {
|
||||
let ex = expectation(description: "")
|
||||
let empty = [Promise<Int>]()
|
||||
race(empty).catch {
|
||||
guard case PMKError.badInput = $0 else { return XCTFail() }
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
}
|
27
Carthage/Checkouts/PromiseKit/Tests/CorePromise/RegressionTests.swift
vendored
Normal file
27
Carthage/Checkouts/PromiseKit/Tests/CorePromise/RegressionTests.swift
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class RegressionTests: XCTestCase {
|
||||
func testReturningPreviousPromiseWorks() {
|
||||
|
||||
// regression test because we were doing this wrong
|
||||
// in our A+ tests implementation for spec: 2.3.1
|
||||
|
||||
do {
|
||||
let promise1 = Promise()
|
||||
let promise2 = promise1.then(on: nil) { promise1 }
|
||||
promise2.catch(on: nil) { _ in XCTFail() }
|
||||
}
|
||||
do {
|
||||
enum Error: Swift.Error { case dummy }
|
||||
|
||||
let promise1 = Promise<Void>(error: Error.dummy)
|
||||
let promise2 = promise1.recover(on: nil) { _ in promise1 }
|
||||
promise2.catch(on: nil) { err in
|
||||
if case PMKError.returnedSelf = err {
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
166
Carthage/Checkouts/PromiseKit/Tests/CorePromise/ResolverTests.swift
vendored
Normal file
166
Carthage/Checkouts/PromiseKit/Tests/CorePromise/ResolverTests.swift
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class WrapTests: XCTestCase {
|
||||
fileprivate class KittenFetcher {
|
||||
let value: Int?
|
||||
let error: Error?
|
||||
|
||||
init(value: Int?, error: Error?) {
|
||||
self.value = value
|
||||
self.error = error
|
||||
}
|
||||
|
||||
func fetchWithCompletionBlock(block: @escaping(Int?, Error?) -> Void) {
|
||||
after(.milliseconds(20)).done {
|
||||
block(self.value, self.error)
|
||||
}
|
||||
}
|
||||
|
||||
func fetchWithCompletionBlock2(block: @escaping(Error?, Int?) -> Void) {
|
||||
after(.milliseconds(20)).done {
|
||||
block(self.error, self.value)
|
||||
}
|
||||
}
|
||||
|
||||
func fetchWithCompletionBlock3(block: @escaping(Int, Error?) -> Void) {
|
||||
after(.milliseconds(20)).done {
|
||||
block(self.value ?? -99, self.error)
|
||||
}
|
||||
}
|
||||
|
||||
func fetchWithCompletionBlock4(block: @escaping(Error?) -> Void) {
|
||||
after(.milliseconds(20)).done {
|
||||
block(self.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testSuccess() {
|
||||
let ex = expectation(description: "")
|
||||
let kittenFetcher = KittenFetcher(value: 2, error: nil)
|
||||
Promise { seal in
|
||||
kittenFetcher.fetchWithCompletionBlock(block: seal.resolve)
|
||||
}.done {
|
||||
XCTAssertEqual($0, 2)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testError() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
let kittenFetcher = KittenFetcher(value: nil, error: Error.test)
|
||||
Promise { seal in
|
||||
kittenFetcher.fetchWithCompletionBlock(block: seal.resolve)
|
||||
}.catch { error in
|
||||
defer { ex.fulfill() }
|
||||
guard case Error.test = error else {
|
||||
return XCTFail()
|
||||
}
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testInvalidCallingConvention() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
let kittenFetcher = KittenFetcher(value: nil, error: nil)
|
||||
Promise { seal in
|
||||
kittenFetcher.fetchWithCompletionBlock(block: seal.resolve)
|
||||
}.catch { error in
|
||||
defer { ex.fulfill() }
|
||||
guard case PMKError.invalidCallingConvention = error else {
|
||||
return XCTFail()
|
||||
}
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testInvertedCallingConvention() {
|
||||
let ex = expectation(description: "")
|
||||
let kittenFetcher = KittenFetcher(value: 2, error: nil)
|
||||
Promise { seal in
|
||||
kittenFetcher.fetchWithCompletionBlock2(block: seal.resolve)
|
||||
}.done {
|
||||
XCTAssertEqual($0, 2)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
|
||||
}
|
||||
|
||||
func testNonOptionalFirstParameter() {
|
||||
let ex1 = expectation(description: "")
|
||||
let kf1 = KittenFetcher(value: 2, error: nil)
|
||||
Promise { seal in
|
||||
kf1.fetchWithCompletionBlock3(block: seal.resolve)
|
||||
}.done {
|
||||
XCTAssertEqual($0, 2)
|
||||
ex1.fulfill()
|
||||
}.silenceWarning()
|
||||
|
||||
let ex2 = expectation(description: "")
|
||||
let kf2 = KittenFetcher(value: -100, error: Error.test)
|
||||
Promise { seal in
|
||||
kf2.fetchWithCompletionBlock3(block: seal.resolve)
|
||||
}.catch { _ in ex2.fulfill() }
|
||||
|
||||
wait(for: [ex1, ex2] ,timeout: 1)
|
||||
}
|
||||
|
||||
#if swift(>=3.1)
|
||||
func testVoidCompletionValue() {
|
||||
let ex1 = expectation(description: "")
|
||||
let kf1 = KittenFetcher(value: nil, error: nil)
|
||||
Promise { seal in
|
||||
kf1.fetchWithCompletionBlock4(block: seal.resolve)
|
||||
}.done(ex1.fulfill).silenceWarning()
|
||||
|
||||
let ex2 = expectation(description: "")
|
||||
let kf2 = KittenFetcher(value: nil, error: Error.test)
|
||||
Promise { seal in
|
||||
kf2.fetchWithCompletionBlock4(block: seal.resolve)
|
||||
}.catch { _ in ex2.fulfill() }
|
||||
|
||||
wait(for: [ex1, ex2], timeout: 1)
|
||||
}
|
||||
#endif
|
||||
|
||||
func testIsFulfilled() {
|
||||
XCTAssertTrue(Promise.value(()).result?.isFulfilled ?? false)
|
||||
XCTAssertFalse(Promise<Int>(error: Error.test).result?.isFulfilled ?? true)
|
||||
}
|
||||
|
||||
func testPendingPromiseDeallocated() {
|
||||
|
||||
// NOTE this doesn't seem to register the `deinit` as covered :(
|
||||
// BUT putting a breakpoint in the deinit CLEARLY shows it getting covered…
|
||||
|
||||
class Foo {
|
||||
let p = Promise<Void>.pending()
|
||||
var ex: XCTestExpectation!
|
||||
|
||||
deinit {
|
||||
after(.milliseconds(100)).done(ex.fulfill)
|
||||
}
|
||||
}
|
||||
|
||||
let ex = expectation(description: "")
|
||||
do {
|
||||
// for code coverage report for `Resolver.deinit` warning
|
||||
let foo = Foo()
|
||||
foo.ex = ex
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
}
|
||||
|
||||
private enum Error: Swift.Error {
|
||||
case test
|
||||
}
|
78
Carthage/Checkouts/PromiseKit/Tests/CorePromise/StressTests.swift
vendored
Normal file
78
Carthage/Checkouts/PromiseKit/Tests/CorePromise/StressTests.swift
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
import PromiseKit
|
||||
import Dispatch
|
||||
import XCTest
|
||||
|
||||
class StressTests: XCTestCase {
|
||||
func testThenDataRace() {
|
||||
let e1 = expectation(description: "")
|
||||
|
||||
//will crash if then doesn't protect handlers
|
||||
stressDataRace(expectation: e1, stressFunction: { promise in
|
||||
promise.done { s in
|
||||
XCTAssertEqual("ok", s)
|
||||
return
|
||||
}.silenceWarning()
|
||||
}, fulfill: { "ok" })
|
||||
|
||||
waitForExpectations(timeout: 10, handler: nil)
|
||||
}
|
||||
|
||||
@available(macOS 10.10, iOS 2.0, tvOS 10.0, watchOS 2.0, *)
|
||||
func testThensAreSequentialForLongTime() {
|
||||
var values = [Int]()
|
||||
let ex = expectation(description: "")
|
||||
var promise = DispatchQueue.global().async(.promise){ 0 }
|
||||
let N = 1000
|
||||
for x in 1..<N {
|
||||
promise = promise.then { y -> Guarantee<Int> in
|
||||
values.append(y)
|
||||
XCTAssertEqual(x - 1, y)
|
||||
return DispatchQueue.global().async(.promise) { x }
|
||||
}
|
||||
}
|
||||
promise.done { x in
|
||||
values.append(x)
|
||||
XCTAssertEqual(values, (0..<N).map{ $0 })
|
||||
ex.fulfill()
|
||||
}
|
||||
waitForExpectations(timeout: 10, handler: nil)
|
||||
}
|
||||
|
||||
func testZalgoDataRace() {
|
||||
let e1 = expectation(description: "")
|
||||
|
||||
//will crash if zalgo doesn't protect handlers
|
||||
stressDataRace(expectation: e1, stressFunction: { promise in
|
||||
promise.done(on: nil) { s in
|
||||
XCTAssertEqual("ok", s)
|
||||
}.silenceWarning()
|
||||
}, fulfill: {
|
||||
return "ok"
|
||||
})
|
||||
|
||||
waitForExpectations(timeout: 10, handler: nil)
|
||||
}
|
||||
}
|
||||
|
||||
private enum Error: Swift.Error {
|
||||
case Dummy
|
||||
}
|
||||
|
||||
private func stressDataRace<T: Equatable>(expectation e1: XCTestExpectation, iterations: Int = 1000, stressFactor: Int = 10, stressFunction: @escaping (Promise<T>) -> Void, fulfill f: @escaping () -> T) {
|
||||
let group = DispatchGroup()
|
||||
let queue = DispatchQueue(label: "the.domain.of.Zalgo", attributes: .concurrent)
|
||||
|
||||
for _ in 0..<iterations {
|
||||
let (promise, seal) = Promise<T>.pending()
|
||||
|
||||
DispatchQueue.concurrentPerform(iterations: stressFactor) { n in
|
||||
stressFunction(promise)
|
||||
}
|
||||
|
||||
queue.async(group: group) {
|
||||
seal.fulfill(f())
|
||||
}
|
||||
}
|
||||
|
||||
group.notify(queue: queue, execute: e1.fulfill)
|
||||
}
|
155
Carthage/Checkouts/PromiseKit/Tests/CorePromise/ThenableTests.swift
vendored
Normal file
155
Carthage/Checkouts/PromiseKit/Tests/CorePromise/ThenableTests.swift
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
import PromiseKit
|
||||
import Dispatch
|
||||
import XCTest
|
||||
|
||||
class ThenableTests: XCTestCase {
|
||||
func testGet() {
|
||||
let ex1 = expectation(description: "")
|
||||
let ex2 = expectation(description: "")
|
||||
Promise.value(1).get {
|
||||
XCTAssertEqual($0, 1)
|
||||
ex1.fulfill()
|
||||
}.done {
|
||||
XCTAssertEqual($0, 1)
|
||||
ex2.fulfill()
|
||||
}.silenceWarning()
|
||||
wait(for: [ex1, ex2], timeout: 10)
|
||||
}
|
||||
|
||||
func testCompactMap() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value(1.0).compactMap {
|
||||
Int($0)
|
||||
}.done {
|
||||
XCTAssertEqual($0, 1)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testCompactMapThrows() {
|
||||
|
||||
enum E: Error { case dummy }
|
||||
|
||||
let ex = expectation(description: "")
|
||||
Promise.value("a").compactMap { x -> Int in
|
||||
throw E.dummy
|
||||
}.catch {
|
||||
if case E.dummy = $0 {} else {
|
||||
XCTFail()
|
||||
}
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testRejectedPromiseCompactMap() {
|
||||
|
||||
enum E: Error { case dummy }
|
||||
|
||||
let ex = expectation(description: "")
|
||||
Promise(error: E.dummy).compactMap {
|
||||
Int($0)
|
||||
}.catch {
|
||||
if case E.dummy = $0 {} else {
|
||||
XCTFail()
|
||||
}
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testPMKErrorCompactMap() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value("a").compactMap {
|
||||
Int($0)
|
||||
}.catch {
|
||||
if case PMKError.compactMap = $0 {} else {
|
||||
XCTFail()
|
||||
}
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testCompactMapValues() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value(["1","2","a","4"]).compactMapValues {
|
||||
Int($0)
|
||||
}.done {
|
||||
XCTAssertEqual([1,2,4], $0)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testThenMap() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value([1,2,3,4]).thenMap {
|
||||
Promise.value($0)
|
||||
}.done {
|
||||
XCTAssertEqual([1,2,3,4], $0)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testThenFlatMap() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value([1,2,3,4]).thenFlatMap {
|
||||
Promise.value([$0, $0])
|
||||
}.done {
|
||||
XCTAssertEqual([1,1,2,2,3,3,4,4], $0)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testLastValueForEmpty() {
|
||||
XCTAssertTrue(Promise.value([]).lastValue.isRejected)
|
||||
}
|
||||
|
||||
func testFirstValueForEmpty() {
|
||||
XCTAssertTrue(Promise.value([]).firstValue.isRejected)
|
||||
}
|
||||
|
||||
func testThenOffRejected() {
|
||||
// surprisingly missing in our CI, mainly due to
|
||||
// extensive use of `done` in A+ tests since PMK 5
|
||||
|
||||
let ex = expectation(description: "")
|
||||
Promise<Int>(error: PMKError.badInput).then { x -> Promise<Int> in
|
||||
XCTFail()
|
||||
return .value(x)
|
||||
}.catch { _ in
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testBarrier() {
|
||||
let ex = expectation(description: "")
|
||||
let q = DispatchQueue(label: "\(#file):\(#line)", attributes: .concurrent)
|
||||
Promise.value(1).done(on: q, flags: .barrier) {
|
||||
XCTAssertEqual($0, 1)
|
||||
dispatchPrecondition(condition: .onQueueAsBarrier(q))
|
||||
ex.fulfill()
|
||||
}.catch { _ in
|
||||
XCTFail()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testDispatchFlagsSyntax() {
|
||||
let ex = expectation(description: "")
|
||||
let q = DispatchQueue(label: "\(#file):\(#line)", attributes: .concurrent)
|
||||
Promise.value(1).done(on: q, flags: [.barrier, .inheritQoS]) {
|
||||
XCTAssertEqual($0, 1)
|
||||
dispatchPrecondition(condition: .onQueueAsBarrier(q))
|
||||
ex.fulfill()
|
||||
}.catch { _ in
|
||||
XCTFail()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
}
|
33
Carthage/Checkouts/PromiseKit/Tests/CorePromise/Utilities.swift
vendored
Normal file
33
Carthage/Checkouts/PromiseKit/Tests/CorePromise/Utilities.swift
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import PromiseKit
|
||||
|
||||
extension Promise {
|
||||
func silenceWarning() {}
|
||||
}
|
||||
|
||||
#if os(Linux)
|
||||
import func CoreFoundation._CFIsMainThread
|
||||
|
||||
extension Thread {
|
||||
// `isMainThread` is not implemented yet in swift-corelibs-foundation.
|
||||
static var isMainThread: Bool {
|
||||
return _CFIsMainThread()
|
||||
}
|
||||
}
|
||||
|
||||
import XCTest
|
||||
|
||||
extension XCTestCase {
|
||||
func wait(for: [XCTestExpectation], timeout: TimeInterval, file: StaticString = #file, line: UInt = #line) {
|
||||
#if !(swift(>=4.0) && !swift(>=4.1))
|
||||
let line = Int(line)
|
||||
#endif
|
||||
waitForExpectations(timeout: timeout, file: file, line: line)
|
||||
}
|
||||
}
|
||||
|
||||
extension XCTestExpectation {
|
||||
func fulfill() {
|
||||
fulfill(#file, line: #line)
|
||||
}
|
||||
}
|
||||
#endif
|
159
Carthage/Checkouts/PromiseKit/Tests/CorePromise/WhenConcurrentTests.swift
vendored
Normal file
159
Carthage/Checkouts/PromiseKit/Tests/CorePromise/WhenConcurrentTests.swift
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
import XCTest
|
||||
import PromiseKit
|
||||
|
||||
class WhenConcurrentTestCase_Swift: XCTestCase {
|
||||
|
||||
func testWhen() {
|
||||
let e = expectation(description: "")
|
||||
|
||||
var numbers = (0..<42).makeIterator()
|
||||
let squareNumbers = numbers.map { $0 * $0 }
|
||||
|
||||
let generator = AnyIterator<Guarantee<Int>> {
|
||||
guard let number = numbers.next() else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return after(.milliseconds(10)).map {
|
||||
return number * number
|
||||
}
|
||||
}
|
||||
|
||||
when(fulfilled: generator, concurrently: 5).done { numbers in
|
||||
if numbers == squareNumbers {
|
||||
e.fulfill()
|
||||
}
|
||||
}.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 3, handler: nil)
|
||||
}
|
||||
|
||||
func testWhenEmptyGenerator() {
|
||||
let e = expectation(description: "")
|
||||
|
||||
let generator = AnyIterator<Promise<Int>> {
|
||||
return nil
|
||||
}
|
||||
|
||||
when(fulfilled: generator, concurrently: 5).done { numbers in
|
||||
if numbers.count == 0 {
|
||||
e.fulfill()
|
||||
}
|
||||
}.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testWhenGeneratorError() {
|
||||
enum LocalError: Error {
|
||||
case Unknown
|
||||
case DivisionByZero
|
||||
}
|
||||
|
||||
let expectedErrorIndex = 42
|
||||
let expectedError = LocalError.DivisionByZero
|
||||
|
||||
let e = expectation(description: "")
|
||||
|
||||
var numbers = (-expectedErrorIndex..<expectedErrorIndex).makeIterator()
|
||||
|
||||
let generator = AnyIterator<Promise<Int>> {
|
||||
guard let number = numbers.next() else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return after(.milliseconds(10)).then { _ -> Promise<Int> in
|
||||
if number != 0 {
|
||||
return Promise(error: expectedError)
|
||||
} else {
|
||||
return .value(100500 / number)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
when(fulfilled: generator, concurrently: 3)
|
||||
.catch { error in
|
||||
guard let error = error as? LocalError else {
|
||||
return
|
||||
}
|
||||
guard case .DivisionByZero = error else {
|
||||
return
|
||||
}
|
||||
e.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 3, handler: nil)
|
||||
}
|
||||
|
||||
func testWhenConcurrency() {
|
||||
let expectedConcurrently = 4
|
||||
var currentConcurrently = 0
|
||||
var maxConcurrently = 0
|
||||
|
||||
let e = expectation(description: "")
|
||||
|
||||
var numbers = (0..<42).makeIterator()
|
||||
|
||||
let generator = AnyIterator<Promise<Int>> {
|
||||
currentConcurrently += 1
|
||||
maxConcurrently = max(maxConcurrently, currentConcurrently)
|
||||
|
||||
guard let number = numbers.next() else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return after(.milliseconds(10)).then(on: .main) { _ -> Promise<Int> in
|
||||
currentConcurrently -= 1
|
||||
return .value(number * number)
|
||||
}
|
||||
}
|
||||
|
||||
when(fulfilled: generator, concurrently: expectedConcurrently).done { _ in
|
||||
XCTAssertEqual(expectedConcurrently, maxConcurrently)
|
||||
e.fulfill()
|
||||
}.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 3)
|
||||
}
|
||||
|
||||
func testWhenConcurrencyLessThanZero() {
|
||||
let generator = AnyIterator<Promise<Int>> { XCTFail(); return nil }
|
||||
|
||||
let p1 = when(fulfilled: generator, concurrently: 0)
|
||||
let p2 = when(fulfilled: generator, concurrently: -1)
|
||||
|
||||
guard let e1 = p1.error else { return XCTFail() }
|
||||
guard let e2 = p2.error else { return XCTFail() }
|
||||
guard case PMKError.badInput = e1 else { return XCTFail() }
|
||||
guard case PMKError.badInput = e2 else { return XCTFail() }
|
||||
}
|
||||
|
||||
func testStopsDequeueingOnceRejected() {
|
||||
let ex = expectation(description: "")
|
||||
enum Error: Swift.Error { case dummy }
|
||||
|
||||
var x: UInt = 0
|
||||
let generator = AnyIterator<Promise<Void>> {
|
||||
x += 1
|
||||
switch x {
|
||||
case 0:
|
||||
fatalError()
|
||||
case 1:
|
||||
return Promise()
|
||||
case 2:
|
||||
return Promise(error: Error.dummy)
|
||||
case _:
|
||||
XCTFail()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
when(fulfilled: generator, concurrently: 1).done {
|
||||
XCTFail("\($0)")
|
||||
}.catch { error in
|
||||
ex.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 3)
|
||||
}
|
||||
}
|
41
Carthage/Checkouts/PromiseKit/Tests/CorePromise/WhenResolvedTests.swift
vendored
Normal file
41
Carthage/Checkouts/PromiseKit/Tests/CorePromise/WhenResolvedTests.swift
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// Created by Austin Feight on 3/19/16.
|
||||
// Copyright © 2016 Max Howell. All rights reserved.
|
||||
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class JoinTests: XCTestCase {
|
||||
func testImmediates() {
|
||||
let successPromise = Promise()
|
||||
|
||||
var joinFinished = false
|
||||
when(resolved: successPromise).done(on: nil) { _ in joinFinished = true }
|
||||
XCTAssert(joinFinished, "Join immediately finishes on fulfilled promise")
|
||||
|
||||
let promise2 = Promise.value(2)
|
||||
let promise3 = Promise.value(3)
|
||||
let promise4 = Promise.value(4)
|
||||
var join2Finished = false
|
||||
when(resolved: promise2, promise3, promise4).done(on: nil) { _ in join2Finished = true }
|
||||
XCTAssert(join2Finished, "Join immediately finishes on fulfilled promises")
|
||||
}
|
||||
|
||||
func testFulfilledAfterAllResolve() {
|
||||
let (promise1, seal1) = Promise<Void>.pending()
|
||||
let (promise2, seal2) = Promise<Void>.pending()
|
||||
let (promise3, seal3) = Promise<Void>.pending()
|
||||
|
||||
var finished = false
|
||||
when(resolved: promise1, promise2, promise3).done(on: nil) { _ in finished = true }
|
||||
XCTAssertFalse(finished, "Not all promises have resolved")
|
||||
|
||||
seal1.fulfill(())
|
||||
XCTAssertFalse(finished, "Not all promises have resolved")
|
||||
|
||||
seal2.fulfill(())
|
||||
XCTAssertFalse(finished, "Not all promises have resolved")
|
||||
|
||||
seal3.fulfill(())
|
||||
XCTAssert(finished, "All promises have resolved")
|
||||
}
|
||||
}
|
265
Carthage/Checkouts/PromiseKit/Tests/CorePromise/WhenTests.swift
vendored
Normal file
265
Carthage/Checkouts/PromiseKit/Tests/CorePromise/WhenTests.swift
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
import PromiseKit
|
||||
import Dispatch
|
||||
import XCTest
|
||||
|
||||
class WhenTests: XCTestCase {
|
||||
|
||||
func testEmpty() {
|
||||
let e1 = expectation(description: "")
|
||||
let promises: [Promise<Void>] = []
|
||||
when(fulfilled: promises).done { _ in
|
||||
e1.fulfill()
|
||||
}.silenceWarning()
|
||||
|
||||
let e2 = expectation(description: "")
|
||||
when(resolved: promises).done { _ in
|
||||
e2.fulfill()
|
||||
}.silenceWarning()
|
||||
|
||||
wait(for: [e1, e2], timeout: 1)
|
||||
}
|
||||
|
||||
func testInt() {
|
||||
let e1 = expectation(description: "")
|
||||
let p1 = Promise.value(1)
|
||||
let p2 = Promise.value(2)
|
||||
let p3 = Promise.value(3)
|
||||
let p4 = Promise.value(4)
|
||||
|
||||
when(fulfilled: [p1, p2, p3, p4]).done { x in
|
||||
XCTAssertEqual(x[0], 1)
|
||||
XCTAssertEqual(x[1], 2)
|
||||
XCTAssertEqual(x[2], 3)
|
||||
XCTAssertEqual(x[3], 4)
|
||||
XCTAssertEqual(x.count, 4)
|
||||
e1.fulfill()
|
||||
}.silenceWarning()
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testDoubleTuple() {
|
||||
let e1 = expectation(description: "")
|
||||
let p1 = Promise.value(1)
|
||||
let p2 = Promise.value("abc")
|
||||
when(fulfilled: p1, p2).done{ x, y in
|
||||
XCTAssertEqual(x, 1)
|
||||
XCTAssertEqual(y, "abc")
|
||||
e1.fulfill()
|
||||
}.silenceWarning()
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testTripleTuple() {
|
||||
let e1 = expectation(description: "")
|
||||
let p1 = Promise.value(1)
|
||||
let p2 = Promise.value("abc")
|
||||
let p3 = Promise.value( 1.0)
|
||||
when(fulfilled: p1, p2, p3).done { u, v, w in
|
||||
XCTAssertEqual(1, u)
|
||||
XCTAssertEqual("abc", v)
|
||||
XCTAssertEqual(1.0, w)
|
||||
e1.fulfill()
|
||||
}.silenceWarning()
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testQuadrupleTuple() {
|
||||
let e1 = expectation(description: "")
|
||||
let p1 = Promise.value(1)
|
||||
let p2 = Promise.value("abc")
|
||||
let p3 = Promise.value(1.0)
|
||||
let p4 = Promise.value(true)
|
||||
when(fulfilled: p1, p2, p3, p4).done { u, v, w, x in
|
||||
XCTAssertEqual(1, u)
|
||||
XCTAssertEqual("abc", v)
|
||||
XCTAssertEqual(1.0, w)
|
||||
XCTAssertEqual(true, x)
|
||||
e1.fulfill()
|
||||
}.silenceWarning()
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testQuintupleTuple() {
|
||||
let e1 = expectation(description: "")
|
||||
let p1 = Promise.value(1)
|
||||
let p2 = Promise.value("abc")
|
||||
let p3 = Promise.value(1.0)
|
||||
let p4 = Promise.value(true)
|
||||
let p5 = Promise.value("a" as Character)
|
||||
when(fulfilled: p1, p2, p3, p4, p5).done { u, v, w, x, y in
|
||||
XCTAssertEqual(1, u)
|
||||
XCTAssertEqual("abc", v)
|
||||
XCTAssertEqual(1.0, w)
|
||||
XCTAssertEqual(true, x)
|
||||
XCTAssertEqual("a" as Character, y)
|
||||
e1.fulfill()
|
||||
}.silenceWarning()
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testVoid() {
|
||||
let e1 = expectation(description: "")
|
||||
let p1 = Promise.value(1).done { _ in }
|
||||
let p2 = Promise.value(2).done { _ in }
|
||||
let p3 = Promise.value(3).done { _ in }
|
||||
let p4 = Promise.value(4).done { _ in }
|
||||
|
||||
when(fulfilled: p1, p2, p3, p4).done(e1.fulfill).silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testRejected() {
|
||||
enum Error: Swift.Error { case dummy }
|
||||
|
||||
let e1 = expectation(description: "")
|
||||
let p1 = after(.milliseconds(100)).map{ true }
|
||||
let p2: Promise<Bool> = after(.milliseconds(200)).map{ throw Error.dummy }
|
||||
let p3 = Promise.value(false)
|
||||
|
||||
when(fulfilled: p1, p2, p3).catch { _ in
|
||||
e1.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testProgress() {
|
||||
let ex = expectation(description: "")
|
||||
|
||||
XCTAssertNil(Progress.current())
|
||||
|
||||
let p1 = after(.milliseconds(10))
|
||||
let p2 = after(.milliseconds(20))
|
||||
let p3 = after(.milliseconds(30))
|
||||
let p4 = after(.milliseconds(40))
|
||||
|
||||
let progress = Progress(totalUnitCount: 1)
|
||||
progress.becomeCurrent(withPendingUnitCount: 1)
|
||||
|
||||
when(fulfilled: p1, p2, p3, p4).done { _ in
|
||||
XCTAssertEqual(progress.completedUnitCount, 1)
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
|
||||
progress.resignCurrent()
|
||||
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testProgressDoesNotExceed100Percent() {
|
||||
let ex1 = expectation(description: "")
|
||||
let ex2 = expectation(description: "")
|
||||
|
||||
XCTAssertNil(Progress.current())
|
||||
|
||||
let p1 = after(.milliseconds(10))
|
||||
let p2 = after(.milliseconds(20)).done { throw NSError(domain: "a", code: 1, userInfo: nil) }
|
||||
let p3 = after(.milliseconds(30))
|
||||
let p4 = after(.milliseconds(40))
|
||||
|
||||
let progress = Progress(totalUnitCount: 1)
|
||||
progress.becomeCurrent(withPendingUnitCount: 1)
|
||||
|
||||
let promise = when(fulfilled: p1, p2, p3, p4)
|
||||
|
||||
progress.resignCurrent()
|
||||
|
||||
promise.catch { _ in
|
||||
ex2.fulfill()
|
||||
}
|
||||
|
||||
var x = 0
|
||||
func finally() {
|
||||
x += 1
|
||||
if x == 4 {
|
||||
XCTAssertLessThanOrEqual(1, progress.fractionCompleted)
|
||||
XCTAssertEqual(progress.completedUnitCount, 1)
|
||||
ex1.fulfill()
|
||||
}
|
||||
}
|
||||
|
||||
let q = DispatchQueue.main
|
||||
p1.done(on: q, finally)
|
||||
p2.ensure(on: q, finally).silenceWarning()
|
||||
p3.done(on: q, finally)
|
||||
p4.done(on: q, finally)
|
||||
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testUnhandledErrorHandlerDoesNotFire() {
|
||||
enum Error: Swift.Error {
|
||||
case test
|
||||
}
|
||||
|
||||
let ex = expectation(description: "")
|
||||
let p1 = Promise<Void>(error: Error.test)
|
||||
let p2 = after(.milliseconds(100))
|
||||
when(fulfilled: p1, p2).done{ _ in XCTFail() }.catch { error in
|
||||
XCTAssertTrue(error as? Error == Error.test)
|
||||
ex.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testUnhandledErrorHandlerDoesNotFireForStragglers() {
|
||||
enum Error: Swift.Error {
|
||||
case test
|
||||
case straggler
|
||||
}
|
||||
|
||||
let ex1 = expectation(description: "")
|
||||
let ex2 = expectation(description: "")
|
||||
let ex3 = expectation(description: "")
|
||||
|
||||
let p1 = Promise<Void>(error: Error.test)
|
||||
let p2 = after(.milliseconds(100)).done { throw Error.straggler }
|
||||
let p3 = after(.milliseconds(200)).done { throw Error.straggler }
|
||||
|
||||
when(fulfilled: p1, p2, p3).catch { error -> Void in
|
||||
XCTAssertTrue(Error.test == error as? Error)
|
||||
ex1.fulfill()
|
||||
}
|
||||
|
||||
p2.ensure { after(.milliseconds(100)).done(ex2.fulfill) }.silenceWarning()
|
||||
p3.ensure { after(.milliseconds(100)).done(ex3.fulfill) }.silenceWarning()
|
||||
|
||||
waitForExpectations(timeout: 1, handler: nil)
|
||||
}
|
||||
|
||||
func testAllSealedRejectedFirstOneRejects() {
|
||||
enum Error: Swift.Error {
|
||||
case test1
|
||||
case test2
|
||||
case test3
|
||||
}
|
||||
|
||||
let ex = expectation(description: "")
|
||||
let p1 = Promise<Void>(error: Error.test1)
|
||||
let p2 = Promise<Void>(error: Error.test2)
|
||||
let p3 = Promise<Void>(error: Error.test3)
|
||||
|
||||
when(fulfilled: p1, p2, p3).catch { error in
|
||||
XCTAssertTrue(error as? Error == Error.test1)
|
||||
ex.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
func testGuaranteeWhen() {
|
||||
let ex1 = expectation(description: "")
|
||||
when(Guarantee(), Guarantee()).done {
|
||||
ex1.fulfill()
|
||||
}
|
||||
|
||||
let ex2 = expectation(description: "")
|
||||
when(guarantees: [Guarantee(), Guarantee()]).done {
|
||||
ex2.fulfill()
|
||||
}
|
||||
|
||||
wait(for: [ex1, ex2], timeout: 10)
|
||||
}
|
||||
}
|
59
Carthage/Checkouts/PromiseKit/Tests/CorePromise/ZalgoTests.swift
vendored
Normal file
59
Carthage/Checkouts/PromiseKit/Tests/CorePromise/ZalgoTests.swift
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
import XCTest
|
||||
import PromiseKit
|
||||
|
||||
class ZalgoTests: XCTestCase {
|
||||
func test1() {
|
||||
var resolved = false
|
||||
Promise.value(1).done(on: nil) { _ in
|
||||
resolved = true
|
||||
}.silenceWarning()
|
||||
XCTAssertTrue(resolved)
|
||||
}
|
||||
|
||||
func test2() {
|
||||
let p1 = Promise.value(1).map(on: nil) { x in
|
||||
return 2
|
||||
}
|
||||
XCTAssertEqual(p1.value!, 2)
|
||||
|
||||
var x = 0
|
||||
|
||||
let (p2, seal) = Promise<Int>.pending()
|
||||
p2.done(on: nil) { _ in
|
||||
x = 1
|
||||
}.silenceWarning()
|
||||
XCTAssertEqual(x, 0)
|
||||
|
||||
seal.fulfill(1)
|
||||
XCTAssertEqual(x, 1)
|
||||
}
|
||||
|
||||
// returning a pending promise from its own zalgo’d then handler doesn’t hang
|
||||
func test3() {
|
||||
let ex = (expectation(description: ""), expectation(description: ""))
|
||||
|
||||
var p1: Promise<Void>!
|
||||
p1 = after(.milliseconds(100)).then(on: nil) { _ -> Promise<Void> in
|
||||
ex.0.fulfill()
|
||||
return p1
|
||||
}
|
||||
|
||||
p1.catch { err in
|
||||
defer{ ex.1.fulfill() }
|
||||
guard case PMKError.returnedSelf = err else { return XCTFail() }
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
|
||||
// return a sealed promise from its own zalgo’d then handler doesn’t hang
|
||||
func test4() {
|
||||
let ex = expectation(description: "")
|
||||
let p1 = Promise.value(1)
|
||||
p1.then(on: nil) { _ -> Promise<Int> in
|
||||
ex.fulfill()
|
||||
return p1
|
||||
}.silenceWarning()
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
}
|
158
Carthage/Checkouts/PromiseKit/Tests/DeprecationTests.swift
vendored
Normal file
158
Carthage/Checkouts/PromiseKit/Tests/DeprecationTests.swift
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
import PromiseKit
|
||||
import XCTest
|
||||
|
||||
class DeprecationTests: XCTestCase {
|
||||
func testWrap1() {
|
||||
let dummy = 10
|
||||
|
||||
func completion(_ body: (_ a: Int?, _ b: Error?) -> Void) {
|
||||
body(dummy, nil)
|
||||
}
|
||||
|
||||
let ex = expectation(description: "")
|
||||
wrap(completion).done {
|
||||
XCTAssertEqual($0, dummy)
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testWrap2() {
|
||||
let dummy = 10
|
||||
|
||||
func completion(_ body: (_ a: Int, _ b: Error?) -> Void) {
|
||||
body(dummy, nil)
|
||||
}
|
||||
|
||||
let ex = expectation(description: "")
|
||||
wrap(completion).done {
|
||||
XCTAssertEqual($0, dummy)
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testWrap3() {
|
||||
let dummy = 10
|
||||
|
||||
func completion(_ body: (_ a: Error?, _ b: Int?) -> Void) {
|
||||
body(nil, dummy)
|
||||
}
|
||||
|
||||
let ex = expectation(description: "")
|
||||
wrap(completion).done {
|
||||
XCTAssertEqual($0, dummy)
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testWrap4() {
|
||||
let dummy = 10
|
||||
|
||||
func completion(_ body: (_ a: Error?) -> Void) {
|
||||
body(nil)
|
||||
}
|
||||
|
||||
let ex = expectation(description: "")
|
||||
wrap(completion).done {
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testWrap5() {
|
||||
let dummy = 10
|
||||
|
||||
func completion(_ body: (_ a: Int) -> Void) {
|
||||
body(dummy)
|
||||
}
|
||||
|
||||
let ex = expectation(description: "")
|
||||
wrap(completion).done {
|
||||
XCTAssertEqual($0, dummy)
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testAlways() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value(1).always(execute: ex.fulfill)
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
#if PMKFullDeprecations
|
||||
func testFlatMap() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value(1).flatMap { _ -> Int? in
|
||||
nil
|
||||
}.catch {
|
||||
//TODO should be `flatMap`, but how to enact that without causing
|
||||
// compiler to warn when building PromiseKit for end-users? LOL
|
||||
guard case PMKError.compactMap = $0 else { return XCTFail() }
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testSequenceMap() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value([1, 2]).map {
|
||||
$0 + 1
|
||||
}.done {
|
||||
XCTAssertEqual($0, [2, 3])
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testSequenceFlatMap() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value([1, 2]).flatMap {
|
||||
[$0 + 1, $0 + 2]
|
||||
}.done {
|
||||
XCTAssertEqual($0, [2, 3, 3, 4])
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
#endif
|
||||
|
||||
func testSequenceFilter() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value([0, 1, 2, 3]).filter {
|
||||
$0 < 2
|
||||
}.done {
|
||||
XCTAssertEqual($0, [0, 1])
|
||||
ex.fulfill()
|
||||
}.silenceWarning()
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testSorted() {
|
||||
let ex = expectation(description: "")
|
||||
Promise.value([5, 2, 1, 8]).sorted().done {
|
||||
XCTAssertEqual($0, [1,2,5,8])
|
||||
ex.fulfill()
|
||||
}
|
||||
wait(for: [ex], timeout: 10)
|
||||
}
|
||||
|
||||
func testFirst() {
|
||||
XCTAssertEqual(Promise.value([1,2]).first.value, 1)
|
||||
}
|
||||
|
||||
func testLast() {
|
||||
XCTAssertEqual(Promise.value([1,2]).last.value, 2)
|
||||
}
|
||||
|
||||
func testPMKErrorFlatMap() {
|
||||
XCTAssertNotNil(PMKError.flatMap(1, Int.self).errorDescription)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension Promise {
|
||||
func silenceWarning() {}
|
||||
}
|
63
Carthage/Checkouts/PromiseKit/Tests/JS-A+/.gitignore
vendored
Normal file
63
Carthage/Checkouts/PromiseKit/Tests/JS-A+/.gitignore
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
# From https://github.com/github/gitignore/blob/master/Node.gitignore
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# next.js build output
|
||||
.next
|
80
Carthage/Checkouts/PromiseKit/Tests/JS-A+/AllTests.swift
vendored
Normal file
80
Carthage/Checkouts/PromiseKit/Tests/JS-A+/AllTests.swift
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// AllTests.swift
|
||||
// PMKJSA+Tests
|
||||
//
|
||||
// Created by Lois Di Qual on 2/28/18.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import PromiseKit
|
||||
import JavaScriptCore
|
||||
|
||||
class AllTests: XCTestCase {
|
||||
|
||||
func testAll() {
|
||||
|
||||
let scriptPath = URL(fileURLWithPath: #file).deletingLastPathComponent().appendingPathComponent("build/build.js")
|
||||
guard FileManager.default.fileExists(atPath: scriptPath.path) else {
|
||||
return print("Skipping JS-A+: see README for instructions on how to build")
|
||||
}
|
||||
|
||||
guard let script = try? String(contentsOf: scriptPath) else {
|
||||
return XCTFail("Couldn't read content of test suite JS file")
|
||||
}
|
||||
|
||||
let context = JSUtils.sharedContext
|
||||
|
||||
// Add a global exception handler
|
||||
context.exceptionHandler = { context, exception in
|
||||
guard let exception = exception else {
|
||||
return XCTFail("Unknown JS exception")
|
||||
}
|
||||
JSUtils.printStackTrace(exception: exception, includeExceptionDescription: true)
|
||||
}
|
||||
|
||||
// Setup mock functions (timers, console.log, etc)
|
||||
let environment = MockNodeEnvironment()
|
||||
environment.setup(with: context)
|
||||
|
||||
// Expose JSPromise in the javascript context
|
||||
context.setObject(JSPromise.self, forKeyedSubscript: "JSPromise" as NSString)
|
||||
|
||||
// Create adapter
|
||||
guard let adapter = JSValue(object: NSDictionary(), in: context) else {
|
||||
fatalError("Couldn't create adapter")
|
||||
}
|
||||
adapter.setObject(JSAdapter.resolved, forKeyedSubscript: "resolved" as NSString)
|
||||
adapter.setObject(JSAdapter.rejected, forKeyedSubscript: "rejected" as NSString)
|
||||
adapter.setObject(JSAdapter.deferred, forKeyedSubscript: "deferred" as NSString)
|
||||
|
||||
// Evaluate contents of `build.js`, which exposes `runTests` in the global context
|
||||
context.evaluateScript(script)
|
||||
guard let runTests = context.objectForKeyedSubscript("runTests") else {
|
||||
return XCTFail("Couldn't find `runTests` in JS context")
|
||||
}
|
||||
|
||||
// Create a callback that's called whenever there's a failure
|
||||
let onFail: @convention(block) (JSValue, JSValue) -> Void = { test, error in
|
||||
guard let test = test.toString(), let error = error.toString() else {
|
||||
return XCTFail("Unknown test failure")
|
||||
}
|
||||
XCTFail("\(test) failed: \(error)")
|
||||
}
|
||||
let onFailValue: JSValue = JSValue(object: onFail, in: context)
|
||||
|
||||
// Create a new callback that we'll send to `runTest` so that it notifies when tests are done running.
|
||||
let expectation = self.expectation(description: "async")
|
||||
let onDone: @convention(block) (JSValue) -> Void = { failures in
|
||||
expectation.fulfill()
|
||||
}
|
||||
let onDoneValue: JSValue = JSValue(object: onDone, in: context)
|
||||
|
||||
// If there's a need to only run one specific test, uncomment the next line and comment the one after
|
||||
// let testName: JSValue = JSValue(object: "2.3.1", in: context)
|
||||
let testName = JSUtils.undefined
|
||||
|
||||
// Call `runTests`
|
||||
runTests.call(withArguments: [adapter, onFailValue, onDoneValue, testName])
|
||||
self.wait(for: [expectation], timeout: 60)
|
||||
}
|
||||
}
|
53
Carthage/Checkouts/PromiseKit/Tests/JS-A+/JSAdapter.swift
vendored
Normal file
53
Carthage/Checkouts/PromiseKit/Tests/JS-A+/JSAdapter.swift
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// JSAdapter.swift
|
||||
// PMKJSA+Tests
|
||||
//
|
||||
// Created by Lois Di Qual on 3/2/18.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import JavaScriptCore
|
||||
import PromiseKit
|
||||
|
||||
enum JSAdapter {
|
||||
|
||||
static let resolved: @convention(block) (JSValue) -> JSPromise = { value in
|
||||
return JSPromise(promise: .value(value))
|
||||
}
|
||||
|
||||
static let rejected: @convention(block) (JSValue) -> JSPromise = { reason in
|
||||
let error = JSUtils.JSError(reason: reason)
|
||||
let promise = Promise<JSValue>(error: error)
|
||||
return JSPromise(promise: promise)
|
||||
}
|
||||
|
||||
static let deferred: @convention(block) () -> JSValue = {
|
||||
|
||||
let context = JSContext.current()
|
||||
|
||||
guard let object = JSValue(object: NSDictionary(), in: context) else {
|
||||
fatalError("Couldn't create object")
|
||||
}
|
||||
|
||||
let pendingPromise = Promise<JSValue>.pending()
|
||||
let jsPromise = JSPromise(promise: pendingPromise.promise)
|
||||
|
||||
// promise
|
||||
object.setObject(jsPromise, forKeyedSubscript: "promise" as NSString)
|
||||
|
||||
// resolve
|
||||
let resolve: @convention(block) (JSValue) -> Void = { value in
|
||||
pendingPromise.resolver.fulfill(value)
|
||||
}
|
||||
object.setObject(resolve, forKeyedSubscript: "resolve" as NSString)
|
||||
|
||||
// reject
|
||||
let reject: @convention(block) (JSValue) -> Void = { reason in
|
||||
let error = JSUtils.JSError(reason: reason)
|
||||
pendingPromise.resolver.reject(error)
|
||||
}
|
||||
object.setObject(reject, forKeyedSubscript: "reject" as NSString)
|
||||
|
||||
return object
|
||||
}
|
||||
}
|
94
Carthage/Checkouts/PromiseKit/Tests/JS-A+/JSPromise.swift
vendored
Normal file
94
Carthage/Checkouts/PromiseKit/Tests/JS-A+/JSPromise.swift
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// JSPromise.swift
|
||||
// PMKJSA+Tests
|
||||
//
|
||||
// Created by Lois Di Qual on 3/1/18.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import XCTest
|
||||
import PromiseKit
|
||||
import JavaScriptCore
|
||||
|
||||
@objc protocol JSPromiseProtocol: JSExport {
|
||||
func then(_: JSValue, _: JSValue) -> JSPromise
|
||||
}
|
||||
|
||||
class JSPromise: NSObject, JSPromiseProtocol {
|
||||
|
||||
let promise: Promise<JSValue>
|
||||
|
||||
init(promise: Promise<JSValue>) {
|
||||
self.promise = promise
|
||||
}
|
||||
|
||||
func then(_ onFulfilled: JSValue, _ onRejected: JSValue) -> JSPromise {
|
||||
|
||||
// Keep a reference to the returned promise so we can comply to 2.3.1
|
||||
var returnedPromiseRef: Promise<JSValue>?
|
||||
|
||||
let afterFulfill = promise.then { value -> Promise<JSValue> in
|
||||
|
||||
// 2.2.1: ignored if not a function
|
||||
guard JSUtils.isFunction(value: onFulfilled) else {
|
||||
return .value(value)
|
||||
}
|
||||
|
||||
// Call `onFulfilled`
|
||||
// 2.2.5: onFulfilled/onRejected must be called as functions (with no `this` value)
|
||||
guard let returnValue = try JSUtils.call(function: onFulfilled, arguments: [JSUtils.undefined, value]) else {
|
||||
return .value(value)
|
||||
}
|
||||
|
||||
// Extract JSPromise.promise if available, or use plain return value
|
||||
if let jsPromise = returnValue.toObjectOf(JSPromise.self) as? JSPromise {
|
||||
|
||||
// 2.3.1: if returned value is the promise that `then` returned, throw TypeError
|
||||
if jsPromise.promise === returnedPromiseRef {
|
||||
throw JSUtils.JSError(reason: JSUtils.typeError(message: "Returned self"))
|
||||
}
|
||||
return jsPromise.promise
|
||||
} else {
|
||||
return .value(returnValue)
|
||||
}
|
||||
}
|
||||
|
||||
let afterReject = promise.recover { error -> Promise<JSValue> in
|
||||
|
||||
// 2.2.1: ignored if not a function
|
||||
guard let jsError = error as? JSUtils.JSError, JSUtils.isFunction(value: onRejected) else {
|
||||
throw error
|
||||
}
|
||||
|
||||
// Call `onRejected`
|
||||
// 2.2.5: onFulfilled/onRejected must be called as functions (with no `this` value)
|
||||
guard let returnValue = try JSUtils.call(function: onRejected, arguments: [JSUtils.undefined, jsError.reason]) else {
|
||||
throw error
|
||||
}
|
||||
|
||||
// Extract JSPromise.promise if available, or use plain return value
|
||||
if let jsPromise = returnValue.toObjectOf(JSPromise.self) as? JSPromise {
|
||||
|
||||
// 2.3.1: if returned value is the promise that `then` returned, throw TypeError
|
||||
if jsPromise.promise === returnedPromiseRef {
|
||||
throw JSUtils.JSError(reason: JSUtils.typeError(message: "Returned self"))
|
||||
}
|
||||
return jsPromise.promise
|
||||
} else {
|
||||
return .value(returnValue)
|
||||
}
|
||||
}
|
||||
|
||||
let newPromise = Promise<Result<JSValue>> { resolver in
|
||||
_ = promise.tap(resolver.fulfill)
|
||||
}.then(on: nil) { result -> Promise<JSValue> in
|
||||
switch result {
|
||||
case .fulfilled: return afterFulfill
|
||||
case .rejected: return afterReject
|
||||
}
|
||||
}
|
||||
returnedPromiseRef = newPromise
|
||||
|
||||
return JSPromise(promise: newPromise)
|
||||
}
|
||||
}
|
116
Carthage/Checkouts/PromiseKit/Tests/JS-A+/JSUtils.swift
vendored
Normal file
116
Carthage/Checkouts/PromiseKit/Tests/JS-A+/JSUtils.swift
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
//
|
||||
// JSUtils.swift
|
||||
// PMKJSA+Tests
|
||||
//
|
||||
// Created by Lois Di Qual on 3/2/18.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import JavaScriptCore
|
||||
|
||||
enum JSUtils {
|
||||
|
||||
class JSError: Error {
|
||||
let reason: JSValue
|
||||
init(reason: JSValue) {
|
||||
self.reason = reason
|
||||
}
|
||||
}
|
||||
|
||||
static let sharedContext: JSContext = {
|
||||
guard let context = JSContext() else {
|
||||
fatalError("Couldn't create JS context")
|
||||
}
|
||||
return context
|
||||
}()
|
||||
|
||||
static var undefined: JSValue {
|
||||
guard let undefined = JSValue(undefinedIn: JSUtils.sharedContext) else {
|
||||
fatalError("Couldn't create `undefined` value")
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
static func typeError(message: String) -> JSValue {
|
||||
let message = message.replacingOccurrences(of: "\"", with: "\\\"")
|
||||
let script = "new TypeError(\"\(message)\")"
|
||||
guard let result = sharedContext.evaluateScript(script) else {
|
||||
fatalError("Couldn't create TypeError")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// @warning: relies on lodash to be present
|
||||
static func isFunction(value: JSValue) -> Bool {
|
||||
guard let context = value.context else {
|
||||
return false
|
||||
}
|
||||
guard let lodash = context.objectForKeyedSubscript("_") else {
|
||||
fatalError("Couldn't get lodash in JS context")
|
||||
}
|
||||
guard let result = lodash.invokeMethod("isFunction", withArguments: [value]) else {
|
||||
fatalError("Couldn't invoke _.isFunction")
|
||||
}
|
||||
return result.toBool()
|
||||
}
|
||||
|
||||
// Calls a JS function using `Function.prototype.call` and throws any potential exception wrapped in a JSError
|
||||
static func call(function: JSValue, arguments: [JSValue]) throws -> JSValue? {
|
||||
|
||||
let context = JSUtils.sharedContext
|
||||
|
||||
// Create a new exception handler that will store a potential exception
|
||||
// thrown in the handler. Save the value of the old handler.
|
||||
var caughtException: JSValue?
|
||||
let savedExceptionHandler = context.exceptionHandler
|
||||
context.exceptionHandler = { context, exception in
|
||||
caughtException = exception
|
||||
}
|
||||
|
||||
// Call the handler
|
||||
let returnValue = function.invokeMethod("call", withArguments: arguments)
|
||||
context.exceptionHandler = savedExceptionHandler
|
||||
|
||||
// If an exception was caught, throw it
|
||||
if let exception = caughtException {
|
||||
throw JSError(reason: exception)
|
||||
}
|
||||
|
||||
return returnValue
|
||||
}
|
||||
|
||||
static func printCurrentStackTrace() {
|
||||
guard let exception = JSUtils.sharedContext.evaluateScript("new Error()") else {
|
||||
return print("Couldn't get current stack trace")
|
||||
}
|
||||
printStackTrace(exception: exception, includeExceptionDescription: false)
|
||||
}
|
||||
|
||||
static func printStackTrace(exception: JSValue, includeExceptionDescription: Bool) {
|
||||
guard let lineNumber = exception.objectForKeyedSubscript("line"),
|
||||
let column = exception.objectForKeyedSubscript("column"),
|
||||
let message = exception.objectForKeyedSubscript("message"),
|
||||
let stacktrace = exception.objectForKeyedSubscript("stack")?.toString() else {
|
||||
return print("Couldn't print stack trace")
|
||||
}
|
||||
|
||||
if includeExceptionDescription {
|
||||
print("JS Exception at \(lineNumber):\(column): \(message)")
|
||||
}
|
||||
|
||||
let lines = stacktrace.split(separator: "\n").map { "\t> \($0)" }.joined(separator: "\n")
|
||||
print(lines)
|
||||
}
|
||||
}
|
||||
|
||||
#if !swift(>=3.2)
|
||||
extension String {
|
||||
func split(separator: Character, omittingEmptySubsequences: Bool = true) -> [String] {
|
||||
return characters.split(separator: separator, omittingEmptySubsequences: omittingEmptySubsequences).map(String.init)
|
||||
}
|
||||
|
||||
var first: Character? {
|
||||
return characters.first
|
||||
}
|
||||
}
|
||||
#endif
|
117
Carthage/Checkouts/PromiseKit/Tests/JS-A+/MockNodeEnvironment.swift
vendored
Normal file
117
Carthage/Checkouts/PromiseKit/Tests/JS-A+/MockNodeEnvironment.swift
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
//
|
||||
// MockNodeEnvironment.swift
|
||||
// PMKJSA+Tests
|
||||
//
|
||||
// Created by Lois Di Qual on 3/1/18.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import JavaScriptCore
|
||||
|
||||
class MockNodeEnvironment {
|
||||
|
||||
private var timers: [UInt32: Timer] = [:]
|
||||
|
||||
func setup(with context: JSContext) {
|
||||
|
||||
// console.log / console.error
|
||||
setupConsole(context: context)
|
||||
|
||||
// setTimeout
|
||||
let setTimeout: @convention(block) (JSValue, Double) -> UInt32 = { function, intervalMs in
|
||||
let timerID = self.addTimer(interval: intervalMs / 1000, repeats: false, function: function)
|
||||
return timerID
|
||||
}
|
||||
context.setObject(setTimeout, forKeyedSubscript: "setTimeout" as NSString)
|
||||
|
||||
// clearTimeout
|
||||
let clearTimeout: @convention(block) (JSValue) -> Void = { timeoutID in
|
||||
guard timeoutID.isNumber else {
|
||||
return
|
||||
}
|
||||
self.removeTimer(timerID: timeoutID.toUInt32())
|
||||
}
|
||||
context.setObject(clearTimeout, forKeyedSubscript: "clearTimeout" as NSString)
|
||||
|
||||
// setInterval
|
||||
let setInterval: @convention(block) (JSValue, Double) -> UInt32 = { function, intervalMs in
|
||||
let timerID = self.addTimer(interval: intervalMs / 1000, repeats: true, function: function)
|
||||
return timerID
|
||||
}
|
||||
context.setObject(setInterval, forKeyedSubscript: "setInterval" as NSString)
|
||||
|
||||
// clearInterval
|
||||
let clearInterval: @convention(block) (JSValue) -> Void = { intervalID in
|
||||
guard intervalID.isNumber else {
|
||||
return
|
||||
}
|
||||
self.removeTimer(timerID: intervalID.toUInt32())
|
||||
}
|
||||
context.setObject(clearInterval, forKeyedSubscript: "clearInterval" as NSString)
|
||||
}
|
||||
|
||||
private func setupConsole(context: JSContext) {
|
||||
|
||||
guard let console = context.objectForKeyedSubscript("console") else {
|
||||
fatalError("Couldn't get global `console` object")
|
||||
}
|
||||
|
||||
let consoleLog: @convention(block) () -> Void = {
|
||||
guard let arguments = JSContext.currentArguments(), let format = arguments.first as? JSValue else {
|
||||
return
|
||||
}
|
||||
|
||||
let otherArguments = arguments.dropFirst()
|
||||
if otherArguments.count == 0 {
|
||||
print(format)
|
||||
} else {
|
||||
|
||||
let otherArguments = otherArguments.compactMap { $0 as? JSValue }
|
||||
let format = format.toString().replacingOccurrences(of: "%s", with: "%@")
|
||||
let expectedTypes = format.split(separator: "%", omittingEmptySubsequences: false).dropFirst().compactMap { $0.first }.map { String($0) }
|
||||
|
||||
let typedArguments = otherArguments.enumerated().compactMap { index, value -> CVarArg? in
|
||||
let expectedType = expectedTypes[index]
|
||||
let converted: CVarArg
|
||||
switch expectedType {
|
||||
case "s": converted = value.toString()
|
||||
case "d": converted = value.toInt32()
|
||||
case "f": converted = value.toDouble()
|
||||
default: converted = value.toString()
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
let output = String(format: format, arguments: typedArguments)
|
||||
print(output)
|
||||
}
|
||||
}
|
||||
console.setObject(consoleLog, forKeyedSubscript: "log" as NSString)
|
||||
console.setObject(consoleLog, forKeyedSubscript: "error" as NSString)
|
||||
}
|
||||
|
||||
private func addTimer(interval: TimeInterval, repeats: Bool, function: JSValue) -> UInt32 {
|
||||
let block = BlockOperation {
|
||||
DispatchQueue.main.async {
|
||||
function.call(withArguments: [])
|
||||
}
|
||||
}
|
||||
let timer = Timer.scheduledTimer(timeInterval: interval, target: block, selector: #selector(Operation.main), userInfo: nil, repeats: repeats)
|
||||
let rawHash = UUID().uuidString.hashValue
|
||||
#if swift(>=4.0)
|
||||
let hash = UInt32(truncatingIfNeeded: rawHash)
|
||||
#else
|
||||
let hash = UInt32(truncatingBitPattern: rawHash)
|
||||
#endif
|
||||
timers[hash] = timer
|
||||
return hash
|
||||
}
|
||||
|
||||
private func removeTimer(timerID: UInt32) {
|
||||
guard let timer = timers[timerID] else {
|
||||
return print("Couldn't find timer \(timerID)")
|
||||
}
|
||||
timer.invalidate()
|
||||
timers[timerID] = nil
|
||||
}
|
||||
}
|
75
Carthage/Checkouts/PromiseKit/Tests/JS-A+/README.md
vendored
Normal file
75
Carthage/Checkouts/PromiseKit/Tests/JS-A+/README.md
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
Promises/A+ Compliance Test Suite (JavaScript)
|
||||
==============================================
|
||||
|
||||
What is this?
|
||||
-------------
|
||||
|
||||
This contains the necessary Swift and JS files to run the Promises/A+ compliance test suite from PromiseKit's unit tests.
|
||||
|
||||
- Promise/A+ Spec: <https://promisesaplus.com/>
|
||||
- Compliance Test Suite: <https://github.com/promises-aplus/promises-tests>
|
||||
|
||||
Run tests
|
||||
---------
|
||||
|
||||
```
|
||||
$ npm install
|
||||
$ npm run build
|
||||
```
|
||||
|
||||
then open `PromiseKit.xcodeproj` and run the `PMKJSA+Tests` unit test scheme.
|
||||
|
||||
Known limitations
|
||||
-----------------
|
||||
|
||||
See `ignoredTests` in `index.js`.
|
||||
|
||||
|
||||
- 2.3.3 is disabled: Otherwise, if x is an object or function. This spec is a NOOP for Swift:
|
||||
- We have decided not to interact with other Promises A+ implementations
|
||||
- functions cannot have properties
|
||||
|
||||
Upgrade the test suite
|
||||
----------------------
|
||||
|
||||
```
|
||||
$ npm install --save promises-aplus-tests@latest
|
||||
$ npm run build
|
||||
```
|
||||
|
||||
Develop
|
||||
-------
|
||||
|
||||
JavaScriptCore is a bit tedious to work with so here are a couple tips in case you're trying to debug the test suite.
|
||||
|
||||
If you're editing JS files, enable live rebuilds:
|
||||
|
||||
```
|
||||
$ npm run watch
|
||||
```
|
||||
|
||||
If you're editing Swift files, a couple things you can do:
|
||||
|
||||
- You can adjust `testName` in `AllTests.swift` to only run one test suite
|
||||
- You can call `JSUtils.printCurrentStackTrace()` at any time. It won't contain line numbers but some of the frame names might help.
|
||||
|
||||
How it works
|
||||
------------
|
||||
|
||||
The Promises/A+ test suite is written in JavaScript but PromiseKit is written in Swift/ObjC. For the test suite to run against swift code, we expose a promise wrapper `JSPromise` inside a JavaScriptCore context. This is done in a regular XCTestCase.
|
||||
|
||||
Since JavaScriptCore doesn't support CommonJS imports, we inline all the JavaScript code into `build/build.js` using webpack. This includes all the npm dependencies (`promises-aplus-tests`, `mocha`, `sinon`, etc) as well as the glue code in `index.js`.
|
||||
|
||||
`build.js` exposes one global variable `runTests(adapter, onFail, onDone, [testName])`. In our XCTestCase, a shared JavaScriptCore context is created, `build.js` is evaluated and now `runTests` is accessible from the Swift context.
|
||||
|
||||
In our swift test, we create a JS-bridged `JSPromise` which only has one method `then(onFulfilled, onRejected) -> Promise`. It wraps a swift `Promise` and delegates call `then` calls to it.
|
||||
|
||||
An [adapter](https://github.com/promises-aplus/promises-tests#adapters) – plain JS object which provides `revoled(value), rejected(reason), and deferred()` – is passed to `runTests` to run the whole JavaScript test suite.
|
||||
|
||||
Errors and end events are reported back to Swift and piped to `XCTFail()` if necessary.
|
||||
|
||||
Since JavaScriptCore isn't a node/web environment, there is quite a bit of stubbing necessary for all this to work:
|
||||
|
||||
- The `fs` module is stubbed with an empty function
|
||||
- `console.log` redirects to `Swift.print` and provides only basic format parsing
|
||||
- `setTimeout/setInterval` are implemented with `Swift.Timer` behind the scenes and stored in a `[TimerID: Timer]` map.
|
42
Carthage/Checkouts/PromiseKit/Tests/JS-A+/index.js
vendored
Normal file
42
Carthage/Checkouts/PromiseKit/Tests/JS-A+/index.js
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
const _ = require('lodash')
|
||||
require('mocha')
|
||||
|
||||
// Ignored by design
|
||||
const ignoredTests = [
|
||||
'2.3.3'
|
||||
]
|
||||
|
||||
module.exports = function(adapter, onFail, onDone, testName) {
|
||||
|
||||
global.adapter = adapter
|
||||
const mocha = new Mocha({ ui: 'bdd' })
|
||||
|
||||
// Require all tests
|
||||
console.log('Loading test files')
|
||||
const requireTest = require.context('promises-aplus-tests/lib/tests', false, /\.js$/)
|
||||
requireTest.keys().forEach(file => {
|
||||
|
||||
let currentTestName = _.replace(_.replace(file, './', ''), '.js', '')
|
||||
if (testName && currentTestName !== testName) {
|
||||
return
|
||||
}
|
||||
|
||||
if (_.includes(ignoredTests, currentTestName)) {
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`\t${currentTestName}`)
|
||||
mocha.suite.emit('pre-require', global, file, mocha)
|
||||
mocha.suite.emit('require', requireTest(file), file, mocha)
|
||||
mocha.suite.emit('post-require', global, file, mocha)
|
||||
})
|
||||
|
||||
const runner = mocha.run(failures => {
|
||||
onDone(failures)
|
||||
})
|
||||
|
||||
runner.on('fail', (test, err) => {
|
||||
console.error(err)
|
||||
onFail(test.title, err)
|
||||
})
|
||||
}
|
7869
Carthage/Checkouts/PromiseKit/Tests/JS-A+/package-lock.json
generated
vendored
Normal file
7869
Carthage/Checkouts/PromiseKit/Tests/JS-A+/package-lock.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
17
Carthage/Checkouts/PromiseKit/Tests/JS-A+/package.json
vendored
Normal file
17
Carthage/Checkouts/PromiseKit/Tests/JS-A+/package.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "webpack-cli",
|
||||
"watch": "webpack-cli --watch --mode development"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-loader": "^7.1.3",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"lodash": "^4.17.5",
|
||||
"mocha": "^5.0.1",
|
||||
"promises-aplus-tests": "^2.1.2",
|
||||
"sinon": "^4.4.2",
|
||||
"webpack": "^4.0.1",
|
||||
"webpack-cli": "^2.0.9"
|
||||
}
|
||||
}
|
29
Carthage/Checkouts/PromiseKit/Tests/JS-A+/webpack.config.js
vendored
Normal file
29
Carthage/Checkouts/PromiseKit/Tests/JS-A+/webpack.config.js
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
var webpack = require('webpack');
|
||||
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
context: __dirname,
|
||||
entry: './index.js',
|
||||
output: {
|
||||
path: __dirname + '/build',
|
||||
filename: 'build.js',
|
||||
library: 'runTests'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /(node_modules)/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: ['env']
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
node: {
|
||||
fs: 'empty'
|
||||
},
|
||||
};
|
288
Carthage/Checkouts/PromiseKit/Tests/LinuxMain.swift
vendored
Normal file
288
Carthage/Checkouts/PromiseKit/Tests/LinuxMain.swift
vendored
Normal file
@@ -0,0 +1,288 @@
|
||||
// Generated using Sourcery 0.10.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
|
||||
|
||||
@testable import CorePromise
|
||||
@testable import A_
|
||||
import XCTest
|
||||
|
||||
//TODO get this to run on CI and don’t have it committed
|
||||
//NOTE problem is Sourcery doesn’t support Linux currently
|
||||
//USAGE: cd PromiseKit/Sources/.. && sourcery --config .github/sourcery.yml
|
||||
|
||||
extension AfterTests {
|
||||
static var allTests = [
|
||||
("testZero", AfterTests.testZero),
|
||||
("testNegative", AfterTests.testNegative),
|
||||
("testPositive", AfterTests.testPositive),
|
||||
]
|
||||
}
|
||||
|
||||
extension CancellationTests {
|
||||
static var allTests = [
|
||||
("testCancellation", CancellationTests.testCancellation),
|
||||
("testThrowCancellableErrorThatIsNotCancelled", CancellationTests.testThrowCancellableErrorThatIsNotCancelled),
|
||||
("testRecoverWithCancellation", CancellationTests.testRecoverWithCancellation),
|
||||
("testFoundationBridging1", CancellationTests.testFoundationBridging1),
|
||||
("testFoundationBridging2", CancellationTests.testFoundationBridging2),
|
||||
("testIsCancelled", CancellationTests.testIsCancelled),
|
||||
("testIsCancelled", CancellationTests.testIsCancelled),
|
||||
]
|
||||
}
|
||||
|
||||
extension CatchableTests {
|
||||
static var allTests = [
|
||||
("testFinally", CatchableTests.testFinally),
|
||||
("testCauterize", CatchableTests.testCauterize),
|
||||
("test__void_specialized_full_recover", CatchableTests.test__void_specialized_full_recover),
|
||||
("test__void_specialized_full_recover__fulfilled_path", CatchableTests.test__void_specialized_full_recover__fulfilled_path),
|
||||
("test__void_specialized_conditional_recover", CatchableTests.test__void_specialized_conditional_recover),
|
||||
("test__void_specialized_conditional_recover__no_recover", CatchableTests.test__void_specialized_conditional_recover__no_recover),
|
||||
("test__void_specialized_conditional_recover__ignores_cancellation_but_fed_cancellation", CatchableTests.test__void_specialized_conditional_recover__ignores_cancellation_but_fed_cancellation),
|
||||
("test__void_specialized_conditional_recover__fulfilled_path", CatchableTests.test__void_specialized_conditional_recover__fulfilled_path),
|
||||
("test__full_recover", CatchableTests.test__full_recover),
|
||||
("test__full_recover__fulfilled_path", CatchableTests.test__full_recover__fulfilled_path),
|
||||
("test__conditional_recover", CatchableTests.test__conditional_recover),
|
||||
("test__conditional_recover__no_recover", CatchableTests.test__conditional_recover__no_recover),
|
||||
("test__conditional_recover__ignores_cancellation_but_fed_cancellation", CatchableTests.test__conditional_recover__ignores_cancellation_but_fed_cancellation),
|
||||
("test__conditional_recover__fulfilled_path", CatchableTests.test__conditional_recover__fulfilled_path),
|
||||
]
|
||||
}
|
||||
|
||||
extension GuaranteeTests {
|
||||
static var allTests = [
|
||||
("testInit", GuaranteeTests.testInit),
|
||||
("testWait", GuaranteeTests.testWait),
|
||||
]
|
||||
}
|
||||
|
||||
extension HangTests {
|
||||
static var allTests = [
|
||||
("test", HangTests.test),
|
||||
("testError", HangTests.testError),
|
||||
]
|
||||
}
|
||||
|
||||
extension JoinTests {
|
||||
static var allTests = [
|
||||
("testImmediates", JoinTests.testImmediates),
|
||||
("testFulfilledAfterAllResolve", JoinTests.testFulfilledAfterAllResolve),
|
||||
]
|
||||
}
|
||||
|
||||
extension PMKDefaultDispatchQueueTest {
|
||||
static var allTests = [
|
||||
("testOverrodeDefaultThenQueue", PMKDefaultDispatchQueueTest.testOverrodeDefaultThenQueue),
|
||||
("testOverrodeDefaultCatchQueue", PMKDefaultDispatchQueueTest.testOverrodeDefaultCatchQueue),
|
||||
("testOverrodeDefaultAlwaysQueue", PMKDefaultDispatchQueueTest.testOverrodeDefaultAlwaysQueue),
|
||||
]
|
||||
}
|
||||
|
||||
extension PMKErrorTests {
|
||||
static var allTests = [
|
||||
("testCustomStringConvertible", PMKErrorTests.testCustomStringConvertible),
|
||||
("testCustomDebugStringConvertible", PMKErrorTests.testCustomDebugStringConvertible),
|
||||
]
|
||||
}
|
||||
|
||||
extension PromiseTests {
|
||||
static var allTests = [
|
||||
("testIsPending", PromiseTests.testIsPending),
|
||||
("testIsResolved", PromiseTests.testIsResolved),
|
||||
("testIsFulfilled", PromiseTests.testIsFulfilled),
|
||||
("testIsRejected", PromiseTests.testIsRejected),
|
||||
("testDispatchQueueAsyncExtensionReturnsPromise", PromiseTests.testDispatchQueueAsyncExtensionReturnsPromise),
|
||||
("testDispatchQueueAsyncExtensionCanThrowInBody", PromiseTests.testDispatchQueueAsyncExtensionCanThrowInBody),
|
||||
("testCustomStringConvertible", PromiseTests.testCustomStringConvertible),
|
||||
("testCannotFulfillWithError", PromiseTests.testCannotFulfillWithError),
|
||||
("testCanMakeVoidPromise", PromiseTests.testCanMakeVoidPromise),
|
||||
("testCanMakeVoidPromise", PromiseTests.testCanMakeVoidPromise),
|
||||
("testThrowInInitializer", PromiseTests.testThrowInInitializer),
|
||||
("testThrowInFirstly", PromiseTests.testThrowInFirstly),
|
||||
("testWait", PromiseTests.testWait),
|
||||
("testPipeForResolved", PromiseTests.testPipeForResolved),
|
||||
]
|
||||
}
|
||||
|
||||
extension RaceTests {
|
||||
static var allTests = [
|
||||
("test1", RaceTests.test1),
|
||||
("test2", RaceTests.test2),
|
||||
("test1Array", RaceTests.test1Array),
|
||||
("test2Array", RaceTests.test2Array),
|
||||
("testEmptyArray", RaceTests.testEmptyArray),
|
||||
]
|
||||
}
|
||||
|
||||
extension RegressionTests {
|
||||
static var allTests = [
|
||||
("testReturningPreviousPromiseWorks", RegressionTests.testReturningPreviousPromiseWorks),
|
||||
]
|
||||
}
|
||||
|
||||
extension StressTests {
|
||||
static var allTests = [
|
||||
("testThenDataRace", StressTests.testThenDataRace),
|
||||
("testThensAreSequentialForLongTime", StressTests.testThensAreSequentialForLongTime),
|
||||
("testZalgoDataRace", StressTests.testZalgoDataRace),
|
||||
]
|
||||
}
|
||||
|
||||
extension Test212 {
|
||||
static var allTests = [
|
||||
("test", Test212.test),
|
||||
]
|
||||
}
|
||||
|
||||
extension Test213 {
|
||||
static var allTests = [
|
||||
("test", Test213.test),
|
||||
]
|
||||
}
|
||||
|
||||
extension Test222 {
|
||||
static var allTests = [
|
||||
("test", Test222.test),
|
||||
]
|
||||
}
|
||||
|
||||
extension Test223 {
|
||||
static var allTests = [
|
||||
("test", Test223.test),
|
||||
]
|
||||
}
|
||||
|
||||
extension Test224 {
|
||||
static var allTests = [
|
||||
("test", Test224.test),
|
||||
]
|
||||
}
|
||||
|
||||
extension Test226 {
|
||||
static var allTests = [
|
||||
("test", Test226.test),
|
||||
]
|
||||
}
|
||||
|
||||
extension Test227 {
|
||||
static var allTests = [
|
||||
("test", Test227.test),
|
||||
]
|
||||
}
|
||||
|
||||
extension Test231 {
|
||||
static var allTests = [
|
||||
("test", Test231.test),
|
||||
]
|
||||
}
|
||||
|
||||
extension Test232 {
|
||||
static var allTests = [
|
||||
("test", Test232.test),
|
||||
]
|
||||
}
|
||||
|
||||
extension Test234 {
|
||||
static var allTests = [
|
||||
("test", Test234.test),
|
||||
]
|
||||
}
|
||||
|
||||
extension ThenableTests {
|
||||
static var allTests = [
|
||||
("testGet", ThenableTests.testGet),
|
||||
("testCompactMap", ThenableTests.testCompactMap),
|
||||
("testCompactMapThrows", ThenableTests.testCompactMapThrows),
|
||||
("testRejectedPromiseCompactMap", ThenableTests.testRejectedPromiseCompactMap),
|
||||
("testPMKErrorCompactMap", ThenableTests.testPMKErrorCompactMap),
|
||||
("testCompactMapValues", ThenableTests.testCompactMapValues),
|
||||
("testThenMap", ThenableTests.testThenMap),
|
||||
("testThenFlatMap", ThenableTests.testThenFlatMap),
|
||||
("testLastValueForEmpty", ThenableTests.testLastValueForEmpty),
|
||||
("testFirstValueForEmpty", ThenableTests.testFirstValueForEmpty),
|
||||
("testThenOffRejected", ThenableTests.testThenOffRejected),
|
||||
]
|
||||
}
|
||||
|
||||
extension WhenConcurrentTestCase_Swift {
|
||||
static var allTests = [
|
||||
("testWhen", WhenConcurrentTestCase_Swift.testWhen),
|
||||
("testWhenEmptyGenerator", WhenConcurrentTestCase_Swift.testWhenEmptyGenerator),
|
||||
("testWhenGeneratorError", WhenConcurrentTestCase_Swift.testWhenGeneratorError),
|
||||
("testWhenConcurrency", WhenConcurrentTestCase_Swift.testWhenConcurrency),
|
||||
("testWhenConcurrencyLessThanZero", WhenConcurrentTestCase_Swift.testWhenConcurrencyLessThanZero),
|
||||
("testStopsDequeueingOnceRejected", WhenConcurrentTestCase_Swift.testStopsDequeueingOnceRejected),
|
||||
]
|
||||
}
|
||||
|
||||
extension WhenTests {
|
||||
static var allTests = [
|
||||
("testEmpty", WhenTests.testEmpty),
|
||||
("testInt", WhenTests.testInt),
|
||||
("testDoubleTuple", WhenTests.testDoubleTuple),
|
||||
("testTripleTuple", WhenTests.testTripleTuple),
|
||||
("testQuadrupleTuple", WhenTests.testQuadrupleTuple),
|
||||
("testQuintupleTuple", WhenTests.testQuintupleTuple),
|
||||
("testVoid", WhenTests.testVoid),
|
||||
("testRejected", WhenTests.testRejected),
|
||||
("testProgress", WhenTests.testProgress),
|
||||
("testProgressDoesNotExceed100Percent", WhenTests.testProgressDoesNotExceed100Percent),
|
||||
("testUnhandledErrorHandlerDoesNotFire", WhenTests.testUnhandledErrorHandlerDoesNotFire),
|
||||
("testUnhandledErrorHandlerDoesNotFireForStragglers", WhenTests.testUnhandledErrorHandlerDoesNotFireForStragglers),
|
||||
("testAllSealedRejectedFirstOneRejects", WhenTests.testAllSealedRejectedFirstOneRejects),
|
||||
("testGuaranteeWhen", WhenTests.testGuaranteeWhen),
|
||||
]
|
||||
}
|
||||
|
||||
extension WrapTests {
|
||||
static var allTests = [
|
||||
("testSuccess", WrapTests.testSuccess),
|
||||
("testError", WrapTests.testError),
|
||||
("testInvalidCallingConvention", WrapTests.testInvalidCallingConvention),
|
||||
("testInvertedCallingConvention", WrapTests.testInvertedCallingConvention),
|
||||
("testNonOptionalFirstParameter", WrapTests.testNonOptionalFirstParameter),
|
||||
("testVoidCompletionValue", WrapTests.testVoidCompletionValue),
|
||||
("testVoidCompletionValue", WrapTests.testVoidCompletionValue),
|
||||
("testIsFulfilled", WrapTests.testIsFulfilled),
|
||||
("testPendingPromiseDeallocated", WrapTests.testPendingPromiseDeallocated),
|
||||
]
|
||||
}
|
||||
|
||||
extension ZalgoTests {
|
||||
static var allTests = [
|
||||
("test1", ZalgoTests.test1),
|
||||
("test2", ZalgoTests.test2),
|
||||
("test3", ZalgoTests.test3),
|
||||
("test4", ZalgoTests.test4),
|
||||
]
|
||||
}
|
||||
|
||||
XCTMain([
|
||||
testCase(AfterTests.allTests),
|
||||
testCase(CancellationTests.allTests),
|
||||
testCase(CatchableTests.allTests),
|
||||
testCase(GuaranteeTests.allTests),
|
||||
testCase(HangTests.allTests),
|
||||
testCase(JoinTests.allTests),
|
||||
testCase(PMKDefaultDispatchQueueTest.allTests),
|
||||
testCase(PMKErrorTests.allTests),
|
||||
testCase(PromiseTests.allTests),
|
||||
testCase(RaceTests.allTests),
|
||||
testCase(RegressionTests.allTests),
|
||||
testCase(StressTests.allTests),
|
||||
testCase(Test212.allTests),
|
||||
testCase(Test213.allTests),
|
||||
testCase(Test222.allTests),
|
||||
testCase(Test223.allTests),
|
||||
testCase(Test224.allTests),
|
||||
testCase(Test226.allTests),
|
||||
testCase(Test227.allTests),
|
||||
testCase(Test231.allTests),
|
||||
testCase(Test232.allTests),
|
||||
testCase(Test234.allTests),
|
||||
testCase(ThenableTests.allTests),
|
||||
testCase(WhenConcurrentTestCase_Swift.allTests),
|
||||
testCase(WhenTests.allTests),
|
||||
testCase(WrapTests.allTests),
|
||||
testCase(ZalgoTests.allTests),
|
||||
])
|
Reference in New Issue
Block a user