Skip to content

Commit a66bc0f

Browse files
committed
Split up cli.js tests
Tests from this file are now consistently timing out in TravisCI. Split across multiple files in the hope that this reduces the failure rate.
1 parent 9cdc29b commit a66bc0f

File tree

13 files changed

+964
-919
lines changed

13 files changed

+964
-919
lines changed

test/cli.js

Lines changed: 0 additions & 919 deletions
This file was deleted.

test/helper/cli.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
'use strict';
2+
const path = require('path');
3+
const childProcess = require('child_process');
4+
const getStream = require('get-stream');
5+
6+
const cliPath = path.join(__dirname, '../../cli.js');
7+
8+
function execCli(args, opts, cb) {
9+
let dirname;
10+
let env;
11+
12+
if (typeof opts === 'function') {
13+
cb = opts;
14+
dirname = path.resolve(__dirname, '..');
15+
env = {};
16+
} else {
17+
dirname = path.resolve(__dirname, '..', opts.dirname ? opts.dirname : '');
18+
env = opts.env || {};
19+
}
20+
21+
let child;
22+
let stdout;
23+
let stderr;
24+
25+
const processPromise = new Promise(resolve => {
26+
child = childProcess.spawn(process.execPath, [cliPath].concat(args), {
27+
cwd: dirname,
28+
env: Object.assign({CI: '1'}, env), // Force CI to ensure the correct reporter is selected
29+
// env,
30+
stdio: [null, 'pipe', 'pipe']
31+
});
32+
33+
child.on('close', (code, signal) => {
34+
if (code) {
35+
const err = new Error(`test-worker exited with a non-zero exit code: ${code}`);
36+
err.code = code;
37+
err.signal = signal;
38+
resolve(err);
39+
return;
40+
}
41+
42+
resolve(code);
43+
});
44+
45+
stdout = getStream(child.stdout);
46+
stderr = getStream(child.stderr);
47+
});
48+
49+
Promise.all([processPromise, stdout, stderr]).then(args => {
50+
cb.apply(null, args);
51+
});
52+
53+
return child;
54+
}
55+
exports.execCli = execCli;

