| Index: chrome/browser/resources/google_now/common_test_util.js
|
| diff --git a/chrome/browser/resources/google_now/common_test_util.js b/chrome/browser/resources/google_now/common_test_util.js
|
| index 66d65f49d9efa9d3f0f77aa6db76165f119cf9c1..c090c9545bb0e6fdf4c1ee68e712ca7faf98745f 100644
|
| --- a/chrome/browser/resources/google_now/common_test_util.js
|
| +++ b/chrome/browser/resources/google_now/common_test_util.js
|
| @@ -78,36 +78,70 @@ function getMockHandlerContainer(eventIdentifier) {
|
| * As a result, we can't use built-in JS promises since they run asynchronously.
|
| * Instead of mocking all possible calls to promises, a skeleton
|
| * implementation is provided to get the tests to pass.
|
| + *
|
| + * This functionality and logic originates from ECMAScript 6's spec of promises.
|
| */
|
| var Promise = function() {
|
| function PromisePrototypeObject(asyncTask) {
|
| - var result;
|
| - var resolved = false;
|
| - asyncTask(
|
| - function(asyncResult) {
|
| - result = asyncResult;
|
| - resolved = true;
|
| - },
|
| - function(asyncFailureResult) {
|
| - result = asyncFailureResult;
|
| - resolved = false;
|
| - });
|
| + function isThenable(value) {
|
| + return (typeof value === 'object') && isCallable(value.then);
|
| + }
|
|
|
| - function then(callback) {
|
| - if (resolved) {
|
| - callback.call(null, result);
|
| + function isCallable(value) {
|
| + return typeof value === 'function';
|
| + }
|
| +
|
| + function callResolveRejectFunc(func) {
|
| + var funcResult;
|
| + var funcResolved = false;
|
| + func(
|
| + function(resolveResult) {
|
| + funcResult = resolveResult;
|
| + funcResolved = true;
|
| + },
|
| + function(rejectResult) {
|
| + funcResult = rejectResult;
|
| + funcResolved = false;
|
| + });
|
| + return { result: funcResult, resolved: funcResolved };
|
| + }
|
| +
|
| + function then(onResolve, onReject) {
|
| + var resolutionHandler =
|
| + isCallable(onResolve) ? onResolve : function() { return result; };
|
| + var rejectionHandler =
|
| + isCallable(onReject) ? onReject : function() { return result; };
|
| + var handlerResult =
|
| + resolved ? resolutionHandler(result) : rejectionHandler(result);
|
| + var promiseResolved = resolved;
|
| + if (isThenable(handlerResult)) {
|
| + var resolveReject = callResolveRejectFunc(handlerResult.then);
|
| + handlerResult = resolveReject.result;
|
| + promiseResolved = resolveReject.resolved;
|
| + }
|
| +
|
| + if (promiseResolved) {
|
| + return Promise.resolve(handlerResult);
|
| + } else {
|
| + return Promise.reject(handlerResult);
|
| }
|
| - return this;
|
| }
|
|
|
| // Promises use the function name "catch" to call back error handlers.
|
| // We can't use "catch" since function or variable names cannot use the word
|
| // "catch".
|
| - function catchFunc(callback) {
|
| - if (!resolved) {
|
| - callback.call(null, result);
|
| - }
|
| - return this;
|
| + function catchFunc(onRejected) {
|
| + return this.then(undefined, onRejected);
|
| + }
|
| +
|
| + var resolveReject = callResolveRejectFunc(asyncTask);
|
| + var result = resolveReject.result;
|
| + var resolved = resolveReject.resolved;
|
| +
|
| + if (isThenable(result)) {
|
| + var thenResolveReject = callResolveRejectFunc(result.then);
|
| + result = thenResolveReject.result;
|
| + resolved = thenResolveReject.resolved;
|
| }
|
|
|
| return {then: then, catch: catchFunc, isPromise: true};
|
| @@ -137,12 +171,19 @@ var Promise = function() {
|
| return promise;
|
| }
|
|
|
| + function reject(value) {
|
| + var promise = new PromisePrototypeObject(function(resolve, reject) {
|
| + reject(value);
|
| + });
|
| + return promise;
|
| + }
|
| +
|
| PromisePrototypeObject.all = all;
|
| PromisePrototypeObject.resolve = resolve;
|
| + PromisePrototypeObject.reject = reject;
|
| return PromisePrototypeObject;
|
| }();
|
|
|
| -
|
| /**
|
| * Sets up the test to expect a Chrome Local Storage call.
|
| * @param {Object} fixture Mock JS Test Object.
|
|
|