]> source.dussan.org Git - sonarqube.git/commitdiff
[NO JIRA] Fix typo in local eslint rule
authorViktor Vorona <viktor.vorona@sonarsource.com>
Tue, 24 Oct 2023 12:08:51 +0000 (14:08 +0200)
committersonartech <sonartech@sonarsource.com>
Tue, 24 Oct 2023 20:02:49 +0000 (20:02 +0000)
server/sonar-web/.eslintrc
server/sonar-web/eslint-local-rules/__tests__/no-implicit-coercion-test.js [new file with mode: 0644]
server/sonar-web/eslint-local-rules/__tests__/no-implicit-coersion-test.js [deleted file]
server/sonar-web/eslint-local-rules/index.js
server/sonar-web/eslint-local-rules/no-implicit-coercion.js [new file with mode: 0644]
server/sonar-web/eslint-local-rules/no-implicit-coersion.js [deleted file]

index dbf974557766a0d3bd87b57f0665fc255c9d10f3..dd5618dbdf266dcea4e3d4ee14188fb526c94b2b 100644 (file)
@@ -16,7 +16,7 @@
     "local-rules/no-conditional-rendering-of-deferredspinner": "warn",
     "local-rules/use-jest-mocked": "warn",
     "local-rules/use-await-expect-async-matcher": "warn",
-    "local-rules/no-implicit-coersion": "warn",
+    "local-rules/no-implicit-coercion": "warn",
     "local-rules/no-api-imports": "warn"
   }
 }
