Skip to content

Commit

Permalink
Add support for recursiveDenylist option as an alternative to `recu…
Browse files Browse the repository at this point in the history
…rsiveBlacklist` (#10649)
  • Loading branch information
wojtekmaj committed Oct 19, 2020
1 parent 33eab98 commit 194701f
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 15 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,8 @@

### Features

- `[jest-validate]` Add support for `recursiveDenylist` option as an alternative to `recursiveBlacklist` ([#10236](https://github.com/facebook/jest/pull/10236))

### Fixes

### Chore & Maintenance
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-validate/README.md
Expand Up @@ -62,7 +62,7 @@ Almost anything can be overwritten to suite your needs.

### Options

- `recursiveBlacklist` – optional array of string keyPaths that should be excluded from deep (recursive) validation.
- `recursiveDenylist` – 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.
Expand Down
38 changes: 36 additions & 2 deletions packages/jest-validate/src/__tests__/validate.test.ts
Expand Up @@ -101,7 +101,7 @@ test.each([
},
);

test('respects blacklist', () => {
test('respects recursiveBlacklist', () => {
const warn = console.warn;
console.warn = jest.fn();
const config = {
Expand Down Expand Up @@ -135,6 +135,40 @@ test('respects blacklist', () => {
console.warn = warn;
});

test('respects recursiveDenylist', () => {
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});

expect(console.warn).toBeCalled();

console.warn.mockReset();

validate(config, {
exampleConfig,
recursiveDenylist: ['something.nested'],
});

expect(console.warn).not.toBeCalled();
console.warn = warn;
});

test('displays warning for unknown config options', () => {
const config = {unkwon: {}};
const validConfig = {unknown: 'string'};
Expand Down Expand Up @@ -292,7 +326,7 @@ test('Comments in config JSON using "//" key are not warned', () => {

validate(config, {
exampleConfig: validConfig,
recursiveBlacklist: ['myCustomKey' as "don't validate this"],
recursiveDenylist: ['myCustomKey' as "don't validate this"],
});
expect(console.warn).not.toBeCalled();

Expand Down
2 changes: 1 addition & 1 deletion packages/jest-validate/src/defaultConfig.ts
Expand Up @@ -22,7 +22,7 @@ const validationOptions: ValidationOptions = {
exampleConfig: {},
recursive: true,
// Allow NPM-sanctioned comments in package.json. Use a "//" key.
recursiveBlacklist: ['//'],
recursiveDenylist: ['//'],
title: {
deprecation: DEPRECATION,
error: ERROR,
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-validate/src/exampleConfig.ts
Expand Up @@ -17,7 +17,7 @@ const config: ValidationOptions = {
error: () => {},
exampleConfig: {key: 'value', test: 'case'},
recursive: true,
recursiveBlacklist: [],
recursiveDenylist: [],
title: {
deprecation: 'Deprecation Warning',
error: 'Validation Error',
Expand Down
1 change: 1 addition & 0 deletions packages/jest-validate/src/types.ts
Expand Up @@ -35,6 +35,7 @@ export type ValidationOptions = {
exampleConfig: Record<string, unknown>;
recursive?: boolean;
recursiveBlacklist?: Array<string>;
recursiveDenylist?: Array<string>;
title?: Title;
unknown?: (
config: Record<string, unknown>,
Expand Down
28 changes: 18 additions & 10 deletions packages/jest-validate/src/validate.ts
Expand Up @@ -14,8 +14,8 @@ let hasDeprecationWarnings = false;
const shouldSkipValidationForPath = (
path: Array<string>,
key: string,
blacklist?: Array<string>,
) => (blacklist ? blacklist.includes([...path, key].join('.')) : false);
denylist?: Array<string>,
) => (denylist ? denylist.includes([...path, key].join('.')) : false);

const _validate = (
config: Record<string, any>,
Expand Down Expand Up @@ -70,7 +70,11 @@ const _validate = (
options.error(key, config[key], exampleConfig[key], options, path);
}
} else if (
shouldSkipValidationForPath(path, key, options.recursiveBlacklist)
shouldSkipValidationForPath(
path,
key,
options.recursiveDenylist || options.recursiveBlacklist,
)
) {
// skip validating unknown options inside blacklisted paths
} else {
Expand All @@ -81,8 +85,12 @@ const _validate = (
if (
options.recursive &&
!Array.isArray(exampleConfig[key]) &&
options.recursiveBlacklist &&
!shouldSkipValidationForPath(path, key, options.recursiveBlacklist)
(options.recursiveDenylist || options.recursiveBlacklist) &&
!shouldSkipValidationForPath(
path,
key,
options.recursiveDenylist || options.recursiveBlacklist,
)
) {
_validate(config[key], exampleConfig[key], options, [...path, key]);
}
Expand All @@ -101,16 +109,16 @@ const validate = (
): {hasDeprecationWarnings: boolean; isValid: boolean} => {
hasDeprecationWarnings = false;

// Preserve default blacklist entries even with user-supplied blacklist
const combinedBlacklist: Array<string> = [
...(defaultConfig.recursiveBlacklist || []),
...(options.recursiveBlacklist || []),
// Preserve default denylist entries even with user-supplied denylist
const combinedDenylist: Array<string> = [
...(defaultConfig.recursiveDenylist || []),
...(options.recursiveDenylist || options.recursiveBlacklist || []),
];

const defaultedOptions: ValidationOptions = Object.assign({
...defaultConfig,
...options,
recursiveBlacklist: combinedBlacklist,
recursiveDenylist: combinedDenylist,
title: options.title || defaultConfig.title,
});

Expand Down

0 comments on commit 194701f

Please sign in to comment.