From 3e85c5549086ebf52f1f2b71cec8e758781052bc Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Wed, 16 Aug 2017 22:36:03 +0300 Subject: [PATCH 01/13] Attempt at Flow 0.53 support --- lib/rules/prop-types.js | 6 ++++++ tests/lib/rules/prop-types.js | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/rules/prop-types.js b/lib/rules/prop-types.js index 6e7f48dfc8..92f78fe70f 100644 --- a/lib/rules/prop-types.js +++ b/lib/rules/prop-types.js @@ -917,6 +917,12 @@ module.exports = { } }, + TypeParameterInstantiation: function(node) { + if (node.params && node.params[0].type === 'GenericTypeAnnotation' && node.params[0].id.name === 'Props') { + markPropTypesAsDeclared(node, resolveTypeAnnotation(node)); + } + }, + VariableDeclarator: function(node) { const destructuring = node.init && node.id && node.id.type === 'ObjectPattern'; // let {props: {firstname}} = this diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index da938c7929..4678e4b74d 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -1558,6 +1558,20 @@ ruleTester.run('prop-types', rule, { ].join('\n'), parser: 'babel-eslint' }, + { + code: ` + type Props = { + foo: string, + }; + + class Bar extends React.Component { + render() { + return
{this.props.foo}
+ } + } + `, + parser: 'babel-eslint' + }, // issue #1288 `function Foo() { const props = {} From 585b94ae6ca5538319d4dfdc925a9af7f568d4c2 Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Wed, 16 Aug 2017 22:51:38 +0300 Subject: [PATCH 02/13] Add invalid test case --- lib/rules/prop-types.js | 2 +- tests/lib/rules/prop-types.js | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/rules/prop-types.js b/lib/rules/prop-types.js index 92f78fe70f..5915acc26e 100644 --- a/lib/rules/prop-types.js +++ b/lib/rules/prop-types.js @@ -919,7 +919,7 @@ module.exports = { TypeParameterInstantiation: function(node) { if (node.params && node.params[0].type === 'GenericTypeAnnotation' && node.params[0].id.name === 'Props') { - markPropTypesAsDeclared(node, resolveTypeAnnotation(node)); + markPropTypesAsDeclared(node, resolveTypeAnnotation(node.params[0])); } }, diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 4678e4b74d..750e32f850 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -2942,6 +2942,25 @@ ruleTester.run('prop-types', rule, { type: 'Identifier' }], parser: 'babel-eslint' + }, { + code: ` + type Props = { + foo: string, + }; + + class Bar extends React.Component { + render() { + return
{this.props.bar}
+ } + } + `, + errors: [{ + message: '\'bar\' is missing in props validation', + line: 8, + column: 37, + type: 'Identifier' + }], + parser: 'babel-eslint' } ] }); From f767f681c4058c6b1a5a523e36a5fddc047cbdb0 Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Thu, 17 Aug 2017 20:16:27 +0300 Subject: [PATCH 03/13] Add support and test for custom props name --- lib/rules/prop-types.js | 2 +- tests/lib/rules/prop-types.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/rules/prop-types.js b/lib/rules/prop-types.js index 5915acc26e..390d3045c5 100644 --- a/lib/rules/prop-types.js +++ b/lib/rules/prop-types.js @@ -918,7 +918,7 @@ module.exports = { }, TypeParameterInstantiation: function(node) { - if (node.params && node.params[0].type === 'GenericTypeAnnotation' && node.params[0].id.name === 'Props') { + if (node.params && node.params[0].type === 'GenericTypeAnnotation') { markPropTypesAsDeclared(node, resolveTypeAnnotation(node.params[0])); } }, diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 750e32f850..ff700273a2 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -1572,6 +1572,20 @@ ruleTester.run('prop-types', rule, { `, parser: 'babel-eslint' }, + { + code: ` + type FancyProps = { + foo: string, + }; + + class Bar extends React.Component { + render() { + return
{this.props.foo}
+ } + } + `, + parser: 'babel-eslint' + }, // issue #1288 `function Foo() { const props = {} From deb3b6171168d2ad8173756d858060545d5e9a7e Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Thu, 17 Aug 2017 20:18:11 +0300 Subject: [PATCH 04/13] Add invalid test case for custom prop names --- tests/lib/rules/prop-types.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index ff700273a2..33c39d9b3e 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -2975,6 +2975,25 @@ ruleTester.run('prop-types', rule, { type: 'Identifier' }], parser: 'babel-eslint' + }, { + code: ` + type FancyProps = { + foo: string, + }; + + class Bar extends React.Component { + render() { + return
{this.props.bar}
+ } + } + `, + errors: [{ + message: '\'bar\' is missing in props validation', + line: 8, + column: 37, + type: 'Identifier' + }], + parser: 'babel-eslint' } ] }); From 1a8af56182f3a75ae0a774a8f4d752eebbe219ac Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Fri, 18 Aug 2017 08:03:45 +0300 Subject: [PATCH 05/13] Revert old implementation and replace by configurable flowVersion --- lib/rules/prop-types.js | 17 +++++++++-------- lib/util/flowVersion.js | 28 ++++++++++++++++++++++++++++ tests/lib/rules/prop-types.js | 19 +++++++++++++++++-- 3 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 lib/util/flowVersion.js diff --git a/lib/rules/prop-types.js b/lib/rules/prop-types.js index 390d3045c5..15c932e8d1 100644 --- a/lib/rules/prop-types.js +++ b/lib/rules/prop-types.js @@ -11,6 +11,7 @@ const has = require('has'); const Components = require('../util/Components'); const variable = require('../util/variable'); const annotations = require('../util/annotations'); +const flowVersionUtil = require('../util/flowVersion'); // ------------------------------------------------------------------------------ // Constants @@ -173,7 +174,7 @@ module.exports = { */ function isSuperTypeParameterPropsDeclaration(node) { if (node && node.type === 'ClassDeclaration') { - if (node.superTypeParameters && node.superTypeParameters.params.length >= 2) { + if (node.superTypeParameters && node.superTypeParameters.params.length) { return true; } } @@ -857,7 +858,13 @@ module.exports = { * @returns {ASTNode} The resolved type annotation for the node. */ function resolveSuperParameterPropsType(node) { - let annotation = node.superTypeParameters.params[1]; + let annotation; + if (flowVersionUtil.test(context, '0.53.0')) { + annotation = node.superTypeParameters.params[0]; + } else { + annotation = node.superTypeParameters.params[1]; + } + while (annotation && (annotation.type === 'TypeAnnotation' || annotation.type === 'NullableTypeAnnotation')) { annotation = annotation.typeAnnotation; } @@ -917,12 +924,6 @@ module.exports = { } }, - TypeParameterInstantiation: function(node) { - if (node.params && node.params[0].type === 'GenericTypeAnnotation') { - markPropTypesAsDeclared(node, resolveTypeAnnotation(node.params[0])); - } - }, - VariableDeclarator: function(node) { const destructuring = node.init && node.id && node.id.type === 'ObjectPattern'; // let {props: {firstname}} = this diff --git a/lib/util/flowVersion.js b/lib/util/flowVersion.js new file mode 100644 index 0000000000..57fcaf3857 --- /dev/null +++ b/lib/util/flowVersion.js @@ -0,0 +1,28 @@ +/** + * @fileoverview Utility functions for Flow version configuration + */ +'use strict'; + +function getFromContext(context) { + let confVer = '999.999.999'; + // .eslintrc shared settings (http://eslint.org/docs/user-guide/configuring#adding-shared-settings) + if (context.settings.react && context.settings.react.flowVersion) { + confVer = context.settings.react.flowVersion; + } + confVer = /^[0-9]+\.[0-9]+$/.test(confVer) ? `${confVer}.0` : confVer; + return confVer.split('.').map(part => Number(part)); +} + +function test(context, methodVer) { + const confVer = getFromContext(context); + methodVer = methodVer.split('.').map(part => Number(part)); + const higherMajor = methodVer[0] < confVer[0]; + const higherMinor = methodVer[0] === confVer[0] && methodVer[1] < confVer[1]; + const higherOrEqualPatch = methodVer[0] === confVer[0] && methodVer[1] === confVer[1] && methodVer[2] <= confVer[2]; + + return higherMajor || higherMinor || higherOrEqualPatch; +} + +module.exports = { + test: test +}; diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 33c39d9b3e..5a3671608e 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -1486,6 +1486,7 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -1499,6 +1500,7 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -1514,6 +1516,7 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -1534,6 +1537,7 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -1546,6 +1550,7 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -1556,6 +1561,7 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { @@ -1570,9 +1576,9 @@ ruleTester.run('prop-types', rule, { } } `, + settings: {react: {flowVersion: '0.53.0'}}, parser: 'babel-eslint' - }, - { + }, { code: ` type FancyProps = { foo: string, @@ -1584,6 +1590,7 @@ ruleTester.run('prop-types', rule, { } } `, + settings: {react: {flowVersion: '0.53.0'}}, parser: 'babel-eslint' }, // issue #1288 @@ -2865,6 +2872,7 @@ ruleTester.run('prop-types', rule, { column: 35, type: 'Identifier' }], + settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -2884,6 +2892,7 @@ ruleTester.run('prop-types', rule, { column: 13, type: 'Property' }], + settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -2905,6 +2914,7 @@ ruleTester.run('prop-types', rule, { column: 7, type: 'Property' }], + settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -2921,6 +2931,7 @@ ruleTester.run('prop-types', rule, { column: 40, type: 'Identifier' }], + settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -2937,6 +2948,7 @@ ruleTester.run('prop-types', rule, { column: 42, type: 'Identifier' }], + settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -2955,6 +2967,7 @@ ruleTester.run('prop-types', rule, { column: 42, type: 'Identifier' }], + settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: ` @@ -2974,6 +2987,7 @@ ruleTester.run('prop-types', rule, { column: 37, type: 'Identifier' }], + settings: {react: {flowVersion: '0.53.0'}}, parser: 'babel-eslint' }, { code: ` @@ -2993,6 +3007,7 @@ ruleTester.run('prop-types', rule, { column: 37, type: 'Identifier' }], + settings: {react: {flowVersion: '0.53.0'}}, parser: 'babel-eslint' } ] From d232811ac1863b0dc0505382335281bb3365286b Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Mon, 21 Aug 2017 18:41:31 +0300 Subject: [PATCH 06/13] Remove flow version and decide the Props argument location based on the number of TypedArguments --- lib/rules/prop-types.js | 6 ++++-- lib/util/flowVersion.js | 28 ---------------------------- tests/lib/rules/prop-types.js | 16 ---------------- 3 files changed, 4 insertions(+), 46 deletions(-) delete mode 100644 lib/util/flowVersion.js diff --git a/lib/rules/prop-types.js b/lib/rules/prop-types.js index 15c932e8d1..556bdc2406 100644 --- a/lib/rules/prop-types.js +++ b/lib/rules/prop-types.js @@ -11,7 +11,6 @@ const has = require('has'); const Components = require('../util/Components'); const variable = require('../util/variable'); const annotations = require('../util/annotations'); -const flowVersionUtil = require('../util/flowVersion'); // ------------------------------------------------------------------------------ // Constants @@ -859,7 +858,10 @@ module.exports = { */ function resolveSuperParameterPropsType(node) { let annotation; - if (flowVersionUtil.test(context, '0.53.0')) { + + // Flow <=0.52 had 3 required TypedParameters of which the second one is the Props. + // Flow >=0.53 has 2 optional TypedParameters of which the first one is the Props. + if (node.superTypeParameters.params.length <= 2) { annotation = node.superTypeParameters.params[0]; } else { annotation = node.superTypeParameters.params[1]; diff --git a/lib/util/flowVersion.js b/lib/util/flowVersion.js deleted file mode 100644 index 57fcaf3857..0000000000 --- a/lib/util/flowVersion.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @fileoverview Utility functions for Flow version configuration - */ -'use strict'; - -function getFromContext(context) { - let confVer = '999.999.999'; - // .eslintrc shared settings (http://eslint.org/docs/user-guide/configuring#adding-shared-settings) - if (context.settings.react && context.settings.react.flowVersion) { - confVer = context.settings.react.flowVersion; - } - confVer = /^[0-9]+\.[0-9]+$/.test(confVer) ? `${confVer}.0` : confVer; - return confVer.split('.').map(part => Number(part)); -} - -function test(context, methodVer) { - const confVer = getFromContext(context); - methodVer = methodVer.split('.').map(part => Number(part)); - const higherMajor = methodVer[0] < confVer[0]; - const higherMinor = methodVer[0] === confVer[0] && methodVer[1] < confVer[1]; - const higherOrEqualPatch = methodVer[0] === confVer[0] && methodVer[1] === confVer[1] && methodVer[2] <= confVer[2]; - - return higherMajor || higherMinor || higherOrEqualPatch; -} - -module.exports = { - test: test -}; diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 5a3671608e..04f4d411a0 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -1486,7 +1486,6 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), - settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -1500,7 +1499,6 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), - settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -1516,7 +1514,6 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), - settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -1537,7 +1534,6 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), - settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -1550,7 +1546,6 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), - settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -1561,7 +1556,6 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), - settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { @@ -1576,7 +1570,6 @@ ruleTester.run('prop-types', rule, { } } `, - settings: {react: {flowVersion: '0.53.0'}}, parser: 'babel-eslint' }, { code: ` @@ -1590,7 +1583,6 @@ ruleTester.run('prop-types', rule, { } } `, - settings: {react: {flowVersion: '0.53.0'}}, parser: 'babel-eslint' }, // issue #1288 @@ -2872,7 +2864,6 @@ ruleTester.run('prop-types', rule, { column: 35, type: 'Identifier' }], - settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -2892,7 +2883,6 @@ ruleTester.run('prop-types', rule, { column: 13, type: 'Property' }], - settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -2914,7 +2904,6 @@ ruleTester.run('prop-types', rule, { column: 7, type: 'Property' }], - settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -2931,7 +2920,6 @@ ruleTester.run('prop-types', rule, { column: 40, type: 'Identifier' }], - settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -2948,7 +2936,6 @@ ruleTester.run('prop-types', rule, { column: 42, type: 'Identifier' }], - settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: [ @@ -2967,7 +2954,6 @@ ruleTester.run('prop-types', rule, { column: 42, type: 'Identifier' }], - settings: {react: {flowVersion: '0.52.0'}}, parser: 'babel-eslint' }, { code: ` @@ -2987,7 +2973,6 @@ ruleTester.run('prop-types', rule, { column: 37, type: 'Identifier' }], - settings: {react: {flowVersion: '0.53.0'}}, parser: 'babel-eslint' }, { code: ` @@ -3007,7 +2992,6 @@ ruleTester.run('prop-types', rule, { column: 37, type: 'Identifier' }], - settings: {react: {flowVersion: '0.53.0'}}, parser: 'babel-eslint' } ] From 1ebfcee2af0043c0275ab924ce09933bccc9ab5a Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Mon, 21 Aug 2017 21:47:21 +0300 Subject: [PATCH 07/13] Add flowVersion back but without a default. When there is no flow version, we detect the props argument position by the arguments length' --- lib/rules/no-deprecated.js | 2 +- lib/rules/no-render-return-value.js | 6 +++--- lib/rules/prefer-stateless-function.js | 2 +- lib/rules/prop-types.js | 18 +++++++++------- lib/util/version.js | 30 +++++++++++++++++++++----- 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/lib/rules/no-deprecated.js b/lib/rules/no-deprecated.js index 688046372d..0504798c5e 100644 --- a/lib/rules/no-deprecated.js +++ b/lib/rules/no-deprecated.js @@ -78,7 +78,7 @@ module.exports = { return ( deprecated && deprecated[method] && - versionUtil.test(context, deprecated[method][0]) + versionUtil.testReactVersion(context, deprecated[method][0]) ); } diff --git a/lib/rules/no-render-return-value.js b/lib/rules/no-render-return-value.js index e854481392..db38731026 100644 --- a/lib/rules/no-render-return-value.js +++ b/lib/rules/no-render-return-value.js @@ -35,11 +35,11 @@ module.exports = { } let calleeObjectName = /^ReactDOM$/; - if (versionUtil.test(context, '15.0.0')) { + if (versionUtil.testReactVersion(context, '15.0.0')) { calleeObjectName = /^ReactDOM$/; - } else if (versionUtil.test(context, '0.14.0')) { + } else if (versionUtil.testReactVersion(context, '0.14.0')) { calleeObjectName = /^React(DOM)?$/; - } else if (versionUtil.test(context, '0.13.0')) { + } else if (versionUtil.testReactVersion(context, '0.13.0')) { calleeObjectName = /^React$/; } diff --git a/lib/rules/prefer-stateless-function.js b/lib/rules/prefer-stateless-function.js index 5e89724532..e3c4ff5204 100644 --- a/lib/rules/prefer-stateless-function.js +++ b/lib/rules/prefer-stateless-function.js @@ -371,7 +371,7 @@ module.exports = { scope = scope.upper; } const isRender = blockNode && blockNode.key && blockNode.key.name === 'render'; - const allowNull = versionUtil.test(context, '15.0.0'); // Stateless components can return null since React 15 + const allowNull = versionUtil.testReactVersion(context, '15.0.0'); // Stateless components can return null since React 15 const isReturningJSX = utils.isReturningJSX(node, !allowNull); const isReturningNull = node.argument && (node.argument.value === null || node.argument.value === false); if ( diff --git a/lib/rules/prop-types.js b/lib/rules/prop-types.js index 556bdc2406..df40bf0ffb 100644 --- a/lib/rules/prop-types.js +++ b/lib/rules/prop-types.js @@ -11,6 +11,7 @@ const has = require('has'); const Components = require('../util/Components'); const variable = require('../util/variable'); const annotations = require('../util/annotations'); +const versionUtil = require('../util/version'); // ------------------------------------------------------------------------------ // Constants @@ -857,16 +858,17 @@ module.exports = { * @returns {ASTNode} The resolved type annotation for the node. */ function resolveSuperParameterPropsType(node) { - let annotation; - - // Flow <=0.52 had 3 required TypedParameters of which the second one is the Props. - // Flow >=0.53 has 2 optional TypedParameters of which the first one is the Props. - if (node.superTypeParameters.params.length <= 2) { - annotation = node.superTypeParameters.params[0]; - } else { - annotation = node.superTypeParameters.params[1]; + let propsParameterPosition; + try { + // Flow <=0.52 had 3 required TypedParameters of which the second one is the Props. + // Flow >=0.53 has 2 optional TypedParameters of which the first one is the Props. + propsParameterPosition = versionUtil.testFlowVersion(context, 0.53) ? 1 : 0; + } catch (e) { + // In case there is no flow version defined, we can safely assume that when there are 3 Props we are dealing with version <= 0.52 + propsParameterPosition = node.superTypeParameters.params.length <= 2 ? 0 : 1; } + let annotation = node.superTypeParameters.params[propsParameterPosition]; while (annotation && (annotation.type === 'TypeAnnotation' || annotation.type === 'NullableTypeAnnotation')) { annotation = annotation.typeAnnotation; } diff --git a/lib/util/version.js b/lib/util/version.js index a3847fd1a8..cbdec7d919 100644 --- a/lib/util/version.js +++ b/lib/util/version.js @@ -1,10 +1,10 @@ /** - * @fileoverview Utility functions for React version configuration + * @fileoverview Utility functions for React and Flow version configuration * @author Yannick Croissant */ 'use strict'; -function getFromContext(context) { +function getReactVersionFromContext(context) { let confVer = '999.999.999'; // .eslintrc shared settings (http://eslint.org/docs/user-guide/configuring#adding-shared-settings) if (context.settings.react && context.settings.react.version) { @@ -14,8 +14,19 @@ function getFromContext(context) { return confVer.split('.').map(part => Number(part)); } -function test(context, methodVer) { - const confVer = getFromContext(context); +function getFlowVersionFromContext(context) { + let confVer = '999.999.999'; + // .eslintrc shared settings (http://eslint.org/docs/user-guide/configuring#adding-shared-settings) + if (context.settings.react && context.settings.react.flowVersion) { + confVer = context.settings.react.flowVersion; + } else { + throw 'Could not retrieve flowVersion from settings'; + } + confVer = /^[0-9]+\.[0-9]+$/.test(confVer) ? `${confVer}.0` : confVer; + return confVer.split('.').map(part => Number(part)); +} + +function test(context, methodVer, confVer) { methodVer = methodVer.split('.').map(part => Number(part)); const higherMajor = methodVer[0] < confVer[0]; const higherMinor = methodVer[0] === confVer[0] && methodVer[1] < confVer[1]; @@ -24,6 +35,15 @@ function test(context, methodVer) { return higherMajor || higherMinor || higherOrEqualPatch; } +function testReactVersion(context, methodVer) { + return test(context, methodVer, getReactVersionFromContext(context)); +} + +function testFlowVersion(context, methodVer) { + return test(context, methodVer, getFlowVersionFromContext(context)); +} + module.exports = { - test: test + testReactVersion, + testFlowVersion }; From a7957a1417cf99873fe2610238e1aeb0b9b4c106 Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Mon, 21 Aug 2017 22:36:37 +0300 Subject: [PATCH 08/13] update readme regarding the flowVersion setting --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6bb0836761..8afe26911e 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ You can also specify some settings that will be shared across all the plugin rul "createClass": "createReactClass", // Regex for Component Factory to use, default to "createReactClass" "pragma": "React", // Pragma to use, default to "React" "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, such as `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped. } From 18ad186e9d62128f45a9cbfa13523404f3a9d84f Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Mon, 21 Aug 2017 22:51:12 +0300 Subject: [PATCH 09/13] Fix bug and add tests through helper function --- lib/rules/prop-types.js | 2 +- tests/lib/rules/prop-types.js | 43 +++++++++++++++++++---------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/lib/rules/prop-types.js b/lib/rules/prop-types.js index df40bf0ffb..033f3fdaa3 100644 --- a/lib/rules/prop-types.js +++ b/lib/rules/prop-types.js @@ -862,7 +862,7 @@ module.exports = { try { // Flow <=0.52 had 3 required TypedParameters of which the second one is the Props. // Flow >=0.53 has 2 optional TypedParameters of which the first one is the Props. - propsParameterPosition = versionUtil.testFlowVersion(context, 0.53) ? 1 : 0; + propsParameterPosition = versionUtil.testFlowVersion(context, '0.53.0') ? 0 : 1; } catch (e) { // In case there is no flow version defined, we can safely assume that when there are 3 Props we are dealing with version <= 0.52 propsParameterPosition = node.superTypeParameters.params.length <= 2 ? 0 : 1; diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 04f4d411a0..8761c703d0 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -28,6 +28,10 @@ const settings = { require('babel-eslint'); +function withAndWithoutFlowVersion(flowVersion, test) { + return [test, Object.assign({}, test, {settings: {react: {flowVersion}}})]; +} + // ------------------------------------------------------------------------------ // Tests // ------------------------------------------------------------------------------ @@ -1475,7 +1479,7 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }, { + }, ...withAndWithoutFlowVersion('0.52', { code: [ 'type Person = {', ' firstname: string', @@ -1487,7 +1491,7 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.52', { code: [ 'type Person = {', ' firstname: string', @@ -1500,7 +1504,7 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.52', { code: [ 'type Person = {', ' firstname: string', @@ -1515,7 +1519,7 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.52', { code: [ 'type Props = {name: {firstname: string;};};', 'class Hello extends React.Component {', @@ -1525,7 +1529,7 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.52', { code: [ 'import type Props from "fake";', 'class Hello extends React.Component {', @@ -1535,7 +1539,7 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.52', { code: [ 'type Person = {', ' firstname: string', @@ -1547,7 +1551,7 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.52', { code: [ 'type Props = {result?: {ok?: ?string | boolean;}|{ok?: ?number | Array}};', 'class Hello extends React.Component {', @@ -1557,8 +1561,7 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }, - { + }), ...withAndWithoutFlowVersion('0.53', { code: ` type Props = { foo: string, @@ -1571,7 +1574,7 @@ ruleTester.run('prop-types', rule, { } `, parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.53', { code: ` type FancyProps = { foo: string, @@ -1584,7 +1587,7 @@ ruleTester.run('prop-types', rule, { } `, parser: 'babel-eslint' - }, + }), // issue #1288 `function Foo() { const props = {} @@ -2847,7 +2850,7 @@ ruleTester.run('prop-types', rule, { errors: [ {message: '\'name\' is missing in props validation'} ] - }, { + }, ...withAndWithoutFlowVersion('0.52', { code: [ 'type Person = {', ' firstname: string', @@ -2865,7 +2868,7 @@ ruleTester.run('prop-types', rule, { type: 'Identifier' }], parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.52', { code: [ 'type Person = {', ' firstname: string', @@ -2884,7 +2887,7 @@ ruleTester.run('prop-types', rule, { type: 'Property' }], parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.52', { code: [ 'type Person = {', ' firstname: string', @@ -2905,7 +2908,7 @@ ruleTester.run('prop-types', rule, { type: 'Property' }], parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.52', { code: [ 'type Props = {name: {firstname: string;};};', 'class Hello extends React.Component {', @@ -2921,7 +2924,7 @@ ruleTester.run('prop-types', rule, { type: 'Identifier' }], parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.52', { code: [ 'type Props = {result?: {ok: string | boolean;}|{ok: number | Array}};', 'class Hello extends React.Component {', @@ -2937,7 +2940,7 @@ ruleTester.run('prop-types', rule, { type: 'Identifier' }], parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.52', { code: [ 'type Person = {', ' firstname: string', @@ -2955,7 +2958,7 @@ ruleTester.run('prop-types', rule, { type: 'Identifier' }], parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.53', { code: ` type Props = { foo: string, @@ -2974,7 +2977,7 @@ ruleTester.run('prop-types', rule, { type: 'Identifier' }], parser: 'babel-eslint' - }, { + }), ...withAndWithoutFlowVersion('0.53', { code: ` type FancyProps = { foo: string, @@ -2993,6 +2996,6 @@ ruleTester.run('prop-types', rule, { type: 'Identifier' }], parser: 'babel-eslint' - } + }) ] }); From bb0a4579d82069f8c61944461f9bc3efc2efed1a Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Tue, 22 Aug 2017 07:36:42 +0300 Subject: [PATCH 10/13] Add explicit > check for params length --- lib/rules/prop-types.js | 2 +- tests/lib/rules/prop-types.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rules/prop-types.js b/lib/rules/prop-types.js index 033f3fdaa3..13aa98e718 100644 --- a/lib/rules/prop-types.js +++ b/lib/rules/prop-types.js @@ -174,7 +174,7 @@ module.exports = { */ function isSuperTypeParameterPropsDeclaration(node) { if (node && node.type === 'ClassDeclaration') { - if (node.superTypeParameters && node.superTypeParameters.params.length) { + if (node.superTypeParameters && node.superTypeParameters.params.length > 0) { return true; } } diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 8761c703d0..f7be2eae8f 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -29,7 +29,7 @@ const settings = { require('babel-eslint'); function withAndWithoutFlowVersion(flowVersion, test) { - return [test, Object.assign({}, test, {settings: {react: {flowVersion}}})]; + return [test, Object.assign({}, test, {settings: {react: {flowVersion: flowVersion}}})]; } // ------------------------------------------------------------------------------ From cd96ec934cb1fbbc40311ef9d8f4d44f7269ff0b Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Tue, 22 Aug 2017 07:49:27 +0300 Subject: [PATCH 11/13] remove test helper function as we cannot use spread operator --- tests/lib/rules/prop-types.js | 255 ++++++++++++++++++++++++++++++---- 1 file changed, 226 insertions(+), 29 deletions(-) diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index f7be2eae8f..7a75a266d1 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -28,10 +28,6 @@ const settings = { require('babel-eslint'); -function withAndWithoutFlowVersion(flowVersion, test) { - return [test, Object.assign({}, test, {settings: {react: {flowVersion: flowVersion}}})]; -} - // ------------------------------------------------------------------------------ // Tests // ------------------------------------------------------------------------------ @@ -1479,7 +1475,7 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }, ...withAndWithoutFlowVersion('0.52', { + }, { code: [ 'type Person = {', ' firstname: string', @@ -1491,7 +1487,20 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.52', { + }, { + code: [ + 'type Person = {', + ' firstname: string', + '};', + 'class Hello extends React.Component {', + ' render () {', + ' return
Hello {this.props.firstname}
;', + ' }', + '}' + ].join('\n'), + settings: {react: {flowVersion: '0.52'}}, + parser: 'babel-eslint' + }, { code: [ 'type Person = {', ' firstname: string', @@ -1504,22 +1513,31 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.52', { + }, { code: [ 'type Person = {', ' firstname: string', '};', 'class Hello extends React.Component {', ' render () {', - ' const {', - ' firstname,', - ' } = this.props;', + ' const { firstname } = this.props;', ' return
Hello {firstname}
;', ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52'}}, + parser: 'babel-eslint' + }, { + code: [ + 'type Props = {name: {firstname: string;};};', + 'class Hello extends React.Component {', + ' render () {', + ' return
Hello {this.props.name.firstname}
;', + ' }', + '}' + ].join('\n'), parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.52', { + }, { code: [ 'type Props = {name: {firstname: string;};};', 'class Hello extends React.Component {', @@ -1528,8 +1546,9 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52'}}, parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.52', { + }, { code: [ 'import type Props from "fake";', 'class Hello extends React.Component {', @@ -1539,7 +1558,18 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.52', { + }, { + code: [ + 'import type Props from "fake";', + 'class Hello extends React.Component {', + ' render () {', + ' return
Hello {this.props.firstname}
;', + ' }', + '}' + ].join('\n'), + settings: {react: {flowVersion: '0.52'}}, + parser: 'babel-eslint' + }, { code: [ 'type Person = {', ' firstname: string', @@ -1551,7 +1581,30 @@ ruleTester.run('prop-types', rule, { '}' ].join('\n'), parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.52', { + }, { + code: [ + 'type Person = {', + ' firstname: string', + '};', + 'class Hello extends React.Component {', + ' render () {', + ' return
Hello {this.props.person.firstname}
;', + ' }', + '}' + ].join('\n'), + settings: {react: {flowVersion: '0.52'}}, + parser: 'babel-eslint' + }, { + code: [ + 'type Props = {result?: {ok?: ?string | boolean;}|{ok?: ?number | Array}};', + 'class Hello extends React.Component {', + ' render () {', + ' return
Hello {this.props.result.ok}
;', + ' }', + '}' + ].join('\n'), + parser: 'babel-eslint' + }, { code: [ 'type Props = {result?: {ok?: ?string | boolean;}|{ok?: ?number | Array}};', 'class Hello extends React.Component {', @@ -1560,8 +1613,9 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52'}}, parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.53', { + }, { code: ` type Props = { foo: string, @@ -1574,7 +1628,21 @@ ruleTester.run('prop-types', rule, { } `, parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.53', { + }, { + code: ` + type Props = { + foo: string, + }; + + class Bar extends React.Component { + render() { + return
{this.props.foo}
+ } + } + `, + settings: {react: {flowVersion: '0.53'}}, + parser: 'babel-eslint' + }, { code: ` type FancyProps = { foo: string, @@ -1587,7 +1655,21 @@ ruleTester.run('prop-types', rule, { } `, parser: 'babel-eslint' - }), + }, { + code: ` + type FancyProps = { + foo: string, + }; + + class Bar extends React.Component { + render() { + return
{this.props.foo}
+ } + } + `, + settings: {react: {flowVersion: '0.53'}}, + parser: 'babel-eslint' + }, // issue #1288 `function Foo() { const props = {} @@ -2850,7 +2932,7 @@ ruleTester.run('prop-types', rule, { errors: [ {message: '\'name\' is missing in props validation'} ] - }, ...withAndWithoutFlowVersion('0.52', { + }, { code: [ 'type Person = {', ' firstname: string', @@ -2868,26 +2950,47 @@ ruleTester.run('prop-types', rule, { type: 'Identifier' }], parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.52', { + }, { code: [ 'type Person = {', ' firstname: string', '};', 'class Hello extends React.Component {', ' render () {', - ' const { lastname } = this.props;', - ' return
Hello {lastname}
;', + ' return
Hello {this.props.lastname}
;', ' }', '}' ].join('\n'), errors: [{ message: '\'lastname\' is missing in props validation', line: 6, - column: 13, + column: 35, + type: 'Identifier' + }], + settings: {react: {flowVersion: '0.52'}}, + parser: 'babel-eslint' + }, { + code: [ + 'type Person = {', + ' firstname: string', + '};', + 'class Hello extends React.Component {', + ' render () {', + ' const {', + ' lastname,', + ' } = this.props;', + ' return
Hello {lastname}
;', + ' }', + '}' + ].join('\n'), + errors: [{ + message: '\'lastname\' is missing in props validation', + line: 7, + column: 7, type: 'Property' }], parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.52', { + }, { code: [ 'type Person = {', ' firstname: string', @@ -2907,8 +3010,25 @@ ruleTester.run('prop-types', rule, { column: 7, type: 'Property' }], + settings: {react: {flowVersion: '0.52'}}, + parser: 'babel-eslint' + }, { + code: [ + 'type Props = {name: {firstname: string;};};', + 'class Hello extends React.Component {', + ' render () {', + ' return
Hello {this.props.name.lastname}
;', + ' }', + '}' + ].join('\n'), + errors: [{ + message: '\'name.lastname\' is missing in props validation', + line: 4, + column: 40, + type: 'Identifier' + }], parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.52', { + }, { code: [ 'type Props = {name: {firstname: string;};};', 'class Hello extends React.Component {', @@ -2923,8 +3043,9 @@ ruleTester.run('prop-types', rule, { column: 40, type: 'Identifier' }], + settings: {react: {flowVersion: '0.52'}}, parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.52', { + }, { code: [ 'type Props = {result?: {ok: string | boolean;}|{ok: number | Array}};', 'class Hello extends React.Component {', @@ -2940,7 +3061,24 @@ ruleTester.run('prop-types', rule, { type: 'Identifier' }], parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.52', { + }, { + code: [ + 'type Props = {result?: {ok: string | boolean;}|{ok: number | Array}};', + 'class Hello extends React.Component {', + ' render () {', + ' return
Hello {this.props.result.notok}
;', + ' }', + '}' + ].join('\n'), + errors: [{ + message: '\'result.notok\' is missing in props validation', + line: 4, + column: 42, + type: 'Identifier' + }], + settings: {react: {flowVersion: '0.52'}}, + parser: 'babel-eslint' + }, { code: [ 'type Person = {', ' firstname: string', @@ -2958,7 +3096,26 @@ ruleTester.run('prop-types', rule, { type: 'Identifier' }], parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.53', { + }, { + code: [ + 'type Person = {', + ' firstname: string', + '};', + 'class Hello extends React.Component {', + ' render () {', + ' return
Hello {this.props.person.lastname}
;', + ' }', + '}' + ].join('\n'), + errors: [{ + message: '\'person.lastname\' is missing in props validation', + line: 6, + column: 42, + type: 'Identifier' + }], + settings: {react: {flowVersion: '0.52'}}, + parser: 'babel-eslint' + }, { code: ` type Props = { foo: string, @@ -2977,7 +3134,46 @@ ruleTester.run('prop-types', rule, { type: 'Identifier' }], parser: 'babel-eslint' - }), ...withAndWithoutFlowVersion('0.53', { + }, { + code: ` + type Props = { + foo: string, + }; + + class Bar extends React.Component { + render() { + return
{this.props.bar}
+ } + } + `, + errors: [{ + message: '\'bar\' is missing in props validation', + line: 8, + column: 37, + type: 'Identifier' + }], + settings: {react: {flowVersion: '0.53'}}, + parser: 'babel-eslint' + }, { + code: ` + type FancyProps = { + foo: string, + }; + + class Bar extends React.Component { + render() { + return
{this.props.bar}
+ } + } + `, + errors: [{ + message: '\'bar\' is missing in props validation', + line: 8, + column: 37, + type: 'Identifier' + }], + parser: 'babel-eslint' + }, { code: ` type FancyProps = { foo: string, @@ -2995,7 +3191,8 @@ ruleTester.run('prop-types', rule, { column: 37, type: 'Identifier' }], + settings: {react: {flowVersion: '0.53'}}, parser: 'babel-eslint' - }) + } ] }); From 6d1b7f1bbf41ceed46cb4d90056d97ace6904172 Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Tue, 22 Aug 2017 07:53:52 +0300 Subject: [PATCH 12/13] Add one more test case for the new syntax --- tests/lib/rules/prop-types.js | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 7a75a266d1..f03f5bd28b 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -3193,6 +3193,43 @@ ruleTester.run('prop-types', rule, { }], settings: {react: {flowVersion: '0.53'}}, parser: 'babel-eslint' + }, { + code: ` + type Person = { + firstname: string + }; + class Hello extends React.Component<{ person: Person }> { + render () { + return
Hello {this.props.person.lastname}
; + } + } + `, + errors: [{ + message: '\'person.lastname\' is missing in props validation', + line: 7, + column: 50, + type: 'Identifier' + }], + parser: 'babel-eslint' + }, { + code: ` + type Person = { + firstname: string + }; + class Hello extends React.Component<{ person: Person }> { + render () { + return
Hello {this.props.person.lastname}
; + } + } + `, + errors: [{ + message: '\'person.lastname\' is missing in props validation', + line: 7, + column: 50, + type: 'Identifier' + }], + settings: {react: {flowVersion: '0.53'}}, + parser: 'babel-eslint' } ] }); From a6d26d9c83646d683192b9dd39cd4b9de2959499 Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Tue, 22 Aug 2017 07:56:51 +0300 Subject: [PATCH 13/13] Move flowVersion setting in invalid tests closer to the code --- tests/lib/rules/prop-types.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index f03f5bd28b..3bcc2c61e7 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -2961,13 +2961,13 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52'}}, errors: [{ message: '\'lastname\' is missing in props validation', line: 6, column: 35, type: 'Identifier' }], - settings: {react: {flowVersion: '0.52'}}, parser: 'babel-eslint' }, { code: [ @@ -3004,13 +3004,13 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52'}}, errors: [{ message: '\'lastname\' is missing in props validation', line: 7, column: 7, type: 'Property' }], - settings: {react: {flowVersion: '0.52'}}, parser: 'babel-eslint' }, { code: [ @@ -3037,13 +3037,13 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52'}}, errors: [{ message: '\'name.lastname\' is missing in props validation', line: 4, column: 40, type: 'Identifier' }], - settings: {react: {flowVersion: '0.52'}}, parser: 'babel-eslint' }, { code: [ @@ -3070,13 +3070,13 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52'}}, errors: [{ message: '\'result.notok\' is missing in props validation', line: 4, column: 42, type: 'Identifier' }], - settings: {react: {flowVersion: '0.52'}}, parser: 'babel-eslint' }, { code: [ @@ -3107,13 +3107,13 @@ ruleTester.run('prop-types', rule, { ' }', '}' ].join('\n'), + settings: {react: {flowVersion: '0.52'}}, errors: [{ message: '\'person.lastname\' is missing in props validation', line: 6, column: 42, type: 'Identifier' }], - settings: {react: {flowVersion: '0.52'}}, parser: 'babel-eslint' }, { code: ` @@ -3146,13 +3146,13 @@ ruleTester.run('prop-types', rule, { } } `, + settings: {react: {flowVersion: '0.53'}}, errors: [{ message: '\'bar\' is missing in props validation', line: 8, column: 37, type: 'Identifier' }], - settings: {react: {flowVersion: '0.53'}}, parser: 'babel-eslint' }, { code: ` @@ -3185,13 +3185,13 @@ ruleTester.run('prop-types', rule, { } } `, + settings: {react: {flowVersion: '0.53'}}, errors: [{ message: '\'bar\' is missing in props validation', line: 8, column: 37, type: 'Identifier' }], - settings: {react: {flowVersion: '0.53'}}, parser: 'babel-eslint' }, { code: ` @@ -3222,13 +3222,13 @@ ruleTester.run('prop-types', rule, { } } `, + settings: {react: {flowVersion: '0.53'}}, errors: [{ message: '\'person.lastname\' is missing in props validation', line: 7, column: 50, type: 'Identifier' }], - settings: {react: {flowVersion: '0.53'}}, parser: 'babel-eslint' } ]