Skip to content

Change allowed propWrapperFunctions setting values #2065

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

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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ You should also specify settings that will be shared across all the plugin rules
"version": "15.0", // React version, default to the latest React stable release
"flowVersion": "0.53" // Flow version
},
"propWrapperFunctions": [ "forbidExtraProps" ] // The names of any functions used to wrap the
// propTypes object, e.g. `forbidExtraProps`.
// If this isn't set, any propTypes wrapped in
// a function will be skipped.
"propWrapperFunctions": [
// The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.
"forbidExtraProps",
{"property": "freeze", "object": "Object"}
{"property": "myFavoriteWrapper"}
]
}
}
```
Expand Down
6 changes: 3 additions & 3 deletions lib/rules/boolean-prop-naming.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
const Components = require('../util/Components');
const propsUtil = require('../util/props');
const docsUrl = require('../util/docsUrl');
const propWrapperUtil = require('../util/propWrapper');

// ------------------------------------------------------------------------------
// Rule Definition
Expand Down Expand Up @@ -51,7 +52,6 @@ module.exports = {
const config = context.options[0] || {};
const rule = config.rule ? new RegExp(config.rule) : null;
const propTypeNames = config.propTypeNames || ['bool'];
const propWrapperFunctions = new Set(context.settings.propWrapperFunctions || []);

// Remembers all Flowtype object definitions
const objectTypeAnnotations = new Map();
Expand Down Expand Up @@ -171,7 +171,7 @@ module.exports = {
if (!rule || !propsUtil.isPropTypesDeclaration(node)) {
return;
}
if (node.value && node.value.type === 'CallExpression' && propWrapperFunctions.has(sourceCode.getText(node.value.callee))) {
if (node.value && node.value.type === 'CallExpression' && propWrapperUtil.isPropWrapperFunction(context, sourceCode.getText(node.value.callee))) {
checkPropWrapperArguments(node, node.value.arguments);
}
if (node.value && node.value.properties) {
Expand All @@ -191,7 +191,7 @@ module.exports = {
return;
}
const right = node.parent.right;
if (right.type === 'CallExpression' && propWrapperFunctions.has(sourceCode.getText(right.callee))) {
if (right.type === 'CallExpression' && propWrapperUtil.isPropWrapperFunction(context, sourceCode.getText(right.callee))) {
checkPropWrapperArguments(component.node, right.arguments);
return;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/rules/forbid-prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const variableUtil = require('../util/variable');
const propsUtil = require('../util/props');
const astUtil = require('../util/ast');
const docsUrl = require('../util/docsUrl');
const propWrapperUtil = require('../util/propWrapper');

// ------------------------------------------------------------------------------
// Constants
Expand Down Expand Up @@ -48,7 +49,6 @@ module.exports = {
},

create: function(context) {
const propWrapperFunctions = new Set(context.settings.propWrapperFunctions || []);
const configuration = context.options[0] || {};
const checkContextTypes = configuration.checkContextTypes || false;
const checkChildContextTypes = configuration.checkChildContextTypes || false;
Expand Down Expand Up @@ -125,7 +125,7 @@ module.exports = {
break;
case 'CallExpression':
const innerNode = node.arguments && node.arguments[0];
if (propWrapperFunctions.has(node.callee.name) && innerNode) {
if (propWrapperUtil.isPropWrapperFunction(context, node.callee.name) && innerNode) {
checkNode(innerNode);
}
break;
Expand Down
4 changes: 2 additions & 2 deletions lib/rules/jsx-sort-default-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

const variableUtil = require('../util/variable');
const docsUrl = require('../util/docsUrl');
const propWrapperUtil = require('../util/propWrapper');

// ------------------------------------------------------------------------------
// Rule Definition
Expand Down Expand Up @@ -35,7 +36,6 @@ module.exports = {
const sourceCode = context.getSourceCode();
const configuration = context.options[0] || {};
const ignoreCase = configuration.ignoreCase || false;
const propWrapperFunctions = new Set(context.settings.propWrapperFunctions || []);

/**
* Get properties name
Expand Down Expand Up @@ -134,7 +134,7 @@ module.exports = {
break;
case 'CallExpression':
const innerNode = node.arguments && node.arguments[0];
if (propWrapperFunctions.has(node.callee.name) && innerNode) {
if (propWrapperUtil.isPropWrapperFunction(context, node.callee.name) && innerNode) {
checkNode(innerNode);
}
break;
Expand Down
4 changes: 2 additions & 2 deletions lib/rules/sort-prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
const variableUtil = require('../util/variable');
const propsUtil = require('../util/props');
const docsUrl = require('../util/docsUrl');
const propWrapperUtil = require('../util/propWrapper');

// ------------------------------------------------------------------------------
// Rule Definition
Expand Down Expand Up @@ -54,7 +55,6 @@ module.exports = {
const ignoreCase = configuration.ignoreCase || false;
const noSortAlphabetically = configuration.noSortAlphabetically || false;
const sortShapeProp = configuration.sortShapeProp || false;
const propWrapperFunctions = new Set(context.settings.propWrapperFunctions || []);

function getKey(node) {
if (node.key && node.key.value) {
Expand Down Expand Up @@ -250,7 +250,7 @@ module.exports = {
break;
case 'CallExpression':
const innerNode = node.arguments && node.arguments[0];
if (propWrapperFunctions.has(node.callee.name) && innerNode) {
if (propWrapperUtil.isPropWrapperFunction(context, node.callee.name) && innerNode) {
checkNode(innerNode);
}
break;
Expand Down
4 changes: 2 additions & 2 deletions lib/util/defaultProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ const fromEntries = require('object.fromentries');
const astUtil = require('./ast');
const propsUtil = require('./props');
const variableUtil = require('./variable');
const propWrapperUtil = require('../util/propWrapper');

const QUOTES_REGEX = /^["']|["']$/g;

module.exports = function defaultPropsInstructions(context, components, utils) {
const sourceCode = context.getSourceCode();
const propWrapperFunctions = new Set(context.settings.propWrapperFunctions || []);

/**
* Try to resolve the node passed in to a variable in the current scope. If the node passed in is not
Expand All @@ -26,7 +26,7 @@ module.exports = function defaultPropsInstructions(context, components, utils) {
}
if (
node.type === 'CallExpression' &&
propWrapperFunctions.has(node.callee.name) &&
propWrapperUtil.isPropWrapperFunction(context, node.callee.name) &&
node.arguments && node.arguments[0]
) {
return resolveNodeValue(node.arguments[0]);
Expand Down
4 changes: 2 additions & 2 deletions lib/util/propTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const annotations = require('./annotations');
const propsUtil = require('./props');
const variableUtil = require('./variable');
const versionUtil = require('./version');
const propWrapperUtil = require('../util/propWrapper');

/**
* Checks if we are declaring a props as a generic type in a flow-annotated class.
Expand Down Expand Up @@ -76,7 +77,6 @@ module.exports = function propTypesInstructions(context, components, utils) {
const configuration = Object.assign({}, defaults, context.options[0] || {});
const customValidators = configuration.customValidators;
const sourceCode = context.getSourceCode();
const propWrapperFunctions = new Set(context.settings.propWrapperFunctions);

/**
* Returns the full scope.
Expand Down Expand Up @@ -522,7 +522,7 @@ module.exports = function propTypesInstructions(context, components, utils) {
break;
case 'CallExpression':
if (
propWrapperFunctions.has(sourceCode.getText(propTypes.callee)) &&
propWrapperUtil.isPropWrapperFunction(context, sourceCode.getText(propTypes.callee)) &&
propTypes.arguments && propTypes.arguments[0]
) {
markPropTypesAsDeclared(node, propTypes.arguments[0]);
Expand Down
24 changes: 24 additions & 0 deletions lib/util/propWrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @fileoverview Utility functions for propWrapperFunctions setting
*/
'use strict';

function getPropWrapperFunctions(context) {
return new Set(context.settings.propWrapperFunctions || []);
}

function isPropWrapperFunction(context, name) {
const propWrapperFunctions = getPropWrapperFunctions(context);
const splitName = name.split('.');
return Array.from(propWrapperFunctions).some(func => {
if (splitName.length === 2 && func.object === splitName[0] && func.property === splitName[1]) {
return true;
}
return name === func || func.property === name;
});
}

module.exports = {
getPropWrapperFunctions: getPropWrapperFunctions,
isPropWrapperFunction: isPropWrapperFunction
};
62 changes: 62 additions & 0 deletions tests/util/propWrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* eslint-env mocha */
'use strict';

const assert = require('assert');
const propWrapperUtil = require('../../lib/util/propWrapper');

describe('PropWrapperFunctions', () => {
describe('getPropWrapperFunctions', () => {
it('returns set of functions if setting exists', () => {
const propWrapperFunctions = ['Object.freeze', {
property: 'forbidExtraProps'
}];
const context = {
settings: {
propWrapperFunctions: propWrapperFunctions
}
};
assert.deepStrictEqual(propWrapperUtil.getPropWrapperFunctions(context), new Set(propWrapperFunctions));
});

it('returns empty array if no setting', () => {
const context = {
settings: {}
};
assert.deepStrictEqual(propWrapperUtil.getPropWrapperFunctions(context), new Set([]));
});
});

describe('isPropWrapperFunction', () => {
it('with string', () => {
const context = {
settings: {
propWrapperFunctions: ['Object.freeze']
}
};
assert.equal(propWrapperUtil.isPropWrapperFunction(context, 'Object.freeze'), true);
});

it('with Object with object and property keys', () => {
const context = {
settings: {
propWrapperFunctions: [{
property: 'freeze',
object: 'Object'
}]
}
};
assert.equal(propWrapperUtil.isPropWrapperFunction(context, 'Object.freeze'), true);
});

it('with Object with only property key', () => {
const context = {
settings: {
propWrapperFunctions: [{
property: 'forbidExtraProps'
}]
}
};
assert.equal(propWrapperUtil.isPropWrapperFunction(context, 'forbidExtraProps'), true);
});
});
});