From 7b6e578dce32a6561e61ed6e2be6de8237b37800 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 17 Dec 2018 10:35:49 +0100 Subject: [PATCH] Use newer ES syntax where possible As detected via XO. Also apply other XO fixes. --- api.js | 11 +++--- bench/run.js | 2 +- lib/assert.js | 10 +++--- lib/ava-files.js | 7 ++-- lib/babel-pipeline.js | 5 +++ lib/chalk.js | 3 ++ lib/code-excerpt.js | 7 ++-- lib/context-ref.js | 1 + lib/create-chain.js | 12 ++++--- lib/enhance-assert.js | 4 ++- lib/extensions.js | 1 + lib/load-config.js | 4 +++ lib/reporters/format-serialized-error.js | 1 + lib/reporters/improper-usage-messages.js | 8 ++--- lib/reporters/mini.js | 23 +++++++++++- lib/reporters/tap.js | 6 ++++ lib/reporters/verbose.js | 21 ++++++++++- lib/reporters/while-corked.js | 5 +-- lib/run-status.js | 22 +++++++----- lib/runner.js | 9 +++-- lib/serialize-error.js | 5 +++ lib/snapshot-manager.js | 18 ++++++---- lib/test.js | 10 ++++-- lib/watcher.js | 4 ++- lib/worker/dependency-tracker.js | 4 +++ lib/worker/fake-tty.js | 2 +- lib/worker/ipc.js | 3 ++ lib/worker/main.js | 5 +-- lib/worker/options.js | 3 ++ lib/worker/precompiler-hook.js | 1 + package-lock.json | 36 +++++++++---------- package.json | 6 +--- test/api.js | 7 ++-- test/assert.js | 7 +++- test/ava-files.js | 7 ++-- test/beautify-stack.js | 2 +- test/code-excerpt.js | 2 +- test/fixture/babel-plugin-test-capitalizer.js | 2 +- test/fixture/babel-plugin-test-doubler.js | 4 +-- test/fixture/formatting.js | 3 ++ test/fixture/report/regular/test.js | 2 ++ test/fixture/trigger-worker-exception/hack.js | 2 ++ test/helper/cli.js | 3 +- test/helper/report.js | 2 ++ test/helper/tty-stream.js | 3 ++ test/hooks.js | 2 +- test/integration/assorted.js | 2 +- test/integration/babel.js | 2 +- test/integration/compilation.js | 2 +- test/integration/concurrency.js | 2 +- test/integration/config.js | 2 +- test/integration/extensions.js | 2 +- test/integration/node-assertions.js | 2 +- test/integration/parallel-runs.js | 2 +- test/integration/repl.js | 2 +- test/integration/snapshots.js | 6 +++- test/integration/stack-traces.js | 2 +- test/integration/stalled.js | 2 +- test/integration/t-throws.js | 2 +- test/integration/tty.js | 2 +- test/integration/watcher.js | 17 ++++----- test/observable.js | 2 +- test/profile.js | 2 +- test/promise.js | 2 +- test/reporters/improper-usage-messages.js | 2 +- test/reporters/mini.js | 2 +- test/reporters/mini.regular.log | 22 ++++++------ test/reporters/prefix-title.js | 2 +- test/reporters/tap.js | 2 +- test/reporters/tap.regular.log | 2 +- test/reporters/verbose.js | 2 +- test/reporters/verbose.regular.log | 22 ++++++------ test/runner.js | 30 +++++++++------- test/serialize-error.js | 2 +- test/test.js | 3 +- test/watcher.js | 21 ++++++----- 76 files changed, 305 insertions(+), 169 deletions(-) diff --git a/api.js b/api.js index fc71adcf0..4da50c88f 100644 --- a/api.js +++ b/api.js @@ -45,9 +45,8 @@ class Api extends Emittery { this._precompiler = null; } - run(files, runtimeOptions) { + run(files, runtimeOptions = {}) { const apiOptions = this.options; - runtimeOptions = runtimeOptions || {}; // Each run will have its own status. It can only be created when test files // have been found. @@ -161,9 +160,10 @@ class Api extends Emittery { if (cachePath) { acc[realpath] = cachePath; } - } catch (err) { - throw Object.assign(err, {file}); + } catch (error) { + throw Object.assign(error, {file}); } + return acc; }, {}) }; @@ -175,6 +175,7 @@ class Api extends Emittery { if (apiOptions.concurrency > 0) { concurrency = apiOptions.concurrency; } + if (apiOptions.serial) { concurrency = 1; } @@ -198,6 +199,7 @@ class Api extends Emittery { } else { options.precompiled = {}; } + if (runtimeOptions.updateSnapshots) { // Don't use in Object.assign() since it'll override options.updateSnapshots even when false. options.updateSnapshots = true; @@ -245,6 +247,7 @@ class Api extends Emittery { filename => { throw new Error(`Cannot apply full precompilation, possible bad usage: ${filename}`); }; + let precompileEnhancementsOnly = () => null; if (compileEnhancements) { precompileEnhancementsOnly = this.options.extensions.enhancementsOnly.length > 0 ? diff --git a/bench/run.js b/bench/run.js index 723b45295..e87d7d27e 100644 --- a/bench/run.js +++ b/bench/run.js @@ -101,7 +101,7 @@ for (let i = 0; i < 11; i++) { const results = {}; Promise.each(combined, definition => { - const args = definition.args; + const {args} = definition; return runTests(args).then(result => { const key = result.args.join(' '); diff --git a/lib/assert.js b/lib/assert.js index 77829a82c..9e9d78046 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -221,10 +221,7 @@ function assertExpectations({assertion, actual, expectations, message, prefix, s } function wrapAssertions(callbacks) { - const pass = callbacks.pass; - const pending = callbacks.pending; - const fail = callbacks.fail; - + const {pass, pending, fail} = callbacks; const noop = () => {}; const assertions = { @@ -336,6 +333,7 @@ function wrapAssertions(callbacks) { try { retval.catch(noop); } catch (_) {} + fail(this, new AssertionError({ assertion: 'throws', message, @@ -539,6 +537,7 @@ function wrapAssertions(callbacks) { } else if (optionsOrMessage) { options.id = optionsOrMessage.id; } + options.expected = expected; options.message = message; @@ -633,6 +632,7 @@ function wrapAssertions(callbacks) { values: [formatWithLabel('Called with:', string)] }); } + if (!(regex instanceof RegExp)) { throw new AssertionError({ assertion: 'regex', @@ -663,6 +663,7 @@ function wrapAssertions(callbacks) { values: [formatWithLabel('Called with:', string)] }); } + if (!(regex instanceof RegExp)) { throw new AssertionError({ assertion: 'notRegex', @@ -687,4 +688,5 @@ function wrapAssertions(callbacks) { return Object.assign(assertions, enhancedAssertions); } + exports.wrapAssertions = wrapAssertions; diff --git a/lib/ava-files.js b/lib/ava-files.js index f9d199650..f23f5d0ee 100644 --- a/lib/ava-files.js +++ b/lib/ava-files.js @@ -101,9 +101,7 @@ const getDefaultIgnorePatterns = () => defaultIgnore.map(dir => `${dir}/**/*`); const matchable = process.platform === 'win32' ? slash : (path => path); class AvaFiles { - constructor(options) { - options = options || {}; - + constructor(options = {}) { let files = (options.files || []).map(file => { // `./` should be removed from the beginning of patterns because // otherwise they won't match change events from Chokidar @@ -121,6 +119,7 @@ class AvaFiles { if (files.length === 0) { files = defaultIncludePatterns(this.extensionPattern); } + this.files = files; this.sources = options.sources || []; this.cwd = options.cwd || process.cwd(); @@ -202,7 +201,7 @@ class AvaFiles { } isTest(filePath) { - const excludePatterns = this.excludePatterns; + const {excludePatterns} = this; const initialPatterns = this.files.concat(excludePatterns); // Like in `api.js`, tests must be `.js` files and not start with `_` diff --git a/lib/babel-pipeline.js b/lib/babel-pipeline.js index 0c5af5581..a00954f85 100644 --- a/lib/babel-pipeline.js +++ b/lib/babel-pipeline.js @@ -114,6 +114,7 @@ function hashPartialTestConfig({babelrc, config, options: {plugins, presets}}, p inputs.push(stripBomBuf(fs.readFileSync(babelrc))); } } + if (config) { inputs.push(config, stripBomBuf(fs.readFileSync(config))); } @@ -196,16 +197,20 @@ function build(projectDir, cacheDir, userOptions, compileEnhancements) { if (!testOptions.plugins.some(containsAsyncGenerators)) { // TODO: Remove once Babel can parse this syntax unaided. testOptions.plugins.unshift(createConfigItem('@babel/plugin-syntax-async-generators', 'plugin')); } + if (!testOptions.plugins.some(containsObjectRestSpread)) { // TODO: Remove once Babel can parse this syntax unaided. testOptions.plugins.unshift(createConfigItem('@babel/plugin-syntax-object-rest-spread', 'plugin')); } + if (!testOptions.plugins.some(containsOptionalCatchBinding)) { // TODO: Remove once Babel can parse this syntax unaided. testOptions.plugins.unshift(createConfigItem('@babel/plugin-syntax-optional-catch-binding', 'plugin')); } + if (ensureStage4 && !testOptions.presets.some(containsStage4)) { // Apply last. testOptions.presets.unshift(createConfigItem('../stage-4', 'preset')); } + if (compileEnhancements && !testOptions.presets.some(containsTransformTestFiles)) { // Apply first. testOptions.presets.push(createConfigItem('@ava/babel-preset-transform-test-files', 'preset', {powerAssert: true})); diff --git a/lib/chalk.js b/lib/chalk.js index 5500e8f28..01d6de022 100644 --- a/lib/chalk.js +++ b/lib/chalk.js @@ -6,12 +6,15 @@ exports.get = () => { if (!ctx) { throw new Error('Chalk has not yet been configured'); } + return ctx; }; + exports.set = options => { if (ctx) { throw new Error('Chalk has already been configured'); } + ctx = new Chalk(options); return ctx; }; diff --git a/lib/code-excerpt.js b/lib/code-excerpt.js index c63112962..75ef45fd8 100644 --- a/lib/code-excerpt.js +++ b/lib/code-excerpt.js @@ -8,15 +8,12 @@ const chalk = require('./chalk').get(); const formatLineNumber = (lineNumber, maxLineNumber) => ' '.repeat(Math.max(0, String(maxLineNumber).length - String(lineNumber).length)) + lineNumber; -module.exports = (source, options) => { +module.exports = (source, options = {}) => { if (!source.isWithinProject || source.isDependency) { return null; } - const file = source.file; - const line = source.line; - - options = options || {}; + const {file, line} = source; const maxWidth = options.maxWidth || 80; let contents; diff --git a/lib/context-ref.js b/lib/context-ref.js index 5529bfc3d..a3d3edf23 100644 --- a/lib/context-ref.js +++ b/lib/context-ref.js @@ -31,6 +31,7 @@ class LateBinding extends ContextRef { if (!this.bound) { this.set(clone(this.ref.get())); } + return super.get(); } diff --git a/lib/create-chain.js b/lib/create-chain.js index 5f567f4d4..f512f8291 100644 --- a/lib/create-chain.js +++ b/lib/create-chain.js @@ -2,9 +2,10 @@ const chainRegistry = new WeakMap(); function startChain(name, call, defaults) { - const fn = function () { - call(Object.assign({}, defaults), Array.from(arguments)); + const fn = (...args) => { + call(Object.assign({}, defaults), args); }; + Object.defineProperty(fn, 'name', {value: name}); chainRegistry.set(fn, {call, defaults, fullName: name}); return fn; @@ -15,9 +16,10 @@ function extendChain(prev, name, flag) { flag = name; } - const fn = function () { - callWithFlag(prev, flag, Array.from(arguments)); + const fn = (...args) => { + callWithFlag(prev, flag, args); }; + const fullName = `${chainRegistry.get(prev).fullName}.${name}`; Object.defineProperty(fn, 'name', {value: fullName}); prev[name] = fn; @@ -55,6 +57,7 @@ function createHookChain(hook, isAfterHook) { extendChain(hook.always, 'skip', 'skipped'); extendChain(hook.always.cb, 'skip', 'skipped'); } + return hook; } @@ -107,4 +110,5 @@ function createChain(fn, defaults) { return root; } + module.exports = createChain; diff --git a/lib/enhance-assert.js b/lib/enhance-assert.js index ac8e6d735..ee8db37c2 100644 --- a/lib/enhance-assert.js +++ b/lib/enhance-assert.js @@ -37,10 +37,11 @@ const enhanceAssert = (pass, fail, assertions) => { return empower(assertions, { destructive: true, onError(event) { - const error = event.error; + const {error} = event; if (event.powerAssertContext) { // Context may be missing in internal tests. error.statements = formatter(event.powerAssertContext); } + fail(this, error); }, onSuccess() { @@ -50,4 +51,5 @@ const enhanceAssert = (pass, fail, assertions) => { bindReceiver: false }); }; + module.exports = enhanceAssert; diff --git a/lib/extensions.js b/lib/extensions.js index 5a87ff379..a73a6acd8 100644 --- a/lib/extensions.js +++ b/lib/extensions.js @@ -19,6 +19,7 @@ module.exports = (enhancementsOnly, babelConfig) => { seen.add('js'); full.push('js'); } + if (!babelConfig && enhancementsOnly.length === 0) { seen.add('js'); enhancementsOnly.push('js'); diff --git a/lib/load-config.js b/lib/load-config.js index fcfc8cecd..03789f933 100644 --- a/lib/load-config.js +++ b/lib/load-config.js @@ -39,6 +39,7 @@ function loadConfig(defaults = {}) { if (fileConf && typeof fileConf.then === 'function') { throw new TypeError('ava.config.js must not export a promise'); } + if (!isPlainObject(fileConf) && typeof fileConf !== 'function') { throw new TypeError('ava.config.js must export a plain object or factory function'); } @@ -48,10 +49,12 @@ function loadConfig(defaults = {}) { if (fileConf && typeof fileConf.then === 'function') { throw new TypeError('Factory method exported by ava.config.js must not return a promise'); } + if (!isPlainObject(fileConf)) { throw new TypeError('Factory method exported by ava.config.js must return a plain object'); } } + if ('ava' in fileConf) { throw new Error('Encountered \'ava\' property in ava.config.js; avoid wrapping the configuration'); } @@ -59,4 +62,5 @@ function loadConfig(defaults = {}) { return Object.assign({}, defaults, fileConf, packageConf, {projectDir}); } + module.exports = loadConfig; diff --git a/lib/reporters/format-serialized-error.js b/lib/reporters/format-serialized-error.js index a5af5e9ea..d9cfe2659 100644 --- a/lib/reporters/format-serialized-error.js +++ b/lib/reporters/format-serialized-error.js @@ -23,4 +23,5 @@ function formatSerializedError(error) { formatted = trimOffNewlines(formatted); return {formatted, printMessage}; } + module.exports = formatSerializedError; diff --git a/lib/reporters/improper-usage-messages.js b/lib/reporters/improper-usage-messages.js index b974b0734..3a158ac49 100644 --- a/lib/reporters/improper-usage-messages.js +++ b/lib/reporters/improper-usage-messages.js @@ -7,7 +7,7 @@ exports.forError = error => { return null; } - const assertion = error.assertion; + const {assertion} = error; if (assertion === 'throws' || assertion === 'notThrows') { return `Try wrapping the first argument to \`t.${assertion}()\` in a function: @@ -19,8 +19,7 @@ Visit the following URL for more details: } if (assertion === 'snapshot') { - const name = error.improperUsage.name; - const snapPath = error.improperUsage.snapPath; + const {name, snapPath} = error.improperUsage; if (name === 'ChecksumError') { return `The snapshot file is corrupted. @@ -39,8 +38,7 @@ Please run AVA again with the ${chalk.cyan('--update-snapshots')} flag to upgrad } if (name === 'VersionMismatchError') { - const snapVersion = error.improperUsage.snapVersion; - const expectedVersion = error.improperUsage.expectedVersion; + const {snapVersion, expectedVersion} = error.improperUsage; const upgradeMessage = snapVersion < expectedVersion ? `Please run AVA again with the ${chalk.cyan('--update-snapshots')} flag to upgrade.` : 'You should upgrade AVA.'; diff --git a/lib/reporters/mini.js b/lib/reporters/mini.js index 1d135a84e..e129aafbd 100644 --- a/lib/reporters/mini.js +++ b/lib/reporters/mini.js @@ -47,6 +47,7 @@ class LineWriter extends stream.Writable { for (const piece of pieces) { this.dest.write(piece.chunk); } + this._writeWithSpinner(last.chunk.toString('utf8')); callback(); } @@ -153,6 +154,7 @@ class MiniReporter { } else { this.writeWithCounts(colors.error(`${figures.cross} Internal error`)); } + break; case 'missing-ava-import': this.filesWithMissingAvaImports.add(evt.testFile); @@ -172,6 +174,7 @@ class MiniReporter { if (evt.knownFailing) { this.knownFailures.push(evt); } + this.writeTestSummary(evt); break; case 'timeout': @@ -187,12 +190,14 @@ class MiniReporter { if (this.stats.byFile.get(evt.testFile).declaredTests === 0) { this.filesWithoutDeclaredTests.add(evt.testFile); } + break; case 'worker-finished': if (this.stats.byFile.get(evt.testFile).declaredTests === 0) { this.filesWithoutDeclaredTests.add(evt.testFile); this.writeWithCounts(colors.error(`${figures.cross} No tests found in ${path.relative('.', evt.testFile)}`)); } + break; case 'worker-stderr': case 'worker-stdout': @@ -238,20 +243,25 @@ class MiniReporter { str += os.EOL + colors.pass(`${this.stats.passedTests} passed`) + firstLinePostfix; firstLinePostfix = ''; } + if (this.stats.passedKnownFailingTests > 0) { str += os.EOL + colors.error(`${this.stats.passedKnownFailingTests} ${plur('known failure', this.stats.passedKnownFailingTests)}`); } + if (this.stats.failedHooks > 0) { str += os.EOL + colors.error(`${this.stats.failedHooks} ${plur('hook', this.stats.failedHooks)} failed`) + firstLinePostfix; firstLinePostfix = ''; } + if (this.stats.failedTests > 0) { str += os.EOL + colors.error(`${this.stats.failedTests} ${plur('test', this.stats.failedTests)} failed`) + firstLinePostfix; firstLinePostfix = ''; } + if (this.stats.skippedTests > 0) { str += os.EOL + colors.skip(`${this.stats.skippedTests} skipped`); } + if (this.stats.todoTests > 0) { str += os.EOL + colors.todo(`${this.stats.todoTests} todo`); } @@ -299,7 +309,7 @@ class MiniReporter { } if (evt.err.stack) { - const stack = evt.err.stack; + const {stack} = evt.err; if (stack.includes(os.EOL)) { this.lineWriter.writeLine(); this.lineWriter.writeLine(colors.errorStack(stack)); @@ -383,29 +393,37 @@ class MiniReporter { this.lineWriter.writeLine(colors.error(`${this.stats.failedHooks} ${plur('hook', this.stats.failedHooks)} failed`) + firstLinePostfix); firstLinePostfix = ''; } + if (this.stats.failedTests > 0) { this.lineWriter.writeLine(colors.error(`${this.stats.failedTests} ${plur('test', this.stats.failedTests)} failed`) + firstLinePostfix); firstLinePostfix = ''; } + if (this.stats.failedHooks === 0 && this.stats.failedTests === 0 && this.stats.passedTests > 0) { this.lineWriter.writeLine(colors.pass(`${this.stats.passedTests} ${plur('test', this.stats.passedTests)} passed`) + firstLinePostfix); firstLinePostfix = ''; } + if (this.stats.passedKnownFailingTests > 0) { this.lineWriter.writeLine(colors.error(`${this.stats.passedKnownFailingTests} ${plur('known failure', this.stats.passedKnownFailingTests)}`)); } + if (this.stats.skippedTests > 0) { this.lineWriter.writeLine(colors.skip(`${this.stats.skippedTests} ${plur('test', this.stats.skippedTests)} skipped`)); } + if (this.stats.todoTests > 0) { this.lineWriter.writeLine(colors.todo(`${this.stats.todoTests} ${plur('test', this.stats.todoTests)} todo`)); } + if (this.stats.unhandledRejections > 0) { this.lineWriter.writeLine(colors.error(`${this.stats.unhandledRejections} unhandled ${plur('rejection', this.stats.unhandledRejections)}`)); } + if (this.stats.uncaughtExceptions > 0) { this.lineWriter.writeLine(colors.error(`${this.stats.uncaughtExceptions} uncaught ${plur('exception', this.stats.uncaughtExceptions)}`)); } + if (this.previousFailures > 0) { this.lineWriter.writeLine(colors.error(`${this.previousFailures} previous ${plur('failure', this.previousFailures)} in test files that were not rerun`)); } @@ -449,6 +467,7 @@ class MiniReporter { } else { this.lineWriter.writeLine(colors.error(`${figures.cross} Internal error`)); } + this.lineWriter.writeLine(colors.stack(evt.err.summary)); this.lineWriter.writeLine(colors.errorStack(evt.err.stack)); if (evt !== last || writeTrailingLines) { @@ -509,6 +528,7 @@ class MiniReporter { remaining += ', as well as '; } } + if (this.stats.files > this.stats.finishedWorkers) { const skippedFileCount = this.stats.files - this.stats.finishedWorkers; remaining += `${skippedFileCount} ${plur('test file', 'test files', skippedFileCount)}`; @@ -516,6 +536,7 @@ class MiniReporter { remaining += ` ${plur('was', 'were', skippedFileCount)} skipped`; } } + this.lineWriter.writeLine(colors.information(`\`--fail-fast\` is on. ${remaining}.`)); } diff --git a/lib/reporters/tap.js b/lib/reporters/tap.js index 0d1296c3a..708a08791 100644 --- a/lib/reporters/tap.js +++ b/lib/reporters/tap.js @@ -13,6 +13,7 @@ function dumpError(error) { if (error.name) { obj.name = error.name; } + if (error.message) { obj.message = error.message; } @@ -21,9 +22,11 @@ function dumpError(error) { if (error.assertion) { obj.assertion = error.assertion; } + if (error.operator) { obj.operator = error.operator; } + if (error.values.length > 0) { obj.values = error.values.reduce((acc, value) => { acc[value.label] = stripAnsi(value.formatted); @@ -138,6 +141,7 @@ class TapReporter { } else if (evt.todo) { this.writeTest(evt, {passed: false, todo: true, skip: false}); } + break; case 'stats': this.stats = evt.stats; @@ -165,6 +169,7 @@ class TapReporter { this.writeCrash(evt, `${path.relative('.', evt.testFile)} exited due to ${evt.signal}`); } } + break; case 'worker-finished': if (!evt.forcedExit && !this.filesWithMissingAvaImports.has(evt.testFile)) { @@ -174,6 +179,7 @@ class TapReporter { this.writeCrash(evt, `${fileStats.remainingTests} ${plur('test', fileStats.remainingTests)} remaining in ${path.relative('.', evt.testFile)}`); } } + break; case 'worker-stderr': case 'worker-stdout': diff --git a/lib/reporters/verbose.js b/lib/reporters/verbose.js index 9a429a9b7..b35a31549 100644 --- a/lib/reporters/verbose.js +++ b/lib/reporters/verbose.js @@ -116,6 +116,7 @@ class VerboseReporter { } else { this.lineWriter.writeLine(colors.error(`${figures.cross} Internal error`)); } + this.lineWriter.writeLine(colors.stack(evt.err.summary)); this.lineWriter.writeLine(colors.errorStack(evt.err.stack)); this.lineWriter.writeLine(); @@ -131,6 +132,7 @@ class VerboseReporter { } else if (evt.todo) { this.lineWriter.writeLine(colors.todo(`- ${this.prefixTitle(evt.testFile, evt.title)}`)); } + break; case 'stats': this.stats = evt.stats; @@ -145,6 +147,7 @@ class VerboseReporter { if (evt.knownFailing) { this.knownFailures.push(evt); } + this.writeTestSummary(evt); break; case 'timeout': @@ -172,6 +175,7 @@ class VerboseReporter { this.lineWriter.writeLine(colors.error(`${figures.cross} ${path.relative('.', evt.testFile)} exited due to ${evt.signal}`)); } } + break; case 'worker-finished': if (!evt.forcedExit && !this.filesWithMissingAvaImports.has(evt.testFile)) { @@ -181,6 +185,7 @@ class VerboseReporter { this.lineWriter.writeLine(colors.error(`${figures.cross} ${fileStats.remainingTests} ${plur('test', fileStats.remainingTests)} remaining in ${path.relative('.', evt.testFile)}`)); } } + break; case 'worker-stderr': case 'worker-stdout': @@ -194,6 +199,7 @@ class VerboseReporter { if (evt.chunk[evt.chunk.length - 1] !== 0x0A) { this.reportStream.write(os.EOL); } + break; default: break; @@ -240,7 +246,7 @@ class VerboseReporter { } if (evt.err.stack) { - const stack = evt.err.stack; + const {stack} = evt.err; if (stack.includes('\n')) { this.lineWriter.writeLine(); this.lineWriter.writeLine(colors.errorStack(stack)); @@ -252,6 +258,7 @@ class VerboseReporter { if (!this.runningTestFiles.has(file)) { this.runningTestFiles.set(file, new Set()); } + this.runningTestFiles.get(file).add(title); } @@ -274,10 +281,12 @@ class VerboseReporter { if (!wroteTrailingSeparator) { this.lineWriter.writeLine(''); } + this.lineWriter.writeLine(`${byFile.size} tests still running in ${timedOutFile}:\n`); for (const title of byFile) { this.lineWriter.writeLine(`${figures.circleDotted} ${this.prefixTitle(timedOutFile, title)}`); } + this.lineWriter.writeLine(''); wroteTrailingSeparator = true; } @@ -349,29 +358,37 @@ class VerboseReporter { this.lineWriter.writeLine(colors.error(`${this.stats.failedHooks} ${plur('hook', this.stats.failedHooks)} failed`) + firstLinePostfix); firstLinePostfix = ''; } + if (this.stats.failedTests > 0) { this.lineWriter.writeLine(colors.error(`${this.stats.failedTests} ${plur('test', this.stats.failedTests)} failed`) + firstLinePostfix); firstLinePostfix = ''; } + if (this.stats.failedHooks === 0 && this.stats.failedTests === 0 && this.stats.passedTests > 0) { this.lineWriter.writeLine(colors.pass(`${this.stats.passedTests} ${plur('test', this.stats.passedTests)} passed`) + firstLinePostfix); firstLinePostfix = ''; } + if (this.stats.passedKnownFailingTests > 0) { this.lineWriter.writeLine(colors.error(`${this.stats.passedKnownFailingTests} ${plur('known failure', this.stats.passedKnownFailingTests)}`)); } + if (this.stats.skippedTests > 0) { this.lineWriter.writeLine(colors.skip(`${this.stats.skippedTests} ${plur('test', this.stats.skippedTests)} skipped`)); } + if (this.stats.todoTests > 0) { this.lineWriter.writeLine(colors.todo(`${this.stats.todoTests} ${plur('test', this.stats.todoTests)} todo`)); } + if (this.stats.unhandledRejections > 0) { this.lineWriter.writeLine(colors.error(`${this.stats.unhandledRejections} unhandled ${plur('rejection', this.stats.unhandledRejections)}`)); } + if (this.stats.uncaughtExceptions > 0) { this.lineWriter.writeLine(colors.error(`${this.stats.uncaughtExceptions} uncaught ${plur('exception', this.stats.uncaughtExceptions)}`)); } + if (this.previousFailures > 0) { this.lineWriter.writeLine(colors.error(`${this.previousFailures} previous ${plur('failure', this.previousFailures)} in test files that were not rerun`)); } @@ -407,6 +424,7 @@ class VerboseReporter { remaining += ', as well as '; } } + if (this.stats.files > this.stats.finishedWorkers) { const skippedFileCount = this.stats.files - this.stats.finishedWorkers; remaining += `${skippedFileCount} ${plur('test file', 'test files', skippedFileCount)}`; @@ -414,6 +432,7 @@ class VerboseReporter { remaining += ` ${plur('was', 'were', skippedFileCount)} skipped`; } } + this.lineWriter.writeLine(colors.information(`\`--fail-fast\` is on. ${remaining}.`)); } diff --git a/lib/reporters/while-corked.js b/lib/reporters/while-corked.js index 1c1e382b1..dd151a34f 100644 --- a/lib/reporters/while-corked.js +++ b/lib/reporters/while-corked.js @@ -1,12 +1,13 @@ 'use strict'; function whileCorked(stream, fn) { - return function () { + return function (...args) { stream.cork(); try { - fn.apply(this, arguments); + fn.apply(this, args); } finally { stream.uncork(); } }; } + module.exports = whileCorked; diff --git a/lib/run-status.js b/lib/run-status.js index ed84b232d..e70031566 100644 --- a/lib/run-status.js +++ b/lib/run-status.js @@ -46,12 +46,12 @@ class RunStatus extends Emittery { worker.onStateChange(data => this.emitStateChange(data)); } - emitStateChange(evt) { - const stats = this.stats; - const fileStats = this.stats.byFile.get(evt.testFile); + emitStateChange(event) { + const {stats} = this; + const fileStats = stats.byFile.get(event.testFile); let changedStats = true; - switch (evt.type) { + switch (event.type) { case 'declared-test': stats.declaredTests++; fileStats.declaredTests++; @@ -62,23 +62,25 @@ class RunStatus extends Emittery { break; case 'internal-error': stats.internalErrors++; - if (evt.testFile) { + if (event.testFile) { fileStats.internalErrors++; } + break; case 'selected-test': stats.selectedTests++; fileStats.selectedTests++; - if (evt.skip) { + if (event.skip) { stats.skippedTests++; fileStats.skippedTests++; - } else if (evt.todo) { + } else if (event.todo) { stats.todoTests++; fileStats.todoTests++; } else { stats.remainingTests++; fileStats.remainingTests++; } + break; case 'test-failed': stats.failedTests++; @@ -87,13 +89,14 @@ class RunStatus extends Emittery { fileStats.remainingTests--; break; case 'test-passed': - if (evt.knownFailing) { + if (event.knownFailing) { stats.passedKnownFailingTests++; fileStats.passedKnownFailingTests++; } else { stats.passedTests++; fileStats.passedTests++; } + stats.remainingTests--; fileStats.remainingTests--; break; @@ -122,7 +125,8 @@ class RunStatus extends Emittery { if (changedStats) { this.emit('stateChange', {type: 'stats', stats: cloneDeep(stats)}); } - this.emit('stateChange', evt); + + this.emit('stateChange', event); } suggestExitCode(circumstances) { diff --git a/lib/runner.js b/lib/runner.js index 73bbc1b50..0b3631f3e 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -8,10 +8,9 @@ const serializeError = require('./serialize-error'); const Runnable = require('./test'); class Runner extends Emittery { - constructor(options) { + constructor(options = {}) { super(); - options = options || {}; this.failFast = options.failFast === true; this.failWithoutAssertions = options.failWithoutAssertions !== false; this.file = options.file; @@ -45,6 +44,7 @@ class Runner extends Emittery { if (hasStarted) { throw new Error('All tests and hooks must be declared synchronously in your test file, and cannot be nested within other tests or hooks.'); } + if (!scheduledStart) { scheduledStart = true; process.nextTick(() => { @@ -134,6 +134,7 @@ class Runner extends Emittery { // --match overrides .only() task.metadata.exclusive = matcher([title], this.match).length === 1; } + if (task.metadata.exclusive) { this.runOnlyExclusive = true; } @@ -203,6 +204,7 @@ class Runner extends Emittery { return true; } } + return false; } @@ -220,6 +222,7 @@ class Runner extends Emittery { if (!result.passed) { allPassed = false; } + storedResults.push(result); }); }; @@ -287,6 +290,7 @@ class Runner extends Emittery { }); } } + return false; }); } @@ -360,6 +364,7 @@ class Runner extends Emittery { serialTests.push(task); } } + for (const task of this.tasks.concurrent) { if (this.runOnlyExclusive && !task.metadata.exclusive) { continue; diff --git a/lib/serialize-error.js b/lib/serialize-error.js index 6a1aa9847..bd1a02533 100644 --- a/lib/serialize-error.js +++ b/lib/serialize-error.js @@ -25,6 +25,7 @@ function extractSource(stack) { const firstStackLine = stack.split('\n')[0]; return stackUtils.parseLine(firstStackLine); } + function buildSource(source) { if (!source) { return null; @@ -76,6 +77,7 @@ function trySerializeError(err, shouldBeautifyStack) { if (err.assertion) { retval.assertion = err.assertion; } + if (err.operator) { retval.operator = err.operator; } @@ -84,6 +86,7 @@ function trySerializeError(err, shouldBeautifyStack) { if (typeof err.message === 'string') { retval.message = err.message; } + if (typeof err.name === 'string') { retval.name = err.name; } @@ -99,6 +102,7 @@ function trySerializeError(err, shouldBeautifyStack) { break; } } + retval.summary = retval.summary.trim(); } else { // Skip the source line header inserted by `esm`: @@ -133,4 +137,5 @@ function serializeError(origin, shouldBeautifyStack, err) { }; } } + module.exports = serializeError; diff --git a/lib/snapshot-manager.js b/lib/snapshot-manager.js index cfb131acf..800daabd8 100644 --- a/lib/snapshot-manager.js +++ b/lib/snapshot-manager.js @@ -87,6 +87,7 @@ function withoutLineEndings(buffer) { while (buffer[checkPosition] === 0x0A || buffer[checkPosition] === 0x0D) { checkPosition--; } + return buffer.slice(0, checkPosition + 1); } @@ -94,6 +95,7 @@ function formatEntry(label, descriptor) { if (label) { label = `> ${label}\n\n`; } + const codeBlock = indentString(concordance.formatDescriptor(descriptor, concordanceOptions), 4); return Buffer.from(label + codeBlock, 'utf8'); } @@ -102,7 +104,7 @@ function combineEntries(entries) { const buffers = []; let byteLength = 0; - const sortedKeys = Array.from(entries.keys()).sort(); + const sortedKeys = [...entries.keys()].sort(); for (const key of sortedKeys) { const keyBuffer = Buffer.from(`\n\n## ${key}\n\n`, 'utf8'); buffers.push(keyBuffer); @@ -126,8 +128,8 @@ function combineEntries(entries) { function generateReport(relFile, snapFile, entries) { const combined = combineEntries(entries); - const buffers = combined.buffers; - let byteLength = combined.byteLength; + const {buffers} = combined; + let {byteLength} = combined; const header = Buffer.from(`# Snapshot report for \`${slash(relFile)}\` @@ -144,8 +146,8 @@ Generated by [AVA](https://ava.li).`, 'utf8'); function appendReportEntries(existingReport, entries) { const combined = combineEntries(entries); - const buffers = combined.buffers; - let byteLength = combined.byteLength; + const {buffers} = combined; + let {byteLength} = combined; const prepend = withoutLineEndings(existingReport); buffers.unshift(prepend); @@ -210,6 +212,7 @@ function encodeSnapshots(buffersByHash) { buffers.push(entry.value); bodyOffset = end; } + byteOffset += bodyOffset; const compressed = zlib.gzipSync(Buffer.concat(buffers, byteOffset)); @@ -304,6 +307,7 @@ class Manager { if (options.index > entries.length) { throw new RangeError(`Cannot record snapshot ${options.index} for ${JSON.stringify(options.belongsTo)}, exceeds expected index of ${entries.length}`); } + if (options.index === entries.length) { this.record(hash, options); return {pass: true}; @@ -342,7 +346,7 @@ class Manager { return null; } - const snapPath = this.snapPath; + const {snapPath} = this; const buffer = encodeSnapshots(this.snapshotsByHash); const reportPath = path.join(this.dir, this.reportFile); @@ -370,6 +374,7 @@ function determineSnapshotDir({file, fixedLocation, projectDir}) { if (parts.has('__tests__')) { return path.join(testDir, '__snapshots__'); } + if (parts.has('test') || parts.has('tests')) { // Accept tests, even though it's not in the default test patterns return path.join(testDir, 'snapshots'); } @@ -426,4 +431,5 @@ function load({file, fixedLocation, projectDir, updating}) { snapshotsByHash: snapshotsByHash || new Map() }); } + exports.load = load; diff --git a/lib/test.js b/lib/test.js index fe32accb3..729c17f3d 100644 --- a/lib/test.js +++ b/lib/test.js @@ -37,8 +37,8 @@ const assertions = assert.wrapAssertions({ }); const assertionNames = Object.keys(assertions); -function log() { - const args = Array.from(arguments, value => { +function log(...inputArgs) { + const args = inputArgs.map(value => { return typeof value === 'string' ? value : concordance.format(value, concordanceOptions); @@ -61,6 +61,7 @@ class ExecutionContext { const skip = () => { test.countPassedAssertion(); }; + const boundPlan = plan.bind(test); boundPlan.skip = () => {}; @@ -117,11 +118,12 @@ class Test { this.snapshotInvocationCount = 0; this.compareWithSnapshot = assertionOptions => { const belongsTo = assertionOptions.id || this.title; - const expected = assertionOptions.expected; + const {expected} = assertionOptions; const index = assertionOptions.id ? 0 : this.snapshotInvocationCount++; const label = assertionOptions.id ? '' : assertionOptions.message || `Snapshot ${this.snapshotInvocationCount}`; return options.compareTestSnapshot({belongsTo, expected, index, label}); }; + this.skipSnapshot = () => { if (options.updateSnapshots) { this.addFailedAssertion(new Error('Snapshot assertions cannot be skipped when updating snapshots')); @@ -160,6 +162,7 @@ class Test { this.saveFirstError(new Error('`t.end()` called more than once')); return; } + this.calledEnd = true; if (error) { @@ -332,6 +335,7 @@ class Test { values: [formatErrorValue('Error thrown in test:', result.error)] })); } + return this.finishPromised(); } diff --git a/lib/watcher.js b/lib/watcher.js index 980736594..8f9c8446a 100644 --- a/lib/watcher.js +++ b/lib/watcher.js @@ -95,6 +95,7 @@ class Watcher { if (this.runVector > 0) { this.clearLogOnNextRun = true; } + this.runVector++; let runOnlyExclusive = false; @@ -351,7 +352,7 @@ class Watcher { } runAfterChanges() { - const dirtyStates = this.dirtyStates; + const {dirtyStates} = this; this.dirtyStates = {}; const dirtyPaths = Object.keys(dirtyStates).filter(path => { @@ -360,6 +361,7 @@ class Watcher { this.touchedFiles.delete(path); return false; } + return true; }); const dirtyTests = dirtyPaths.filter(filePath => this.avaFiles.isTest(filePath)); diff --git a/lib/worker/dependency-tracker.js b/lib/worker/dependency-tracker.js index c14a1987f..0d08bab45 100644 --- a/lib/worker/dependency-tracker.js +++ b/lib/worker/dependency-tracker.js @@ -12,6 +12,7 @@ function flush() { ipc.send({type: 'dependencies', dependencies: newDependencies}); newDependencies = []; } + exports.flush = flush; function track(filename) { @@ -22,9 +23,11 @@ function track(filename) { if (newDependencies.length === 0) { process.nextTick(flush); } + seenDependencies.add(filename); newDependencies.push(filename); } + exports.track = track; function install(testPath) { @@ -40,4 +43,5 @@ function install(testPath) { }; } } + exports.install = install; diff --git a/lib/worker/fake-tty.js b/lib/worker/fake-tty.js index 4d0f30d32..c40153c77 100644 --- a/lib/worker/fake-tty.js +++ b/lib/worker/fake-tty.js @@ -4,7 +4,7 @@ const options = require('./options').get(); const fakeTTYs = new Set(); -const isatty = tty.isatty; +const {isatty} = tty; tty.isatty = fd => fakeTTYs.has(fd) || isatty(fd); const simulateTTY = (stream, {colorDepth, columns, rows}) => { diff --git a/lib/worker/ipc.js b/lib/worker/ipc.js index 695edae0f..2b0f4d119 100644 --- a/lib/worker/ipc.js +++ b/lib/worker/ipc.js @@ -30,11 +30,13 @@ function send(evt) { process.send({ava: evt}); } } + exports.send = send; function unref() { channel.unref(); } + exports.unref = unref; let pendingPings = Promise.resolve(); @@ -51,4 +53,5 @@ function flush() { pendingPings = promise; return promise; } + exports.flush = flush; diff --git a/lib/worker/main.js b/lib/worker/main.js index 251d3f242..80f0497c7 100644 --- a/lib/worker/main.js +++ b/lib/worker/main.js @@ -2,9 +2,10 @@ const runner = require('./subprocess').getRunner(); const makeCjsExport = () => { - function test() { - return runner.chain.apply(null, arguments); + function test(...args) { + return runner.chain(...args); } + return Object.assign(test, runner.chain); }; diff --git a/lib/worker/options.js b/lib/worker/options.js index 65a7c1756..8a6ca21fa 100644 --- a/lib/worker/options.js +++ b/lib/worker/options.js @@ -4,11 +4,14 @@ exports.get = () => { if (!options) { throw new Error('Options have not yet been set'); } + return options; }; + exports.set = newOptions => { if (options) { throw new Error('Options have already been set'); } + options = newOptions; }; diff --git a/lib/worker/precompiler-hook.js b/lib/worker/precompiler-hook.js index 2a0a8210c..7e7a6466a 100644 --- a/lib/worker/precompiler-hook.js +++ b/lib/worker/precompiler-hook.js @@ -38,4 +38,5 @@ function install() { null; }); } + exports.install = install; diff --git a/package-lock.json b/package-lock.json index e62090791..e84e7ca8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1362,7 +1362,7 @@ }, "callsites": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "resolved": "http://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", "dev": true }, @@ -1788,7 +1788,7 @@ }, "core-assert": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz", + "resolved": "http://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz", "integrity": "sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8=", "dev": true, "requires": { @@ -1832,7 +1832,7 @@ }, "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -2459,7 +2459,7 @@ }, "doctrine": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "resolved": "http://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", "dev": true, "requires": { @@ -3278,7 +3278,7 @@ }, "foreground-child": { "version": "1.5.6", - "resolved": "http://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "dev": true, "requires": { @@ -3954,7 +3954,7 @@ }, "got": { "version": "6.7.1", - "resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "requires": { "create-error-class": "^3.0.0", @@ -3972,7 +3972,7 @@ "dependencies": { "get-stream": { "version": "3.0.0", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" } } @@ -4288,7 +4288,7 @@ }, "is-builtin-module": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "requires": { "builtin-modules": "^1.0.0" @@ -4405,7 +4405,7 @@ }, "is-obj": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" }, "is-obj-prop": { @@ -4761,7 +4761,7 @@ }, "load-json-file": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { @@ -5202,7 +5202,7 @@ }, "minimist": { "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "minimist-options": { @@ -5259,7 +5259,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" @@ -7237,7 +7237,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" } } @@ -7596,7 +7596,7 @@ }, "require-uncached": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "resolved": "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { @@ -7740,7 +7740,7 @@ }, "serialize-error": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=" }, "set-getter": { @@ -11142,7 +11142,7 @@ }, "text-encoding": { "version": "0.6.4", - "resolved": "http://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", "dev": true }, @@ -11340,7 +11340,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -11417,7 +11417,7 @@ "dependencies": { "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { diff --git a/package.json b/package.json index 3675ebdfb..50e8459b9 100644 --- a/package.json +++ b/package.json @@ -178,11 +178,7 @@ "test/flow-types/*" ], "rules": { - "no-use-extend-native/no-use-extend-native": "off", - "prefer-destructuring": "off", - "prefer-rest-params": "off", - "prefer-spread": "off", - "unicorn/prefer-spread": "off" + "no-use-extend-native/no-use-extend-native": "off" } }, "nyc": { diff --git a/test/api.js b/test/api.js index a7082b4a2..4e47cc63c 100644 --- a/test/api.js +++ b/test/api.js @@ -5,7 +5,7 @@ const assert = require('assert'); const path = require('path'); const fs = require('fs'); const del = require('del'); -const test = require('tap').test; +const {test} = require('tap'); const Api = require('../api'); const babelPipeline = require('../lib/babel-pipeline'); @@ -19,6 +19,7 @@ function withNodeEnv(value, run) { const reset = () => { delete process.env.NODE_ENV; }; + const promise = new Promise(resolve => { resolve(run()); }); @@ -26,8 +27,7 @@ function withNodeEnv(value, run) { return promise; } -function apiCreator(options) { - options = options || {}; +function apiCreator(options = {}) { options.babelConfig = babelPipeline.validate(options.babelConfig); options.concurrency = 2; options.extensions = options.extensions || {all: ['js'], enhancementsOnly: [], full: ['js']}; @@ -37,6 +37,7 @@ function apiCreator(options) { if (!options.precompileHelpers) { instance._precompileHelpers = () => Promise.resolve(); } + return instance; } diff --git a/test/assert.js b/test/assert.js index f3e4f1a2b..f5f1510f1 100644 --- a/test/assert.js +++ b/test/assert.js @@ -6,7 +6,7 @@ const path = require('path'); const stripAnsi = require('strip-ansi'); const React = require('react'); const renderer = require('react-test-renderer'); -const test = require('tap').test; +const {test} = require('tap'); const assert = require('../lib/assert'); const snapshotManager = require('../lib/snapshot-manager'); const Test = require('../lib/test'); @@ -19,6 +19,7 @@ const assertions = assert.wrapAssertions({ if (testObj !== assertions && !(testObj instanceof Test)) { throw new Error('Expected testObj'); } + lastPassed = true; }, @@ -57,6 +58,7 @@ function assertFailure(t, subset) { t.is(lastFailure.raw.expected, subset.raw.expected); t.is(lastFailure.raw.actual, subset.raw.actual); } + if (subset.statements) { t.is(lastFailure.statements.length, subset.statements.length); lastFailure.statements.forEach((s, i) => { @@ -66,6 +68,7 @@ function assertFailure(t, subset) { } else { t.same(lastFailure.statements, []); } + if (subset.values) { t.is(lastFailure.values.length, subset.values.length); lastFailure.values.forEach((s, i) => { @@ -95,10 +98,12 @@ function gather(run) { } }; } + function add(fn) { if (!gathering) { throw new Error('Cannot add promise, must be called from gather() callback'); } + gatheringPromise = gatheringPromise.then(fn); return gatheringPromise; } diff --git a/test/ava-files.js b/test/ava-files.js index 4c14aa8d7..ac00e49ea 100644 --- a/test/ava-files.js +++ b/test/ava-files.js @@ -3,7 +3,7 @@ const path = require('path'); const tap = require('tap'); const AvaFiles = require('../lib/ava-files'); -const test = tap.test; +const {test} = tap; tap.afterEach(done => { // We changed the CWD in some of the tests @@ -11,10 +11,9 @@ tap.afterEach(done => { done(); }); -function fixture() { - const args = Array.prototype.slice.call(arguments); +function fixture(...args) { args.unshift(__dirname, 'fixture', 'ava-files'); - return path.join.apply(path, args); + return path.join(...args); } test('ignores relativeness in patterns', t => { diff --git a/test/beautify-stack.js b/test/beautify-stack.js index 6ccad1163..88a5e0eff 100644 --- a/test/beautify-stack.js +++ b/test/beautify-stack.js @@ -3,7 +3,7 @@ require('../lib/chalk').set(); require('../lib/worker/options').set({}); const proxyquire = require('proxyquire').noPreserveCache(); -const test = require('tap').test; +const {test} = require('tap'); const Runner = require('../lib/runner'); const beautifyStack = proxyquire('../lib/beautify-stack', { diff --git a/test/code-excerpt.js b/test/code-excerpt.js index 1c5ae2fad..4fe555a47 100644 --- a/test/code-excerpt.js +++ b/test/code-excerpt.js @@ -4,7 +4,7 @@ require('../lib/chalk').set(); const fs = require('fs'); const tempWrite = require('temp-write'); const chalk = require('chalk'); -const test = require('tap').test; +const {test} = require('tap'); const codeExcerpt = require('../lib/code-excerpt'); chalk.enabled = true; diff --git a/test/fixture/babel-plugin-test-capitalizer.js b/test/fixture/babel-plugin-test-capitalizer.js index cfdc033d4..0fc511bd1 100644 --- a/test/fixture/babel-plugin-test-capitalizer.js +++ b/test/fixture/babel-plugin-test-capitalizer.js @@ -13,7 +13,7 @@ module.exports = babel => { // Skip require calls const firstArg = path.get('arguments')[0]; - if (!isRequire(path) && firstArg && firstArg.isStringLiteral() && !/repeated test/.test(firstArg.node.value)) { + if (!isRequire(path) && firstArg && firstArg.isStringLiteral() && !firstArg.node.value.includes('repeated test')) { firstArg.replaceWith(t.stringLiteral(firstArg.node.value.toUpperCase())); } } diff --git a/test/fixture/babel-plugin-test-doubler.js b/test/fixture/babel-plugin-test-doubler.js index 3b2986623..44629df38 100644 --- a/test/fixture/babel-plugin-test-doubler.js +++ b/test/fixture/babel-plugin-test-doubler.js @@ -20,8 +20,8 @@ module.exports = babel => { return { visitor: { CallExpression: path => { - const node = path.node; - const callee = node.callee; + const {node} = path; + const {callee} = node; let args = node.arguments; if (callee.type === 'Identifier' && callee.name === 'test') { diff --git a/test/fixture/formatting.js b/test/fixture/formatting.js index 531cd7352..6a3e395d6 100644 --- a/test/fixture/formatting.js +++ b/test/fixture/formatting.js @@ -84,6 +84,7 @@ test('error thrown in test due to improper throws', t => { date: new Date('1969-07-20T20:17:40.000Z') }); }; + t.throws(improper()); }); test('test returned rejected promise', () => { @@ -148,6 +149,7 @@ test('generator function', t => { t.true(function * foo() {}); // eslint-disable-line func-names }); +/* eslint-disable prefer-rest-params */ test('arguments formatted', t => { const args = (function () { return arguments; @@ -169,6 +171,7 @@ test('arguments diff with normal array', t => { })('foo'); t.deepEqual(foo, ['bar']); }); +/* eslint-enable prefer-rest-params */ if (formatGlobals) { test('global formatted', t => { diff --git a/test/fixture/report/regular/test.js b/test/fixture/report/regular/test.js index 4825784ba..86feeac82 100644 --- a/test/fixture/report/regular/test.js +++ b/test/fixture/report/regular/test.js @@ -34,6 +34,7 @@ test('bad throws', t => { const fn = () => { throw new Error('err'); }; + t.throws(fn()); }); @@ -41,6 +42,7 @@ test('bad notThrows', t => { const fn = () => { throw new Error('err'); }; + t.notThrows(fn()); }); diff --git a/test/fixture/trigger-worker-exception/hack.js b/test/fixture/trigger-worker-exception/hack.js index ebdf251a5..23f721d86 100644 --- a/test/fixture/trigger-worker-exception/hack.js +++ b/test/fixture/trigger-worker-exception/hack.js @@ -9,9 +9,11 @@ StackUtils.prototype.parseLine = function (line) { if (restored) { return original.call(this, line); } + if (restoreAfterFirstCall) { restored = true; } + throw new Error('Forced error'); }; diff --git a/test/helper/cli.js b/test/helper/cli.js index 92ac0fe0d..5f6e31559 100644 --- a/test/helper/cli.js +++ b/test/helper/cli.js @@ -50,9 +50,10 @@ function execCli(args, opts, cb) { }); Promise.all([processPromise, stdout, stderr]).then(args => { - cb.apply(null, args); + cb(...args); }); return child; } + exports.execCli = execCli; diff --git a/test/helper/report.js b/test/helper/report.js index a1b041af0..ce2372020 100644 --- a/test/helper/report.js +++ b/test/helper/report.js @@ -37,6 +37,7 @@ exports.assert = (t, logFile, buffer, stripOptions) => { try { existing = fs.readFileSync(logFile); } catch (_) {} + if (existing === null || process.env.UPDATE_REPORTER_LOG) { fs.writeFileSync(logFile, buffer); existing = buffer; @@ -73,6 +74,7 @@ exports.sanitizers = { if (hasReliableStdIO) { return str; } + return str === 'stdout\n' || str === 'stderr\n' ? '' : str; }, version: str => replaceString(str, `v${pkg.version}`, 'v1.0.0-beta.5.1') diff --git a/test/helper/tty-stream.js b/test/helper/tty-stream.js index eb3d31706..90ad73416 100644 --- a/test/helper/tty-stream.js +++ b/test/helper/tty-stream.js @@ -29,6 +29,7 @@ class TTYStream extends stream.Writable { TTYStream.SEPARATOR ); } + callback(); } @@ -37,9 +38,11 @@ class TTYStream extends stream.Writable { this.chunks.push(Buffer.concat(this.spinnerActivity), TTYStream.SEPARATOR); this.spinnerActivity = []; } + for (const obj of chunks) { this.chunks.push(Buffer.from(this.sanitizers.reduce((str, sanitizer) => sanitizer(str), obj.chunk.toString('utf8')), 'utf8')); } + this.chunks.push(TTYStream.SEPARATOR); callback(); } diff --git a/test/hooks.js b/test/hooks.js index 31e511d84..86d2007b4 100644 --- a/test/hooks.js +++ b/test/hooks.js @@ -2,7 +2,7 @@ require('../lib/chalk').set(); require('../lib/worker/options').set({}); -const test = require('tap').test; +const {test} = require('tap'); const Runner = require('../lib/runner'); const promiseEnd = (runner, next) => { diff --git a/test/integration/assorted.js b/test/integration/assorted.js index 42dd308fb..0458e24f2 100644 --- a/test/integration/assorted.js +++ b/test/integration/assorted.js @@ -4,7 +4,7 @@ const childProcess = require('child_process'); const path = require('path'); const makeDir = require('make-dir'); const stripAnsi = require('strip-ansi'); -const test = require('tap').test; +const {test} = require('tap'); const {execCli} = require('../helper/cli'); test('timeout', t => { diff --git a/test/integration/babel.js b/test/integration/babel.js index 6601989d1..eaf38557f 100644 --- a/test/integration/babel.js +++ b/test/integration/babel.js @@ -2,7 +2,7 @@ const fs = require('fs'); const path = require('path'); const globby = require('globby'); -const test = require('tap').test; +const {test} = require('tap'); const figures = require('figures'); const pkg = require('../../package.json'); const {execCli} = require('../helper/cli'); diff --git a/test/integration/compilation.js b/test/integration/compilation.js index e7ae44af2..0060c119d 100644 --- a/test/integration/compilation.js +++ b/test/integration/compilation.js @@ -1,6 +1,6 @@ 'use strict'; const stripAnsi = require('strip-ansi'); -const test = require('tap').test; +const {test} = require('tap'); const {execCli} = require('../helper/cli'); test('precompiler require hook does not apply to source files', t => { diff --git a/test/integration/concurrency.js b/test/integration/concurrency.js index 7d95eed04..4fa8fd67f 100644 --- a/test/integration/concurrency.js +++ b/test/integration/concurrency.js @@ -1,5 +1,5 @@ 'use strict'; -const test = require('tap').test; +const {test} = require('tap'); const {execCli} = require('../helper/cli'); const concurrencyFlags = ['--concurrency', '-c']; diff --git a/test/integration/config.js b/test/integration/config.js index c74dbbb9e..2332070a3 100644 --- a/test/integration/config.js +++ b/test/integration/config.js @@ -1,7 +1,7 @@ 'use strict'; const fs = require('fs'); const path = require('path'); -const test = require('tap').test; +const {test} = require('tap'); const execa = require('execa'); const figures = require('figures'); const uniqueTempDir = require('unique-temp-dir'); diff --git a/test/integration/extensions.js b/test/integration/extensions.js index 3269921c7..1e73596df 100644 --- a/test/integration/extensions.js +++ b/test/integration/extensions.js @@ -1,5 +1,5 @@ 'use strict'; -const test = require('tap').test; +const {test} = require('tap'); const figures = require('figures'); const {execCli} = require('../helper/cli'); diff --git a/test/integration/node-assertions.js b/test/integration/node-assertions.js index cb4b193ec..964a84039 100644 --- a/test/integration/node-assertions.js +++ b/test/integration/node-assertions.js @@ -1,5 +1,5 @@ 'use strict'; -const test = require('tap').test; +const {test} = require('tap'); const {execCli} = require('../helper/cli'); // The AssertionError constructor in Node 10 depends on the TTY interface diff --git a/test/integration/parallel-runs.js b/test/integration/parallel-runs.js index 1c01cbe9a..af8fe6cb5 100644 --- a/test/integration/parallel-runs.js +++ b/test/integration/parallel-runs.js @@ -1,5 +1,5 @@ 'use strict'; -const test = require('tap').test; +const {test} = require('tap'); const {execCli} = require('../helper/cli'); test('correctly distributes the test files', t => { diff --git a/test/integration/repl.js b/test/integration/repl.js index a5e3903c5..3e53ae367 100644 --- a/test/integration/repl.js +++ b/test/integration/repl.js @@ -1,5 +1,5 @@ 'use strict'; -const test = require('tap').test; +const {test} = require('tap'); const execa = require('execa'); test('Throws error when required from the REPL', t => { diff --git a/test/integration/snapshots.js b/test/integration/snapshots.js index 6564bc978..f9f7a62cc 100644 --- a/test/integration/snapshots.js +++ b/test/integration/snapshots.js @@ -3,7 +3,7 @@ const fs = require('fs'); const path = require('path'); const execa = require('execa'); const uniqueTempDir = require('unique-temp-dir'); -const test = require('tap').test; +const {test} = require('tap'); const {execCli} = require('../helper/cli'); for (const obj of [ @@ -155,10 +155,12 @@ test('snapshots infer their location and name from sourcemaps', t => { } } }; + snapFixtureFilePaths.forEach(x => removeExistingSnapFixtureFiles(x)); const verifySnapFixtureFiles = relFilePath => { t.true(fs.existsSync(relFilePath)); }; + execCli([], {dirname: relativeFixtureDir}, (error, stdout) => { t.ifError(error); snapFixtureFilePaths.forEach(x => verifySnapFixtureFiles(x)); @@ -194,10 +196,12 @@ test('snapshots resolved location from "snapshotDir" in AVA config', t => { } } }; + snapFixtureFilePaths.forEach(x => removeExistingSnapFixtureFiles(x)); const verifySnapFixtureFiles = relFilePath => { t.true(fs.existsSync(relFilePath)); }; + execCli([], {dirname: relativeFixtureDir}, (error, stdout) => { t.ifError(error); snapFixtureFilePaths.forEach(x => verifySnapFixtureFiles(x)); diff --git a/test/integration/stack-traces.js b/test/integration/stack-traces.js index 654c46755..51efe3ff1 100644 --- a/test/integration/stack-traces.js +++ b/test/integration/stack-traces.js @@ -1,5 +1,5 @@ 'use strict'; -const test = require('tap').test; +const {test} = require('tap'); const {execCli} = require('../helper/cli'); test('enabling long stack traces will provide detailed debug information', t => { diff --git a/test/integration/stalled.js b/test/integration/stalled.js index 8b992179f..98ef3553c 100644 --- a/test/integration/stalled.js +++ b/test/integration/stalled.js @@ -1,5 +1,5 @@ 'use strict'; -const test = require('tap').test; +const {test} = require('tap'); const {execCli} = require('../helper/cli'); test('callback tests fail if event loop empties before they\'re ended', t => { diff --git a/test/integration/t-throws.js b/test/integration/t-throws.js index c983ae0cb..ad6b746ef 100644 --- a/test/integration/t-throws.js +++ b/test/integration/t-throws.js @@ -1,5 +1,5 @@ 'use strict'; -const test = require('tap').test; +const {test} = require('tap'); const {execCli} = require('../helper/cli'); test('improper use of t.throws will be reported to the console', t => { diff --git a/test/integration/tty.js b/test/integration/tty.js index 09dad71a4..a8503ad2e 100644 --- a/test/integration/tty.js +++ b/test/integration/tty.js @@ -1,5 +1,5 @@ 'use strict'; -const test = require('tap').test; +const {test} = require('tap'); const {execCli} = require('../helper/cli'); test('test workers do not get TTYs when ava is not run with TTYs', t => { diff --git a/test/integration/watcher.js b/test/integration/watcher.js index 76431a943..780c03c50 100644 --- a/test/integration/watcher.js +++ b/test/integration/watcher.js @@ -1,6 +1,6 @@ 'use strict'; const path = require('path'); -const test = require('tap').test; +const {test} = require('tap'); const touch = require('touch'); const {execCli} = require('../helper/cli'); @@ -17,7 +17,7 @@ test('watcher reruns test files when they changed', t => { let passedFirst = false; child.stdout.on('data', str => { buffer += str; - if (/1 test passed/.test(buffer)) { + if (buffer.includes('1 test passed')) { if (!passedFirst) { touch.sync(path.join(__dirname, '../fixture/watcher/test.js')); buffer = ''; @@ -43,7 +43,7 @@ test('watcher respects custom test file extensions', t => { let passedFirst = false; child.stdout.on('data', str => { buffer += str; - if (/1 test passed/.test(buffer)) { + if (buffer.includes('1 test passed')) { if (!passedFirst) { touch.sync(path.join(__dirname, '../fixture/watcher/custom-extensions/test.foo')); buffer = ''; @@ -69,11 +69,11 @@ test('watcher reruns test files when source dependencies change', t => { let passedFirst = false; child.stdout.on('data', str => { buffer += str; - if (/2 tests passed/.test(buffer) && !passedFirst) { + if (buffer.includes('2 tests passed') && !passedFirst) { touch.sync(path.join(__dirname, '../fixture/watcher/with-dependencies/source.js')); buffer = ''; passedFirst = true; - } else if (/1 test passed/.test(buffer) && !killed) { + } else if (buffer.includes('1 test passed') && !killed) { child.kill(); killed = true; } @@ -93,7 +93,7 @@ test('watcher does not rerun test files when they write snapshot files', t => { let passedFirst = false; child.stdout.on('data', str => { buffer += str; - if (/2 tests passed/.test(buffer) && !passedFirst) { + if (buffer.includes('2 tests passed') && !passedFirst) { buffer = ''; passedFirst = true; setTimeout(() => { @@ -119,7 +119,7 @@ test('watcher reruns test files when snapshot dependencies change', t => { let passedFirst = false; child.stdout.on('data', str => { buffer += str; - if (/2 tests passed/.test(buffer)) { + if (buffer.includes('2 tests passed')) { buffer = ''; if (passedFirst) { child.kill(); @@ -146,11 +146,12 @@ test('`"tap": true` config is ignored when --watch is given', t => { const testOutput = output => { combined += output; t.notMatch(combined, /TAP/); - if (/works/.test(combined)) { + if (combined.includes('works')) { child.kill(); killed = true; } }; + child.stdout.on('data', testOutput); child.stderr.on('data', testOutput); }); diff --git a/test/observable.js b/test/observable.js index 7ce179bc9..51f73e33e 100644 --- a/test/observable.js +++ b/test/observable.js @@ -2,7 +2,7 @@ require('../lib/chalk').set(); require('../lib/worker/options').set({}); -const test = require('tap').test; +const {test} = require('tap'); const Test = require('../lib/test'); const Observable = require('zen-observable'); // eslint-disable-line import/order diff --git a/test/profile.js b/test/profile.js index b305267d3..42bdcf109 100644 --- a/test/profile.js +++ b/test/profile.js @@ -1,6 +1,6 @@ 'use strict'; const path = require('path'); -const test = require('tap').test; +const {test} = require('tap'); const execa = require('execa'); const arrify = require('arrify'); diff --git a/test/promise.js b/test/promise.js index 7d7a3d50b..3f110afb5 100644 --- a/test/promise.js +++ b/test/promise.js @@ -3,7 +3,7 @@ require('../lib/chalk').set(); require('../lib/worker/options').set({color: false}); const Promise = require('bluebird'); -const test = require('tap').test; +const {test} = require('tap'); const Test = require('../lib/test'); function ava(fn) { diff --git a/test/reporters/improper-usage-messages.js b/test/reporters/improper-usage-messages.js index 190d87de0..79929834b 100644 --- a/test/reporters/improper-usage-messages.js +++ b/test/reporters/improper-usage-messages.js @@ -1,7 +1,7 @@ 'use strict'; require('../../lib/chalk').set(); -const test = require('tap').test; +const {test} = require('tap'); const improperUsageMessages = require('../../lib/reporters/improper-usage-messages'); test('results when nothing is applicable', t => { diff --git a/test/reporters/mini.js b/test/reporters/mini.js index 2798f2b7b..3e4d7caaf 100644 --- a/test/reporters/mini.js +++ b/test/reporters/mini.js @@ -3,7 +3,7 @@ require('../helper/report').captureStdIOReliability(); require('../helper/fix-reporter-env')(); const path = require('path'); -const test = require('tap').test; +const {test} = require('tap'); const TTYStream = require('../helper/tty-stream'); const report = require('../helper/report'); const MiniReporter = require('../../lib/reporters/mini'); diff --git a/test/reporters/mini.regular.log b/test/reporters/mini.regular.log index 942c9b732..6d70bc3b5 100644 --- a/test/reporters/mini.regular.log +++ b/test/reporters/mini.regular.log @@ -189,11 +189,11 @@ stderr test › bad throws - ~/test/fixture/report/regular/test.js:37 + ~/test/fixture/report/regular/test.js:38 - 36: }; -  37: t.throws(fn()); - 38: }); + 37: +  38: t.throws(fn()); + 39: }); Improper usage of `t.throws()` detected @@ -212,17 +212,17 @@ stderr https://github.com/avajs/ava/blob/v1.0.0-beta.5.1/readme.md#throwsthrower-expected-message fn (test.js:35:9) - fn (test.js:37:11) + fn (test.js:38:11) test › bad notThrows - ~/test/fixture/report/regular/test.js:44 + ~/test/fixture/report/regular/test.js:46 - 43: }; -  44: t.notThrows(fn()); - 45: }); + 45: +  46: t.notThrows(fn()); + 47: }); Improper usage of `t.notThrows()` detected @@ -240,8 +240,8 @@ stderr https://github.com/avajs/ava/blob/v1.0.0-beta.5.1/readme.md#throwsthrower-expected-message - fn (test.js:42:9) - fn (test.js:44:14) + fn (test.js:43:9) + fn (test.js:46:14) diff --git a/test/reporters/prefix-title.js b/test/reporters/prefix-title.js index 9772eccb7..2dd705a60 100644 --- a/test/reporters/prefix-title.js +++ b/test/reporters/prefix-title.js @@ -3,7 +3,7 @@ require('../../lib/chalk').set(); const path = require('path'); const figures = require('figures'); -const test = require('tap').test; +const {test} = require('tap'); const chalk = require('../../lib/chalk').get(); const prefixTitle = require('../../lib/reporters/prefix-title'); diff --git a/test/reporters/tap.js b/test/reporters/tap.js index 4bfa06f6d..311f6aa27 100644 --- a/test/reporters/tap.js +++ b/test/reporters/tap.js @@ -3,7 +3,7 @@ require('../helper/report').captureStdIOReliability(); require('../helper/fix-reporter-env')(); const path = require('path'); -const test = require('tap').test; +const {test} = require('tap'); const TTYStream = require('../helper/tty-stream'); const report = require('../helper/report'); const TapReporter = require('../../lib/reporters/tap'); diff --git a/test/reporters/tap.regular.log b/test/reporters/tap.regular.log index bf68c881c..09434adf6 100644 --- a/test/reporters/tap.regular.log +++ b/test/reporters/tap.regular.log @@ -139,7 +139,7 @@ not ok 20 - test › bad notThrows Error { message: 'err', } - at: 'fn (test.js:42:9)' + at: 'fn (test.js:43:9)' ... ---tty-stream-chunk-separator # test › implementation throws non-error diff --git a/test/reporters/verbose.js b/test/reporters/verbose.js index 7cc2bf127..c51272306 100644 --- a/test/reporters/verbose.js +++ b/test/reporters/verbose.js @@ -2,7 +2,7 @@ require('../helper/report').captureStdIOReliability(); const path = require('path'); -const test = require('tap').test; +const {test} = require('tap'); const {restoreClock} = require('../helper/fix-reporter-env')(); const TTYStream = require('../helper/tty-stream'); const report = require('../helper/report'); diff --git a/test/reporters/verbose.regular.log b/test/reporters/verbose.regular.log index b7ffd60f8..d7159bfd2 100644 --- a/test/reporters/verbose.regular.log +++ b/test/reporters/verbose.regular.log @@ -159,11 +159,11 @@ stderr test › bad throws - ~/test/fixture/report/regular/test.js:37 + ~/test/fixture/report/regular/test.js:38 - 36: }; -  37: t.throws(fn()); - 38: }); + 37: +  38: t.throws(fn()); + 39: }); Improper usage of `t.throws()` detected @@ -182,17 +182,17 @@ stderr https://github.com/avajs/ava/blob/v1.0.0-beta.5.1/readme.md#throwsthrower-expected-message fn (test.js:35:9) - fn (test.js:37:11) + fn (test.js:38:11) test › bad notThrows - ~/test/fixture/report/regular/test.js:44 + ~/test/fixture/report/regular/test.js:46 - 43: }; -  44: t.notThrows(fn()); - 45: }); + 45: +  46: t.notThrows(fn()); + 47: }); Improper usage of `t.notThrows()` detected @@ -210,8 +210,8 @@ stderr https://github.com/avajs/ava/blob/v1.0.0-beta.5.1/readme.md#throwsthrower-expected-message - fn (test.js:42:9) - fn (test.js:44:14) + fn (test.js:43:9) + fn (test.js:46:14) diff --git a/test/runner.js b/test/runner.js index 1fbed8e8d..1c1b1f63e 100644 --- a/test/runner.js +++ b/test/runner.js @@ -2,10 +2,9 @@ require('../lib/chalk').set(); require('../lib/worker/options').set({}); -const test = require('tap').test; +const {test} = require('tap'); const Runner = require('../lib/runner'); -const slice = Array.prototype.slice; const noop = () => {}; const promiseEnd = (runner, next) => { @@ -197,6 +196,7 @@ test('skip test', t => { if (evt.type === 'selected-test' && evt.skip) { t.pass(); } + if (evt.type === 'test-passed') { t.pass(); } @@ -256,6 +256,7 @@ test('todo test', t => { if (evt.type === 'selected-test' && evt.todo) { t.pass(); } + if (evt.type === 'test-passed') { t.pass(); } @@ -579,13 +580,13 @@ test('macros: Additional args will be spread as additional args on implementatio } }); - runner.chain.before(function (a) { - t.deepEqual(slice.call(arguments, 1), ['foo', 'bar']); + runner.chain.before((a, ...rest) => { + t.deepEqual(rest, ['foo', 'bar']); a.pass(); }, 'foo', 'bar'); - runner.chain('test1', function (a) { - t.deepEqual(slice.call(arguments, 1), ['foo', 'bar']); + runner.chain('test1', (a, ...rest) => { + t.deepEqual(rest, ['foo', 'bar']); a.pass(); }, 'foo', 'bar'); }); @@ -606,8 +607,8 @@ test('macros: Customize test names attaching a `title` function', t => { ['C'] ]; - function macroFn(avaT) { - t.deepEqual(slice.call(arguments, 1), expectedArgs.shift()); + function macroFn(avaT, ...rest) { + t.deepEqual(rest, expectedArgs.shift()); avaT.pass(); } @@ -684,16 +685,18 @@ test('arrays of macros', t => { ['D'] ]; - function macroFnA(a) { - t.deepEqual(slice.call(arguments, 1), expectedArgsA.shift()); + function macroFnA(a, ...rest) { + t.deepEqual(rest, expectedArgsA.shift()); a.pass(); } + macroFnA.title = prefix => `${prefix}.A`; - function macroFnB(a) { - t.deepEqual(slice.call(arguments, 1), expectedArgsB.shift()); + function macroFnB(a, ...rest) { + t.deepEqual(rest, expectedArgsB.shift()); a.pass(); } + macroFnB.title = prefix => `${prefix}.B`; return promiseEnd(new Runner(), runner => { @@ -721,17 +724,20 @@ test('match applies to arrays of macros', t => { t.fail(); a.pass(); } + fooMacro.title = (title, firstArg) => `${firstArg}foo`; function barMacro(avaT) { avaT.pass(); } + barMacro.title = (title, firstArg) => `${firstArg}bar`; function bazMacro(a) { t.fail(); a.pass(); } + bazMacro.title = (title, firstArg) => `${firstArg}baz`; return promiseEnd(new Runner({match: ['foobar']}), runner => { diff --git a/test/serialize-error.js b/test/serialize-error.js index 67371085b..073e5823e 100644 --- a/test/serialize-error.js +++ b/test/serialize-error.js @@ -8,7 +8,7 @@ const sourceMapFixtures = require('source-map-fixtures'); const sourceMapSupport = require('source-map-support'); const tempWrite = require('temp-write'); const uniqueTempDir = require('unique-temp-dir'); -const test = require('tap').test; +const {test} = require('tap'); const avaAssert = require('../lib/assert'); const beautifyStack = require('../lib/beautify-stack'); const serializeError = require('../lib/serialize-error'); diff --git a/test/test.js b/test/test.js index 89f74f625..53df88758 100644 --- a/test/test.js +++ b/test/test.js @@ -4,7 +4,7 @@ require('../lib/worker/options').set({color: false}); const path = require('path'); const React = require('react'); -const test = require('tap').test; +const {test} = require('tap'); const delay = require('delay'); const snapshotManager = require('../lib/snapshot-manager'); const Test = require('../lib/test'); @@ -517,6 +517,7 @@ test('multiple resolving and rejecting promises passed to t.throws/t.notThrows', a.notThrowsAsync(delay(10)) ); } + return Promise.all(promises); }); return instance.run().then(result => { diff --git a/test/watcher.js b/test/watcher.js index 336a5c585..94a9f1f5e 100644 --- a/test/watcher.js +++ b/test/watcher.js @@ -2,15 +2,14 @@ 'use strict'; const path = require('path'); const EventEmitter = require('events'); -const PassThrough = require('stream').PassThrough; +const {PassThrough} = require('stream'); const defaultIgnore = require('ignore-by-default').directories(); const lolex = require('lolex'); const proxyquire = require('proxyquire'); const sinon = require('sinon'); -const test = require('tap').test; +const {test} = require('tap'); const AvaFiles = require('../lib/ava-files'); - -const setImmediate = require('../lib/now-and-timers').setImmediate; +const {setImmediate} = require('../lib/now-and-timers'); // Helper to make using beforeEach less arduous function makeGroup(test) { @@ -34,6 +33,7 @@ function makeGroup(test) { }); }; } + const group = makeGroup(test); group('chokidar', (beforeEach, test, group) => { @@ -56,10 +56,8 @@ group('chokidar', (beforeEach, test, group) => { { chokidar, debug(name) { - return function () { - const args = [name]; - args.push.apply(args, arguments); - debug.apply(null, args); + return (...args) => { + debug(...[name, ...args]); }; }, './ava-files': avaFiles @@ -156,9 +154,11 @@ group('chokidar', (beforeEach, test, group) => { const add = path => { emitChokidar('add', path || 'source.js'); }; + const change = path => { emitChokidar('change', path || 'source.js'); }; + const unlink = path => { emitChokidar('unlink', path || 'source.js'); }; @@ -568,6 +568,7 @@ group('chokidar', (beforeEach, test, group) => { ret.excludePatterns = ['!*bar*']; return ret; }; + Subject = proxyWatcher(); files = ['foo-{bar,baz}.js']; @@ -890,6 +891,7 @@ group('chokidar', (beforeEach, test, group) => { api.on = (event, fn) => { apiEmitter.on(event, fn); }; + runStatusEmitter = new EventEmitter(); runStatus = { stats: { @@ -1109,6 +1111,7 @@ group('chokidar', (beforeEach, test, group) => { for (let i = index; i >= 0; i--) { relPath = path.join(relPath, String(i)); } + return `${relPath}.js`; }); @@ -1217,6 +1220,7 @@ group('chokidar', (beforeEach, test, group) => { api.on = (event, fn) => { apiEmitter.on(event, fn); }; + runStatusEmitter = new EventEmitter(); runStatus = { stats: { @@ -1382,6 +1386,7 @@ group('chokidar', (beforeEach, test, group) => { api.on = (event, fn) => { apiEmitter.on(event, fn); }; + runStatusEmitter = new EventEmitter(); runStatus = { stats: {