Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set default display name color based on runner #8689

Merged
merged 1 commit into from Aug 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,8 @@

### Features

- `[jest-config]` [**BREAKING**] Set default display name color based on runner ([#8689](https://github.com/facebook/jest/pull/8689))

### Fixes

- `[expect]` Display expectedDiff more carefully in toBeCloseTo ([#8389](https://github.com/facebook/jest/pull/8389))
Expand Down
Expand Up @@ -17,6 +17,16 @@ exports[`Upgrade help logs a warning when \`scriptPreprocessor\` and/or \`prepro
<yellow></>"
`;

exports[`displayName generates a default color for the runner jest-runner 1`] = `"yellow"`;

exports[`displayName generates a default color for the runner jest-runner-eslint 1`] = `"magenta"`;

exports[`displayName generates a default color for the runner jest-runner-tsc 1`] = `"red"`;

exports[`displayName generates a default color for the runner jest-runner-tslint 1`] = `"green"`;

exports[`displayName generates a default color for the runner undefined 1`] = `"white"`;

exports[`displayName should throw an error when displayName is is an empty object 1`] = `
"<red><bold><bold>● <bold>Validation Error</>:</>
<red></>
Expand Down
26 changes: 25 additions & 1 deletion packages/jest-config/src/__tests__/normalize.test.js
Expand Up @@ -24,8 +24,10 @@ let expectedPathFooQux;
let expectedPathAbs;
let expectedPathAbsAnother;

let virtualModuleRegexes;
beforeEach(() => (virtualModuleRegexes = [/jest-jasmine2/, /babel-jest/]));
const findNodeModule = jest.fn(name => {
if (name.match(/jest-jasmine2|babel-jest/)) {
if (virtualModuleRegexes.some(regex => regex.test(name))) {
return name;
}
return null;
Expand Down Expand Up @@ -1579,6 +1581,28 @@ describe('displayName', () => {
}).toThrowErrorMatchingSnapshot();
},
);

it.each([
undefined,
'jest-runner',
'jest-runner-eslint',
'jest-runner-tslint',
'jest-runner-tsc',
])('generates a default color for the runner %s', runner => {
virtualModuleRegexes.push(/jest-runner-.+/);
const {
options: {displayName},
} = normalize(
{
rootDir: '/root/',
displayName: 'project',
runner,
},
{},
);
expect(displayName.name).toBe('project');
expect(displayName.color).toMatchSnapshot();
});
});

describe('testTimeout', () => {
Expand Down
30 changes: 30 additions & 0 deletions packages/jest-config/src/color.ts
@@ -0,0 +1,30 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import {createHash} from 'crypto';
import chalk from 'chalk';

const colors: Array<keyof typeof chalk> = [
'red',
'green',
'yellow',
'blue',
'magenta',
'cyan',
'white',
];

export const getDisplayNameColor = (seed?: string) => {
if (seed === undefined) {
return 'white';
}

const hash = createHash('sha256');
hash.update(seed);
const num = hash.digest().readUInt32LE(0);
return colors[num % colors.length];
};
41 changes: 14 additions & 27 deletions packages/jest-config/src/normalize.ts
Expand Up @@ -16,7 +16,6 @@ import micromatch = require('micromatch');
import {sync as realpath} from 'realpath-native';
import Resolver = require('jest-resolve');
import {replacePathSepForRegex} from 'jest-regex-util';
import getType = require('jest-get-type');
import validatePattern from './validatePattern';
import getMaxWorkers from './getMaxWorkers';
import {
Expand All @@ -37,6 +36,7 @@ import DEFAULT_CONFIG from './Defaults';
import DEPRECATED_CONFIG from './Deprecated';
import setFromArgv from './setFromArgv';
import VALID_CONFIG from './ValidConfig';
import {getDisplayNameColor} from './color';
const ERROR = `${BULLET}Validation Error`;
const PRESET_EXTENSIONS = ['.json', '.js'];
const PRESET_NAME = 'jest-preset';
Expand Down Expand Up @@ -761,46 +761,33 @@ export default function normalize(
}
case 'displayName': {
const displayName = oldOptions[key] as Config.DisplayName;
if (typeof displayName === 'string') {
value = displayName;
break;
}
/**
* Ensuring that displayName shape is correct here so that the
* reporters can trust the shape of the data
* TODO: Normalize "displayName" such that given a config option
* {
* "displayName": "Test"
* }
* becomes
* {
* displayName: {
* name: "Test",
* color: "white"
* }
* }
*
* This can't be done now since this will be a breaking change
* for custom reporters
*/
if (getType(displayName) === 'object') {
const errorMessage =
` Option "${chalk.bold('displayName')}" must be of type:\n\n` +
' {\n' +
' name: string;\n' +
' color: string;\n' +
' }\n';
if (typeof displayName === 'object') {
const {name, color} = displayName;
if (
!name ||
!color ||
typeof name !== 'string' ||
typeof color !== 'string'
) {
const errorMessage =
` Option "${chalk.bold('displayName')}" must be of type:\n\n` +
' {\n' +
' name: string;\n' +
' color: string;\n' +
' }\n';
throw createConfigError(errorMessage);
}
value = oldOptions[key];
} else {
jeysal marked this conversation as resolved.
Show resolved Hide resolved
value = {
color: getDisplayNameColor(options.runner),
name: displayName,
};
}
value = oldOptions[key];
break;
}
case 'testTimeout': {
Expand Down