From 877ae08061f614d6e240b04ff65dadfffc1f2c85 Mon Sep 17 00:00:00 2001 From: Filipp Riabchun Date: Sat, 8 Aug 2020 19:47:49 +0200 Subject: [PATCH] [New] `button-has-type`: support trivial ternary expressions --- docs/rules/button-has-type.md | 4 + lib/rules/button-has-type.js | 37 +++++++-- tests/lib/rules/button-has-type.js | 121 ++++++++++++++++++++++++++++- 3 files changed, 153 insertions(+), 9 deletions(-) diff --git a/docs/rules/button-has-type.md b/docs/rules/button-has-type.md index 63a6038e29..2ed0716738 100644 --- a/docs/rules/button-has-type.md +++ b/docs/rules/button-has-type.md @@ -24,12 +24,14 @@ var Hello = Hello var Hello = var Hello = var Hello = +var Hello = var Hello = React.createElement('span', {}, 'Hello') var Hello = React.createElement('span', {type: 'foo'}, 'Hello') var Hello = React.createElement('button', {type: 'button'}, 'Hello') var Hello = React.createElement('button', {type: 'submit'}, 'Hello') var Hello = React.createElement('button', {type: 'reset'}, 'Hello') +var Hello = React.createElement('button', {type: condition ? 'button' : 'submit'}, 'Hello') ``` ## Rule Options @@ -50,8 +52,10 @@ The following patterns are considered errors when using `"react/button-has-type" ```jsx var Hello = +var Hello = var Hello = React.createElement('button', {type: 'reset'}, 'Hello') +var Hello = React.createElement('button', {type: condition ? "button" : "reset"}, 'Hello') ``` ## When Not To Use It diff --git a/lib/rules/button-has-type.js b/lib/rules/button-has-type.js index 76e09c605b..2dde70896f 100644 --- a/lib/rules/button-has-type.js +++ b/lib/rules/button-has-type.js @@ -72,6 +72,13 @@ module.exports = { }); } + function reportComplex(node) { + context.report({ + node, + message: 'The button type attribute must be specified by a static string or a trivial ternary expression' + }); + } + function checkValue(node, value) { const q = (x) => `"${x}"`; if (!(value in configuration)) { @@ -87,6 +94,27 @@ module.exports = { } } + function checkExpression(node, expression) { + switch (expression.type) { + case 'Literal': + checkValue(node, expression.value); + return; + case 'TemplateLiteral': + if (expression.expressions.length === 0) { + checkValue(node, expression.quasis[0].value.raw); + } else { + reportComplex(expression); + } + return; + case 'ConditionalExpression': + checkExpression(node, expression.consequent); + checkExpression(node, expression.alternate); + return; + default: + reportComplex(expression); + } + } + return { JSXElement(node) { if (node.openingElement.name.name !== 'button') { @@ -101,10 +129,7 @@ module.exports = { } if (typeProp.value.type === 'JSXExpressionContainer') { - context.report({ - node: typeProp, - message: 'The button type attribute must be specified by a static string' - }); + checkExpression(node, typeProp.value.expression); return; } @@ -128,12 +153,12 @@ module.exports = { const props = node.arguments[1].properties; const typeProp = props.find((prop) => prop.key && prop.key.name === 'type'); - if (!typeProp || typeProp.value.type !== 'Literal') { + if (!typeProp) { reportMissing(node); return; } - checkValue(node, typeProp.value.value); + checkExpression(node, typeProp.value); } }; } diff --git a/tests/lib/rules/button-has-type.js b/tests/lib/rules/button-has-type.js index da343af73e..d6a90c9ba1 100644 --- a/tests/lib/rules/button-has-type.js +++ b/tests/lib/rules/button-has-type.js @@ -32,6 +32,12 @@ ruleTester.run('button-has-type', rule, { {code: '