-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from oat-sa/release-0.5.0
Release 0.5.0
- Loading branch information
Showing
5 changed files
with
240 additions
and
2 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; under version 2 | ||
* of the License (non-upgradable). | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
* | ||
* Copyright (c) 2019 Open Assessment Technologies SA | ||
*/ | ||
|
||
/** | ||
* @author Jean-Sébastien Conan <jean-sebastien@taotesting.com> | ||
*/ | ||
|
||
/** | ||
* Watch a promise and raise a timeout if it takes more time than the expected amount of milliseconds. | ||
* If a timeout occurs, the promise is rejected with an Error containing the optional provided message, | ||
* and a `timeout property set to `true`. | ||
* | ||
* By default the timeout is set to 30 seconds. | ||
* | ||
* @example | ||
* promiseTimeout(new Promise((resolve, reject) => { | ||
* // ... | ||
* }).then(() => { | ||
* // ... | ||
* }).catch(err => { | ||
* if (err && err.timeout) { | ||
* // ... | ||
* } else { | ||
* // ... | ||
* } | ||
* }); | ||
* | ||
* promiseTimeout(new Promise((resolve, reject) => { | ||
* // ... | ||
* }).then(() => { | ||
* // ... | ||
* }).catch(err => { | ||
* if (err && err.timeout) { | ||
* // ... | ||
* } else { | ||
* // ... | ||
* } | ||
* }, { | ||
* timeout: 20000, // 20sec timout | ||
* message: 'A timeout occurred!' | ||
* }); | ||
* | ||
* @param {Promise} promise - The main promise to watch | ||
* @param {Object} [config] - Setup the watcher | ||
* @param {Number} [config.timeout] - Grace period to give to the main promise to complete, in milliseconds | ||
* @param {String} [config.message] - Message of the error returned if the timeout occurred | ||
* @returns {Promise} | ||
*/ | ||
function promiseTimeout(promise, {timeout = 30000, message = 'The process took too long!'} = {}) { | ||
return Promise.race([ | ||
promise, | ||
new Promise((resolve, reject) => { | ||
window.setTimeout(() => { | ||
const err = new Error(message); | ||
err.timeout = true; | ||
reject(err); | ||
}, timeout); | ||
}) | ||
]); | ||
} | ||
|
||
export default promiseTimeout; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<title>Test - Promise Timeout</title> | ||
<script type="text/javascript" src="/environment/require.js"></script> | ||
<script type="text/javascript"> | ||
require(['/environment/config.js'], function() { | ||
require(['qunitEnv'], function() { | ||
require(['test/core/promiseTimeout/test'], function() { | ||
QUnit.start(); | ||
}); | ||
}); | ||
}); | ||
</script> | ||
</head> | ||
<body> | ||
<div id="qunit"></div> | ||
<div id="qunit-fixture"></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
/** | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; under version 2 | ||
* of the License (non-upgradable). | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
* | ||
* Copyright (c) 2019 (original work) Open Assessment Technologies SA ; | ||
*/ | ||
define(['core/promiseTimeout'], function(promiseTimeout) { | ||
'use strict'; | ||
|
||
QUnit.module('promiseTimeout'); | ||
|
||
QUnit.test('module', function(assert) { | ||
var promise = Promise.resolve(); | ||
assert.expect(3); | ||
|
||
assert.equal(typeof promiseTimeout, 'function', 'The module exports a function'); | ||
assert.equal(promiseTimeout(promise) instanceof Promise, true, 'The factory returns a promise'); | ||
assert.notEqual(promiseTimeout(promise), promise, 'The factory creates a new promise on each call'); | ||
}); | ||
|
||
QUnit.test('resolved promise', function(assert) { | ||
var ready = assert.async(); | ||
assert.expect(1); | ||
|
||
promiseTimeout(Promise.resolve()) | ||
.then(function() { | ||
assert.ok(true, 'The promise is resolved'); | ||
}) | ||
.catch(function() { | ||
assert.ok(false, 'The promise should resolve'); | ||
}) | ||
.then(ready); | ||
}); | ||
|
||
QUnit.test('rejected promise', function(assert) { | ||
var ready = assert.async(); | ||
var error = new Error('This is a test'); | ||
assert.expect(3); | ||
|
||
promiseTimeout(Promise.reject(error)) | ||
.then(function() { | ||
assert.ok(false, 'The promise should not resolve'); | ||
}) | ||
.catch(function(err) { | ||
assert.ok(true, 'The promise should not resolve'); | ||
assert.equal(err, error, 'The expected error is thrown'); | ||
assert.ok(!err.timeout, 'No timeout occurred'); | ||
}) | ||
.then(ready); | ||
}); | ||
|
||
QUnit.test('long promise resolve', function(assert) { | ||
var ready = assert.async(); | ||
assert.expect(1); | ||
|
||
promiseTimeout(new Promise(function(resolve) { | ||
setTimeout(resolve, 100); | ||
}), {timeout: 200}) | ||
.then(function() { | ||
assert.ok(true, 'The promise is resolved'); | ||
}) | ||
.catch(function() { | ||
assert.ok(false, 'The promise should resolve'); | ||
}) | ||
.then(ready); | ||
}); | ||
|
||
QUnit.test('long rejected promise', function(assert) { | ||
var ready = assert.async(); | ||
var error = new Error('This is a test'); | ||
assert.expect(3); | ||
|
||
promiseTimeout(new Promise(function(resolve, reject) { | ||
setTimeout(function() { | ||
reject(error); | ||
}, 100); | ||
}), {timeout: 200}) | ||
.then(function() { | ||
assert.ok(false, 'The promise should not resolve'); | ||
}) | ||
.catch(function(err) { | ||
assert.ok(true, 'The promise should not resolve'); | ||
assert.equal(err, error, 'The expected error is thrown'); | ||
assert.ok(!err.timeout, 'No timeout occurred'); | ||
}) | ||
.then(ready); | ||
}); | ||
|
||
QUnit.test('timeout of rejected promise', function(assert) { | ||
var ready = assert.async(); | ||
var error = new Error('This is a test'); | ||
var message = 'A timeout occurred'; | ||
assert.expect(3); | ||
|
||
promiseTimeout(new Promise(function(resolve, reject) { | ||
setTimeout(function() { | ||
reject(error); | ||
}, 500); | ||
}), {timeout: 200, message: message}) | ||
.then(function() { | ||
assert.ok(false, 'The promise should not resolve'); | ||
}) | ||
.catch(function(err) { | ||
assert.ok(true, 'The promise should not resolve'); | ||
assert.equal(err.message, message, 'The expected message is attached'); | ||
assert.ok(err.timeout, 'A timeout occurred'); | ||
}) | ||
.then(ready); | ||
}); | ||
|
||
QUnit.test('timeout of resolved promise', function(assert) { | ||
var ready = assert.async(); | ||
var message = 'A timeout occurred'; | ||
assert.expect(3); | ||
|
||
promiseTimeout(new Promise(function(resolve) { | ||
setTimeout(resolve, 500); | ||
}), {timeout: 200, message: message}) | ||
.then(function() { | ||
assert.ok(false, 'The promise should not resolve'); | ||
}) | ||
.catch(function(err) { | ||
assert.ok(true, 'The promise should not resolve'); | ||
assert.equal(err.message, message, 'The expected message is attached'); | ||
assert.ok(err.timeout, 'A timeout occurred'); | ||
}) | ||
.then(ready); | ||
}); | ||
}); |