diff --git a/Source/Promise.swift b/Source/Promise.swift index 72fc5fd0dea..a5bc600c759 100644 --- a/Source/Promise.swift +++ b/Source/Promise.swift @@ -27,7 +27,8 @@ public class Promise { private var successBlocks = [SuccessBlock]() private typealias FailBlock = (ErrorType) -> Void private var failBlocks = [FailBlock]() - private var progressBlock:(Float) -> Void = { t in } + private typealias ProgressBlock = (Float) -> Void + private var progressBlocks = [ProgressBlock]() private var finallyBlock:() -> Void = { t in } private var promiseCallBack:PromiseCallBack! private var promiseProgressCallBack:PromiseProgressCallBack? @@ -78,7 +79,9 @@ public class Promise { }) self.failBlocks.append(reject) } - self.progressBlock = progress + self.progressBlocks.append({ p in + progress(p) + }) } p.start() passAlongFirstPromiseStartFunctionAndStateTo(p) @@ -133,8 +136,8 @@ public class Promise { public func registerOnError(block:(ErrorType) -> Void) -> Promise{ let p = Promise { resolve, reject, progress in switch self.state { - case .Fulfilled:() - reject(NSError(domain: "", code: 123, userInfo: nil)) + case .Fulfilled: + reject(NSError(domain: "", code: 123, userInfo: nil)) // No error so do nothing. case .Rejected: // Already failed so call error block @@ -150,7 +153,9 @@ public class Promise { resolve() }) } - self.progressBlock = progress + self.progressBlocks.append({ p in + progress(p) + }) } p.start() passAlongFirstPromiseStartFunctionAndStateTo(p) @@ -168,7 +173,7 @@ public class Promise { public func registerFinally(block:() -> X) -> Promise{ let p = Promise{ resolve, reject, progress in switch self.state { - case .Fulfilled:() + case .Fulfilled: resolve(block()) case .Rejected: resolve(block()) @@ -180,7 +185,9 @@ public class Promise { resolve(block()) }) } - self.progressBlock = progress + self.progressBlocks.append({ p in + progress(p) + }) } p.start() passAlongFirstPromiseStartFunctionAndStateTo(p) @@ -188,12 +195,37 @@ public class Promise { } //MARK: - Progress - - public func progress(block:(Float) -> Void) -> Self { - progressBlock = block - return self + + public func progress(block:(Float) -> Void) -> Promise { + tryStartInitialPromise() + startPromiseIfNeeded() + return registerProgress(block) } + public func registerProgress(block:(Float) -> Void) -> Promise{ + let p = Promise { resolve, reject, progress in + switch self.state { + case .Fulfilled: + resolve() + case .Rejected: + reject(self.error!) + case .Pending:() + self.failBlocks.append(reject) + self.successBlocks.append({ _ in + resolve() + }) + } + self.progressBlocks.append({ p in + block(p) + progress(p) + }) + } + p.start() + passAlongFirstPromiseStartFunctionAndStateTo(p) + return p + } + + //MARK: - Helpers private func passAlongFirstPromiseStartFunctionAndStateTo(p:Promise) { @@ -245,6 +277,10 @@ public class Promise { private func progressPromise(p:Float) { progress = p - progressBlock(progress!) + for pb in progressBlocks { + if let progress = progress { + pb(progress) + } + } } } \ No newline at end of file diff --git a/thenTests/thenTests.swift b/thenTests/thenTests.swift index bd8eff186f3..11272ef9a1f 100644 --- a/thenTests/thenTests.swift +++ b/thenTests/thenTests.swift @@ -321,21 +321,34 @@ class thenTests: XCTestCase { } func testProgress() { - let progressExpectation = expectationWithDescription("thenExpectation") - let thenExpectation = expectationWithDescription("thenExpectation") - - upload().registerThen { - print("Done") + let thenExpectation = expectationWithDescription("thenExpectation") + upload().progress { p in + print("PROGRESS \(p)") + XCTAssertEqual(p, 0.8) + progressExpectation.fulfill() }.then { print("Done") thenExpectation.fulfill() - }.progress { p in - print("PROGRESS \(p)") + }.onError { e in + print("ERROR") + } + + waitForExpectationsWithTimeout(3, handler: nil) + } + + func testProgressFails() { + let progressExpectation = expectationWithDescription("thenExpectation") + let errorExpectation = expectationWithDescription("errorExpectation") + failingUpload().progress { p in XCTAssertEqual(p, 0.8) progressExpectation.fulfill() + }.then { + XCTFail() + }.onError { e in + errorExpectation.fulfill() } - + waitForExpectationsWithTimeout(3, handler: nil) } @@ -486,6 +499,17 @@ func upload() -> Promise { } } +func failingUpload() -> Promise { + return Promise { resolve, reject, progress in + wait { + progress(0.8) + wait { + reject(NSError(domain: "", code: 1223, userInfo: nil)) + } + } + } +} + func promiseA() -> Promise { return Promise { resolve, reject in XCTAssertTrue(globalCount == 0)