Merge pull request #3272 from Nemo157/when-tests

Add tests for when
This commit is contained in:
Masahiro Wakame
2014-12-07 11:37:14 +09:00
2 changed files with 262 additions and 5 deletions

184
when/when-tests.ts Normal file
View File

@@ -0,0 +1,184 @@
/// <reference path="when.d.ts" />
import when = require("when");
class ForeignPromise<T> {
constructor(private value: T) {
}
then<U>(onFulfilled: (value: T) => U, onRejected?: (reason: any) => U) { return new ForeignPromise<U>(onFulfilled(this.value)); }
};
var promise: when.Promise<number>;
var foreign = new ForeignPromise<number>(1);
var error = new Error("boom!");
// TODO: with TypeScript 1.4 a lot of these functions should change to use PromiseOrValue<T>
// type PromiseOrValue<T> = Promise<T> | T;
/* * * * * * *
* Core *
* * * * * * */
/* when(x) */
promise = when(1);
promise = when(when(1));
promise = when(foreign);
/* when(x, f) */
promise = when(1, val => val + val);
promise = when(when(1), val => val + val);
promise = when(foreign, val => val + val);
/* when.try(f, ...args) */
promise = when.attempt(() => 1);
promise = when.attempt((a: number) => a + a, 1);
promise = when.attempt((a: number) => a + a, when(1));
promise = when.attempt((a: number, b: number) => a + b, 1, 2);
promise = when.attempt((a: number, b: number) => a + b, 1, when(2));
promise = when.attempt((a: number, b: number) => a + b, when(1), 2);
promise = when.attempt((a: number, b: number) => a + b, when(1), when(2));
promise = when.attempt((a: number, b: number, c: number) => a + b + c, 1, 2, 3);
promise = when.attempt((a: number, b: number, c: number) => a + b + c, 1, when(2), 3);
promise = when.attempt((a: number, b: number, c: number) => a + b + c, when(1), 2, 3);
promise = when.attempt((a: number, b: number, c: number) => a + b + c, when(1), when(2), 3);
promise = when.attempt((a: number, b: number, c: number) => a + b + c, 1, 2, when(3));
promise = when.attempt((a: number, b: number, c: number) => a + b + c, 1, when(2), when(3));
promise = when.attempt((a: number, b: number, c: number) => a + b + c, when(1), 2, when(3));
promise = when.attempt((a: number, b: number, c: number) => a + b + c, when(1), when(2), when(3));
/* when.lift(f) */
// TODO: This is the major issue with lack of union types, it's not possible to represent the return type of when.lift without them.
var liftedFunc0: () => when.Promise<number> = when.lift(() => 2);
var liftedFunc1: (a: when.Promise<number>) => when.Promise<number> = when.lift((a: number) => a + a);
var liftedFunc2: (a: when.Promise<number>, b: when.Promise<number>) => when.Promise<number> = when.lift((a: number, b: number) => a + b);
var liftedFunc3: (a: when.Promise<number>, b: when.Promise<number>, c: when.Promise<number>) => when.Promise<number> = when.lift((a: number, b: number, c: number) => a + b + c);
/* when.join(...promises) */
var joinedPromise: when.Promise<number[]> = when.join(when(1), when(2), when(3));
/* when.promise(resolver) */
promise = when.promise<number>(resolve => resolve(5));
promise = when.promise<number>((resolve, reject) => reject(error));
/* when.resolve(x) */
promise = when.resolve(1);
promise = when.resolve(promise);
promise = when.resolve(foreign);
/* when.reject(error) */
promise = when.reject<number>(error);
/* when.defer() */
var deferred = when.defer<number>();
promise = deferred.promise;
deferred.resolve(1);
deferred.reject(error);
/* * * * * * * *
* Promise *
* * * * * * * */
/* promise.done(handleResult, handleError) */
when(1).done((val: number) => console.log(val));
when(1).done((val: number) => console.log(val), (err: any) => console.log(err));
/* promise.then(onFulfilled) */
promise = when(1).then((val: number) => val + val);
promise = when(1).then((val: number) => when(val + val));
promise = when(1).then((val: number) => val + val, (err: any) => 2);
promise = when(1).then((val: number) => when(val + val), (err: any) => 2);
/* promise.spread(onFulfilledArray) */
// TODO: Work out how to do this...
// promise = when([1, 2, 3]).spread((a: number, b: number) => a + b);
// promise = when([1, 2, 3]).spread((a: number, b: number) => when(a + b));
/* promise.fold(combine, promise2) */
promise = when(1).fold((a: number, b: number) => a + b, 2);
promise = when(1).fold((a: number, b: number) => a + b, when(2));
promise = when(1).fold((a: number, b: number) => when(a + b), 2);
promise = when(1).fold((a: number, b: number) => when(a + b), when(2));
/* promise.catch(onRejected) */
promise = when(1).catch((err: any) => 2);
promise = when(1).catch((err: any) => when(2));
promise = when(1).catch((err: any) => err.good, (err: any) => 2);
promise = when(1).catch((err: any) => err.good, (err: any) => when(2));
//TODO: error constructor predicate
promise = when(1).otherwise((err: any) => 2);
promise = when(1).otherwise((err: any) => when(2));
promise = when(1).otherwise((err: any) => err.good, (err: any) => 2);
promise = when(1).otherwise((err: any) => err.good, (err: any) => when(2));
/* promise.finally(cleanup) */
promise = when(1).finally(() => console.log('Cleaning up'));
promise = when(1).ensure(() => console.log('Cleaning up'));
/* promise.yield(x) */
promise = when(true).yield(1);
promise = when(true).yield(when(2));
/* promise.else(x) */
promise = when(1).else(2);
promise = when(1).else(2);
promise = when(1).orElse(2);
promise = when(1).orElse(2);
/* promise.tap(onFulfilledSideEffect) */
promise = when(1).tap(val => console.log(val));
/* promise.delay(milliseconds) */
promise = when(1).delay(1000);
/* promise.timeout(milliseconds, reason) */
promise = when(1).timeout(1000);
promise = when(1).timeout(1000, new Error('Too SLOW!'));
/* promise.inspect() */
var status: {
state: string;
value?: number;
reason?: any;
};
status = when(1).inspect()
/* promise.with(thisArg) */
promise = when(1).with(2);
promise = when(1).withThis(2);

