From 7248e89824f640b55335f55daf04d64f76c27235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Sun, 29 Jul 2018 10:11:53 +0200 Subject: [PATCH 1/9] wip --- packages/jest-config/src/valid_config.js | 4 +++ packages/jest-validate/src/utils.js | 4 ++- packages/jest-validate/src/validate.js | 41 +++++++++++++++++------- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/packages/jest-config/src/valid_config.js b/packages/jest-config/src/valid_config.js index 9dd1f21abb95..9c280a46e6aa 100644 --- a/packages/jest-config/src/valid_config.js +++ b/packages/jest-config/src/valid_config.js @@ -34,6 +34,9 @@ export default ({ coverageThreshold: { global: { branches: 50, + functions: 100, + lines: 100, + statements: 100, }, }, displayName: 'project-name', @@ -46,6 +49,7 @@ export default ({ globalTeardown: 'teardown.js', globals: {}, haste: { + platforms: ['ios', 'android'], providesModuleNodeModules: ['react', 'react-native'], }, json: false, diff --git a/packages/jest-validate/src/utils.js b/packages/jest-validate/src/utils.js index dccc27def3fd..64a47cfe5831 100644 --- a/packages/jest-validate/src/utils.js +++ b/packages/jest-validate/src/utils.js @@ -19,7 +19,9 @@ export const WARNING = `${BULLET} Validation Warning`; export const format = (value: any): string => typeof value === 'function' ? value.toString() - : prettyFormat(value, {min: true}); + : JSON.stringify(value, null, 2) + .split('\n') + .join('\n '); export class ValidationError extends Error { name: string; diff --git a/packages/jest-validate/src/validate.js b/packages/jest-validate/src/validate.js index 4faf817b67a4..036cbc7e9ab2 100644 --- a/packages/jest-validate/src/validate.js +++ b/packages/jest-validate/src/validate.js @@ -11,8 +11,21 @@ import type {ValidationOptions} from './types'; import defaultConfig from './default_config'; -const _validate = (config: Object, options: ValidationOptions) => { - let hasDeprecationWarnings = false; +let hasDeprecationWarnings = false; + +const _validate = ( + config: Object, + exampleConfig: Object, + options: ValidationOptions, +) => { + if ( + typeof config !== 'object' || + config == null || + typeof exampleConfig !== 'object' || + exampleConfig == null + ) { + return {hasDeprecationWarnings}; + } for (const key in config) { if ( @@ -28,26 +41,28 @@ const _validate = (config: Object, options: ValidationOptions) => { ); hasDeprecationWarnings = hasDeprecationWarnings || isDeprecatedKey; - } else if (hasOwnProperty.call(options.exampleConfig, key)) { + } else if (hasOwnProperty.call(exampleConfig, key)) { if ( typeof options.condition === 'function' && typeof options.error === 'function' && - !options.condition(config[key], options.exampleConfig[key]) + !options.condition(config[key], exampleConfig[key]) ) { - options.error(key, config[key], options.exampleConfig[key], options); + options.error(key, config[key], exampleConfig[key], options); } } else { - options.unknown && - options.unknown(config, options.exampleConfig, key, options); + options.unknown && options.unknown(config, exampleConfig, key, options); } + _validate(config[key], exampleConfig[key], options); } return {hasDeprecationWarnings}; }; const validate = (config: Object, options: ValidationOptions) => { - _validate(options, defaultConfig); // validate against jest-validate config - + hasDeprecationWarnings = false; + // _validate(options, options.exampleConfig, defaultConfig); // validate against jest-validate config + console.log(config); + console.log(config.exampleConfig); const defaultedOptions: ValidationOptions = Object.assign( {}, defaultConfig, @@ -55,10 +70,14 @@ const validate = (config: Object, options: ValidationOptions) => { {title: Object.assign({}, defaultConfig.title, options.title)}, ); - const {hasDeprecationWarnings} = _validate(config, defaultedOptions); + const {hasDeprecationWarnings: hdw} = _validate( + config, + options.exampleConfig, + defaultedOptions, + ); return { - hasDeprecationWarnings, + hasDeprecationWarnings: hdw, isValid: true, }; }; From 1edc9a28845249e8cd7d3cfd49e8e06262cb4a30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 1 Aug 2018 22:25:48 +0200 Subject: [PATCH 2/9] wip --- packages/jest-config/src/normalize.js | 6 +++++ packages/jest-config/src/valid_config.js | 2 ++ packages/jest-validate/src/default_config.js | 1 + packages/jest-validate/src/errors.js | 11 ++++++--- packages/jest-validate/src/types.js | 3 +++ packages/jest-validate/src/utils.js | 5 ++++ packages/jest-validate/src/validate.js | 24 +++++++++++++++----- packages/jest-validate/src/warnings.js | 7 +++--- 8 files changed, 47 insertions(+), 12 deletions(-) diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 5581f68247a7..19d2a8d962ac 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -332,6 +332,12 @@ const showTestPathPatternError = (testPathPattern: string) => { export default function normalize(options: InitialOptions, argv: Argv) { const {hasDeprecationWarnings} = validate(options, { + blacklist: [ + 'moduleNameMapper', + 'transform', + 'globals', + 'collectCoverageOnlyFrom', + ], comment: DOCUMENTATION_NOTE, deprecatedConfig: DEPRECATED_CONFIG, exampleConfig: VALID_CONFIG, diff --git a/packages/jest-config/src/valid_config.js b/packages/jest-config/src/valid_config.js index 9c280a46e6aa..d68aa7f001d6 100644 --- a/packages/jest-config/src/valid_config.js +++ b/packages/jest-config/src/valid_config.js @@ -49,6 +49,8 @@ export default ({ globalTeardown: 'teardown.js', globals: {}, haste: { + defaultPlatform: 'ios', + hasteImplModulePath: '/haste_impl.js', platforms: ['ios', 'android'], providesModuleNodeModules: ['react', 'react-native'], }, diff --git a/packages/jest-validate/src/default_config.js b/packages/jest-validate/src/default_config.js index a0d85b428146..a581efe11699 100644 --- a/packages/jest-validate/src/default_config.js +++ b/packages/jest-validate/src/default_config.js @@ -17,6 +17,7 @@ import validationCondition from './condition'; import {ERROR, DEPRECATION, WARNING} from './utils'; export default ({ + blacklist: [], comment: '', condition: validationCondition, deprecate: deprecationWarning, diff --git a/packages/jest-validate/src/errors.js b/packages/jest-validate/src/errors.js index 00d6fae5e47b..cb1589c71616 100644 --- a/packages/jest-validate/src/errors.js +++ b/packages/jest-validate/src/errors.js @@ -11,22 +11,27 @@ import type {ValidationOptions} from './types'; import chalk from 'chalk'; import getType from 'jest-get-type'; -import {format, ValidationError, ERROR} from './utils'; +import {formatPrettyObject, ValidationError, ERROR} from './utils'; export const errorMessage = ( option: string, received: any, defaultValue: any, options: ValidationOptions, + path?: Array, ): void => { - const message = ` Option ${chalk.bold(`"${option}"`)} must be of type: + const message = ` Option ${chalk.bold( + `"${path && path.length > 0 ? path.join('.') + '.' : ''}${option}"`, + )} must be of type: ${chalk.bold.green(getType(defaultValue))} but instead received: ${chalk.bold.red(getType(received))} Example: { - ${chalk.bold(`"${option}"`)}: ${chalk.bold(format(defaultValue))} + ${chalk.bold(`"${option}"`)}: ${chalk.bold( + formatPrettyObject(defaultValue), + )} }`; const comment = options.comment; diff --git a/packages/jest-validate/src/types.js b/packages/jest-validate/src/types.js index 3e32e567be24..805e2304b5b2 100644 --- a/packages/jest-validate/src/types.js +++ b/packages/jest-validate/src/types.js @@ -14,6 +14,7 @@ type Title = {| |}; export type ValidationOptions = { + blacklist?: Array, comment?: string, condition?: (option: any, validOption: any) => boolean, deprecate?: ( @@ -28,6 +29,7 @@ export type ValidationOptions = { received: any, defaultValue: any, options: ValidationOptions, + path?: Array, ) => void, exampleConfig: Object, title?: Title, @@ -36,5 +38,6 @@ export type ValidationOptions = { exampleConfig: Object, option: string, options: ValidationOptions, + path?: Array, ) => void, }; diff --git a/packages/jest-validate/src/utils.js b/packages/jest-validate/src/utils.js index 64a47cfe5831..f44912b6b723 100644 --- a/packages/jest-validate/src/utils.js +++ b/packages/jest-validate/src/utils.js @@ -17,6 +17,11 @@ export const ERROR = `${BULLET} Validation Error`; export const WARNING = `${BULLET} Validation Warning`; export const format = (value: any): string => + typeof value === 'function' + ? value.toString() + : prettyFormat(value, {min: true}); + +export const formatPrettyObject = (value: any): string => typeof value === 'function' ? value.toString() : JSON.stringify(value, null, 2) diff --git a/packages/jest-validate/src/validate.js b/packages/jest-validate/src/validate.js index 036cbc7e9ab2..881aeeb95e9d 100644 --- a/packages/jest-validate/src/validate.js +++ b/packages/jest-validate/src/validate.js @@ -17,6 +17,7 @@ const _validate = ( config: Object, exampleConfig: Object, options: ValidationOptions, + path: Array = [], ) => { if ( typeof config !== 'object' || @@ -47,12 +48,25 @@ const _validate = ( typeof options.error === 'function' && !options.condition(config[key], exampleConfig[key]) ) { - options.error(key, config[key], exampleConfig[key], options); + options.error(key, config[key], exampleConfig[key], options, path); } + } else if ( + options.blacklist && + options.blacklist.includes(path.join('.')) + ) { + // skip validating unknown options inside blacklisted paths } else { - options.unknown && options.unknown(config, exampleConfig, key, options); + options.unknown && + options.unknown(config, exampleConfig, key, options, path); + } + + if ( + !Array.isArray(exampleConfig[key]) && + options.blacklist && + !options.blacklist.includes(path.join('.')) + ) { + _validate(config[key], exampleConfig[key], options, [...path, key]); } - _validate(config[key], exampleConfig[key], options); } return {hasDeprecationWarnings}; @@ -60,9 +74,7 @@ const _validate = ( const validate = (config: Object, options: ValidationOptions) => { hasDeprecationWarnings = false; - // _validate(options, options.exampleConfig, defaultConfig); // validate against jest-validate config - console.log(config); - console.log(config.exampleConfig); + const defaultedOptions: ValidationOptions = Object.assign( {}, defaultConfig, diff --git a/packages/jest-validate/src/warnings.js b/packages/jest-validate/src/warnings.js index 435576c04eb6..69147f44718b 100644 --- a/packages/jest-validate/src/warnings.js +++ b/packages/jest-validate/src/warnings.js @@ -22,15 +22,16 @@ export const unknownOptionWarning = ( exampleConfig: Object, option: string, options: ValidationOptions, + path?: Array, ): void => { const didYouMean = createDidYouMeanMessage( option, Object.keys(exampleConfig), ); const message = - ` Unknown option ${chalk.bold(`"${option}"`)} with value ${chalk.bold( - format(config[option]), - )} was found.` + + ` Unknown option ${chalk.bold( + `"${path && path.length > 0 ? path.join('.') + '.' : ''}${option}"`, + )} with value ${chalk.bold(format(config[option]))} was found.` + (didYouMean && ` ${didYouMean}`) + `\n This is probably a typing mistake. Fixing it will remove this message.`; From 5c917e2a26dab5793f4662e355ecea11f3025784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Fri, 3 Aug 2018 18:06:30 +0200 Subject: [PATCH 3/9] update tests --- packages/jest-config/src/normalize.js | 1 + packages/jest-validate/README.md | 9 +- .../__snapshots__/validate.test.js.snap | 19 ++++- .../src/__tests__/validate.test.js | 84 +++++++++++++++---- packages/jest-validate/src/default_config.js | 4 +- packages/jest-validate/src/example_config.js | 2 + packages/jest-validate/src/types.js | 1 + packages/jest-validate/src/validate.js | 14 ++-- 8 files changed, 108 insertions(+), 26 deletions(-) diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 19d2a8d962ac..361dc6da7233 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -341,6 +341,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { comment: DOCUMENTATION_NOTE, deprecatedConfig: DEPRECATED_CONFIG, exampleConfig: VALID_CONFIG, + recursive: true, }); options = normalizePreprocessor( diff --git a/packages/jest-validate/README.md b/packages/jest-validate/README.md index a490975fe96f..680013ca4d67 100644 --- a/packages/jest-validate/README.md +++ b/packages/jest-validate/README.md @@ -18,6 +18,7 @@ Where `ValidationOptions` are: ```js type ValidationOptions = { + blacklist?: Array comment?: string, condition?: (option: any, validOption: any) => boolean, deprecate?: ( @@ -34,6 +35,7 @@ type ValidationOptions = { options: ValidationOptions, ) => void, exampleConfig: Object, + recursive?: boolean title?: Title, unknown?: ( config: Object, @@ -60,11 +62,13 @@ Almost anything can be overwritten to suite your needs. ### Options +- `blacklist` – optional array of string keyPaths that should be excluded from deep (recursive) validation. - `comment` – optional string to be rendered below error/warning message. - `condition` – an optional function with validation condition. - `deprecate`, `error`, `unknown` – optional functions responsible for displaying warning and error messages. - `deprecatedConfig` – optional object with deprecated config keys. - `exampleConfig` – the only **required** option with configuration against which you'd like to test. +- `recursive` - optional boolean determining whether recursively compare `exampleConfig` to `config`. - `title` – optional object of titles for errors and messages. You will find examples of `condition`, `deprecate`, `error`, `unknown`, and `deprecatedConfig` inside source of this repository, named respectively. @@ -84,6 +88,7 @@ validate(config, { comment: ' Documentation: http://custom-docs.com', deprecatedConfig, exampleConfig, + recursive: true, title: { deprecation: 'Custom Deprecation', // leaving 'error' and 'warning' as default @@ -116,7 +121,9 @@ This will output: Example: { - "transform": {"^.+\\.js$": "/preprocessor.js"} + "transform": { + "^.+\\.js$": "/preprocessor.js" + } } Documentation: http://custom-docs.com diff --git a/packages/jest-validate/src/__tests__/__snapshots__/validate.test.js.snap b/packages/jest-validate/src/__tests__/__snapshots__/validate.test.js.snap index de79961455f5..2571b7454576 100644 --- a/packages/jest-validate/src/__tests__/__snapshots__/validate.test.js.snap +++ b/packages/jest-validate/src/__tests__/__snapshots__/validate.test.js.snap @@ -32,7 +32,12 @@ exports[`pretty prints valid config for Array 1`] = ` Example: { - \\"coverageReporters\\": [\\"json\\", \\"text\\", \\"lcov\\", \\"clover\\"] + \\"coverageReporters\\": [ + \\"json\\", + \\"text\\", + \\"lcov\\", + \\"clover\\" + ] } " `; @@ -77,7 +82,12 @@ exports[`pretty prints valid config for Object 1`] = ` Example: { - \\"haste\\": {\\"providesModuleNodeModules\\": [\\"react\\", \\"react-native\\"]} + \\"haste\\": { + \\"providesModuleNodeModules\\": [ + \\"react\\", + \\"react-native\\" + ] + } } " `; @@ -122,7 +132,10 @@ exports[`works with custom errors 1`] = ` Example: { - \\"test\\": [1, 2] + \\"test\\": [ + 1, + 2 + ] } My custom comment" diff --git a/packages/jest-validate/src/__tests__/validate.test.js b/packages/jest-validate/src/__tests__/validate.test.js index abef68fbd9f3..b1f61369e81a 100644 --- a/packages/jest-validate/src/__tests__/validate.test.js +++ b/packages/jest-validate/src/__tests__/validate.test.js @@ -18,10 +18,11 @@ const { deprecatedConfig, } = require('./fixtures/jest_config'); -test('validates default Jest config', () => { +test('recursively validates default Jest config', () => { expect( validate(defaultConfig, { exampleConfig: validConfig, + recursive: true, }), ).toEqual({ hasDeprecationWarnings: false, @@ -29,10 +30,11 @@ test('validates default Jest config', () => { }); }); -test('validates default jest-validate config', () => { +test('recursively validates default jest-validate config', () => { expect( validate(jestValidateDefaultConfig, { exampleConfig: jestValidateExampleConfig, + recursive: true, }), ).toEqual({ hasDeprecationWarnings: false, @@ -40,19 +42,17 @@ test('validates default jest-validate config', () => { }); }); -[ - [{automock: []}, 'Boolean'], - [{coverageReporters: {}}, 'Array'], - [{preset: 1337}, 'String'], - [{haste: 42}, 'Object'], -].forEach(([config, type]) => { - test(`pretty prints valid config for ${type}`, () => { - expect(() => - validate(config, { - exampleConfig: validConfig, - }), - ).toThrowErrorMatchingSnapshot(); - }); +test.each([ + ['Boolean', {automock: []}], + ['Array', {coverageReporters: {}}], + ['String', {preset: 1337}], + ['Object', {haste: 42}], +])('pretty prints valid config for %s', (type, config) => { + expect(() => + validate(config, { + exampleConfig: validConfig, + }), + ).toThrowErrorMatchingSnapshot(); }); test(`pretty prints valid config for Function`, () => { @@ -61,6 +61,7 @@ test(`pretty prints valid config for Function`, () => { expect(() => validate(config, { exampleConfig: validConfig, + recursive: true, }), ).toThrowErrorMatchingSnapshot(); }); @@ -76,6 +77,58 @@ test('omits null and undefined config values', () => { }); }); +test('recursively omits null and undefined config values', () => { + const config = { + haste: { + providesModuleNodeModules: null, + }, + }; + expect( + validate(config, {exampleConfig: validConfig, recursive: true}), + ).toEqual({ + hasDeprecationWarnings: false, + isValid: true, + }); +}); + +test('respects blacklist', () => { + const warn = console.warn; + console.warn = jest.fn(); + const config = { + something: { + nested: { + some_random_key: 'value', + some_random_key2: 'value2', + }, + }, + }; + const exampleConfig = { + something: { + nested: { + test: true, + }, + }, + }; + + validate(config, { + exampleConfig, + recursive: true, + }); + + expect(console.warn).toBeCalled(); + + console.warn.mockReset(); + + validate(config, { + blacklist: ['something.nested'], + exampleConfig, + recursive: true, + }); + + expect(console.warn).not.toBeCalled(); + console.warn = warn; +}); + test('displays warning for unknown config options', () => { const config = {unkwon: {}}; const validConfig = {unknown: 'string'}; @@ -97,6 +150,7 @@ test('displays warning for deprecated config options', () => { validate(config, { deprecatedConfig, exampleConfig: validConfig, + recursive: true, }), ).toEqual({ hasDeprecationWarnings: true, diff --git a/packages/jest-validate/src/default_config.js b/packages/jest-validate/src/default_config.js index a581efe11699..1fb9ed976fd2 100644 --- a/packages/jest-validate/src/default_config.js +++ b/packages/jest-validate/src/default_config.js @@ -12,7 +12,6 @@ import type {ValidationOptions} from './types'; import {deprecationWarning} from './deprecated'; import {unknownOptionWarning} from './warnings'; import {errorMessage} from './errors'; -import exampleConfig from './example_config'; import validationCondition from './condition'; import {ERROR, DEPRECATION, WARNING} from './utils'; @@ -23,7 +22,8 @@ export default ({ deprecate: deprecationWarning, deprecatedConfig: {}, error: errorMessage, - exampleConfig, + exampleConfig: {}, + recursive: false, title: { deprecation: DEPRECATION, error: ERROR, diff --git a/packages/jest-validate/src/example_config.js b/packages/jest-validate/src/example_config.js index 4503dda59868..6af1f05c9282 100644 --- a/packages/jest-validate/src/example_config.js +++ b/packages/jest-validate/src/example_config.js @@ -10,6 +10,7 @@ import type {ValidationOptions} from './types'; const config: ValidationOptions = { + blacklist: [], comment: ' A comment', condition: (option, validOption) => true, deprecate: (config, option, deprecatedOptions, options) => false, @@ -18,6 +19,7 @@ const config: ValidationOptions = { }, error: (option, received, defaultValue, options) => {}, exampleConfig: {key: 'value', test: 'case'}, + recursive: true, title: { deprecation: 'Deprecation Warning', error: 'Validation Error', diff --git a/packages/jest-validate/src/types.js b/packages/jest-validate/src/types.js index 805e2304b5b2..29ffae338ead 100644 --- a/packages/jest-validate/src/types.js +++ b/packages/jest-validate/src/types.js @@ -32,6 +32,7 @@ export type ValidationOptions = { path?: Array, ) => void, exampleConfig: Object, + recursive?: boolean, title?: Title, unknown?: ( config: Object, diff --git a/packages/jest-validate/src/validate.js b/packages/jest-validate/src/validate.js index 881aeeb95e9d..1503cce76e55 100644 --- a/packages/jest-validate/src/validate.js +++ b/packages/jest-validate/src/validate.js @@ -13,6 +13,12 @@ import defaultConfig from './default_config'; let hasDeprecationWarnings = false; +const shouldSkipValidationForPath = ( + path: Array, + key: string, + blacklist: ?Array, +) => (blacklist ? blacklist.includes([...path, key].join('.')) : false); + const _validate = ( config: Object, exampleConfig: Object, @@ -50,10 +56,7 @@ const _validate = ( ) { options.error(key, config[key], exampleConfig[key], options, path); } - } else if ( - options.blacklist && - options.blacklist.includes(path.join('.')) - ) { + } else if (shouldSkipValidationForPath(path, key, options.blacklist)) { // skip validating unknown options inside blacklisted paths } else { options.unknown && @@ -61,9 +64,10 @@ const _validate = ( } if ( + options.recursive && !Array.isArray(exampleConfig[key]) && options.blacklist && - !options.blacklist.includes(path.join('.')) + !shouldSkipValidationForPath(path, key, options.blacklist) ) { _validate(config[key], exampleConfig[key], options, [...path, key]); } From 432c952f7298c9f51f78b799e9979ab1064896c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Fri, 3 Aug 2018 18:23:23 +0200 Subject: [PATCH 4/9] add changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39dfdbd77b9a..0fc1b6f1e066 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## master +### Features + +- `[jest-validate]` Add `recursive` and `blacklist` options for deep config checks ([#6802](https://github.com/facebook/jest/pull/6802)) + ### Fixes - `[jest-config]` Fix `--coverage` with `--findRelatedTests` overwriting `collectCoverageFrom` options ([#6736](https://github.com/facebook/jest/pull/6736)) From d92a72c4a4e187d7b54e6d07b4d15b88f733e6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Fri, 3 Aug 2018 21:57:06 +0200 Subject: [PATCH 5/9] fix lint --- packages/jest-validate/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/jest-validate/README.md b/packages/jest-validate/README.md index 680013ca4d67..b9bc3fcb2bfd 100644 --- a/packages/jest-validate/README.md +++ b/packages/jest-validate/README.md @@ -18,7 +18,7 @@ Where `ValidationOptions` are: ```js type ValidationOptions = { - blacklist?: Array + blacklist?: Array, comment?: string, condition?: (option: any, validOption: any) => boolean, deprecate?: ( @@ -35,7 +35,7 @@ type ValidationOptions = { options: ValidationOptions, ) => void, exampleConfig: Object, - recursive?: boolean + recursive?: boolean, title?: Title, unknown?: ( config: Object, From 158a58f1bfcc48f5f5c14b100035d069e103414e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Sun, 5 Aug 2018 15:12:03 +0200 Subject: [PATCH 6/9] blacklist -> recursiveBlacklist --- packages/jest-config/src/normalize.js | 10 +++++----- packages/jest-validate/src/__tests__/validate.test.js | 2 +- packages/jest-validate/src/default_config.js | 2 +- packages/jest-validate/src/example_config.js | 2 +- packages/jest-validate/src/types.js | 2 +- packages/jest-validate/src/validate.js | 8 +++++--- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 361dc6da7233..1db5995aa4e4 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -332,16 +332,16 @@ const showTestPathPatternError = (testPathPattern: string) => { export default function normalize(options: InitialOptions, argv: Argv) { const {hasDeprecationWarnings} = validate(options, { - blacklist: [ + comment: DOCUMENTATION_NOTE, + deprecatedConfig: DEPRECATED_CONFIG, + exampleConfig: VALID_CONFIG, + recursive: true, + recursiveBlacklist: [ 'moduleNameMapper', 'transform', 'globals', 'collectCoverageOnlyFrom', ], - comment: DOCUMENTATION_NOTE, - deprecatedConfig: DEPRECATED_CONFIG, - exampleConfig: VALID_CONFIG, - recursive: true, }); options = normalizePreprocessor( diff --git a/packages/jest-validate/src/__tests__/validate.test.js b/packages/jest-validate/src/__tests__/validate.test.js index b1f61369e81a..8fdd1fb4710d 100644 --- a/packages/jest-validate/src/__tests__/validate.test.js +++ b/packages/jest-validate/src/__tests__/validate.test.js @@ -120,9 +120,9 @@ test('respects blacklist', () => { console.warn.mockReset(); validate(config, { - blacklist: ['something.nested'], exampleConfig, recursive: true, + recursiveBlacklist: ['something.nested'], }); expect(console.warn).not.toBeCalled(); diff --git a/packages/jest-validate/src/default_config.js b/packages/jest-validate/src/default_config.js index 1fb9ed976fd2..1495b430e917 100644 --- a/packages/jest-validate/src/default_config.js +++ b/packages/jest-validate/src/default_config.js @@ -16,7 +16,6 @@ import validationCondition from './condition'; import {ERROR, DEPRECATION, WARNING} from './utils'; export default ({ - blacklist: [], comment: '', condition: validationCondition, deprecate: deprecationWarning, @@ -24,6 +23,7 @@ export default ({ error: errorMessage, exampleConfig: {}, recursive: false, + recursiveBlacklist: [], title: { deprecation: DEPRECATION, error: ERROR, diff --git a/packages/jest-validate/src/example_config.js b/packages/jest-validate/src/example_config.js index 6af1f05c9282..8230a568e3ed 100644 --- a/packages/jest-validate/src/example_config.js +++ b/packages/jest-validate/src/example_config.js @@ -10,7 +10,6 @@ import type {ValidationOptions} from './types'; const config: ValidationOptions = { - blacklist: [], comment: ' A comment', condition: (option, validOption) => true, deprecate: (config, option, deprecatedOptions, options) => false, @@ -20,6 +19,7 @@ const config: ValidationOptions = { error: (option, received, defaultValue, options) => {}, exampleConfig: {key: 'value', test: 'case'}, recursive: true, + recursiveBlacklist: [], title: { deprecation: 'Deprecation Warning', error: 'Validation Error', diff --git a/packages/jest-validate/src/types.js b/packages/jest-validate/src/types.js index 29ffae338ead..89fb390942b4 100644 --- a/packages/jest-validate/src/types.js +++ b/packages/jest-validate/src/types.js @@ -14,7 +14,6 @@ type Title = {| |}; export type ValidationOptions = { - blacklist?: Array, comment?: string, condition?: (option: any, validOption: any) => boolean, deprecate?: ( @@ -33,6 +32,7 @@ export type ValidationOptions = { ) => void, exampleConfig: Object, recursive?: boolean, + recursiveBlacklist?: Array, title?: Title, unknown?: ( config: Object, diff --git a/packages/jest-validate/src/validate.js b/packages/jest-validate/src/validate.js index 1503cce76e55..96c54cdcf7a4 100644 --- a/packages/jest-validate/src/validate.js +++ b/packages/jest-validate/src/validate.js @@ -56,7 +56,9 @@ const _validate = ( ) { options.error(key, config[key], exampleConfig[key], options, path); } - } else if (shouldSkipValidationForPath(path, key, options.blacklist)) { + } else if ( + shouldSkipValidationForPath(path, key, options.recursiveBlacklist) + ) { // skip validating unknown options inside blacklisted paths } else { options.unknown && @@ -66,8 +68,8 @@ const _validate = ( if ( options.recursive && !Array.isArray(exampleConfig[key]) && - options.blacklist && - !shouldSkipValidationForPath(path, key, options.blacklist) + options.recursiveBlacklist && + !shouldSkipValidationForPath(path, key, options.recursiveBlacklist) ) { _validate(config[key], exampleConfig[key], options, [...path, key]); } From a7638f7107bbea98248f05b0b49b39c75ed42b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Sun, 5 Aug 2018 15:25:52 +0200 Subject: [PATCH 7/9] update valid config --- packages/jest-config/src/normalize.js | 7 +++++-- packages/jest-config/src/valid_config.js | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 1db5995aa4e4..d8d1d68286d8 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -337,10 +337,13 @@ export default function normalize(options: InitialOptions, argv: Argv) { exampleConfig: VALID_CONFIG, recursive: true, recursiveBlacklist: [ + 'collectCoverageOnlyFrom', + // 'coverageThreshold' allows to use 'global' and glob strings on the same + // level, there's currently no way we can deal with such config + 'coverageThreshold', + 'globals', 'moduleNameMapper', 'transform', - 'globals', - 'collectCoverageOnlyFrom', ], }); diff --git a/packages/jest-config/src/valid_config.js b/packages/jest-config/src/valid_config.js index d68aa7f001d6..d711a520a7fc 100644 --- a/packages/jest-config/src/valid_config.js +++ b/packages/jest-config/src/valid_config.js @@ -21,7 +21,7 @@ export default ({ cache: true, cacheDirectory: '/tmp/user/jest', changedFilesWithAncestor: false, - changedSince: '', + changedSince: 'master', clearMocks: false, collectCoverage: true, collectCoverageFrom: ['src', '!public'], @@ -47,7 +47,7 @@ export default ({ forceExit: false, globalSetup: 'setup.js', globalTeardown: 'teardown.js', - globals: {}, + globals: {__DEV__: true}, haste: { defaultPlatform: 'ios', hasteImplModulePath: '/haste_impl.js', @@ -93,7 +93,7 @@ export default ({ skipNodeResolution: false, snapshotSerializers: ['my-serializer-module'], testEnvironment: 'jest-environment-jsdom', - testEnvironmentOptions: {}, + testEnvironmentOptions: {userAgent: 'Agent/007'}, testFailureExitCode: 1, testLocationInResults: false, testMatch: ['**/__tests__/**/*.js?(x)', '**/?(*.)+(spec|test).js?(x)'], @@ -113,7 +113,16 @@ export default ({ useStderr: false, verbose: false, watch: false, - watchPathIgnorePatterns: [], - watchPlugins: [], + watchPathIgnorePatterns: ['/e2e/'], + watchPlugins: [ + 'path/to/yourWatchPlugin', + [ + 'jest-watch-typeahead/filename', + { + key: 'k', + prompt: 'do something with my custom prompt', + }, + ], + ], watchman: true, }: InitialOptions); From d4bc3fc3b6708c2e3ef87a27111bb592153d055b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Mon, 6 Aug 2018 10:24:25 +0200 Subject: [PATCH 8/9] make recursive true by default --- packages/jest-config/src/normalize.js | 1 - packages/jest-validate/README.md | 5 ++--- packages/jest-validate/src/__tests__/validate.test.js | 10 +--------- packages/jest-validate/src/default_config.js | 2 +- 4 files changed, 4 insertions(+), 14 deletions(-) diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index d8d1d68286d8..193ae99a20f6 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -335,7 +335,6 @@ export default function normalize(options: InitialOptions, argv: Argv) { comment: DOCUMENTATION_NOTE, deprecatedConfig: DEPRECATED_CONFIG, exampleConfig: VALID_CONFIG, - recursive: true, recursiveBlacklist: [ 'collectCoverageOnlyFrom', // 'coverageThreshold' allows to use 'global' and glob strings on the same diff --git a/packages/jest-validate/README.md b/packages/jest-validate/README.md index b9bc3fcb2bfd..178bb7c486da 100644 --- a/packages/jest-validate/README.md +++ b/packages/jest-validate/README.md @@ -62,13 +62,13 @@ Almost anything can be overwritten to suite your needs. ### Options -- `blacklist` – optional array of string keyPaths that should be excluded from deep (recursive) validation. +- `recursiveBlacklist` – optional array of string keyPaths that should be excluded from deep (recursive) validation. - `comment` – optional string to be rendered below error/warning message. - `condition` – an optional function with validation condition. - `deprecate`, `error`, `unknown` – optional functions responsible for displaying warning and error messages. - `deprecatedConfig` – optional object with deprecated config keys. - `exampleConfig` – the only **required** option with configuration against which you'd like to test. -- `recursive` - optional boolean determining whether recursively compare `exampleConfig` to `config`. +- `recursive` - optional boolean determining whether recursively compare `exampleConfig` to `config` (default: `true`). - `title` – optional object of titles for errors and messages. You will find examples of `condition`, `deprecate`, `error`, `unknown`, and `deprecatedConfig` inside source of this repository, named respectively. @@ -88,7 +88,6 @@ validate(config, { comment: ' Documentation: http://custom-docs.com', deprecatedConfig, exampleConfig, - recursive: true, title: { deprecation: 'Custom Deprecation', // leaving 'error' and 'warning' as default diff --git a/packages/jest-validate/src/__tests__/validate.test.js b/packages/jest-validate/src/__tests__/validate.test.js index 8fdd1fb4710d..ec4de4d38b92 100644 --- a/packages/jest-validate/src/__tests__/validate.test.js +++ b/packages/jest-validate/src/__tests__/validate.test.js @@ -22,7 +22,6 @@ test('recursively validates default Jest config', () => { expect( validate(defaultConfig, { exampleConfig: validConfig, - recursive: true, }), ).toEqual({ hasDeprecationWarnings: false, @@ -34,7 +33,6 @@ test('recursively validates default jest-validate config', () => { expect( validate(jestValidateDefaultConfig, { exampleConfig: jestValidateExampleConfig, - recursive: true, }), ).toEqual({ hasDeprecationWarnings: false, @@ -61,7 +59,6 @@ test(`pretty prints valid config for Function`, () => { expect(() => validate(config, { exampleConfig: validConfig, - recursive: true, }), ).toThrowErrorMatchingSnapshot(); }); @@ -110,10 +107,7 @@ test('respects blacklist', () => { }, }; - validate(config, { - exampleConfig, - recursive: true, - }); + validate(config, {exampleConfig}); expect(console.warn).toBeCalled(); @@ -121,7 +115,6 @@ test('respects blacklist', () => { validate(config, { exampleConfig, - recursive: true, recursiveBlacklist: ['something.nested'], }); @@ -150,7 +143,6 @@ test('displays warning for deprecated config options', () => { validate(config, { deprecatedConfig, exampleConfig: validConfig, - recursive: true, }), ).toEqual({ hasDeprecationWarnings: true, diff --git a/packages/jest-validate/src/default_config.js b/packages/jest-validate/src/default_config.js index 1495b430e917..735037968c60 100644 --- a/packages/jest-validate/src/default_config.js +++ b/packages/jest-validate/src/default_config.js @@ -22,7 +22,7 @@ export default ({ deprecatedConfig: {}, error: errorMessage, exampleConfig: {}, - recursive: false, + recursive: true, recursiveBlacklist: [], title: { deprecation: DEPRECATION, From d16059034ff1e90b2543e0a1e153c4d8ecf6a712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 8 Aug 2018 22:02:24 +0200 Subject: [PATCH 9/9] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc1e6304f7e9..fa9426ef5523 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - `[jest-runner]` print stack trace when `process.exit` is called from user code ([#6714](https://github.com/facebook/jest/pull/6714)) - `[jest-each]` introduces `%#` option to add index of the test to its title ([#6414](https://github.com/facebook/jest/pull/6414)) - `[pretty-format]` Support serializing `DocumentFragment` ([#6705](https://github.com/facebook/jest/pull/6705)) -- `[jest-validate]` Add `recursive` and `blacklist` options for deep config checks ([#6802](https://github.com/facebook/jest/pull/6802)) +- `[jest-validate]` Add `recursive` and `recursiveBlacklist` options for deep config checks ([#6802](https://github.com/facebook/jest/pull/6802)) ### Fixes