diff --git a/server/sonar-web/eslint-local-rules/__tests__/no-implicit-coercion-test.js b/server/sonar-web/eslint-local-rules/__tests__/no-implicit-coercion-test.js
new file mode 100644 (file)
index 0000000..03cb3df
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+const { RuleTester } = require('eslint');
+const noImplicitCoercion = require('../no-implicit-coercion');
+
+const ruleTester = new RuleTester({
+  parserOptions: {
+    ecmaFeatures: {
+      jsx: true,
+    },
+  },
+  parser: require.resolve('@typescript-eslint/parser'),
+});
+
+ruleTester.run('no-implicit-coercion', noImplicitCoercion, {
+  valid: [
+    {
+      code: `
+      function test(value?: number) {
+        if (value === undefined) {
+          return true;
+        }
+      }`,
+    },
+    {
+      code: `
+      function test(value?: number) {
+        if (Boolean(value)) {
+          return true;
+        }
+      }`,
+    },
+    {
+      code: `
+      function test(value?: {}) {
+        if (!value) {
+          return true;
+        }
+      }`,
+    },
+    {
+      code: `
+      function test(value: string) {
+        if (value !== '') {
+          return true;
+        }
+      }`,
+    },
+    {
+      code: `
+      function test(value?: number | {}) {
+        return value !== undefined && value.toString();
+      }`,
+    },
+    {
+      code: `
+      function test(value?: number) {
+        return value ?? 100;
+      }`,
+    },
+    {
+      code: `
+      interface Props {
+        test?: number;
+      }
+      function Test(props: Props) {
+        if (props.test !== undefined) {
+          return props.test * 10;
+        }
+        return 100;
+      }`,
+    },
+    {
+      code: `
+      interface Props {
+        test?: number;
+        check: boolean
+      }
+      function Test(props: Props) {
+        if (props.check && props.test !== undefined) {
+          return props.test * 10;
+        }
+        return 100;
+      }`,
+    },
+    {
+      code: `
+      interface Props {
+        test?: React.ReactNode;
+      }
+      function Test(props: Props) {
+        if (props.test) {
+          return props.test;
+        }
+        return null;
+      }`,
+    },
+    {
+      code: `
+      interface Props {
+        test?: number;
+      }
+      function Test(props: Props) {
+        return (
+          <div>
+            {props.test !== undefined && <span>{props.test}</span>}
+            {props.test === undefined && <span>100</span>}
+          </div>
+        );
+      }`,
+    },
+  ],
+  invalid: [
+    {
+      code: `
+        function test(value?: number) {
+          if (!value) {
+            return true;
+          }
+        }`,
+      errors: [{ messageId: 'noImplicitCoercion' }],
+    },
+    {
+      code: `
+        function test(value?: number) {
+          if (value) {
+            return true;
+          }
+        }`,
+      errors: [{ messageId: 'noImplicitCoercion' }],
+    },
+    {
+      code: `
+        function test(value: string) {
+          if (value) {
+            return true;
+          }
+        }`,
+      errors: [{ messageId: 'noImplicitCoercion' }],
+    },
+    {
+      code: `
+        function test(value?: number) {
+          return value && value > -1;
+        }`,
+      errors: [{ messageId: 'noImplicitCoercion' }],
+    },
+    {
+      code: `
+        function test(value?: string | {}) {
+          if (value) {
+            return 1;
+          }
+        }`,
+      errors: [{ messageId: 'noImplicitCoercion' }],
+    },
+    {
+      code: `
+        function test(value?: number) {
+          return value || 100;
+        }`,
+      errors: [{ messageId: 'noImplicitCoercion' }],
+    },
+    {
+      code: `
+        interface Props {
+          test?: number | {};
+        }
+        function Test(props: Props) {
+          return props.test && props.test.toString();
+        }`,
+      errors: [{ messageId: 'noImplicitCoercion' }],
+    },
+    {
+      code: `
+        interface Props {
+          test?: number;
+        }
+        function Test(props: Props) {
+          if (props.test) {
+            return props.test * 10;
+          }
+          return 100;
+        }`,
+      errors: [{ messageId: 'noImplicitCoercion' }],
+    },
+    {
+      code: `
+        interface Props {
+          test?: number;
+          check: boolean
+        }
+        function Test(props: Props) {
+          if (props.check && props.test) {
+            return props.test * 10;
+          }
+          return 100;
+        }`,
+      errors: [{ messageId: 'noImplicitCoercion' }],
+    },
+    {
+      code: `
+      interface Props {
+        test?: number;
+      }
+      function Test(props: Props) {
+        return (
+          <div>
+            {props.test && <span>{props.test}</span>}
+            {!props.test && <span>100</span>}
+          </div>
+        );
+      }`,
+      errors: [{ messageId: 'noImplicitCoercion' }, { messageId: 'noImplicitCoercion' }],
+    },
+  ],
+});
diff --git a/server/sonar-web/eslint-local-rules/__tests__/no-implicit-coersion-test.js b/server/sonar-web/eslint-local-rules/__tests__/no-implicit-coersion-test.js
deleted file mode 100644 (file)
index fe5c346..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-const { RuleTester } = require('eslint');
-const noImplicitCoersion = require('../no-implicit-coersion');
-
-const ruleTester = new RuleTester({
-  parserOptions: {
-    ecmaFeatures: {
-      jsx: true,
-    },
-  },
-  parser: require.resolve('@typescript-eslint/parser'),
-});
-
-ruleTester.run('no-implicit-coersion', noImplicitCoersion, {
-  valid: [
-    {
-      code: `
-      function test(value?: number) {
-        if (value === undefined) {
-          return true;
-        }
-      }`,
-    },
-    {
-      code: `
-      function test(value?: number) {
-        if (Boolean(value)) {
-          return true;
-        }
-      }`,
-    },
-    {
-      code: `
-      function test(value?: {}) {
-        if (!value) {
-          return true;
-        }
-      }`,
-    },
-    {
-      code: `
-      function test(value: string) {
-        if (value !== '') {
-          return true;
-        }
-      }`,
-    },
-    {
-      code: `
-      function test(value?: number | {}) {
-        return value !== undefined && value.toString();
-      }`,
-    },
-    {
-      code: `
-      function test(value?: number) {
-        return value ?? 100;
-      }`,
-    },
-    {
-      code: `
-      interface Props {
-        test?: number;
-      }
-      function Test(props: Props) {
-        if (props.test !== undefined) {
-          return props.test * 10;
-        }
-        return 100;
-      }`,
-    },
-    {
-      code: `
-      interface Props {
-        test?: number;
-        check: boolean
-      }
-      function Test(props: Props) {
-        if (props.check && props.test !== undefined) {
-          return props.test * 10;
-        }
-        return 100;
-      }`,
-    },
-    {
-      code: `
-      interface Props {
-        test?: React.ReactNode;
-      }
-      function Test(props: Props) {
-        if (props.test) {
-          return props.test;
-        }
-        return null;
-      }`,
-    },
-    {
-      code: `
-      interface Props {
-        test?: number;
-      }
-      function Test(props: Props) {
-        return (
-          <div>
-            {props.test !== undefined && <span>{props.test}</span>}
-            {props.test === undefined && <span>100</span>}
-          </div>
-        );
-      }`,
-    },
-  ],
-  invalid: [
-    {
-      code: `
-        function test(value?: number) {
-          if (!value) {
-            return true;
-          }
-        }`,
-      errors: [{ messageId: 'noImplicitCoersion' }],
-    },
-    {
-      code: `
-        function test(value?: number) {
-          if (value) {
-            return true;
-          }
-        }`,
-      errors: [{ messageId: 'noImplicitCoersion' }],
-    },
-    {
-      code: `
-        function test(value: string) {
-          if (value) {
-            return true;
-          }
-        }`,
-      errors: [{ messageId: 'noImplicitCoersion' }],
-    },
-    {
-      code: `
-        function test(value?: number) {
-          return value && value > -1;
-        }`,
-      errors: [{ messageId: 'noImplicitCoersion' }],
-    },
-    {
-      code: `
-        function test(value?: string | {}) {
-          if (value) {
-            return 1;
-          }
-        }`,
-      errors: [{ messageId: 'noImplicitCoersion' }],
-    },
-    {
-      code: `
-        function test(value?: number) {
-          return value || 100;
-        }`,
-      errors: [{ messageId: 'noImplicitCoersion' }],
-    },
-    {
-      code: `
-        interface Props {
-          test?: number | {};
-        }
-        function Test(props: Props) {
-          return props.test && props.test.toString();
-        }`,
-      errors: [{ messageId: 'noImplicitCoersion' }],
-    },
-    {
-      code: `
-        interface Props {
-          test?: number;
-        }
-        function Test(props: Props) {
-          if (props.test) {
-            return props.test * 10;
-          }
-          return 100;
-        }`,
-      errors: [{ messageId: 'noImplicitCoersion' }],
-    },
-    {
-      code: `
-        interface Props {
-          test?: number;
-          check: boolean
-        }
-        function Test(props: Props) {
-          if (props.check && props.test) {
-            return props.test * 10;
-          }
-          return 100;
-        }`,
-      errors: [{ messageId: 'noImplicitCoersion' }],
-    },
-    {
-      code: `
-      interface Props {
-        test?: number;
-      }
-      function Test(props: Props) {
-        return (
-          <div>
-            {props.test && <span>{props.test}</span>}
-            {!props.test && <span>100</span>}
-          </div>
-        );
-      }`,
-      errors: [{ messageId: 'noImplicitCoersion' }, { messageId: 'noImplicitCoersion' }],
-    },
-  ],
-});
index 5ea46f3a2109ce6413e76c31728171997365f184..aecf29ef9c106963cb13b5e53fa8b4f1763367f2 100644 (file)
@@ -26,6 +26,6 @@ module.exports = {
   'use-metrickey-enum': require('./use-metrickey-enum'),
   'use-metrictype-enum': require('./use-metrictype-enum'),
   'use-await-expect-async-matcher': require('./use-await-expect-async-matcher'),
-  'no-implicit-coersion': require('./no-implicit-coersion'),
+  'no-implicit-coercion': require('./no-implicit-coercion'),
   'no-api-imports': require('./no-api-imports'),
 };
