mirror of
https://github.com/zebrajr/react.git
synced 2025-12-07 00:20:28 +01:00
The old version of prettier we were using didn't support the Flow syntax to access properties in a type using `SomeType['prop']`. This updates `prettier` and `rollup-plugin-prettier` to the latest versions. I added the prettier config `arrowParens: "avoid"` to reduce the diff size as the default has changed in Prettier 2.0. The largest amount of changes comes from function expressions now having a space. This doesn't have an option to preserve the old behavior, so we have to update this.
288 lines
7.4 KiB
JavaScript
288 lines
7.4 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @emails react-core
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const rule = require('../safe-string-coercion');
|
|
const {RuleTester} = require('eslint');
|
|
|
|
RuleTester.setDefaultConfig({
|
|
parser: require.resolve('babel-eslint'),
|
|
parserOptions: {
|
|
ecmaVersion: 6,
|
|
sourceType: 'module',
|
|
},
|
|
});
|
|
|
|
const ruleTester = new RuleTester();
|
|
|
|
const missingDevCheckMessage =
|
|
'Missing DEV check before this string coercion.' +
|
|
' Check should be in this format:\n' +
|
|
' if (__DEV__) {\n' +
|
|
' checkXxxxxStringCoercion(value);\n' +
|
|
' }';
|
|
const prevStatementNotDevCheckMessage =
|
|
'The statement before this coercion must be a DEV check in this format:\n' +
|
|
' if (__DEV__) {\n' +
|
|
' checkXxxxxStringCoercion(value);\n' +
|
|
' }';
|
|
const message =
|
|
"Using `'' + value` or `value + ''` is fast to coerce strings, but may throw." +
|
|
' For prod code, add a DEV check from shared/CheckStringCoercion immediately' +
|
|
' before this coercion.' +
|
|
' For non-prod code and prod error handling, use `String(value)` instead.';
|
|
|
|
ruleTester.run('eslint-rules/safe-string-coercion', rule, {
|
|
valid: [
|
|
{
|
|
code: 'String(obj)',
|
|
options: [{isProductionUserAppCode: false}],
|
|
},
|
|
'String(obj)',
|
|
"'a' + obj",
|
|
`
|
|
function getValueForAttribute(
|
|
node,
|
|
name,
|
|
expected
|
|
) {
|
|
if (__DEV__) {
|
|
var value = node.getAttribute(name);
|
|
if (__DEV__) {
|
|
checkAttributeStringCoercion(expected, name);
|
|
}
|
|
if (value === '' + expected) {
|
|
return expected;
|
|
}
|
|
return value;
|
|
}
|
|
}
|
|
`,
|
|
`
|
|
if (__DEV__) { checkFormFieldValueStringCoercion (obj) }
|
|
'' + obj;
|
|
`,
|
|
`
|
|
function f(a, index) {
|
|
if (typeof a === 'object' && a !== null && a.key != null) {
|
|
if (__DEV__) {
|
|
checkKeyStringCoercion(a.key);
|
|
}
|
|
return f('' + a.key);
|
|
}
|
|
return a;
|
|
}
|
|
`,
|
|
"'' + i++",
|
|
"'' + +i",
|
|
"'' + +i",
|
|
"+i + ''",
|
|
"if (typeof obj === 'string') { '' + obj }",
|
|
"if (typeof obj === 'string' || typeof obj === 'number') { '' + obj }",
|
|
"if (typeof obj === 'string' && somethingElse) { '' + obj }",
|
|
"if (typeof obj === 'number' && somethingElse) { '' + obj }",
|
|
"if (typeof obj === 'bigint' && somethingElse) { '' + obj }",
|
|
"if (typeof obj === 'undefined' && somethingElse) { '' + obj }",
|
|
"if (typeof nextProp === 'number') { setTextContent(domElement, '' + nextProp); }",
|
|
// These twe below are sneaky. The inner `if` is unsafe, but the outer `if`
|
|
// ensures that the unsafe code will never be run. It's bad code, but
|
|
// doesn't violate this rule.
|
|
"if (typeof obj === 'string') { if (typeof obj === 'string' && obj.length) {} else {'' + obj} }",
|
|
"if (typeof obj === 'string') if (typeof obj === 'string' && obj.length) {} else {'' + obj}",
|
|
"'' + ''",
|
|
"'' + '' + ''",
|
|
"`test${foo}` + ''",
|
|
],
|
|
invalid: [
|
|
{
|
|
code: "'' + obj",
|
|
errors: [
|
|
{
|
|
message: missingDevCheckMessage + '\n' + message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: "obj + ''",
|
|
errors: [
|
|
{
|
|
message: missingDevCheckMessage + '\n' + message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: 'String(obj)',
|
|
options: [{isProductionUserAppCode: true}],
|
|
errors: [
|
|
{
|
|
message:
|
|
"For perf-sensitive coercion, avoid `String(value)`. Instead, use `'' + value`." +
|
|
' Precede it with a DEV check from shared/CheckStringCoercion' +
|
|
' unless Symbol and Temporal.* values are impossible.' +
|
|
' For non-prod code and prod error handling, use `String(value)` and disable this rule.',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: "if (typeof obj === 'object') { '' + obj }",
|
|
errors: [
|
|
{
|
|
message: missingDevCheckMessage + '\n' + message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: "if (typeof obj === 'string') { } else if (typeof obj === 'object') {'' + obj}",
|
|
errors: [
|
|
{
|
|
message: missingDevCheckMessage + '\n' + message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: "if (typeof obj === 'string' && obj.length) {} else {'' + obj}",
|
|
errors: [
|
|
{
|
|
message: missingDevCheckMessage + '\n' + message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: `
|
|
if (__D__) { checkFormFieldValueStringCoercion (obj) }
|
|
'' + obj;
|
|
`,
|
|
errors: [
|
|
{
|
|
message: prevStatementNotDevCheckMessage + '\n' + message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: `
|
|
if (__DEV__) { checkFormFieldValueStringCoercion (obj) }
|
|
'' + notobjj;
|
|
`,
|
|
errors: [
|
|
{
|
|
message:
|
|
'Value passed to the check function before this coercion must match the value being coerced.' +
|
|
'\n' +
|
|
message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: `
|
|
if (__DEV__) { checkFormFieldValueStringCoercion (obj) }
|
|
// must be right before the check call
|
|
someOtherCode();
|
|
'' + objj;
|
|
`,
|
|
errors: [
|
|
{
|
|
message: prevStatementNotDevCheckMessage + '\n' + message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: `
|
|
if (__DEV__) { chexxxxBadNameCoercion (obj) }
|
|
'' + objj;
|
|
`,
|
|
errors: [
|
|
{
|
|
message:
|
|
'Missing or invalid check function call before this coercion.' +
|
|
' Expected: call of a function like checkXXXStringCoercion. ' +
|
|
prevStatementNotDevCheckMessage +
|
|
'\n' +
|
|
message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: `
|
|
if (__DEV__) { }
|
|
'' + objj;
|
|
`,
|
|
errors: [
|
|
{
|
|
message: prevStatementNotDevCheckMessage + '\n' + message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: `
|
|
if (__DEV__) { if (x) {} }
|
|
'' + objj;
|
|
`,
|
|
errors: [
|
|
{
|
|
message:
|
|
'The DEV block before this coercion must only contain an expression. ' +
|
|
prevStatementNotDevCheckMessage +
|
|
'\n' +
|
|
message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: `
|
|
if (a) {
|
|
if (__DEV__) {
|
|
// can't have additional code before the check call
|
|
if (b) {
|
|
checkKeyStringCoercion(obj);
|
|
}
|
|
}
|
|
g = f( c, d + (b ? '' + obj : '') + e);
|
|
}
|
|
`,
|
|
errors: [
|
|
{
|
|
message:
|
|
'The DEV block before this coercion must only contain an expression. ' +
|
|
prevStatementNotDevCheckMessage +
|
|
'\n' +
|
|
message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: `
|
|
if (__DEV__) {
|
|
checkAttributeStringCoercion(expected, name);
|
|
}
|
|
// DEV check should be inside the if block
|
|
if (a && b) {
|
|
f('' + expected);
|
|
}
|
|
`,
|
|
errors: [
|
|
{
|
|
message: missingDevCheckMessage + '\n' + message,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
code: `'' + obj + ''`,
|
|
errors: [
|
|
{message: missingDevCheckMessage + '\n' + message},
|
|
{message: missingDevCheckMessage + '\n' + message},
|
|
],
|
|
},
|
|
{
|
|
code: `foo\`text\` + ""`,
|
|
errors: [{message: missingDevCheckMessage + '\n' + message}],
|
|
},
|
|
],
|
|
});
|