83
when/when.d.ts vendored
View File

@@ -3,7 +3,42 @@
// Definitions by: Derek Cicerone <https://github.com/derekcicerone>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
declare function When<T>(value: When.Promise<T>): When.Promise<T>;
declare function When<T>(value: When.Thenable<T>): When.Promise<T>;
declare function When<T>(value: T): When.Promise<T>;
declare function When<T, U>(value: When.Promise<T>, transform: (val: T) => U): When.Promise<U>;
declare function When<T, U>(value: When.Thenable<T>, transform: (val: T) => U): When.Promise<U>;
declare function When<T, U>(value: T, transform: (val: T) => U): When.Promise<U>;
declare module When {
function attempt<T>(f: () => T): Promise<T>;
function attempt<T, A>(f: (a: A) => T, a: Promise<A>): Promise<T>;
function attempt<T, A>(f: (a: A) => T, a: A): Promise<T>;
function attempt<T, A, B>(f: (a: A, b: B) => T, a: Promise<A>, b: Promise<B>): Promise<T>;
function attempt<T, A, B>(f: (a: A, b: B) => T, a: Promise<A>, b: B): Promise<T>;
function attempt<T, A, B>(f: (a: A, b: B) => T, a: A, b: Promise<B>): Promise<T>;
function attempt<T, A, B>(f: (a: A, b: B) => T, a: A, b: B): Promise<T>;
function attempt<T, A, B, C>(f: (a: A, b: B, c: C) => T, a: Promise<A>, b: Promise<B>, c: Promise<C>): Promise<T>;
function attempt<T, A, B, C>(f: (a: A, b: B, c: C) => T, a: Promise<A>, b: Promise<B>, c: C): Promise<T>;
function attempt<T, A, B, C>(f: (a: A, b: B, c: C) => T, a: Promise<A>, b: B, c: Promise<C>): Promise<T>;
function attempt<T, A, B, C>(f: (a: A, b: B, c: C) => T, a: Promise<A>, b: B, c: C): Promise<T>;
function attempt<T, A, B, C>(f: (a: A, b: B, c: C) => T, a: A, b: Promise<B>, c: Promise<C>): Promise<T>;
function attempt<T, A, B, C>(f: (a: A, b: B, c: C) => T, a: A, b: Promise<B>, c: C): Promise<T>;
function attempt<T, A, B, C>(f: (a: A, b: B, c: C) => T, a: A, b: B, c: Promise<C>): Promise<T>;
function attempt<T, A, B, C>(f: (a: A, b: B, c: C) => T, a: A, b: B, c: C): Promise<T>;
function lift<T>(f: () => T): () => Promise<T>;
function lift<T, A>(f: (a: A) => T): (a: Promise<A>) => Promise<T>;
function lift<T, A, B>(f: (a: A, b: B) => T): (a: Promise<A>, b: Promise<B>) => Promise<T>;
function lift<T, A, B, C>(f: (a: A, b: B, c: C) => T): (a: Promise<A>, b: Promise<B>, c: Promise<C>) => Promise<T>;
function promise<T>(resolver: (resolve: (value: T) => void, reject: (reason: any) => void) => void): Promise<T>;
function reject<T>(reason: any): Promise<T>;
/**
* Return a promise that will resolve only once all the supplied promisesOrValues
@@ -45,6 +80,7 @@ declare module When {
* - rejected with promiseOrValue's reason after it is rejected
*/
function resolve<T>(promise: Promise<T>): Promise<T>;
function resolve<T>(foreign: Thenable<T>): Promise<T>;
function resolve<T>(value?: T): Promise<T>;
interface Deferred<T> {
@@ -56,28 +92,65 @@ declare module When {
}
interface Promise<T> {
catch<U>(onRejected?: (reason: any) => Promise<U>): Promise<U>;
catch<U>(onRejected?: (reason: any) => U): Promise<U>;
catch<U>(filter: (reason: any) => boolean, onRejected?: (reason: any) => Promise<U>): Promise<U>;
catch<U>(filter: (reason: any) => boolean, onRejected?: (reason: any) => U): Promise<U>;
// Make sure you test any usage of these overloads, exceptionType must
// be a constructor with prototype set to an instance of Error.
catch<U>(exceptionType: any, onRejected?: (reason: any) => Promise<U>): Promise<U>;
catch<U>(exceptionType: any, onRejected?: (reason: any) => U): Promise<U>;
catch<U>(filter: (reason: any) => boolean, onRejected?: (reason: any) => Promise<U>): Promise<U>;
catch<U>(filter: (reason: any) => boolean, onRejected?: (reason: any) => U): Promise<U>;
catch<U>(onRejected?: (reason: any) => Promise<U>): Promise<U>;
catch<U>(onRejected?: (reason: any) => U): Promise<U>;
finally(onFulfilledOrRejected: Function): Promise<T>;
ensure(onFulfilledOrRejected: Function): Promise<T>;
inspect(): Snapshot<T>;
yield<U>(value: Promise<U>): Promise<U>;
yield<U>(value: U): Promise<U>;
else(value: T): Promise<T>;
orElse(value: T): Promise<T>;
tap(onFulfilledSideEffect: (value: T) => void): Promise<T>;
delay(milliseconds: number): Promise<T>;
timeout(milliseconds: number, reason?: any): Promise<T>;
with(thisArg: any): Promise<T>;
withThis(thisArg: any): Promise<T>;
otherwise<U>(onRejected?: (reason: any) => Promise<U>): Promise<U>;
otherwise<U>(onRejected?: (reason: any) => U): Promise<U>;
otherwise<U>(predicate: (reason: any) => boolean, onRejected?: (reason: any) => Promise<U>): Promise<U>;
otherwise<U>(predicate: (reason: any) => boolean, onRejected?: (reason: any) => U): Promise<U>;
// Make sure you test any usage of these overloads, exceptionType must
// be a constructor with prototype set to an instance of Error.
otherwise<U>(exceptionType: any, onRejected?: (reason: any) => Promise<U>): Promise<U>;
otherwise<U>(exceptionType: any, onRejected?: (reason: any) => U): Promise<U>;
then<U>(onFulfilled: (value: T) => Promise<U>, onRejected?: (reason: any) => Promise<U>, onProgress?: (update: any) => void): Promise<U>;
then<U>(onFulfilled: (value: T) => Promise<U>, onRejected?: (reason: any) => U, onProgress?: (update: any) => void): Promise<U>;
then<U>(onFulfilled: (value: T) => U, onRejected?: (reason: any) => Promise<U>, onProgress?: (update: any) => void): Promise<U>;
then<U>(onFulfilled: (value: T) => U, onRejected?: (reason: any) => U, onProgress?: (update: any) => void): Promise<U>;
done<U>(onFulfilled: (value: T) => void, onRejected?: (reason: any) => void): void;
fold<U, V>(combine: (value1: T, value2: V) => Promise<U>, value2: V): Promise<U>;
fold<U, V>(combine: (value1: T, value2: V) => Promise<U>, value2: Promise<V>): Promise<U>;
fold<U, V>(combine: (value1: T, value2: V) => U, value2: V): Promise<U>;
fold<U, V>(combine: (value1: T, value2: V) => U, value2: Promise<V>): Promise<U>;
}
interface Thenable<T> {
then<U>(onFulfilled: (value: T) => U, onRejected?: (reason: any) => U): Thenable<U>;
}
interface Snapshot<T> {