Skip to content

Commit

Permalink
add timeout functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
vdemedes committed Mar 17, 2016
1 parent efc89fd commit 8de33a1
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 28 deletions.
31 changes: 30 additions & 1 deletion cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var Promise = require('bluebird');
var pkgConf = require('pkg-conf');
var chalk = require('chalk');
var isCi = require('is-ci');
var ms = require('ms');
var colors = require('./lib/colors');
var verboseReporter = require('./lib/reporters/verbose');
var miniReporter = require('./lib/reporters/mini');
Expand Down Expand Up @@ -69,6 +70,7 @@ var cli = meow([
' --match, -m Only run tests with matching title (Can be repeated)',
' --watch, -w Re-run tests when tests and source files change',
' --source, -S Pattern to match source files so tests can be re-run (Can be repeated)',
' --timeout, -T Set global timeout',
'',
'Examples',
' ava',
Expand All @@ -84,6 +86,7 @@ var cli = meow([
string: [
'_',
'require',
'timeout',
'source',
'match'
],
Expand All @@ -102,7 +105,8 @@ var cli = meow([
s: 'serial',
m: 'match',
w: 'watch',
S: 'source'
S: 'source',
T: 'timeout'
}
});

Expand Down Expand Up @@ -153,6 +157,27 @@ if (files.length === 0) {
];
}

var timeout;
var timer;

function restartTimer() {
clearTimeout(timer);

timer = setTimeout(onTimeout, timeout);
}

function onTimeout() {
logger.finish();
console.log(' ' + colors.error(figures.cross) + ' Exited because no new tests completed within last ' + cli.flags.timeout + ' of inactivity.');
logger.exit(1);
}

if (cli.flags.timeout && !cli.flags.watch) {
timeout = ms(cli.flags.timeout);

api.on('test', restartTimer);
}

if (cli.flags.watch) {
try {
var watcher = new Watcher(logger, api, files, arrify(cli.flags.source));
Expand All @@ -168,6 +193,10 @@ if (cli.flags.watch) {
}
}
} else {
if (cli.flags.timeout) {
restartTimer();
}

api.run(files)
.then(function () {
logger.finish();
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
"max-timeout": "^1.0.0",
"md5-hex": "^1.2.0",
"meow": "^3.7.0",
"ms": "^0.7.1",
"multimatch": "^2.1.0",
"object-assign": "^4.0.1",
"observable-to-promise": "^0.3.0",
Expand Down
15 changes: 15 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ $ ava --help
--match, -m Only run tests with matching title (Can be repeated)',
--watch, -w Re-run tests when tests and source files change
--source, -S Pattern to match source files so tests can be re-run (Can be repeated)
--timeout, -T Set global timeout

Examples
ava
Expand Down Expand Up @@ -679,6 +680,20 @@ AVA automatically removes unrelated lines in stack traces, allowing you to find

<img src="media/stack-traces.png" width="300">

### Global timeout

A global timeout can be set via `--timeout` option.
Timeout in AVA behaves differently than in other test frameworks.
AVA resets a timer after each test, forcing tests to quit if no new test results received within specified "timeout time".

You can set timeouts in a human-readable way:

```
$ ava --timeout 10s # 10 seconds
$ ava --timeout 2m # 2 minutes
$ ava --timeout 100 # 100 milliseconds
```

## API

### `test([title], callback)`
Expand Down
8 changes: 8 additions & 0 deletions test/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ test('disallow invalid babel config shortcuts', function (t) {
});
});

test('timeout', function (t) {
execCli(['fixture/long-running.js', '-T', '1s'], function (err, stdout) {
t.ok(err);
t.match(stdout, /Exited because no new tests completed within last 1s of inactivity/);
t.end();
});
});

test('throwing a named function will report the to the console', function (t) {
execCli('fixture/throw-named-function.js', function (err, stdout, stderr) {
t.ok(err);
Expand Down
30 changes: 4 additions & 26 deletions test/fixture/long-running.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,9 @@
import test from '../../';
import signalExit from 'signal-exit';

test.cb('long running', t => {
t.plan(1);

signalExit(() => {
// simulate an exit hook that lasts a short while
const start = Date.now();

while (Date.now() - start < 2000) {
// synchronously wait for 2 seconds
}

process.send({
name: 'cleanup-completed',
data: {completed: true},
ava: true
});
}, {alwaysLast: true});
test.cb('slow', t => {
setTimeout(t.end, 5000);
});

setTimeout(() => {
t.ok(true);
t.end();
});
test('fast', t => {

setTimeout(() => {
// this would keep the process running for a long time
console.log('I\'m gonna live forever!!');
}, 15000);
});
31 changes: 31 additions & 0 deletions test/fixture/slow-exit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import test from '../../';
import signalExit from 'signal-exit';

test.cb('long running', t => {
t.plan(1);

signalExit(() => {
// simulate an exit hook that lasts a short while
const start = Date.now();

while (Date.now() - start < 2000) {
// synchronously wait for 2 seconds
}

process.send({
name: 'cleanup-completed',
data: {completed: true},
ava: true
});
}, {alwaysLast: true});

setTimeout(() => {
t.ok(true);
t.end();
});

setTimeout(() => {
// this would keep the process running for a long time
console.log('I\'m gonna live forever!!');
}, 15000);
});
2 changes: 1 addition & 1 deletion test/fork.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ test('exit after tests are finished', function (t) {
var start = Date.now();
var cleanupCompleted = false;

fork(fixture('long-running.js'))
fork(fixture('slow-exit.js'))
.run({})
.on('exit', function () {
t.true(Date.now() - start < 10000, 'test waited for a pending setTimeout');
Expand Down

0 comments on commit 8de33a1

Please sign in to comment.