diff --git a/server/sonar-web/eslint-local-rules/no-implicit-coercion.js b/server/sonar-web/eslint-local-rules/no-implicit-coercion.js
new file mode 100644 (file)
index 0000000..3ca8ec0
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+module.exports = {
+  meta: {
+    type: 'suggestion',
+    docs: {
+      description:
+        'Enforce using explicit comparison instead of implicit coercion for certain variable types',
+      category: 'Best Practices',
+      recommended: true,
+    },
+    messages: {
+      noImplicitCoercion:
+        'Use explicit comparison instead of implicit coercion for strings and numbers.',
+    },
+  },
+  create(context) {
+    return {
+      UnaryExpression: (node) => {
+        const { argument, operator } = node;
+
+        if (operator === '!') {
+          checkImplicitCoercion(context, argument);
+        }
+      },
+      LogicalExpression: (node) => {
+        const { left, operator } = node;
+        if (operator === '??') {
+          return;
+        }
+        if (isVariableOrObjectField(left)) {
+          checkImplicitCoercion(context, left);
+        }
+      },
+      IfStatement: (node) => {
+        const { test } = node;
+        checkImplicitCoercion(context, test);
+      },
+    };
+  },
+};
+
+const isForbiddenType = (type) =>
+  type.intrinsicName === 'number' || type.intrinsicName === 'string';
+
+const isVariableOrObjectField = (node) =>
+  node.type === 'Identifier' || node.type === 'MemberExpression';
+
+function checkImplicitCoercion(context, argument) {
+  const tsNodeMap = context.parserServices.esTreeNodeToTSNodeMap;
+  const typeChecker = context.parserServices?.program?.getTypeChecker();
+  const type = typeChecker.getTypeAtLocation(tsNodeMap.get(argument));
+  if (type.aliasSymbol && type.aliasSymbol.name === 'ReactNode') {
+    return;
+  }
+  if (type.isUnion() ? type.types.some(isForbiddenType) : isForbiddenType(type)) {
+    context.report({
+      node: argument,
+      messageId: 'noImplicitCoercion',
+    });
+  }
+}
diff --git a/server/sonar-web/eslint-local-rules/no-implicit-coersion.js b/server/sonar-web/eslint-local-rules/no-implicit-coersion.js
deleted file mode 100644 (file)
index 705b16a..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-module.exports = {
-  meta: {
-    type: 'suggestion',
-    docs: {
-      description:
-        'Enforce using explicit comparison instead of implicit coercion for certain variable types',
-      category: 'Best Practices',
-      recommended: true,
-    },
-    messages: {
-      noImplicitCoersion:
-        'Use explicit comparison instead of implicit coercion for strings and numbers.',
-    },
-  },
-  create(context) {
-    return {
-      UnaryExpression: (node) => {
-        const { argument, operator } = node;
-
-        if (operator === '!') {
-          checkImplicitCoercion(context, argument);
-        }
-      },
-      LogicalExpression: (node) => {
-        const { left, operator } = node;
-        if (operator === '??') {
-          return;
-        }
-        if (isVariableOrObjectField(left)) {
-          checkImplicitCoercion(context, left);
-        }
-      },
-      IfStatement: (node) => {
-        const { test } = node;
-        checkImplicitCoercion(context, test);
-      },
-    };
-  },
-};
-
-const isForbiddenType = (type) =>
-  type.intrinsicName === 'number' || type.intrinsicName === 'string';
-
-const isVariableOrObjectField = (node) =>
-  node.type === 'Identifier' || node.type === 'MemberExpression';
-
-function checkImplicitCoercion(context, argument) {
-  const tsNodeMap = context.parserServices.esTreeNodeToTSNodeMap;
-  const typeChecker = context.parserServices?.program?.getTypeChecker();
-  const type = typeChecker.getTypeAtLocation(tsNodeMap.get(argument));
-  if (type.aliasSymbol && type.aliasSymbol.name === 'ReactNode') {
-    return;
-  }
-  if (type.isUnion() ? type.types.some(isForbiddenType) : isForbiddenType(type)) {
-    context.report({
-      node: argument,
-      messageId: 'noImplicitCoersion',
-    });
-  }
-}