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

Add support for recursiveDenylist option as an alternative to recursiveBlacklist #10236

Closed
wants to merge 1 commit into from
Closed
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,7 @@

- `[expect]` Match symbols and bigints in `any()` ([#10223](https://github.com/facebook/jest/pull/10223))
- `[jest-snapshot]` Strip added indentation for inline error snapshots ([#10217](https://github.com/facebook/jest/pull/10217))
- `[jest-validate]` Add support for `recursiveDenylist` option as an alternative to `recursiveBlacklist` ([#10236](https://github.com/facebook/jest/pull/10236))

### 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 @@ -33,6 +33,7 @@ export type ValidationOptions = {
exampleConfig: Record<string, any>;
recursive?: boolean;
recursiveBlacklist?: Array<string>;
recursiveDenylist?: Array<string>;
title?: Title;
unknown?: (
config: Record<string, any>,
Expand Down
24 changes: 16 additions & 8 deletions packages/jest-validate/src/validate.ts
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