From b3861aee8da4afbaceb23eac0dd073312bede614 Mon Sep 17 00:00:00 2001 From: Kitson Kelly Date: Fri, 23 Jun 2017 16:35:59 +0100 Subject: [PATCH 1/3] Forward compatible updates for TS 2.4 --- src/async/ExtensiblePromise.ts | 131 ++++++++++++++++++++++++--------- src/async/Task.ts | 113 +++++++++++++++++++++++----- src/async/iteration.ts | 62 ++++++++-------- src/request/providers/node.ts | 17 ++--- src/text.ts | 6 +- tests/unit/async/iteration.ts | 2 +- tests/unit/async/timing.ts | 4 +- tests/unit/request/node.ts | 20 +++-- 8 files changed, 243 insertions(+), 112 deletions(-) diff --git a/src/async/ExtensiblePromise.ts b/src/async/ExtensiblePromise.ts index 9ee50377..07a0988c 100644 --- a/src/async/ExtensiblePromise.ts +++ b/src/async/ExtensiblePromise.ts @@ -10,7 +10,7 @@ import '@dojo/shim/Symbol'; * @param iterable The list of objects to iterate over * @returns {any[]} The list of objects, as an array, with ExtensiblePromises being replaced by Promises. */ -function unwrapPromises(iterable: Iterable | any[]): any[] { +export function unwrapPromises(iterable: Iterable | any[]): any[] { const unwrapped: any[] = []; forOf(iterable, function (item: any): void { unwrapped.push(item instanceof ExtensiblePromise ? item._promise : item); @@ -29,11 +29,19 @@ export default class ExtensiblePromise { /** * Return a rejected promise wrapped in an ExtensiblePromise * - * @param {Error?} reason The reason for the rejection - * @returns {ExtensiblePromise} + * @param reason The reason for the rejection + * @returns An extensible promise + */ + static reject(reason?: any): ExtensiblePromise; + + /** + * Return a rejected promise wrapped in an ExtensiblePromise + * + * @param reason The reason for the rejection + * @returns An extensible promise */ - static reject(reason?: Error): any { - return new this((resolve, reject) => reject(reason)); + static reject(reason?: any): ExtensiblePromise { + return new this((resolve, reject) => reject(reason)); } /** @@ -41,12 +49,20 @@ export default class ExtensiblePromise { * * @param value The value to resolve the promise with * - * @returns {ExtensiblePromise} + * @returns An extensible promise */ - static resolve>(): F; - static resolve>(value: (T | Thenable)): F; - static resolve>(value?: any): F { - return new this((resolve, reject) => resolve(value)); + static resolve

>(): P; + + /** + * Return a resolved promise wrapped in an ExtensiblePromise + * + * @param value The value to resolve the promise with + * + * @returns An extensible promise + */ + static resolve>(value: T | PromiseLike): P; + static resolve(value?: any | PromiseLike): ExtensiblePromise { + return new this((resolve, reject) => resolve(value)); } /** @@ -58,22 +74,70 @@ export default class ExtensiblePromise { * // { one: 1, two: 2 } * * @param iterable An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects - * @returns {ExtensiblePromise} + * @returns An extensible promise + */ + static all(iterable: DictionaryOfPromises): ExtensiblePromise<{ [key: string]: T }>; + + /** + * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value + * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values. + * + * @example + * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results)); + * // { one: 1, two: 2 } + * + * @param iterable An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects + * @returns An extensible promise + */ + static all(iterable: (T | Thenable)[]): ExtensiblePromise; + + /** + * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value + * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values. + * + * @example + * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results)); + * // { one: 1, two: 2 } + * + * @param iterable An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects + * @returns An extensible promise + */ + static all(iterable: T | Thenable): ExtensiblePromise; + + /** + * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value + * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values. + * + * @example + * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results)); + * // { one: 1, two: 2 } + * + * @param iterable An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects + * @returns An extensible promise + */ + static all(iterable: ListOfPromises): ExtensiblePromise; + + /** + * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value + * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values. + * + * @example + * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results)); + * // { one: 1, two: 2 } + * + * @param iterable An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects + * @returns An extensible promise */ - static all, T>(iterable: DictionaryOfPromises): F; - static all, T>(iterable: (T | Thenable)[]): F; - static all, T>(iterable: T | Thenable): F; - static all, T>(iterable: ListOfPromises): F; - static all, T>(iterable: DictionaryOfPromises | ListOfPromises): F { + static all(iterable: DictionaryOfPromises | ListOfPromises): ExtensiblePromise { if (!isArrayLike(iterable) && !isIterable(iterable)) { const promiseKeys = Object.keys(iterable); - return new this((resolve, reject) => { - Promise.all(promiseKeys.map(key => (> iterable)[ key ])).then((promiseResults: T[]) => { - const returnValue: {[_: string]: T} = {}; + return new this((resolve, reject) => { + Promise.all(promiseKeys.map(key => iterable[key])).then((promiseResults: T[]) => { + const returnValue: { [key: string]: T} = {}; promiseResults.forEach((value: T, index: number) => { - returnValue[ promiseKeys[ index ] ] = value; + returnValue[promiseKeys[index]] = value; }); resolve(returnValue); @@ -81,7 +145,7 @@ export default class ExtensiblePromise { }); } - return new this((resolve, reject) => { + return new this((resolve, reject) => { Promise.all(unwrapPromises(> iterable)).then(resolve, reject); }); } @@ -92,8 +156,8 @@ export default class ExtensiblePromise { * @param iterable An iterable of values to resolve. These can be Promises, ExtensiblePromises, or other objects * @returns {ExtensiblePromise} */ - static race, T>(iterable: Iterable<(T | Thenable)> | (T | Thenable)[]): F { - return new this((resolve, reject) => { + static race(iterable: Iterable<(T | PromiseLike)> | (T | PromiseLike)[]): ExtensiblePromise { + return new this((resolve, reject) => { Promise.race(unwrapPromises(iterable)).then(resolve, reject); }); } @@ -127,9 +191,8 @@ export default class ExtensiblePromise { * * @returns {ExtensiblePromise} */ - catch(onRejected: (reason: Error) => T | Thenable | void): ExtensiblePromise; - catch(onRejected: (reason: Error) => U | Thenable): ExtensiblePromise { - return this.then(undefined, onRejected); + catch(onRejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): ExtensiblePromise { + return this.then(undefined, onRejected); } /** @@ -140,16 +203,14 @@ export default class ExtensiblePromise { * * @returns {ExtensiblePromise} */ - then(onFulfilled: ((value: T) => (U | Thenable | undefined)) | undefined, onRejected: (reason: Error) => (V | Thenable)): ExtensiblePromise; - then(onFulfilled?: ((value: T) => (U | Thenable | undefined)) | undefined, onRejected?: (reason: Error) => void): ExtensiblePromise; - then(onFulfilled?: ((value: T) => (U | Thenable | undefined)) | undefined, onRejected?: (reason: Error) => (U | Thenable)): ExtensiblePromise { - const e: Executor = (resolve, reject) => { - function handler(rejected: boolean, valueOrError: T | U | Error) { - const callback: ((value: T | U | Error) => (U | Thenable | void)) | undefined = rejected ? onRejected : onFulfilled; + then(onFulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onRejected?: ((reason: any) => TResult2 | PromiseLike | void) | undefined | null): ExtensiblePromise { + const e: Executor = (resolve, reject) => { + function handler(rejected: boolean, valueOrError: T | TResult1 | Error) { + const callback: ((value: any) => any) | null | undefined = rejected ? onRejected : onFulfilled; if (typeof callback === 'function') { try { - resolve( callback( valueOrError)); + resolve(callback(valueOrError)); } catch (error) { reject(error); @@ -159,14 +220,14 @@ export default class ExtensiblePromise { reject(valueOrError); } else { - resolve( valueOrError); + resolve(valueOrError as TResult1); } } this._promise.then(handler.bind(null, false), handler.bind(null, true)); }; - return new (<{ new(executor: Executor): any }> this.constructor)(e); + return new (this.constructor as typeof ExtensiblePromise)(e); } readonly [Symbol.toStringTag]: 'Promise'; diff --git a/src/async/Task.ts b/src/async/Task.ts index 9bae2642..87f1bc51 100644 --- a/src/async/Task.ts +++ b/src/async/Task.ts @@ -1,6 +1,6 @@ import { Thenable } from '@dojo/shim/interfaces'; import { Executor } from '@dojo/shim/Promise'; -import ExtensiblePromise, { ListOfPromises, DictionaryOfPromises } from './ExtensiblePromise'; +import ExtensiblePromise, { ListOfPromises, DictionaryOfPromises, unwrapPromises } from './ExtensiblePromise'; import { Iterable } from '@dojo/shim/iterator'; /** @@ -40,18 +40,20 @@ export default class Task extends ExtensiblePromise { * @param iterable An iterable of values to resolve. These can be Promises, ExtensiblePromises, or other objects * @returns {Task} */ - static race, T>(iterable: Iterable<(T | Thenable)> | (T | Thenable)[]): Task { - return > super.race(iterable); + static race(iterable: Iterable<(T | Thenable)> | (T | Thenable)[]): Task { + return new this((resolve, reject) => { + Promise.race(unwrapPromises(iterable)).then(resolve, reject); + }); } /** * Return a rejected promise wrapped in a Task * - * @param {Error?} reason The reason for the rejection - * @returns {Task} + * @param reason The reason for the rejection + * @returns A task */ static reject(reason?: Error): Task { - return new this((resolve, reject) => reject(reason)); + return new this((resolve, reject) => reject(reason)); } /** @@ -59,20 +61,95 @@ export default class Task extends ExtensiblePromise { * * @param value The value to resolve with * - * @return {Task} + * @return A task */ public static resolve(): Task; + + /** + * Return a resolved task. + * + * @param value The value to resolve with + * + * @return A task + */ public static resolve(value: (T | Thenable)): Task; + + /** + * Return a resolved task. + * + * @param value The value to resolve with + * + * @return A task + */ public static resolve(value?: any): Task { return new this((resolve, reject) => resolve(value)); } + /** + * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value + * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values. + * + * @example + * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results)); + * // { one: 1, two: 2 } + * + * @param iterable An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects + * @returns An extensible promise + */ static all(iterable: DictionaryOfPromises): Task<{ [key: string]: T }>; + + /** + * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value + * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values. + * + * @example + * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results)); + * // { one: 1, two: 2 } + * + * @param iterable An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects + * @returns An extensible promise + */ static all(iterable: (T | Thenable)[]): Task; + + /** + * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value + * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values. + * + * @example + * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results)); + * // { one: 1, two: 2 } + * + * @param iterable An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects + * @returns An extensible promise + */ static all(iterable: T | Thenable): Task; + + /** + * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value + * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values. + * + * @example + * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results)); + * // { one: 1, two: 2 } + * + * @param iterable An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects + * @returns An extensible promise + */ static all(iterable: ListOfPromises): Task; + + /** + * Return a ExtensiblePromise that resolves when all of the passed in objects have resolved. When used with a key/value + * pair, the returned promise's argument is a key/value pair of the original keys with their resolved values. + * + * @example + * ExtensiblePromise.all({ one: 1, two: 2 }).then(results => console.log(results)); + * // { one: 1, two: 2 } + * + * @param iterable An iterable of values to resolve, or a key/value pair of values to resolve. These can be Promises, ExtensiblePromises, or other objects + * @returns An extensible promise + */ static all(iterable: DictionaryOfPromises | ListOfPromises): Task { - return > super.all(iterable); + return super.all(iterable) as Task; } /** @@ -195,9 +272,8 @@ export default class Task extends ExtensiblePromise { } } - catch(onRejected: (reason: Error) => T | Thenable | void): Task; - catch(onRejected: (reason: Error) => U | Thenable): Task { - return this.then(undefined, onRejected); + catch(onRejected?: ((reason: any) => TResult | PromiseLike) | undefined): Task { + return this.then(undefined, onRejected) as Task; } /** @@ -225,18 +301,15 @@ export default class Task extends ExtensiblePromise { /** * Adds a callback to be invoked when the Task resolves or is rejected. * - * @param {Function} onFulfilled A function to call to handle the resolution. The paramter to the function will be the resolved value, if any. - * @param {Function} onRejected A function to call to handle the error. The parameter to the function will be the caught error. + * @param onFulfilled A function to call to handle the resolution. The paramter to the function will be the resolved value, if any. + * @param onRejected A function to call to handle the error. The parameter to the function will be the caught error. * - * @returns {ExtensiblePromise} + * @returns A task */ - then(onFulfilled: ((value: T) => (U | Thenable | undefined)) | undefined, onRejected: (reason: Error) => (V | Thenable)): Task; - then(onFulfilled?: ((value: T) => (U | Thenable | undefined)) | undefined, onRejected?: (reason: Error) => void): Task; - then(onFulfilled?: ((value: T) => (U | Thenable | undefined)) | undefined, onRejected?: (reason: Error) => (U | Thenable)): Task; - then(onFulfilled?: (value?: T) => U | Thenable, onRejected?: (error: Error) => U | Thenable): Task { + then(onFulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onRejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Task { // FIXME // tslint:disable-next-line:no-var-keyword - var task = > super.then( + var task = super.then( // Don't call the onFulfilled or onRejected handlers if this Task is canceled function (value) { if (task._state === State.Canceled) { @@ -256,7 +329,7 @@ export default class Task extends ExtensiblePromise { } throw error; } - ); + ) as Task; task.canceler = () => { // If task's parent (this) hasn't been resolved, cancel it; downward propagation will start at the first diff --git a/src/async/iteration.ts b/src/async/iteration.ts index 8f324c46..fb27de42 100644 --- a/src/async/iteration.ts +++ b/src/async/iteration.ts @@ -3,6 +3,10 @@ import { isArrayLike, Iterable } from '@dojo/shim/iterator'; import Promise from '@dojo/shim/Promise'; import { Thenable } from '@dojo/shim/interfaces'; +function isThenable(value: any): value is Thenable { + return value && typeof value.then === 'function'; +} + type ValuesAndResults = { values: T[] | undefined; results: U[] | undefined; }; /** @@ -13,11 +17,11 @@ type ValuesAndResults = { values: T[] | undefined; results: U[] | undefine * @return a list of objects holding the synchronous values and synchronous results. */ function processValuesAndCallback(items: Iterable> | (T | Thenable)[], callback: Mapper): Promise> { - return Promise.all(items) + return Promise.all(items) .then(function (results) { - let pass: (U | Promise)[] = Array.prototype.map.call(results, callback); - return Promise.all(pass) - .then>(function (pass) { + const pass: (U | Promise)[] = Array.prototype.map.call(results, callback); + return Promise.all(pass) + .then(function (pass) { return { values: results, results: pass }; }); }); @@ -27,7 +31,7 @@ function processValuesAndCallback(items: Iterable> | (T | T * Finds the index of the next value in a sparse array-like object * @param list the sparse array-like object * @param offset the starting offset - * @return {number} the offset of the next index with a value; or -1 if not found + * @return the offset of the next index with a value; or -1 if not found */ function findNextValueIndex(list: ArrayLike, offset: number = -1): number { offset++; @@ -39,7 +43,7 @@ function findNextValueIndex(list: ArrayLike, offset: number = -1): number return -1; } -function findLastValueIndex(list: ArrayLike, offset?: number): number { +function findLastValueIndex(list: ArrayLike, offset?: number): number { offset = (offset === undefined ? list.length : offset) - 1; for (; offset >= 0; offset--) { if (offset in list) { @@ -51,9 +55,9 @@ function findLastValueIndex(list: ArrayLike, offset?: number): number { function generalReduce(findNextIndex: (list: ArrayLike | undefined, offset?: number) => number, items: Iterable> | (T | Promise)[], callback: Reducer, initialValue?: U): Promise { const hasInitialValue = arguments.length > 3; - return Promise.all(items) + return Promise.all(items) .then(function (results) { - return new Promise(function (resolve, reject) { + return new Promise(function (resolve, reject) { // As iterators do not have indices like `ArrayLike` objects, the results array // is used to determine the next value. const list = isArrayLike(items) ? items : results; @@ -65,11 +69,11 @@ function generalReduce(findNextIndex: (list: ArrayLike | undefined, o if (currentValue) { const result = callback(currentValue, results[i], i, results); - if ( (> result).then) { - (> result).then(next, reject); + if (isThenable(result)) { + result.then(next, reject); } else { - next( result); + next(result); } } } @@ -99,7 +103,7 @@ function generalReduce(findNextIndex: (list: ArrayLike | undefined, o } function testAndHaltOnCondition(condition: boolean, items: Iterable> | (T | Promise)[], callback: Filterer): Promise { - return Promise.all(items).then(function (results) { + return Promise.all(items).then(function (results) { return new Promise(function(resolve) { let result: (boolean | Thenable); let pendingCount = 0; @@ -109,9 +113,9 @@ function testAndHaltOnCondition(condition: boolean, items: Iterable> result).then) { + else if (isThenable(result)) { pendingCount++; - (> result).then(function (result) { + result.then(function (result) { if (result === condition) { resolve(result); } @@ -147,7 +151,7 @@ export function every(items: Iterable> | (T | Promise)[], c * @return eventually returns a new array with only values that have passed */ export function filter(items: Iterable> | (T | Promise)[], callback: Filterer): Promise { - return processValuesAndCallback(items, callback).then(function (result) { + return processValuesAndCallback(items, callback).then(function (result) { let arr: T[] = []; if (result && result.results && result.values) { for (let i = 0; i < result.results.length; i++) { @@ -164,9 +168,9 @@ export function filter(items: Iterable> | (T | Promise)[], * @param callback a synchronous/asynchronous test * @return a promise eventually containing the item or undefined if a match is not found */ -export function find(items: Iterable> | (T | Promise)[], callback: Filterer): Promise { - const list: (T | Thenable)[] = isArrayLike(items) ? items : <(T | Thenable)[]> array.from(items); - return findIndex(list, callback).then(function (i?: number): T | Thenable | undefined { +export function find(items: Iterable> | (T | Promise)[], callback: Filterer): Promise { + const list = isArrayLike(items) ? items : array.from(items); + return findIndex(list, callback).then(function (i) { return i !== undefined && i >= 0 ? list[i] : undefined; }); } @@ -179,7 +183,7 @@ export function find(items: Iterable> | (T | Promise)[], ca */ export function findIndex(items: Iterable> | (T | Thenable)[], callback: Filterer): Promise { // TODO we can improve this by returning immediately - return processValuesAndCallback(items, callback).then(function (result: ValuesAndResults) { + return processValuesAndCallback(items, callback).then(function (result: ValuesAndResults) { if (result && result.results) { for (let i = 0; i < result.results.length; i++) { if (result.results[i]) { @@ -197,9 +201,9 @@ export function findIndex(items: Iterable> | (T | Thenable) * @param callback a synchronous/asynchronous transform function * @return a promise eventually containing a collection of each transformed value */ -export function map(items: Iterable> | (T | Promise)[], callback: Mapper): Promise { - return processValuesAndCallback(items, callback) - .then(function (result) { +export function map(items: Iterable> | (T | Promise)[], callback: Mapper): Promise { + return processValuesAndCallback(items, callback) + .then(function (result) { return result ? result.results : null; }); } @@ -212,23 +216,23 @@ export function map(items: Iterable> | (T | Promise)[], * @return a promise eventually containing a value that is the result of the reduction */ export function reduce(this: any, items: Iterable> | (T | Promise)[], callback: Reducer, initialValue?: U): Promise { - let args: any[] = array.from(arguments); + const args: any[] = array.from(arguments); args.unshift(findNextValueIndex); return generalReduce.apply(this, args); } export function reduceRight(this: any, items: Iterable> | (T | Promise)[], callback: Reducer, initialValue?: U): Promise { - let args: any[] = array.from(arguments); + const args: any[] = array.from(arguments); args.unshift(findLastValueIndex); return generalReduce.apply(this, args); } export function series(items: Iterable> | (T | Promise)[], operation: Mapper): Promise { - return generalReduce(findNextValueIndex, items, function (previousValue: (Thenable | U)[], currentValue: T, index: number, array: T[]) { + return generalReduce(findNextValueIndex, items, function (previousValue, currentValue: T, index: number, array: T[]) { const result = operation(currentValue, index, array); - if ((> result).then) { - return (> result).then(function (value: U) { + if (isThenable(result)) { + return result.then(function (value) { previousValue.push(value); return previousValue; }); @@ -236,11 +240,11 @@ export function series(items: Iterable> | (T | Promise)[ previousValue.push(result); return previousValue; - }, []); + }, [] as U[]); } export function some(items: Iterable> | Array>, callback: Filterer): Promise { - return testAndHaltOnCondition(true, items, callback); + return testAndHaltOnCondition(true, items, callback); } export interface Filterer extends Mapper {} diff --git a/src/request/providers/node.ts b/src/request/providers/node.ts index 903eaa64..35252283 100644 --- a/src/request/providers/node.ts +++ b/src/request/providers/node.ts @@ -162,18 +162,13 @@ export class NodeResponse extends Response { const headers = this.headers = new Headers(); for (let key in response.headers) { - if (discardedDuplicates.has(key)) { - headers.append(key, response.headers[key]); - } - else if (key === 'set-cookie') { - ( response.headers[key]).forEach(value => { - headers.append(key, value); - }); - } - else { - const values: string[] = response.headers[key].split(', '); - values.forEach(value => { + const value = response.headers[key]; + if (value) { + if (discardedDuplicates.has(key) && !Array.isArray(value)) { headers.append(key, value); + } + (Array.isArray(value) ? value : value.split(/\s*,\s*/)).forEach((v) => { + headers.append(key, v); }); } } diff --git a/src/text.ts b/src/text.ts index 2eb2b5ab..56263cc5 100644 --- a/src/text.ts +++ b/src/text.ts @@ -25,7 +25,7 @@ function strip(text: string): string { /* * Host-specific method to retrieve text */ -let getText: (url: string, callback: (value: string) => void) => void; +let getText: (url: string, callback: (value: string | null) => void) => void; if (has('host-browser')) { getText = function(url: string, callback: (value: string | null) => void): void { @@ -64,8 +64,8 @@ let textCache: { [key: string]: any; } = {}; */ let pending: { [key: string]: any; } = {}; -export function get(url: string): Promise { - let promise = new Promise (function (resolve, reject) { +export function get(url: string): Promise { + let promise = new Promise(function (resolve, reject) { getText(url, function (text) { resolve(text); }); diff --git a/tests/unit/async/iteration.ts b/tests/unit/async/iteration.ts index 0a67388d..80be6216 100644 --- a/tests/unit/async/iteration.ts +++ b/tests/unit/async/iteration.ts @@ -336,7 +336,7 @@ function reduceTests(reduceMethod: (items: (any | Promise)[], callback: ite const { step, initialIndex, callbackValues } = getExpectedSolution(this); const values: string[] = 'hello'.split(''); const iterable = getIterable(useIterator, values); - const results = createTriggerablePromises(values.length); + const results = createTriggerablePromises(values.length); let previousIndex = initialIndex; const promise = reduceMethod(iterable, function (previous: string, value: string, index: number, array: string[]): Promise { diff --git a/tests/unit/async/timing.ts b/tests/unit/async/timing.ts index e0c1afe9..e25f806d 100644 --- a/tests/unit/async/timing.ts +++ b/tests/unit/async/timing.ts @@ -74,7 +74,7 @@ registerSuite({ 'DelayedRejection': { 'is eventually rejected': function () { const start = Date.now(); - return new timing.DelayedRejection(101).then(throwImmediatly, function (reason) { + return new timing.DelayedRejection(101).then(throwImmediatly, function (reason) { assert.isUndefined(reason); assert.isAbove(Date.now(), start + 99); return true; @@ -84,7 +84,7 @@ registerSuite({ 'is eventually rejected with error': function () { const start = Date.now(); const expectedError = new Error('boom!'); - return new timing.DelayedRejection(101, expectedError).then(throwImmediatly, function (reason) { + return new timing.DelayedRejection(101, expectedError).then(throwImmediatly, function (reason) { assert.strictEqual(reason, expectedError); assert.isAbove(Date.now(), start + 99); return true; diff --git a/tests/unit/request/node.ts b/tests/unit/request/node.ts index 227a3e67..709881e4 100644 --- a/tests/unit/request/node.ts +++ b/tests/unit/request/node.ts @@ -705,20 +705,18 @@ registerSuite({ }, 'data cannot be used twice'() { - return nodeRequest(getRequestUrl('foo.json')).then((response?: Response) => { - if (response) { - assert.isFalse(response.bodyUsed); + return nodeRequest(getRequestUrl('foo.json')).then((response) => { + assert.isFalse(response.bodyUsed); - return response.json().then(() => { - assert.isTrue(response.bodyUsed); + return response.json().then(() => { + assert.isTrue(response.bodyUsed); - return response.json().then(() => { - throw new Error('should not have succeeded'); - }, () => { - return true; - }); + return response.json().then(() => { + throw new Error('should not have succeeded'); + }, () => { + return true; }); - } + }); }); }, From 276be733cd55fa6a495a9f8ea243a814186d2631 Mon Sep 17 00:00:00 2001 From: Kitson Kelly Date: Tue, 27 Jun 2017 11:31:27 +0100 Subject: [PATCH 2/3] Address feedback on PR --- src/async/ExtensiblePromise.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/async/ExtensiblePromise.ts b/src/async/ExtensiblePromise.ts index 07a0988c..da7c2ed1 100644 --- a/src/async/ExtensiblePromise.ts +++ b/src/async/ExtensiblePromise.ts @@ -204,7 +204,7 @@ export default class ExtensiblePromise { * @returns {ExtensiblePromise} */ then(onFulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onRejected?: ((reason: any) => TResult2 | PromiseLike | void) | undefined | null): ExtensiblePromise { - const e: Executor = (resolve, reject) => { + const executor: Executor = (resolve, reject) => { function handler(rejected: boolean, valueOrError: T | TResult1 | Error) { const callback: ((value: any) => any) | null | undefined = rejected ? onRejected : onFulfilled; @@ -227,7 +227,7 @@ export default class ExtensiblePromise { this._promise.then(handler.bind(null, false), handler.bind(null, true)); }; - return new (this.constructor as typeof ExtensiblePromise)(e); + return new (this.constructor as typeof ExtensiblePromise)(executor); } readonly [Symbol.toStringTag]: 'Promise'; From 7652173e4814511f661d31f1afaf0d7f679b6993 Mon Sep 17 00:00:00 2001 From: Kitson Kelly Date: Tue, 27 Jun 2017 11:42:14 +0100 Subject: [PATCH 3/3] Address feedback on PR --- src/async/ExtensiblePromise.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/async/ExtensiblePromise.ts b/src/async/ExtensiblePromise.ts index da7c2ed1..f04076be 100644 --- a/src/async/ExtensiblePromise.ts +++ b/src/async/ExtensiblePromise.ts @@ -203,7 +203,10 @@ export default class ExtensiblePromise { * * @returns {ExtensiblePromise} */ - then(onFulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onRejected?: ((reason: any) => TResult2 | PromiseLike | void) | undefined | null): ExtensiblePromise { + then( + onFulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, + onRejected?: ((reason: any) => TResult2 | PromiseLike | void) | undefined | null + ): ExtensiblePromise { const executor: Executor = (resolve, reject) => { function handler(rejected: boolean, valueOrError: T | TResult1 | Error) { const callback: ((value: any) => any) | null | undefined = rejected ? onRejected : onFulfilled;