From 931501a1fe29ecebecf13b35a03783dc1c983b23 Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 16 Jan 2017 15:37:04 +0100 Subject: [PATCH 1/4] Added support for --no-color flag in verbose and mini reporters --- lib/cli.js | 12 ++++++---- lib/fork.js | 4 +++- lib/reporters/mini.js | 9 +++++-- lib/reporters/verbose.js | 9 +++---- readme.md | 1 + test/reporters/mini.js | 37 +++++++++++++++++++++++++---- test/reporters/verbose.js | 50 +++++++++++++++++++++++++++++---------- 7 files changed, 93 insertions(+), 29 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index e170c49b7..51304cdfe 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -68,9 +68,10 @@ exports.run = () => { 'tap', 'verbose', 'watch', - 'update-snapshots' + 'update-snapshots', + 'color' ], - default: conf, + default: Object.assign({color: true}, conf), alias: { t: 'tap', v: 'verbose', @@ -118,7 +119,8 @@ exports.run = () => { pkgDir, timeout: cli.flags.timeout, concurrency: cli.flags.concurrency ? parseInt(cli.flags.concurrency, 10) : 0, - updateSnapshots: cli.flags.updateSnapshots + updateSnapshots: cli.flags.updateSnapshots, + color: cli.flags.color }); let reporter; @@ -126,9 +128,9 @@ exports.run = () => { if (cli.flags.tap && !cli.flags.watch) { reporter = new TapReporter(); } else if (cli.flags.verbose || isCi) { - reporter = new VerboseReporter({basePath: pkgDir}); + reporter = new VerboseReporter({color: cli.flags.color, basePath: pkgDir}); } else { - reporter = new MiniReporter({watching: cli.flags.watch, basePath: pkgDir}); + reporter = new MiniReporter({color: cli.flags.color, watching: cli.flags.watch, basePath: pkgDir}); } reporter.api = api; diff --git a/lib/fork.js b/lib/fork.js index fa960f106..f728c8290 100644 --- a/lib/fork.js +++ b/lib/fork.js @@ -36,7 +36,9 @@ module.exports = (file, opts, execArgv) => { } : false }, opts); - const ps = childProcess.fork(path.join(__dirname, 'test-worker.js'), [JSON.stringify(opts)], { + const args = [JSON.stringify(opts), opts.color ? '--color' : '--no-color']; + + const ps = childProcess.fork(path.join(__dirname, 'test-worker.js'), args, { cwd: opts.pkgDir, silent: true, env, diff --git a/lib/reporters/mini.js b/lib/reporters/mini.js index 05b92a926..cbe858735 100644 --- a/lib/reporters/mini.js +++ b/lib/reporters/mini.js @@ -42,12 +42,17 @@ function eraseLines(count) { class MiniReporter { constructor(options) { + this.options = Object.assign({}, options); + + chalk.enabled = this.options.color; + for (const key of Object.keys(colors)) { + colors[key].enabled = this.options.color; + } + const spinnerDef = spinners[process.platform === 'win32' ? 'line' : 'dots']; this.spinnerFrames = spinnerDef.frames.map(c => chalk.gray.dim(c)); this.spinnerInterval = spinnerDef.interval; - this.options = Object.assign({}, options); - this.reset(); this.stream = process.stderr; this.stringDecoder = new StringDecoder(); diff --git a/lib/reporters/verbose.js b/lib/reporters/verbose.js index bd7f8cf02..46ca74681 100644 --- a/lib/reporters/verbose.js +++ b/lib/reporters/verbose.js @@ -10,13 +10,14 @@ const extractStack = require('../extract-stack'); const codeExcerpt = require('../code-excerpt'); const colors = require('../colors'); -Object.keys(colors).forEach(key => { - colors[key].enabled = true; -}); - class VerboseReporter { constructor(options) { this.options = Object.assign({}, options); + + chalk.enabled = options.color; + for (const key of Object.keys(colors)) { + colors[key].enabled = options.color; + } } start() { return ''; diff --git a/readme.md b/readme.md index 456e900ba..63f788414 100644 --- a/readme.md +++ b/readme.md @@ -163,6 +163,7 @@ $ ava --help --verbose, -v Enable verbose output --no-cache Disable the transpiler cache --no-power-assert Disable Power Assert + --no-color Disable color output --match, -m Only run tests with matching title (Can be repeated) --watch, -w Re-run tests when tests and source files change --timeout, -T Set global timeout diff --git a/test/reporters/mini.js b/test/reporters/mini.js index 804c055d3..d7028f5c4 100644 --- a/test/reporters/mini.js +++ b/test/reporters/mini.js @@ -27,6 +27,9 @@ process.stdout.columns = 5000; const fullWidthLine = chalk.gray.dim('\u2500'.repeat(5000)); function miniReporter(options) { + if (options === undefined) { + options = {color: true}; + } const reporter = new MiniReporter(options); reporter.start = () => ''; return reporter; @@ -35,7 +38,7 @@ function miniReporter(options) { process.stderr.setMaxListeners(50); test('start', t => { - const reporter = new MiniReporter(); + const reporter = new MiniReporter({color: true}); t.is(reporter.start(), ' \n ' + graySpinner + ' '); reporter.clearInterval(); @@ -432,7 +435,7 @@ test('results with errors and disabled code excerpts', t => { err2.expected = JSON.stringify([2]); err2.expectedType = 'array'; - const reporter = miniReporter({basePath: path.dirname(err2Path)}); + const reporter = miniReporter({color: true, basePath: path.dirname(err2Path)}); reporter.failCount = 1; const runStatus = { @@ -495,7 +498,7 @@ test('results with errors and broken code excerpts', t => { err2.expected = JSON.stringify([2]); err2.expectedType = 'array'; - const reporter = miniReporter({basePath: path.dirname(err2Path)}); + const reporter = miniReporter({color: true, basePath: path.dirname(err2Path)}); reporter.failCount = 1; const runStatus = { @@ -559,7 +562,7 @@ test('results with errors and disabled assert output', t => { err2.expected = JSON.stringify([2]); err2.expectedType = 'array'; - const reporter = miniReporter({basePath: path.dirname(err1Path)}); + const reporter = miniReporter({color: true, basePath: path.dirname(err1Path)}); reporter.failCount = 1; const runStatus = { @@ -731,7 +734,7 @@ test('results with watching enabled', t => { lolex.install(new Date(2014, 11, 19, 17, 19, 12, 200).getTime(), ['Date']); const time = ' ' + chalk.grey.dim('[17:19:12]'); - const reporter = miniReporter({watching: true}); + const reporter = miniReporter({color: true, watching: true}); reporter.passCount = 1; reporter.failCount = 0; @@ -905,3 +908,27 @@ test('results when hasExclusive is enabled, but there are multiple remaining tes t.is(actualOutput, expectedOutput); t.end(); }); + +test('result when no-color flag is set', t => { + const reporter = miniReporter({ + color: false + }); + + const runStatus = { + hasExclusive: true, + testCount: 3, + passCount: 1, + failCount: 0, + remainingCount: 2 + }; + + const output = reporter.finish(runStatus); + const expectedOutput = [ + '', + '', + ' The .only() modifier is used in some tests. 2 tests were not run', + '\n' + ].join('\n'); + t.is(output, expectedOutput); + t.end(); +}); diff --git a/test/reporters/verbose.js b/test/reporters/verbose.js index 4286c1696..fce06fd24 100644 --- a/test/reporters/verbose.js +++ b/test/reporters/verbose.js @@ -23,6 +23,9 @@ lolex.install(new Date(2014, 11, 19, 17, 19, 12, 200).getTime(), ['Date']); const time = ' ' + chalk.grey.dim('[17:19:12]'); function createReporter(options) { + if (options === undefined) { + options = {color: true}; + } const reporter = new VerboseReporter(options); return reporter; } @@ -378,7 +381,7 @@ test('results with errors', t => { error2.expected = JSON.stringify([2]); error2.expectedType = 'array'; - const reporter = createReporter({basePath: path.dirname(err1Path)}); + const reporter = createReporter({color: true, basePath: path.dirname(err1Path)}); const runStatus = createRunStatus(); runStatus.failCount = 1; runStatus.tests = [{ @@ -439,7 +442,7 @@ test('results with errors and disabled code excerpts', t => { error2.expected = JSON.stringify([2]); error2.expectedType = 'array'; - const reporter = createReporter({basePath: path.dirname(err2Path)}); + const reporter = createReporter({color: true, basePath: path.dirname(err2Path)}); const runStatus = createRunStatus(); runStatus.failCount = 1; runStatus.tests = [{ @@ -499,7 +502,7 @@ test('results with errors and disabled code excerpts', t => { error2.expected = JSON.stringify([2]); error2.expectedType = 'array'; - const reporter = createReporter({basePath: path.dirname(err2Path)}); + const reporter = createReporter({color: true, basePath: path.dirname(err2Path)}); const runStatus = createRunStatus(); runStatus.failCount = 1; runStatus.tests = [{ @@ -560,7 +563,7 @@ test('results with errors and disabled assert output', t => { error2.expected = JSON.stringify([2]); error2.expectedType = 'array'; - const reporter = createReporter({basePath: path.dirname(err1Path)}); + const reporter = createReporter({color: true, basePath: path.dirname(err1Path)}); const runStatus = createRunStatus(); runStatus.failCount = 1; runStatus.tests = [{ @@ -602,7 +605,7 @@ test('results with errors and disabled assert output', t => { }); test('results when fail-fast is enabled', t => { - const reporter = new VerboseReporter(); + const reporter = createReporter(); const runStatus = createRunStatus(); runStatus.remainingCount = 1; runStatus.failCount = 1; @@ -626,7 +629,7 @@ test('results when fail-fast is enabled', t => { }); test('results without fail-fast if no failing tests', t => { - const reporter = new VerboseReporter(); + const reporter = createReporter(); const runStatus = createRunStatus(); runStatus.remainingCount = 1; runStatus.failCount = 0; @@ -645,7 +648,7 @@ test('results without fail-fast if no failing tests', t => { }); test('results without fail-fast if no skipped tests', t => { - const reporter = new VerboseReporter(); + const reporter = createReporter(); const runStatus = createRunStatus(); runStatus.remainingCount = 0; runStatus.failCount = 1; @@ -715,7 +718,7 @@ test('full-width line when sectioning', t => { test('write calls console.error', t => { const stub = sinon.stub(console, 'error'); - const reporter = new VerboseReporter(); + const reporter = createReporter(); reporter.write('result'); t.true(stub.called); console.error.restore(); @@ -723,7 +726,7 @@ test('write calls console.error', t => { }); test('reporter.stdout and reporter.stderr both use process.stderr.write', t => { - const reporter = new VerboseReporter(); + const reporter = createReporter(); const stub = sinon.stub(process.stderr, 'write'); reporter.stdout('result'); reporter.stderr('result'); @@ -733,7 +736,7 @@ test('reporter.stdout and reporter.stderr both use process.stderr.write', t => { }); test('results when hasExclusive is enabled, but there are no known remaining tests', t => { - const reporter = new VerboseReporter(); + const reporter = createReporter(); const runStatus = createRunStatus(); runStatus.hasExclusive = true; runStatus.passCount = 1; @@ -750,7 +753,7 @@ test('results when hasExclusive is enabled, but there are no known remaining tes }); test('results when hasExclusive is enabled, but there is one remaining tests', t => { - const reporter = new VerboseReporter(); + const reporter = createReporter(); const runStatus = createRunStatus(); runStatus.hasExclusive = true; runStatus.testCount = 2; @@ -773,7 +776,7 @@ test('results when hasExclusive is enabled, but there is one remaining tests', t }); test('results when hasExclusive is enabled, but there are multiple remaining tests', t => { - const reporter = new VerboseReporter(); + const reporter = createReporter(); const runStatus = createRunStatus(); runStatus.hasExclusive = true; runStatus.testCount = 3; @@ -794,3 +797,26 @@ test('results when hasExclusive is enabled, but there are multiple remaining tes t.is(output, expectedOutput); t.end(); }); + +test('result when no-color flag is set', t => { + const reporter = new VerboseReporter({color: false}); + const runStatus = createRunStatus(); + runStatus.hasExclusive = true; + runStatus.testCount = 3; + runStatus.passCount = 1; + runStatus.failCount = 0; + runStatus.remainingCount = 2; + + const output = reporter.finish(runStatus); + const expectedOutput = [ + '', + ' 1 test passed [17:19:12]', + '', + '', + ' The .only() modifier is used in some tests. 2 tests were not run', + '' + ].join('\n'); + + t.is(output, expectedOutput); + t.end(); +}); From 8f07c41e362dd366513aee874c0390c56fc472b1 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 29 Jan 2017 17:03:08 +0100 Subject: [PATCH 2/4] Improve use of for...of loop to enable / disable colors. Removed chalk and colors when throwing bable-config error --- lib/babel-config.js | 6 ++---- lib/reporters/mini.js | 5 ----- test/cli.js | 5 ++--- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/lib/babel-config.js b/lib/babel-config.js index 3ef31a9e1..545648583 100644 --- a/lib/babel-config.js +++ b/lib/babel-config.js @@ -1,9 +1,7 @@ 'use strict'; const path = require('path'); -const chalk = require('chalk'); const figures = require('figures'); const convertSourceMap = require('convert-source-map'); -const colors = require('./colors'); function validate(conf) { if (conf === undefined || conf === null) { @@ -14,9 +12,9 @@ function validate(conf) { const isValidShortcut = conf === 'default' || conf === 'inherit'; if (!conf || (typeof conf === 'string' && !isValidShortcut)) { - let message = colors.error(figures.cross); + let message = figures.cross; message += ' Unexpected Babel configuration for AVA. '; - message += 'See ' + chalk.underline('https://github.com/avajs/ava#es2015-support') + ' for allowed values.'; + message += 'See https://github.com/avajs/ava#es2015-support for allowed values.'; throw new Error(message); } diff --git a/lib/reporters/mini.js b/lib/reporters/mini.js index cbe858735..2588f7eaa 100644 --- a/lib/reporters/mini.js +++ b/lib/reporters/mini.js @@ -14,11 +14,6 @@ const extractStack = require('../extract-stack'); const codeExcerpt = require('../code-excerpt'); const colors = require('../colors'); -chalk.enabled = true; -Object.keys(colors).forEach(key => { - colors[key].enabled = true; -}); - // TODO(@jamestalamge): This should be fixed in log-update and ansi-escapes once we are confident it's a good solution. const CSI = '\u001b['; const ERASE_LINE = CSI + '2K'; diff --git a/test/cli.js b/test/cli.js index de8eddcd4..9b57bc017 100644 --- a/test/cli.js +++ b/test/cli.js @@ -17,7 +17,6 @@ const cliPath = path.join(__dirname, '../cli.js'); // For some reason chalk is disabled by default chalk.enabled = true; -const colors = require('../lib/colors'); function execCli(args, opts, cb) { let dirname; @@ -75,8 +74,8 @@ test('disallow invalid babel config shortcuts', t => { t.ok(err); let expectedOutput = '\n '; - expectedOutput += colors.error(figures.cross) + ' Unexpected Babel configuration for AVA.'; - expectedOutput += ' See ' + chalk.underline('https://github.com/avajs/ava#es2015-support') + ' for allowed values.'; + expectedOutput += figures.cross + ' Unexpected Babel configuration for AVA.'; + expectedOutput += ' See https://github.com/avajs/ava#es2015-support for allowed values.'; expectedOutput += '\n'; t.is(stderr, expectedOutput); From ba6b4e9c5329642b3750e9f29a8546e05625d46d Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 2 Feb 2017 06:49:47 +0100 Subject: [PATCH 3/4] Reverted changes done to babel-config.js. Enabled chalk and colors in cli.js test and pass the --color flag for the babel config test --- lib/babel-config.js | 6 ++++-- test/cli.js | 10 +++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/babel-config.js b/lib/babel-config.js index 545648583..3ef31a9e1 100644 --- a/lib/babel-config.js +++ b/lib/babel-config.js @@ -1,7 +1,9 @@ 'use strict'; const path = require('path'); +const chalk = require('chalk'); const figures = require('figures'); const convertSourceMap = require('convert-source-map'); +const colors = require('./colors'); function validate(conf) { if (conf === undefined || conf === null) { @@ -12,9 +14,9 @@ function validate(conf) { const isValidShortcut = conf === 'default' || conf === 'inherit'; if (!conf || (typeof conf === 'string' && !isValidShortcut)) { - let message = figures.cross; + let message = colors.error(figures.cross); message += ' Unexpected Babel configuration for AVA. '; - message += 'See https://github.com/avajs/ava#es2015-support for allowed values.'; + message += 'See ' + chalk.underline('https://github.com/avajs/ava#es2015-support') + ' for allowed values.'; throw new Error(message); } diff --git a/test/cli.js b/test/cli.js index 9b57bc017..7cd6809ca 100644 --- a/test/cli.js +++ b/test/cli.js @@ -12,11 +12,15 @@ const proxyquire = require('proxyquire'); const sinon = require('sinon'); const uniqueTempDir = require('unique-temp-dir'); const execa = require('execa'); +const colors = require('../lib/colors'); const cliPath = path.join(__dirname, '../cli.js'); // For some reason chalk is disabled by default chalk.enabled = true; +for (const key of Object.keys(colors)) { + colors[key].enabled = true; +} function execCli(args, opts, cb) { let dirname; @@ -70,12 +74,12 @@ function execCli(args, opts, cb) { } test('disallow invalid babel config shortcuts', t => { - execCli('es2015.js', {dirname: 'fixture/invalid-babel-config'}, (err, stdout, stderr) => { + execCli(['--color', 'es2015.js'], {dirname: 'fixture/invalid-babel-config'}, (err, stdout, stderr) => { t.ok(err); let expectedOutput = '\n '; - expectedOutput += figures.cross + ' Unexpected Babel configuration for AVA.'; - expectedOutput += ' See https://github.com/avajs/ava#es2015-support for allowed values.'; + expectedOutput += colors.error(figures.cross) + ' Unexpected Babel configuration for AVA.'; + expectedOutput += ' See ' + chalk.underline('https://github.com/avajs/ava#es2015-support') + ' for allowed values.'; expectedOutput += '\n'; t.is(stderr, expectedOutput); From 241073cb678ab5fde8f09f70074c65cc9cc17181 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 8 Feb 2017 14:51:22 +0700 Subject: [PATCH 4/4] Update cli.js --- lib/cli.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/cli.js b/lib/cli.js index 51304cdfe..968258725 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -38,6 +38,7 @@ exports.run = () => { --verbose, -v Enable verbose output --no-cache Disable the transpiler cache --no-power-assert Disable Power Assert + --no-color Disable color output --match, -m Only run tests with matching title (Can be repeated) --watch, -w Re-run tests when tests and source files change --timeout, -T Set global timeout