/
githubmirror
/
brackets
Обзор
Документация
Войти
/
githubmirror
/
brackets
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
test/spec/Async-test.js
665 строк
25 KB
ficristo
Move most inline jslint directives to config files
12 авг 2016, 10:22
12 авг 2016, 10:22
074382a
Код
Авторство
О чём код?
/* * Copyright (c) 2013 - present Adobe Systems Incorporated. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * */ /*global describe, beforeEach, it, runs, waitsFor, waitsForDone, waitsForFail, expect */ define(function (require, exports, module) { "use strict"; var Async = require("utils/Async"), PromiseQueue = Async.PromiseQueue; describe("Async", function () { describe("Chain", function () { function zeroArgThatSucceeds() { var d = new $.Deferred(); setTimeout(function () { d.resolve(); }, 1); return d.promise(); } function zeroArgThatFails() { var d = new $.Deferred(); setTimeout(function () { d.reject(); }, 1); return d.promise(); } function oneArgThatSucceeds(x) { var d = new $.Deferred(); setTimeout(function () { d.resolveWith(null, [x]); }, 1); return d.promise(); } function twoArgThatSucceeds(x, y) { var d = new $.Deferred(); setTimeout(function () { d.resolveWith(null, [x, y]); }, 1); return d.promise(); } function twoArgThatFails(x, y) { var d = new $.Deferred(); setTimeout(function () { d.rejectWith(null, [x, y]); }, 1); return d.promise(); } function syncAddTwoArg(x, y) { return x + y; } function syncException() { throw new Error("sync error"); } function createArrayComparator(arrayOne) { return function (arrayTwo) { var i, l; expect(arrayOne.length).toBe(arrayTwo.length); l = Math.min(arrayOne.length, arrayTwo.length); for (i = 0; i < l; i++) { expect(arrayOne[i]).toBe(arrayTwo[i]); } }; } function expectChainHelper(functions, args, shouldSucceed, responseComparator) { var done = false; var success = false; var response = null; runs(function () { var result = Async.chain( functions, args ); result.done(function () { done = true; success = true; response = arguments; }); result.fail(function () { done = true; success = false; response = arguments; }); }); waitsFor(function () { return done; }, "The chain should complete", 100); runs(function () { expect(success).toBe(shouldSucceed); responseComparator(response); }); } describe("Zero-argument deferreds", function () { it("[zero-arg] work with a null argument array", function () { expectChainHelper( [zeroArgThatSucceeds, zeroArgThatSucceeds, zeroArgThatSucceeds], null, true, createArrayComparator([]) ); }); it("[zero-arg] call error callback when first deferred fails", function () { expectChainHelper( [zeroArgThatFails, zeroArgThatSucceeds, zeroArgThatSucceeds], [], false, createArrayComparator([]) ); }); it("[zero-arg] call error callback when middle deferred fails", function () { expectChainHelper( [zeroArgThatSucceeds, zeroArgThatFails, zeroArgThatSucceeds], [], false, createArrayComparator([]) ); }); it("[zero-arg] call error callback when last deferred fails", function () { expectChainHelper( [zeroArgThatSucceeds, zeroArgThatSucceeds, zeroArgThatFails], [], false, createArrayComparator([]) ); }); it("[zero-arg] call success callback when all deferreds succeed", function () { expectChainHelper( [zeroArgThatSucceeds, zeroArgThatSucceeds, zeroArgThatSucceeds], [], true, createArrayComparator([]) ); }); it("[zero-arg] call success callback immediately if there are no deferreds", function () { expectChainHelper( [], [], true, createArrayComparator([]) ); }); }); describe("Nonzero-argument deferreds", function () { it("[nonzero-arg] call error callback when first deferred fails", function () { expectChainHelper( [twoArgThatFails, twoArgThatSucceeds, twoArgThatSucceeds], [1, 2], false, createArrayComparator([1, 2]) ); }); it("[nonzero-arg] call error callback when middle deferred fails", function () { expectChainHelper( [twoArgThatSucceeds, twoArgThatFails, twoArgThatSucceeds], [1, 2], false, createArrayComparator([1, 2]) ); }); it("[nonzero-arg] call error callback when last deferred fails", function () { expectChainHelper( [twoArgThatSucceeds, twoArgThatSucceeds, twoArgThatFails], [1, 2], false, createArrayComparator([1, 2]) ); }); it("[nonzero-arg] call success callback when all deferreds succeed", function () { expectChainHelper( [twoArgThatSucceeds, twoArgThatSucceeds, twoArgThatSucceeds], [1, 2], true, createArrayComparator([1, 2]) ); }); it("[nonzero-arg] call success callback immediately if there are no deferreds", function () { expectChainHelper( [], [1, 2], true, createArrayComparator([1, 2]) ); }); }); describe("With Timeout", function () { function promiseThatSucceeds(duration) { var d = new $.Deferred(); setTimeout(function () { d.resolve(); }, duration); return d.promise(); } function promiseThatFails(duration) { var d = new $.Deferred(); setTimeout(function () { d.reject(); }, duration); return d.promise(); } it("should resolve promise before rejected with timeout", function () { var promiseBase, promiseWrapper; runs(function () { promiseBase = promiseThatSucceeds(5); promiseWrapper = Async.withTimeout(promiseBase, 10); waitsForDone(promiseWrapper, "promise resolves before timeout"); }); runs(function () { // base promise resolves wrapper promise expect(promiseBase.state()).toBe("resolved"); expect(promiseWrapper.state()).toBe("resolved"); }); }); it("should reject promise before resolved with timeout", function () { var promiseBase, promiseWrapper; runs(function () { promiseBase = promiseThatFails(5); promiseWrapper = Async.withTimeout(promiseBase, 10, true); waitsForFail(promiseWrapper, "promise rejected before timeout"); }); runs(function () { // base promise rejects wrapper promise expect(promiseBase.state()).toBe("rejected"); expect(promiseWrapper.state()).toBe("rejected"); }); }); it("should timeout with reject before promise resolves", function () { var promiseBase, promiseWrapper; runs(function () { promiseBase = promiseThatSucceeds(10); promiseWrapper = Async.withTimeout(promiseBase, 5); waitsForFail(promiseWrapper, "times out before promise resolves"); }); runs(function () { expect(promiseWrapper.state()).toBe("rejected"); waitsForDone(promiseBase, "promise resolves after timeout"); }); runs(function () { expect(promiseBase.state()).toBe("resolved"); }); }); it("should timeout with resolve before promise rejected", function () { var promiseBase, promiseWrapper; runs(function () { promiseBase = promiseThatFails(10); promiseWrapper = Async.withTimeout(promiseBase, 5, true); waitsForDone(promiseWrapper, "times out before promise is rejected"); }); runs(function () { expect(promiseWrapper.state()).toBe("resolved"); waitsForFail(promiseBase, "promise is rejected after timeout"); }); runs(function () { expect(promiseBase.state()).toBe("rejected"); }); }); }); describe("Async/sync mix", function () { it("[async/sync] succeed with sync command at beginning", function () { expectChainHelper( [syncAddTwoArg, oneArgThatSucceeds, oneArgThatSucceeds], [1, 2], true, createArrayComparator([3]) ); }); it("[async/sync] succeed with sync command at middle", function () { expectChainHelper( [twoArgThatSucceeds, syncAddTwoArg, oneArgThatSucceeds], [1, 2], true, createArrayComparator([3]) ); }); it("[async/sync] succeed with sync command at end", function () { expectChainHelper( [twoArgThatSucceeds, twoArgThatSucceeds, syncAddTwoArg], [1, 2], true, createArrayComparator([3]) ); }); it("[async/sync] call error callback if sync command fails", function () { expectChainHelper( [twoArgThatSucceeds, syncException, twoArgThatSucceeds], [1, 2], false, function (response) { expect(response.length).toBe(1); expect(response[0] instanceof Error).toBe(true); } ); }); it("[async/sync] two sync commands in order are executed completely synchronously", function () { var promise = null, flag = true; runs(function () { function negate(b) { return !b; } function setFlag(b) { flag = b; return flag; } promise = Async.chain([negate, setFlag], [flag]); promise.done(function (b) { expect(b).toBe(flag); }); // note, we WANT to test this synchronously. This is not a bug // in the unit test. A series of synchronous functions should // execute synchronously. expect(flag).toBe(false); }); runs(function () { // With (the current version) of jQuery promises, resolution and // resolution handlers will get called synchronously. However, if we // move to a different promise implementation (e.g. Q) then resolution // handlers will get called asynchronously. So, we check completion // of the promise on a separate pass. waitsForDone(promise, "The chain to complete"); }); }); }); }); describe("promisify", function () { var testObj = { someVal: 5, succeeder: function (input, cb) { cb(null, input, this.someVal); }, failer: function (input, cb) { cb("this is an error"); } }; it("should resolve its returned promise when the errback is called with null err", function () { Async.promisify(testObj, "succeeder", "myInput") .then(function (input, someVal) { expect(input).toBe("myInput"); expect(someVal).toBe(testObj.someVal); }, function (err) { expect("should not have called fail callback").toBe(false); }); }); it("should reject its returned promise when the errback is called with an err", function () { Async.promisify(testObj, "failer", "myInput") .then(function (input, someVal) { expect("should not have called success callback").toBe(false); }, function (err) { expect(err).toBe("this is an error"); }); }); }); describe("Async PromiseQueue", function () { var queue, calledFns; beforeEach(function () { queue = new PromiseQueue(); calledFns = {}; }); function makeFn(id, resolveNow, rejectNow) { var result = new $.Deferred(); return { fn: function () { calledFns[id] = true; if (rejectNow) { result.reject(); } else if (resolveNow) { result.resolve(); } return result.promise(); }, deferred: result }; } it("should immediately execute a function when the queue is empty", function () { var fnInfo = makeFn("one"); queue.add(fnInfo.fn); expect(calledFns.one).toBe(true); fnInfo.deferred.resolve(); expect(queue._queue.length).toBe(0); expect(queue._curPromise).toBe(null); }); it("should wait to execute the second added function", function () { var fnInfo1 = makeFn("one"), fnInfo2 = makeFn("two"); queue.add(fnInfo1.fn); expect(calledFns.one).toBe(true); queue.add(fnInfo2.fn); expect(calledFns.two).toBeUndefined(); fnInfo1.deferred.resolve(); expect(calledFns.two).toBe(true); fnInfo2.deferred.resolve(); expect(queue._queue.length).toBe(0); expect(queue._curPromise).toBe(null); }); it("should properly handle the case where the first function completes synchronously", function () { var fnInfo1 = makeFn("one", true), fnInfo2 = makeFn("two"); queue.add(fnInfo1.fn); expect(calledFns.one).toBe(true); queue.add(fnInfo2.fn); expect(calledFns.two).toBe(true); fnInfo2.deferred.resolve(); expect(queue._queue.length).toBe(0); expect(queue._curPromise).toBe(null); }); it("should sequentially execute a second and third function if they're both added while the first is executing", function () { var fnInfo1 = makeFn("one"), fnInfo2 = makeFn("two"), fnInfo3 = makeFn("three"); queue.add(fnInfo1.fn); expect(calledFns.one).toBe(true); queue.add(fnInfo2.fn); queue.add(fnInfo3.fn); expect(calledFns.two).toBeUndefined(); expect(calledFns.three).toBeUndefined(); fnInfo1.deferred.resolve(); expect(calledFns.two).toBe(true); expect(calledFns.three).toBeUndefined(); fnInfo2.deferred.resolve(); expect(calledFns.three).toBe(true); fnInfo3.deferred.resolve(); expect(queue._queue.length).toBe(0); expect(queue._curPromise).toBe(null); }); it("should sequentially execute a second and third function if the third is added while the second is executing", function () { var fnInfo1 = makeFn("one"), fnInfo2 = makeFn("two"), fnInfo3 = makeFn("three"); queue.add(fnInfo1.fn); expect(calledFns.one).toBe(true); queue.add(fnInfo2.fn); expect(calledFns.two).toBeUndefined(); fnInfo1.deferred.resolve(); expect(calledFns.two).toBe(true); queue.add(fnInfo3.fn); expect(calledFns.three).toBeUndefined(); fnInfo2.deferred.resolve(); expect(calledFns.three).toBe(true); fnInfo3.deferred.resolve(); expect(queue._queue.length).toBe(0); expect(queue._curPromise).toBe(null); }); it("should execute a second function when added to the empty queue after the first function has completed", function () { var fnInfo1 = makeFn("one"), fnInfo2 = makeFn("two"); queue.add(fnInfo1.fn); expect(calledFns.one).toBe(true); fnInfo1.deferred.resolve(); expect(queue._queue.length).toBe(0); expect(queue._curPromise).toBe(null); queue.add(fnInfo2.fn); expect(calledFns.two).toBe(true); fnInfo2.deferred.resolve(); expect(queue._queue.length).toBe(0); expect(queue._curPromise).toBe(null); }); it("should execute the second function if the first function is rejected", function () { var fnInfo1 = makeFn("one"), fnInfo2 = makeFn("two"); queue.add(fnInfo1.fn); expect(calledFns.one).toBe(true); queue.add(fnInfo2.fn); expect(calledFns.two).toBeUndefined(); fnInfo1.deferred.reject(); expect(calledFns.two).toBe(true); fnInfo2.deferred.resolve(); expect(queue._queue.length).toBe(0); expect(queue._curPromise).toBe(null); }); it("should execute the third function after first and second functions are rejected", function () { var fnInfo1 = makeFn("one"), fnInfo2 = makeFn("two"), fnInfo3 = makeFn("three"); queue.add(fnInfo1.fn); expect(calledFns.one).toBe(true); queue.add(fnInfo2.fn); queue.add(fnInfo3.fn); expect(calledFns.two).toBeUndefined(); expect(calledFns.three).toBeUndefined(); fnInfo1.deferred.reject(); expect(calledFns.two).toBe(true); fnInfo2.deferred.reject(); expect(calledFns.three).toBe(true); fnInfo3.deferred.resolve(); expect(queue._queue.length).toBe(0); expect(queue._curPromise).toBe(null); }); it("should execute the second function after the already-rejected first function is added to the queue", function () { var fnInfo1 = makeFn("one", false, true), fnInfo2 = makeFn("two"); queue.add(fnInfo1.fn); expect(calledFns.one).toBe(true); queue.add(fnInfo2.fn); expect(calledFns.two).toBe(true); fnInfo2.deferred.resolve(); expect(queue._queue.length).toBe(0); expect(queue._curPromise).toBe(null); }); it("should be able to run two queues simultaneously without clashing", function () { var queue2 = new PromiseQueue(), q1FnInfo1 = makeFn("one"), q1FnInfo2 = makeFn("two"), q2FnInfo3 = makeFn("three"), q2FnInfo4 = makeFn("four"); //queue one queue.add(q1FnInfo1.fn); queue.add(q1FnInfo2.fn); expect(calledFns.one).toBe(true); expect(calledFns.two).toBeUndefined(); //queue one should have one in _queue, //queue two should have zero in _queue expect(queue._queue.length).toBe(1); expect(queue2._queue.length).toBe(0); //queue two queue2.add(q2FnInfo3.fn); queue2.add(q2FnInfo4.fn); expect(calledFns.three).toBe(true); expect(calledFns.four).toBeUndefined(); //queue one and two should have one in _queue expect(queue._queue.length).toBe(1); expect(queue2._queue.length).toBe(1); q1FnInfo1.deferred.resolve(); expect(calledFns.two).toBe(true); expect(queue._queue.length).toBe(0); q1FnInfo2.deferred.resolve(); expect(queue._queue.length).toBe(0); expect(queue._curPromise).toBe(null); q2FnInfo3.deferred.resolve(); expect(calledFns.three).toBe(true); expect(queue2._queue.length).toBe(0); q2FnInfo4.deferred.resolve(); expect(queue2._queue.length).toBe(0); expect(queue2._curPromise).toBe(null); }); }); }); });