Skip to content

Commit

Permalink
[jest-jasmine2] Rewrite QueueRunner. (jestjs#3187)
Browse files Browse the repository at this point in the history
* [jest-jasmine2] Rewrite `QueueRunner`.

* Make `FakeTimer` test stack agnostic.

* Update snapshot.

Manually.

* Fix `FakeTimer`.

* Lint.

* Do not use async.

* Revert "Merge pull request jestjs#1 from wtgtybhertgeghgtwtg/wtgtybhertgeghgtwtg-patch-1"

This reverts commit 9424111, reversing
changes made to ea0bb8a.
  • Loading branch information
wtgtybhertgeghgtwtg authored and aaronabramov committed Mar 23, 2017
1 parent 184ca29 commit 98bc0a4
Show file tree
Hide file tree
Showing 9 changed files with 280 additions and 182 deletions.
4 changes: 3 additions & 1 deletion packages/jest-jasmine2/package.json
Expand Up @@ -12,6 +12,8 @@
"jest-matcher-utils": "^19.0.0",
"jest-matchers": "^19.0.0",
"jest-message-util": "^19.0.0",
"jest-snapshot": "^19.0.2"
"jest-snapshot": "^19.0.2",
"once": "^1.4.0",
"p-map": "^1.1.1"
}
}
48 changes: 48 additions & 0 deletions packages/jest-jasmine2/src/__tests__/p-timeout-test.js
@@ -0,0 +1,48 @@
/**
* Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @emails oncall+jsinfra
*/
'use strict';

jest.useFakeTimers();

const pTimeout = require('../p-timeout');

describe('pTimeout', () => {
it('calls `clearTimeout` and resolves when `promise` resolves.', async () => {
const onTimeout = jest.fn();
const promise = Promise.resolve();
await pTimeout(promise, 1000, clearTimeout, setTimeout, onTimeout);
expect(setTimeout).toHaveBeenCalled();
expect(clearTimeout).toHaveBeenCalled();
expect(onTimeout).not.toHaveBeenCalled();
});

it('calls `clearTimeout` and rejects when `promise` rejects.', async () => {
const onTimeout = jest.fn();
const promise = Promise.reject();
try {
await pTimeout(promise, 1000, clearTimeout, setTimeout, onTimeout);
} catch (e) { }
expect(setTimeout).toHaveBeenCalled();
expect(clearTimeout).toHaveBeenCalled();
expect(onTimeout).not.toHaveBeenCalled();
});

it('calls `onTimeout` on timeout.', async () => {
const onTimeout = jest.fn();
// A Promise that never resolves or rejects.
const promise = new Promise(() => {});
const timeoutPromise =
pTimeout(promise, 1000, clearTimeout, setTimeout, onTimeout);
jest.runAllTimers();
await timeoutPromise;
expect(setTimeout).toHaveBeenCalled();
expect(onTimeout).toHaveBeenCalled();
});
});
120 changes: 120 additions & 0 deletions packages/jest-jasmine2/src/__tests__/queueRunner-test.js
@@ -0,0 +1,120 @@
/**
* Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @emails oncall+jsinfra
*/
'use strict';

const queueRunner = require('../queueRunner');

describe('queueRunner', () => {
it('runs every function in the queue.', async () => {
const fnOne = jest.fn(next => next());
const fnTwo = jest.fn(next => next());
const onComplete = jest.fn();
const options = {
clearTimeout,
fail: () => {},
onComplete,
onException: () => {},
queueableFns: [{
fn: fnOne,
}, {
fn: fnTwo,
}],
setTimeout,
};
await queueRunner(options);
expect(fnOne).toHaveBeenCalled();
expect(fnTwo).toHaveBeenCalled();
expect(onComplete).toHaveBeenCalled();
});

it('exposes `fail` to `next`.', async () => {
const fail = jest.fn();
const fnOne = jest.fn(next => next.fail());
const fnTwo = jest.fn(next => next());
const onComplete = jest.fn();
const options = {
clearTimeout,
fail,
onComplete,
onException: () => {},
queueableFns: [{
fn: fnOne,
}, {
fn: fnTwo,
}],
setTimeout,
};
await queueRunner(options);
expect(fnOne).toHaveBeenCalled();
expect(fail).toHaveBeenCalled();
// Even if `fail` is called, the queue keeps running.
expect(fnTwo).toHaveBeenCalled();
expect(onComplete).toHaveBeenCalled();
});

it('passes errors to `onException`.', async () => {
const error = new Error('The error a test throws.');
const fnOne = jest.fn(() => {
throw error;
});
const fnTwo = jest.fn(next => next());
const onComplete = jest.fn();
const onException = jest.fn();
const options = {
clearTimeout,
fail: () => {},
onComplete,
onException,
queueableFns: [{
fn: fnOne,
}, {
fn: fnTwo,
}],
setTimeout,
};
await queueRunner(options);
expect(fnOne).toHaveBeenCalled();
expect(onException).toHaveBeenCalledWith(error);
// Even if one of them errors, the queue keeps running.
expect(fnTwo).toHaveBeenCalled();
expect(onComplete).toHaveBeenCalled();
});

it('passes an error to `onException` on timeout.', async () => {
const fnOne = jest.fn(next => {});
const fnTwo = jest.fn(next => next());
const onComplete = jest.fn();
const onException = jest.fn();
const options = {
clearTimeout,
fail: () => {},
onComplete,
onException,
queueableFns: [{
fn: fnOne,
// It times out in zero seconds.
timeout: () => 0,
}, {
fn: fnTwo,
}],
setTimeout,
};
await queueRunner(options);
expect(fnOne).toHaveBeenCalled();
expect(onException).toHaveBeenCalled();
// i.e. the `message` of the error passed to `onException`.
expect(onException.mock.calls[0][0].message).toEqual(
'Timeout - Async callback was not invoked within timeout specified ' +
'by jasmine.DEFAULT_TIMEOUT_INTERVAL.',
);
expect(fnTwo).toHaveBeenCalled();
expect(onComplete).toHaveBeenCalled();
});
});
25 changes: 5 additions & 20 deletions packages/jest-jasmine2/src/jasmine/Env.js
Expand Up @@ -32,6 +32,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* eslint-disable sort-keys */
'use strict';

const queueRunner = require('../queueRunner');

module.exports = function(j$) {
function Env(options) {
options = options || {};
Expand Down Expand Up @@ -135,19 +137,6 @@ module.exports = function(j$) {
return catchExceptions;
};

const maximumSpecCallbackDepth = 20;
let currentSpecCallbackDepth = 0;

function clearStack(fn) {
currentSpecCallbackDepth++;
if (currentSpecCallbackDepth >= maximumSpecCallbackDepth) {
currentSpecCallbackDepth = 0;
realSetTimeout(fn, 0);
} else {
fn();
}
}

const catchException = function(e) {
return j$.Spec.isPendingSpecException(e) || catchExceptions;
};
Expand Down Expand Up @@ -177,14 +166,10 @@ module.exports = function(j$) {

const queueRunnerFactory = function(options) {
options.catchException = catchException;
options.clearStack = options.clearStack || clearStack;
options.timeout = {
setTimeout: realSetTimeout,
clearTimeout: realClearTimeout,
};
options.clearTimeout = realClearTimeout;
options.fail = self.fail;

new j$.QueueRunner(options).execute();
options.setTimeout = realSetTimeout;
queueRunner(options);
};

const topSuite = new j$.Suite({
Expand Down
158 changes: 0 additions & 158 deletions packages/jest-jasmine2/src/jasmine/QueueRunner.js

This file was deleted.

0 comments on commit 98bc0a4

Please sign in to comment.