test/integration/assorted.js

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
'use strict';
2+
const fs = require('fs');
3+
const childProcess = require('child_process');
4+
const path = require('path');
5+
const makeDir = require('make-dir');
6+
const stripAnsi = require('strip-ansi');
7+
const test = require('tap').test;
8+
const {execCli} = require('../helper/cli');
9+
10+
test('timeout', t => {
11+
execCli(['fixture/long-running.js', '-T', '1s'], (err, stdout) => {
12+
t.ok(err);
13+
t.match(stdout, /Exited because no new tests completed within the last 1000ms of inactivity/);
14+
t.end();
15+
});
16+
});
17+
18+
test('include anonymous functions in error reports', t => {
19+
execCli('fixture/error-in-anonymous-function.js', (err, stdout) => {
20+
t.ok(err);
21+
t.match(stdout, /test\/fixture\/error-in-anonymous-function\.js:4:8/);
22+
t.end();
23+
});
24+
});
25+
26+
test('--match works', t => {
27+
execCli(['-m=foo', '-m=bar', '-m=!baz', '-m=t* a* f*', '-m=!t* a* n* f*', 'fixture/matcher-skip.js'], err => {
28+
t.ifError(err);
29+
t.end();
30+
});
31+
});
32+
33+
['--tap', '-t'].forEach(tapFlag => {
34+
test(`${tapFlag} should produce TAP output`, t => {
35+
execCli([tapFlag, 'test.js'], {dirname: 'fixture/watcher'}, err => {
36+
t.ok(!err);
37+
t.end();
38+
});
39+
});
40+
});
41+
42+
test('handles NODE_PATH', t => {
43+
const nodePaths = `fixture/node-paths/modules${path.delimiter}fixture/node-paths/deep/nested`;
44+
45+
execCli('fixture/node-paths.js', {env: {NODE_PATH: nodePaths}}, err => {
46+
t.ifError(err);
47+
t.end();
48+
});
49+
});
50+
51+
test('works when no files are found', t => {
52+
execCli('!*', (err, stdout) => {
53+
t.is(err.code, 1);
54+
t.match(stdout, 'Couldn\'t find any files to test');
55+
t.end();
56+
});
57+
});
58+
59+
test('should warn ava is required without the cli', t => {
60+
childProcess.execFile(process.execPath, [path.resolve(__dirname, '../../index.js')], error => {
61+
t.ok(error);
62+
t.match(error.message, /Test files must be run with the AVA CLI/);
63+
t.end();
64+
});
65+
});
66+
67+
test('prefers local version of ava', t => {
68+
execCli('', {
69+
dirname: 'fixture/local-bin',
70+
env: {
71+
DEBUG: 'ava'
72+
}
73+
}, (err, stdout, stderr) => {
74+
t.ifError(err);
75+
t.match(stderr, 'Using local install of AVA');
76+
t.end();
77+
});
78+
});
79+
80+
test('workers ensure test files load the same version of ava', t => {
81+
const target = path.join(__dirname, '..', 'fixture', 'ava-paths', 'target');
82+
83+
// Copy the index.js so the testFile imports it. It should then load the correct AVA install.
84+
const targetInstall = path.join(target, 'node_modules/ava');
85+
makeDir.sync(targetInstall);
86+
fs.writeFileSync(
87+
path.join(targetInstall, 'index.js'),
88+
fs.readFileSync(path.join(__dirname, '../../index.js'))
89+
);
90+
91+
const testFile = path.join(target, 'test.js');
92+
execCli([testFile], {dirname: path.join('fixture', 'ava-paths', 'cwd')}, err => {
93+
t.ifError(err);
94+
t.end();
95+
});
96+
});
97+
98+
test('tests without assertions do not fail if failWithoutAssertions option is set to false', t => {
99+
execCli([], {dirname: 'fixture/pkg-conf/fail-without-assertions'}, err => {
100+
t.ifError(err);
101+
t.end();
102+
});
103+
});
104+
105+
test('--no-color disables formatting colors', t => {
106+
execCli(['--no-color', '--verbose', 'formatting-color.js'], {dirname: 'fixture'}, (err, stdout) => {
107+
t.ok(err);
108+
t.is(stripAnsi(stdout), stdout);
109+
t.end();
110+
});
111+
});
112+
113+
test('--color enables formatting colors', t => {
114+
execCli(['--color', '--verbose', 'formatting-color.js'], {dirname: 'fixture'}, (err, stdout) => {
115+
t.ok(err);
116+
t.isNot(stripAnsi(stdout), stdout);
117+
t.end();
118+
});
119+
});
120+
121+
test('sets NODE_ENV to test when it is not set', t => {
122+
execCli([path.join('fixture', 'node-env-test.js')], {env: {}}, (err, stdout) => {
123+
t.ifError(err);
124+
t.match(stdout, /1 test passed/);
125+
t.end();
126+
});
127+
});
128+
129+
test('doesn\'t set NODE_ENV when it is set', t => {
130+
execCli([path.join('fixture', 'node-env-foo.js')], {env: {NODE_ENV: 'foo'}}, (err, stdout) => {
131+
t.ifError(err);
132+
t.match(stdout, /1 test passed/);
133+
t.end();
134+
});
135+
});
136+
137+
test('additional arguments are forwarded to the worker', t => {
138+
execCli(['worker-argv.js', '--serial', '--', '--hello', 'world'], {dirname: 'fixture'}, err => {
139+
t.ifError(err);
140+
t.end();
141+
});
142+
});
143+
144+
test('--reset-cache resets cache', t => {
145+
const cacheDir = path.join(__dirname, '..', 'fixture', 'reset-cache', 'node_modules', '.cache', 'ava');
146+
execCli([], {dirname: 'fixture/reset-cache'}, err => {
147+
t.ifError(err);
148+
t.true(fs.readdirSync(cacheDir).length > 0);
149+
150+
execCli(['--reset-cache'], {dirname: 'fixture/reset-cache'}, err => {
151+
t.ifError(err);
152+
t.true(fs.readdirSync(cacheDir).length === 0);
153+
t.end();
154+
});
155+
});
156+
});

test/integration/babel.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
const test = require('tap').test;
3+
const figures = require('figures');
4+
const pkg = require('../../package.json');
5+
const {execCli} = require('../helper/cli');
6+
7+
for (const which of [
8+
'bad-key',
9+
'bad-shortcut',
10+
'array-test-options',
11+
'false-test-options',
12+
'null-test-options',
13+
'null-extensions',
14+
'obj-extensions',
15+
'string-extensions',
16+
'non-string-value-extensions',
17+
'empty-string-value-extensions'
18+
]) {
19+
test(`validates babel config: ${which}`, t => {
20+
execCli(['es2015.js'], {dirname: `fixture/invalid-babel-config/${which}`}, (err, stdout, stderr) => {
21+
t.ok(err);
22+
23+
let expectedOutput = '\n';
24+
expectedOutput += figures.cross + ' Unexpected Babel configuration for AVA.';
25+
expectedOutput += ` See https://github.com/avajs/ava/blob/v${pkg.version}/docs/recipes/babel.md for allowed values.`;
26+
expectedOutput += '\n';
27+
28+
t.is(stderr, expectedOutput);
29+
t.end();
30+
});
31+
});
32+
}

