Skip to content

Commit

Permalink
Use chalk instead of managing our own colorization.
Browse files Browse the repository at this point in the history
Summary:
This is arguably slightly nicer but also avoids having to lookup config.noHighlight, instead just turning that off in chalk at the top level when we see that flag.

The other thing this provides is that we never have to do resets ourselves, which resulted in a bug recently (which was why I looked into this at all).
Closes jestjs#639

Reviewed By: svcscm

Differential Revision: D2746396

fb-gh-sync-id: c66a193d55d0d04c9550d16a4970c5b1fabfcd4a
  • Loading branch information
zpao authored and facebook-github-bot-6 committed Dec 11, 2015
1 parent c90543d commit 02d8803
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 112 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"version": "0.8.1",
"main": "src/jest.js",
"dependencies": {
"chalk": "^1.1.1",
"cover": "^0.2.9",
"diff": "^2.1.1",
"graceful-fs": "^4.1.2",
Expand Down
6 changes: 3 additions & 3 deletions src/Console.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@

const util = require('util');
const Console = require('console').Console;
const colors = require('./lib/colors');
const chalk = require('chalk');

class CustomConsole extends Console {
warn() {
return super.warn(
colors.colorize(util.format.apply(this, arguments), colors.YELLOW)
chalk.yellow(util.format.apply(this, arguments))
);
}

error() {
return super.error(
colors.colorize(util.format.apply(this, arguments), colors.RED)
chalk.red(util.format.apply(this, arguments))
);
}
}
Expand Down
51 changes: 24 additions & 27 deletions src/DefaultTestReporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,22 @@
*/
'use strict';

const colors = require('./lib/colors');
const chalk = require('chalk');
const formatFailureMessage = require('./lib/utils').formatFailureMessage;
const formatMsg = require('./lib/utils').formatMsg;
const path = require('path');
const VerboseLogger = require('./lib/testLogger');

const FAIL_COLOR = colors.RESET + colors.RED_BG + colors.BOLD;
const PASS_COLOR = colors.RESET + colors.GREEN_BG + colors.BOLD;
const TEST_NAME_COLOR = colors.BOLD;
// Explicitly reset for these messages since they can get written out in the
// middle of error logging (should have listened to Spengler and not crossed the
// streams).
const FAIL_COLOR = chalk.reset.bold.bgRed;
const PASS_COLOR = chalk.reset.bold.bgGreen;

const FAIL_RESULTS_COLOR = chalk.bold.red;
const PASS_RESULTS_COLOR = chalk.bold.green;
const RUNNING_TEST_COLOR = chalk.bold.gray;
const TEST_NAME_COLOR = chalk.bold;
const LONG_TEST_COLOR = FAIL_COLOR;

class DefaultTestReporter {

Expand Down Expand Up @@ -53,7 +60,7 @@ class DefaultTestReporter {
if (testRunTime !== null) {
testDetail.push(
testRunTime > 2.5
? this._formatMsg(testRunTime + 's', FAIL_COLOR)
? LONG_TEST_COLOR(testRunTime + 's')
: testRunTime + 's'
);
}
Expand Down Expand Up @@ -130,27 +137,24 @@ class DefaultTestReporter {

let results = '';
if (numFailedTests) {
results += this._formatMsg(
results += FAIL_RESULTS_COLOR(
numFailedTests + ' test' +
(numFailedTests === 1 ? '' : 's') + ' failed',
colors.RED + colors.BOLD
(numFailedTests === 1 ? '' : 's') + ' failed'
);
results += ', ';
}

if (aggregatedResults.numRuntimeErrorTestSuites) {
results += this._formatMsg(
results += FAIL_RESULTS_COLOR(
aggregatedResults.numRuntimeErrorTestSuites + ' test suite' +
(aggregatedResults.numRuntimeErrorTestSuites === 1 ? '' : 's') +
' failed',
colors.RED + colors.BOLD
(aggregatedResults.numRuntimeErrorTestSuites === 1 ? '' : 's') +
' failed'
);
results += ', ';
}

results += this._formatMsg(
numPassedTests + ' test' + (numPassedTests === 1 ? '' : 's') + ' passed',
colors.GREEN + colors.BOLD
results += PASS_RESULTS_COLOR(
numPassedTests + ' test' + (numPassedTests === 1 ? '' : 's') + ' passed'
);

results += ' (' + numTotalTests + ' total in ' +
Expand All @@ -170,18 +174,12 @@ class DefaultTestReporter {
this._process.stdout.write(command);
}

_formatMsg(msg, color) {
return formatMsg(msg, color, this._config);
}

_getResultHeader(passed, testName, columns) {
const passFailTag = passed
? this._formatMsg(' PASS ', PASS_COLOR)
: this._formatMsg(' FAIL ', FAIL_COLOR);
const passFailTag = passed ? PASS_COLOR(' PASS ') : FAIL_COLOR(' FAIL ');

return [
passFailTag,
this._formatMsg(testName, TEST_NAME_COLOR),
TEST_NAME_COLOR(testName),
].concat(columns || []).join(' ');
}

Expand All @@ -197,9 +195,8 @@ class DefaultTestReporter {
const pluralTestSuites =
remainingTestSuites === 1 ? 'test suite' : 'test suites';
this._process.stdout.write(
this._formatMsg(
'Running ' + remainingTestSuites + ' ' + pluralTestSuites + '...',
colors.GRAY + colors.BOLD
RUNNING_TEST_COLOR(
'Running ' + remainingTestSuites + ' ' + pluralTestSuites + '...'
)
);
}
Expand Down
6 changes: 6 additions & 0 deletions src/jest.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const path = require('path');
const TestRunner = require('./TestRunner');
const formatTestResults = require('./lib/formatTestResults');
const utils = require('./lib/utils');
const chalk = require('chalk');

let jestVersion = null;
function getVersion() {
Expand Down Expand Up @@ -202,6 +203,11 @@ function runCLI(argv, packageRoot, onComplete) {
const pipe = argv.json ? process.stderr : process.stdout;
readConfig(argv, packageRoot)
.then(config => {
// Disable colorization
if (config.noHighlight) {
chalk.enabled = false;
}

const testRunner = new TestRunner(config, testRunnerOptions(argv));
const testFramework = require(config.testRunner);
pipe.write(`Using Jest CLI v${getVersion()}, ${testFramework.name}\n`);
Expand Down
25 changes: 0 additions & 25 deletions src/lib/colors.js

This file was deleted.

20 changes: 5 additions & 15 deletions src/lib/testLogger.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
*/
'use strict';

const colors = require('./colors');
const formatMsg = require('./utils').formatMsg;
const chalk = require('chalk');

/**
* Creates a VerboseLogger object used to encapsulate verbose logging.
Expand Down Expand Up @@ -86,31 +85,22 @@ VerboseLogger.prototype.traverseTestResults = function(node, indentation) {
* @param {string} indentation - Indentation used for formatting.
*/
VerboseLogger.prototype.printTestTitles = function(testTitles, indentation) {
let prefixColor, statusPrefix;
let statusPrefix;

for (let i = 0; i < testTitles.length; i++) {
if (testTitles[i].failureMessages.length === 0) {
prefixColor = colors.GREEN;
statusPrefix = this._config.noHighlight ? 'PASS - ' : '\u2713 ';
statusPrefix = chalk.green('\u2713 ');
} else {
prefixColor = colors.RED;
statusPrefix = this._config.noHighlight ? 'FAIL - ' : '\u2715 ';
statusPrefix = chalk.red('\u2715 ');
}
this.log(
this._formatMsg(indentation + statusPrefix, prefixColor)
+ this._formatMsg(testTitles[i].title, colors.GRAY)
);
this.log(indentation + statusPrefix + chalk.gray(testTitles[i].title));
}
};

VerboseLogger.prototype.log = function(str) {
this._process.stdout.write(str + '\n');
};

VerboseLogger.prototype._formatMsg = function(msg, color) {
return formatMsg(msg, color, this._config);
};

/**
* Prepares the test hierarchy for a `test title` by mapping its ancestry.
*
Expand Down
19 changes: 5 additions & 14 deletions src/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
'use strict';

const colors = require('./colors');
const chalk = require('chalk');
const fs = require('graceful-fs');
const path = require('path');

Expand Down Expand Up @@ -376,15 +376,15 @@ function formatFailureMessage(testResult, config) {
const rootPath = config.rootPath;
const useColor = config.useColor;

const colorize = useColor ? colors.colorize : function(str) { return str; };
const localChalk = new chalk.constructor({enabled: !!useColor});
const ancestrySeparator = ' \u203A ';
const descBullet = colorize('\u25cf ', colors.BOLD);
const descBullet = localChalk.bold('\u25cf ');
const msgBullet = ' - ';
const msgIndent = msgBullet.replace(/./g, ' ');

if (testResult.testExecError) {
const text = testResult.testExecError;
return descBullet + colorize('Runtime Error', colors.BOLD) + '\n' + text;
return descBullet + localChalk.bold('Runtime Error') + '\n' + text;
}

return testResult.testResults.filter(function(result) {
Expand Down Expand Up @@ -418,22 +418,14 @@ function formatFailureMessage(testResult, config) {
}).join('\n');

const testTitleAncestry = result.ancestorTitles.map(function(title) {
return colorize(title, colors.BOLD);
return localChalk.bold(title);
}).join(ancestrySeparator) + ancestrySeparator;

return descBullet + testTitleAncestry + result.title + '\n' +
failureMessages;
}).join('\n');
}

function formatMsg(msg, color, _config) {
_config = _config || {};
if (_config.noHighlight) {
return msg;
}
return colors.colorize(msg, color);
}

function deepCopy(obj) {
const newObj = {};
let value;
Expand All @@ -457,7 +449,6 @@ const STACK_TRACE_LINE_IGNORE_RE = new RegExp([

exports.deepCopy = deepCopy;
exports.escapeStrForRegex = escapeStrForRegex;
exports.formatMsg = formatMsg;
exports.getLineCoverageFromCoverageInfo = getLineCoverageFromCoverageInfo;
exports.getLinePercentCoverageFromCoverageInfo =
getLinePercentCoverageFromCoverageInfo;
Expand Down
31 changes: 11 additions & 20 deletions src/testRunners/jasmine/JasmineFormatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@
'use strict';

const diff = require('diff');
const colors = require('../../lib/colors');
const formatMsg = require('../../lib/utils').formatMsg;
const chalk = require('chalk');

const ERROR_TITLE_COLOR = chalk.bold.underline.red;
const KEEP_TRACE_LINES = 2;
const ERROR_TITLE_COLOR = colors.RED + colors.BOLD + colors.UNDERLINE;
const DIFFABLE_MATCHERS = Object.assign(Object.create(null), {
toBe: true,
toNotBe: true,
Expand All @@ -30,24 +29,16 @@ class JasmineFormatter {
this._jasmine = jasmine;
}

formatMsg(msg, color) {
return formatMsg(msg, color, this._config);
}

formatFailure(msg) {
return this.formatMsg(msg, ERROR_TITLE_COLOR);
}

formatDiffable(matcherName, isNot, actual, expected) {
const ppActual = this.prettyPrint(actual);
const ppExpected = this.prettyPrint(expected);
const colorDiff = this.highlightDifferences(ppActual, ppExpected);
matcherName = (isNot ? 'NOT ' : '') + matcherName;

return this.formatMsg('Expected:', ERROR_TITLE_COLOR) +
' ' + colorDiff.a +
' ' + this.formatMsg(matcherName + ':', ERROR_TITLE_COLOR) +
' ' + colorDiff.b;
return (
ERROR_TITLE_COLOR('Expected:') + ' ' + colorDiff.a + ' ' +
ERROR_TITLE_COLOR(matcherName + ':') + ' ' + colorDiff.b
);
}

formatMatchFailure(result) {
Expand All @@ -62,7 +53,7 @@ class JasmineFormatter {
result.expected
);
} else {
message = this.formatFailure(result.message);
message = ERROR_TITLE_COLOR(result.message);
}

// error message & stack live on 'trace' field in jasmine 1.3
Expand All @@ -80,7 +71,7 @@ class JasmineFormatter {
// colorize the `message` value
return this.cleanStackTrace(stackTrace.replace(
/(^(.|\n)*?(?=\n\s*at\s))/,
this.formatFailure('$1')
ERROR_TITLE_COLOR('$1')
));
}

Expand All @@ -100,9 +91,9 @@ class JasmineFormatter {
for (let i = 0, il = changes.length; i < il; i++) {
const change = changes[i];
if (change.added) {
ret.b += this.formatMsg(change.value, colors.RED_BG);
ret.b += chalk.bgRed(change.value);
} else if (change.removed) {
ret.a += this.formatMsg(change.value, colors.RED_BG);
ret.a += chalk.bgRed(change.value);
} else {
ret.a += change.value;
ret.b += change.value;
Expand Down Expand Up @@ -141,7 +132,7 @@ class JasmineFormatter {
const orderedKeys = Object.keys(obj).sort();
let value;
const keysOutput = [];
const keyIndent = this.formatMsg('|', colors.GRAY) + ' ';
const keyIndent = chalk.gray('|') + ' ';
for (let i = 0; i < orderedKeys.length; i++) {
value = obj[orderedKeys[i]];
keysOutput.push(
Expand Down
8 changes: 4 additions & 4 deletions src/testRunners/jasmine/__tests__/Jasmine2Reporter-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ jest.autoMockOff();

describe('Jasmine2Reporter', function() {
var JasmineReporter;
var colors;
var chalk;
var reporter;

beforeEach(function() {
JasmineReporter = require('../Jasmine2Reporter');
colors = require('../../../lib/colors');
chalk = require('chalk');

reporter = new JasmineReporter();
});
Expand Down Expand Up @@ -87,11 +87,11 @@ describe('Jasmine2Reporter', function() {
}

function errorize(str) {
return colors.RED + colors.BOLD + colors.UNDERLINE + str + colors.RESET;
return chalk.bold.underline.red(str);
}

function highlight(str) {
return colors.RED_BG + str + colors.RESET;
return chalk.bgRed(str);
}

pit('colorizes single-line failures using a per-char diff', function() {
Expand Down
Loading

0 comments on commit 02d8803

Please sign in to comment.