Skip to content

Commit

Permalink
Merge pull request #274 from step2yeung/gracefulExit
Browse files Browse the repository at this point in the history
Allow graceful exit when async iterator fails to get a module.
  • Loading branch information
stefanpenner authored Jun 3, 2019
2 parents 20c9d54 + da1207c commit 59263bb
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 17 deletions.
30 changes: 21 additions & 9 deletions addon-test-support/-private/async-iterator.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

const iteratorCompleteResponse = { done: true, value: null };

/**
* A class to iterate a sequencial set of asynchronous events.
*
Expand All @@ -17,6 +19,7 @@ export default class AsyncIterator {
// Set a timeout value from either url parameter or default timeout value, 15 s.
this._timeout = options.timeout || 15;
this._browserId = options.browserId;
this._emberExamExitOnError = options.emberExamExitOnError;

testem.on(this._response, this._boundHandleResponse);
}
Expand Down Expand Up @@ -88,20 +91,29 @@ export default class AsyncIterator {
/**
* Set a timeout to reject a promise if it doesn't get response within the timeout threshold.
*
* @param {*} reject
* @param {*} resolve
*/
_setTimeout(reject) {
_setTimeout(resolve, reject) {
clearTimeout(this.timeout);
this.timer = setTimeout(() => {
if (!this._waiting) {
return;
}
let err = new Error(
`EmberExam: Promise timed out after ${

if (this._emberExamExitOnError) {
let err = new Error(
`EmberExam: Promise timed out after ${
this._timeout
} s while waiting for response for ${this._request}`
);
reject(err);
} else {
// eslint-disable-next-line no-console
console.error(`EmberExam: Promise timed out after ${
this._timeout
} s while waiting for response for ${this._request}`
);
reject(err);
} s while waiting for response for ${this._request}. Closing browser to exit gracefully.`);
resolve(iteratorCompleteResponse);
}
}, this._timeout * 1000);
}

Expand All @@ -113,7 +125,7 @@ export default class AsyncIterator {
*/
next() {
if (this._done) {
return Promise.resolve({ done: true, value: null });
return Promise.resolve(iteratorCompleteResponse);
}
if (this._current) {
return this._current.promise;
Expand All @@ -123,7 +135,7 @@ export default class AsyncIterator {
let promise = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
this._setTimeout(reject);
this._setTimeout(resolve, reject);
});

this._current = {
Expand Down
5 changes: 3 additions & 2 deletions addon-test-support/-private/ember-exam-qunit-test-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ export default class EmberExamQUnitTestLoader extends TestLoader {
const nextModuleAsyncIterator = new AsyncIterator(this._testem, {
request: 'testem:next-module-request',
response: 'testem:next-module-response',
timeout: getUrlParams().get('asyncTimeout'),
browserId: getUrlParams().get('browser')
timeout: this._urlParams.get('asyncTimeout'),
browserId: this._urlParams.get('browser'),
emberExamExitOnError: this._urlParams.get('_emberExamExitOnError'),
});

const nextModuleHandler = () => {
Expand Down
4 changes: 2 additions & 2 deletions node-tests/acceptance/exam-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function getNumberOfTests(str) {
return match && parseInt(match[1], 10);
}

const TOTAL_NUM_TESTS = 47; // Total Number of tests without the global 'Ember.onerror validation tests'
const TOTAL_NUM_TESTS = 48; // Total Number of tests without the global 'Ember.onerror validation tests'

function getTotalNumberOfTests(output) {
// In ember-qunit 3.4.0, this new check was added: https://github.com/emberjs/ember-qunit/commit/a7e93c4b4b535dae62fed992b46c00b62bfc83f4
Expand Down Expand Up @@ -538,7 +538,7 @@ describe('Acceptance | Exam Command', function() {
assertOutput(output, 'Browser Id', ["2"]);
assert.equal(
getNumberOfTests(output),
23,
24,
'ran all of the tests for browser two'
);
});
Expand Down
22 changes: 18 additions & 4 deletions tests/unit/qunit/async-iterator-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,21 +146,35 @@ test('should dispose after iteration.', function(assert) {
});
});

test('should throw a timout error if request is not handled within 2s', function(assert) {
test('should resolve with iterator finishing if request is not handled within 2s', function(assert) {
assert.expect(1);
const done = assert.async();
const iteratorOfPromises = new AsyncIterator(this.testem, {
request: 'next-module-request',
response: 'next-module-response',
timeout: 2
});

iteratorOfPromises.next().catch(err => {
return iteratorOfPromises.next().then(res => {
assert.deepEqual(res.done, true);
});
});

test('should resolve a timeout error if request is not handled within 2s when emberExamExitOnError is true', function(assert) {
assert.expect(1);
const iteratorOfPromises = new AsyncIterator(this.testem, {
request: 'next-module-request',
response: 'next-module-response',
timeout: 2,
emberExamExitOnError: true,
});

return iteratorOfPromises.next().then(() => {
assert.ok(false, 'Promise should not resolve, expecting reject');
},err => {
assert.deepEqual(
err.message,
'EmberExam: Promise timed out after 2 s while waiting for response for next-module-request'
);
done();
});
});

Expand Down

0 comments on commit 59263bb

Please sign in to comment.