test/integration/compilation.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
'use strict';
2+
const stripAnsi = require('strip-ansi');
3+
const test = require('tap').test;
4+
const {execCli} = require('../helper/cli');
5+
6+
test('precompiler require hook does not apply to source files', t => {
7+
t.plan(3);
8+
9+
execCli('fixture/babel-hook.js', (err, stdout) => {
10+
t.ok(err);
11+
t.is(err.code, 1);
12+
t.match(stdout, /Unexpected (token|reserved word)/);
13+
t.end();
14+
});
15+
});
16+
17+
test('skips test file compilation when babel=false and compileEnhancements=false', t => {
18+
execCli(['import.js'], {dirname: 'fixture/no-babel-compilation'}, (err, stdout) => {
19+
t.ok(err);
20+
t.match(stdout, /SyntaxError: Unexpected (reserved word|token import|identifier)/);
21+
t.end();
22+
});
23+
});
24+
25+
test('skips helper file compilation when babel=false and compileEnhancements=false', t => {
26+
execCli(['require-helper.js'], {dirname: 'fixture/no-babel-compilation'}, (err, stdout) => {
27+
t.ifError(err);
28+
t.match(stdout, /1 test passed/);
29+
t.end();
30+
});
31+
});
32+
33+
test('no power-assert when babel=false and compileEnhancements=false', t => {
34+
execCli(['no-power-assert.js'], {dirname: 'fixture/no-babel-compilation'}, (err, stdout) => {
35+
t.ok(err);
36+
t.notMatch(stripAnsi(stdout), /bool\n.*=> false/);
37+
t.end();
38+
});
39+
});
40+
41+
test('skips stage-4 transform when babel=false and compileEnhancements=true', t => {
42+
execCli(['import.js'], {dirname: 'fixture/just-enhancement-compilation'}, (err, stdout) => {
43+
t.ok(err);
44+
t.match(stdout, /SyntaxError: Unexpected (reserved word|token import|identifier)/);
45+
t.end();
46+
});
47+
});
48+
49+
test('power-assert when babel=false and compileEnhancements=true', t => {
50+
execCli(['power-assert.js'], {dirname: 'fixture/just-enhancement-compilation'}, (err, stdout) => {
51+
t.ok(err);
52+
t.match(stripAnsi(stdout), /bool\n.*=> false/);
53+
t.end();
54+
});
55+
});
56+
57+
test('power-assert with custom extension and no regular babel pipeline', t => {
58+
execCli(['.'], {dirname: 'fixture/just-enhancement-compilation/custom-extension'}, (err, stdout) => {
59+
t.ok(err);
60+
t.match(stripAnsi(stdout), /bool\n.*=> false/);
61+
t.end();
62+
});
63+
});
64+
65+
test('workers load compiled helpers if in the require configuration', t => {
66+
execCli(['test/verify.js'], {dirname: 'fixture/require-compiled-helper'}, err => {
67+
t.ifError(err);
68+
t.end();
69+
});
70+
});

test/integration/concurrency.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use strict';
2+
const test = require('tap').test;
3+
const {execCli} = require('../helper/cli');
4+
5+
['--concurrency', '-c'].forEach(concurrencyFlag => {
6+
test(`bails when ${concurrencyFlag} is provided without value`, t => {
7+
execCli(['test.js', concurrencyFlag], {dirname: 'fixture/concurrency'}, (err, stdout, stderr) => {
8+
t.is(err.code, 1);
9+
t.match(stderr, 'The --concurrency or -c flag must be provided with a nonnegative integer.');
10+
t.end();
11+
});
12+
});
13+
});
14+
15+
['--concurrency', '-c'].forEach(concurrencyFlag => {
16+
test(`bails when ${concurrencyFlag} is provided with an input that is a string`, t => {
17+
execCli([`${concurrencyFlag}=foo`, 'test.js', concurrencyFlag], {dirname: 'fixture/concurrency'}, (err, stdout, stderr) => {
18+
t.is(err.code, 1);
19+
t.match(stderr, 'The --concurrency or -c flag must be provided with a nonnegative integer.');
20+
t.end();
21+
});
22+
});
23+
});
24+
25+
['--concurrency', '-c'].forEach(concurrencyFlag => {
26+
test(`bails when ${concurrencyFlag} is provided with an input that is a float`, t => {
27+
execCli([`${concurrencyFlag}=4.7`, 'test.js', concurrencyFlag], {dirname: 'fixture/concurrency'}, (err, stdout, stderr) => {
28+
t.is(err.code, 1);
29+
t.match(stderr, 'The --concurrency or -c flag must be provided with a nonnegative integer.');
30+
t.end();
31+
});
32+
});
33+
});
34+
35+
['--concurrency', '-c'].forEach(concurrencyFlag => {
36+
test(`bails when ${concurrencyFlag} is provided with an input that is negative`, t => {
37+
execCli([`${concurrencyFlag}=-1`, 'test.js', concurrencyFlag], {dirname: 'fixture/concurrency'}, (err, stdout, stderr) => {
38+
t.is(err.code, 1);
39+
t.match(stderr, 'The --concurrency or -c flag must be provided with a nonnegative integer.');
40+
t.end();
41+
});
42+
});
43+
});
44+
45+
['--concurrency', '-c'].forEach(concurrencyFlag => {
46+
test(`works when ${concurrencyFlag} is provided with a value`, t => {
47+
execCli([`${concurrencyFlag}=1`, 'test.js'], {dirname: 'fixture/concurrency'}, err => {
48+
t.ifError(err);
49+
t.end();
50+
});
51+
});
52+
});

0 commit comments

Comments
 (0)