From a3308d229765ef6e7305ce5c7752d1a41e2d008d Mon Sep 17 00:00:00 2001 From: James Talmage Date: Fri, 13 Nov 2015 12:14:28 -0500 Subject: [PATCH] Handle empty results from test files. Fix #198 --- index.js | 1 + lib/babel.js | 15 +++++++++++++++ lib/fork.js | 13 ++++++++++++- test/fixture/empty.js | 8 ++++++++ test/fixture/immediate-0-exit.js | 1 + test/fixture/no-tests.js | 1 + test/test.js | 30 ++++++++++++++++++++++++++++++ 7 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 test/fixture/empty.js create mode 100644 test/fixture/immediate-0-exit.js create mode 100644 test/fixture/no-tests.js diff --git a/index.js b/index.js index fa1e4e000..29469f6fd 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,5 @@ 'use strict'; +require('./lib/babel').avaRequired(); var setImmediate = require('set-immediate-shim'); var hasFlag = require('has-flag'); var chalk = require('chalk'); diff --git a/lib/babel.js b/lib/babel.js index 8f78dd45c..78957dae3 100644 --- a/lib/babel.js +++ b/lib/babel.js @@ -24,11 +24,26 @@ var options = { ] }; +var avaRequired; + +module.exports = { + avaRequired: function () { + avaRequired = true; + } +}; + var transpiled = babel.transformFileSync(testPath, options); requireFromString(transpiled.code, testPath, { appendPaths: module.paths }); +if (!avaRequired) { + console.error('No tests found in ' + testPath + ', make sure to import "ava" at the top of your test file'); + setImmediate(function () { + process.exit(1); + }); +} + process.on('message', function (message) { if (message['ava-kill-command']) { process.exit(0); diff --git a/lib/fork.js b/lib/fork.js index 379650203..8700b86a3 100644 --- a/lib/fork.js +++ b/lib/fork.js @@ -34,8 +34,19 @@ module.exports = function (args) { ps.on('exit', function (code) { if (code > 0 && code !== 143) { reject(new Error(file + ' exited with a non-zero exit code: ' + code)); - } else { + } else if (testResults) { + if (!testResults.tests.length) { + testResults.stats.failCount++; + testResults.tests.push({ + duration: 0, + title: file, + error: new Error('No tests for ' + file), + type: 'test' + }); + } resolve(testResults); + } else { + reject(new Error('Never got test results from: ' + file)); } }); }); diff --git a/test/fixture/empty.js b/test/fixture/empty.js new file mode 100644 index 000000000..03d715446 --- /dev/null +++ b/test/fixture/empty.js @@ -0,0 +1,8 @@ +/* + __ + ____ _____ _______/ |_ ___.__. + _/ __ \ / \\____ \ __< | | + \ ___/| Y Y \ |_> > | \___ | + \___ >__|_| / __/|__| / ____| + \/ \/|__| \/ + */ diff --git a/test/fixture/immediate-0-exit.js b/test/fixture/immediate-0-exit.js new file mode 100644 index 000000000..dcbbff6c9 --- /dev/null +++ b/test/fixture/immediate-0-exit.js @@ -0,0 +1 @@ +process.exit(0); diff --git a/test/fixture/no-tests.js b/test/fixture/no-tests.js new file mode 100644 index 000000000..5be323f69 --- /dev/null +++ b/test/fixture/no-tests.js @@ -0,0 +1 @@ +import test from '../../'; diff --git a/test/test.js b/test/test.js index 2a7dee4d2..0491540f5 100644 --- a/test/test.js +++ b/test/test.js @@ -1087,3 +1087,33 @@ test('titles of both passing and failing tests and AssertionErrors are displayed t.end(); }); }); + +test('empty test files creates a failure with a helpful warning', function (t) { + t.plan(2); + + execCli('fixture/empty.js', function (err, stdout) { + t.ok(err); + t.ok(/No tests found.*?import "ava"/.test(stdout)); + t.end(); + }); +}); + +test('test file with no tests creates a failure with a helpful warning', function (t) { + t.plan(2); + + execCli('fixture/no-tests.js', function (err, stdout, stderr) { + t.ok(err); + t.ok(/No tests/.test(stderr)); + t.end(); + }); +}); + +test('test file that immediately exits with 0 exit code ', function (t) { + t.plan(2); + + execCli('fixture/immediate-0-exit.js', function (err, stdout, stderr) { + t.ok(err); + t.ok(/Never got test results/.test(stderr)); + t.end(); + }); +});