return <>
{loading && <DeferredSpinner />}
</>
+}`,
+ errors: [{ messageId: 'noConditionalRenderingOfDeferredSpinner' }],
+ },
+ {
+ code: `function MyComponent({ loading }) {
+ return <>
+ {loading ? <DeferredSpinner /> : <div />}
+ </>
+}`,
+ errors: [{ messageId: 'noConditionalRenderingOfDeferredSpinner' }],
+ },
+ {
+ code: `function MyCompontent({ loaded }) {
+ return <>
+ {loaded ? <div /> : <DeferredSpinner />}
+ </>
}`,
errors: [{ messageId: 'noConditionalRenderingOfDeferredSpinner' }],
},
+++ /dev/null
-/*
- * 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 useComponentQualifierEnum = require('../use-enum')(
- ['APP', 'DIR', 'DEV', 'FIL', 'VW', 'TRK', 'SVW', 'UTS'],
- 'ComponentQualifier'
-);
-
-const ruleTester = new RuleTester({
- parser: require.resolve('@typescript-eslint/parser'),
-});
-
-ruleTester.run('use-componentqualifier-enum', useComponentQualifierEnum, {
- valid: [
- {
- code: '{ qualifier: ComponentQualifier.Project };',
- },
- {
- code: 'varName === ComponentQualifier.File',
- },
- {
- code: `enum ComponentQualifier {
- Portfolio = 'VW',
- Project = 'TRK',
- SubPortfolio = 'SVW',
-}`,
- },
- ],
- invalid: [
- {
- code: '{ qualifier: "TRK" };',
- errors: [{ messageId: 'useComponentQualifierEnum' }],
- },
- {
- code: 'varName === "FIL"',
- errors: [{ messageId: 'useComponentQualifierEnum' }],
- },
- ],
-});
'use-jest-mocked': require('./use-jest-mocked'),
'convert-class-to-function-component': require('./convert-class-to-function-component'),
'no-conditional-rendering-of-deferredspinner': require('./no-conditional-rendering-of-deferredspinner'),
- 'use-visibility-enum': require('./use-enum')(['public', 'private'], 'Visibility'),
- 'use-componentqualifier-enum': require('./use-enum')(
- ['APP', 'DIR', 'DEV', 'FIL', 'VW', 'TRK', 'SVW', 'UTS'],
- 'ComponentQualifier',
- 'representing qualifiers'
- ),
- 'use-metrickey-enum': require('./use-enum')(
- [
- 'alert_status',
- 'blocker_violations',
- 'branch_coverage',
- 'bugs',
- 'burned_budget',
- 'business_value',
- 'class_complexity',
- 'classes',
- 'code_smells',
- 'cognitive_complexity',
- 'comment_lines',
- 'comment_lines_data',
- 'comment_lines_density',
- 'complexity',
- 'complexity_in_classes',
- 'complexity_in_functions',
- 'conditions_to_cover',
- 'confirmed_issues',
- 'coverage',
- 'critical_violations',
- 'development_cost',
- 'directories',
- 'duplicated_blocks',
- 'duplicated_files',
- 'duplicated_lines',
- 'duplicated_lines_density',
- 'duplications_data',
- 'effort_to_reach_maintainability_rating_a',
- 'executable_lines_data',
- 'false_positive_issues',
- 'file_complexity',
- 'file_complexity_distribution',
- 'filename_size',
- 'filename_size_rating',
- 'files',
- 'function_complexity',
- 'function_complexity_distribution',
- 'functions',
- 'generated_lines',
- 'generated_ncloc',
- 'info_violations',
- 'last_change_on_maintainability_rating',
- 'last_change_on_releasability_rating',
- 'last_change_on_reliability_rating',
- 'last_change_on_security_rating',
- 'last_change_on_security_review_rating',
- 'last_commit_date',
- 'leak_projects',
- 'line_coverage',
- 'lines',
- 'lines_to_cover',
- 'maintainability_rating_effort',
- 'major_violations',
- 'minor_violations',
- 'ncloc',
- 'ncloc_data',
- 'ncloc_language_distribution',
- 'new_blocker_violations',
- 'new_branch_coverage',
- 'new_bugs',
- 'new_code_smells',
- 'new_conditions_to_cover',
- 'new_coverage',
- 'new_critical_violations',
- 'new_development_cost',
- 'new_duplicated_blocks',
- 'new_duplicated_lines',
- 'new_duplicated_lines_density',
- 'new_info_violations',
- 'new_line_coverage',
- 'new_lines',
- 'new_lines_to_cover',
- 'new_maintainability_rating',
- 'new_major_violations',
- 'new_minor_violations',
- 'new_reliability_rating',
- 'new_reliability_remediation_effort',
- 'new_security_hotspots',
- 'new_security_hotspots_reviewed',
- 'new_security_rating',
- 'new_security_remediation_effort',
- 'new_security_review_rating',
- 'new_sqale_debt_ratio',
- 'new_technical_debt',
- 'new_uncovered_conditions',
- 'new_uncovered_lines',
- 'new_violations',
- 'new_vulnerabilities',
- 'open_issues',
- 'projects',
- 'public_api',
- 'public_documented_api_density',
- 'public_undocumented_api',
- 'quality_gate_details',
- 'quality_profiles',
- 'releasability_effort',
- 'releasability_rating',
- 'reliability_rating',
- 'reliability_rating_effort',
- 'reliability_remediation_effort',
- 'reopened_issues',
- 'security_hotspots',
- 'security_hotspots_reviewed',
- 'security_rating',
- 'security_rating_effort',
- 'security_remediation_effort',
- 'security_review_rating',
- 'security_review_rating_effort',
- 'skipped_tests',
- 'sonarjava_feedback',
- 'sqale_debt_ratio',
- 'sqale_index',
- 'sqale_rating',
- 'statements',
- 'team_at_sonarsource',
- 'team_size',
- 'test_errors',
- 'test_execution_time',
- 'test_failures',
- 'test_success_density',
- 'tests',
- 'uncovered_conditions',
- 'uncovered_lines',
- 'violations',
- 'vulnerabilities',
- 'wont_fix_issues',
- ],
- 'MetricKey',
- 'representing metric keys'
- ),
- 'use-metrictype-enum': require('./use-enum')(
- ['RATING', 'PERCENT', 'INT', 'LEVEL', 'SHORT_INT', 'SHORT_WORK_DUR', 'DATA'],
- 'MetricType',
- 'representing metric types'
- ),
+ 'use-visibility-enum': require('./use-visibility-enum'),
+ 'use-componentqualifier-enum': require('./use-componentqualifier-enum'),
+ 'use-metrickey-enum': require('./use-metrickey-enum'),
+ 'use-metrictype-enum': require('./use-metrictype-enum'),
};
--- /dev/null
+module.exports = {
+ testRegex: '(/__tests__/.*|\\-test)\\.(t|j)s$',
+ transform: {
+ '^.+\\.(t|j)s$': [
+ '@swc/jest',
+ {
+ jsc: {
+ target: 'es2018',
+ },
+ },
+ ],
+ },
+};
--- /dev/null
+/*
+ * 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 { useEnum } = require('../use-enum');
+const useSomeEnum = useEnum(['Val1', 'Val2', 'Val3'], 'SomeEnum');
+
+const ruleTester = new RuleTester({
+ parser: require.resolve('@typescript-eslint/parser'),
+});
+
+ruleTester.run('use-some-enum', useSomeEnum, {
+ valid: [
+ {
+ code: '{ qualifier: SomeEnum.FirstValue };',
+ },
+ {
+ code: 'varName === SomeEnum.SecondValue',
+ },
+ {
+ code: `enum SomeEnum {
+ FirstValue = 'Val1',
+ SecondValue = 'Val2',
+ ThirdValue = 'Val3',
+}`,
+ },
+ ],
+ invalid: [
+ {
+ code: '{ value: "Val1" };',
+ errors: [{ messageId: 'useSomeEnumEnum' }],
+ },
+ {
+ code: "varName === 'Val2'",
+ errors: [{ messageId: 'useSomeEnumEnum' }],
+ },
+ ],
+});
--- /dev/null
+/*
+ * 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 = {
+ useEnum(values, name, help) {
+ return {
+ meta: {
+ messages: {
+ [`use${name}Enum`]: `Hard-coded strings ${
+ help ? help + ' ' : ''
+ }are not allowed; use the ${name} enum instead`,
+ },
+ },
+ create(context) {
+ return {
+ Literal(node) {
+ if (node.parent.type !== 'TSEnumMember' && values.includes(node.value)) {
+ context.report({ node, messageId: `use${name}Enum` });
+ }
+ },
+ };
+ },
+ };
+ },
+};
create(context) {
return {
JSXExpressionContainer(node) {
- if (
- node.expression.type === 'LogicalExpression' &&
- node.expression.right.type === 'JSXElement' &&
- node.expression.right.openingElement.name.name === 'DeferredSpinner'
- ) {
- context.report({ node, messageId: 'noConditionalRenderingOfDeferredSpinner' });
+ switch (node.expression.type) {
+ case 'LogicalExpression':
+ const { right } = node.expression;
+ if (isDeferredSpinnerComponent(right)) {
+ context.report({ node, messageId: 'noConditionalRenderingOfDeferredSpinner' });
+ }
+ break;
+
+ case 'ConditionalExpression':
+ const { consequent, alternate } = node.expression;
+ if (isDeferredSpinnerComponent(consequent)) {
+ context.report({ node, messageId: 'noConditionalRenderingOfDeferredSpinner' });
+ }
+ if (isDeferredSpinnerComponent(alternate)) {
+ context.report({ node, messageId: 'noConditionalRenderingOfDeferredSpinner' });
+ }
+ break;
}
},
};
},
};
+
+function isDeferredSpinnerComponent(element) {
+ return (
+ element.type === 'JSXElement' &&
+ element.openingElement &&
+ element.openingElement.name.name === 'DeferredSpinner'
+ );
+}
--- /dev/null
+/*
+ * 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 { useEnum } = require('./lib/use-enum');
+module.exports = useEnum(
+ ['APP', 'DIR', 'DEV', 'FIL', 'VW', 'TRK', 'SVW', 'UTS'],
+ 'ComponentQualifier'
+);
+++ /dev/null
-/*
- * 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 = (values, name, help) => ({
- meta: {
- messages: {
- [`use${name}Enum`]: `Hard-coded strings ${
- help ? help + ' ' : ''
- }are not allowed; use the ${name} enum instead`,
- },
- },
- create(context) {
- return {
- Literal(node) {
- if (node.parent.type !== 'TSEnumMember' && values.includes(node.value)) {
- context.report({ node, messageId: `use${name}Enum` });
- }
- },
- };
- },
-});
--- /dev/null
+/*
+ * 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 { useEnum } = require('./lib/use-enum');
+module.exports = useEnum(
+ [
+ 'alert_status',
+ 'blocker_violations',
+ 'branch_coverage',
+ 'bugs',
+ 'burned_budget',
+ 'business_value',
+ 'class_complexity',
+ 'classes',
+ 'code_smells',
+ 'cognitive_complexity',
+ 'comment_lines',
+ 'comment_lines_data',
+ 'comment_lines_density',
+ 'complexity',
+ 'complexity_in_classes',
+ 'complexity_in_functions',
+ 'conditions_to_cover',
+ 'confirmed_issues',
+ 'coverage',
+ 'critical_violations',
+ 'development_cost',
+ 'directories',
+ 'duplicated_blocks',
+ 'duplicated_files',
+ 'duplicated_lines',
+ 'duplicated_lines_density',
+ 'duplications_data',
+ 'effort_to_reach_maintainability_rating_a',
+ 'executable_lines_data',
+ 'false_positive_issues',
+ 'file_complexity',
+ 'file_complexity_distribution',
+ 'filename_size',
+ 'filename_size_rating',
+ 'files',
+ 'function_complexity',
+ 'function_complexity_distribution',
+ 'functions',
+ 'generated_lines',
+ 'generated_ncloc',
+ 'info_violations',
+ 'last_change_on_maintainability_rating',
+ 'last_change_on_releasability_rating',
+ 'last_change_on_reliability_rating',
+ 'last_change_on_security_rating',
+ 'last_change_on_security_review_rating',
+ 'last_commit_date',
+ 'leak_projects',
+ 'line_coverage',
+ 'lines',
+ 'lines_to_cover',
+ 'maintainability_rating_effort',
+ 'major_violations',
+ 'minor_violations',
+ 'ncloc',
+ 'ncloc_data',
+ 'ncloc_language_distribution',
+ 'new_blocker_violations',
+ 'new_branch_coverage',
+ 'new_bugs',
+ 'new_code_smells',
+ 'new_conditions_to_cover',
+ 'new_coverage',
+ 'new_critical_violations',
+ 'new_development_cost',
+ 'new_duplicated_blocks',
+ 'new_duplicated_lines',
+ 'new_duplicated_lines_density',
+ 'new_info_violations',
+ 'new_line_coverage',
+ 'new_lines',
+ 'new_lines_to_cover',
+ 'new_maintainability_rating',
+ 'new_major_violations',
+ 'new_minor_violations',
+ 'new_reliability_rating',
+ 'new_reliability_remediation_effort',
+ 'new_security_hotspots',
+ 'new_security_hotspots_reviewed',
+ 'new_security_rating',
+ 'new_security_remediation_effort',
+ 'new_security_review_rating',
+ 'new_sqale_debt_ratio',
+ 'new_technical_debt',
+ 'new_uncovered_conditions',
+ 'new_uncovered_lines',
+ 'new_violations',
+ 'new_vulnerabilities',
+ 'open_issues',
+ 'projects',
+ 'public_api',
+ 'public_documented_api_density',
+ 'public_undocumented_api',
+ 'quality_gate_details',
+ 'quality_profiles',
+ 'releasability_effort',
+ 'releasability_rating',
+ 'reliability_rating',
+ 'reliability_rating_effort',
+ 'reliability_remediation_effort',
+ 'reopened_issues',
+ 'security_hotspots',
+ 'security_hotspots_reviewed',
+ 'security_rating',
+ 'security_rating_effort',
+ 'security_remediation_effort',
+ 'security_review_rating',
+ 'security_review_rating_effort',
+ 'skipped_tests',
+ 'sonarjava_feedback',
+ 'sqale_debt_ratio',
+ 'sqale_index',
+ 'sqale_rating',
+ 'statements',
+ 'team_at_sonarsource',
+ 'team_size',
+ 'test_errors',
+ 'test_execution_time',
+ 'test_failures',
+ 'test_success_density',
+ 'tests',
+ 'uncovered_conditions',
+ 'uncovered_lines',
+ 'violations',
+ 'vulnerabilities',
+ 'wont_fix_issues',
+ ],
+ 'MetricKey',
+ 'representing metric keys'
+);
--- /dev/null
+/*
+ * 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 { useEnum } = require('./lib/use-enum');
+module.exports = useEnum(
+ ['RATING', 'PERCENT', 'INT', 'LEVEL', 'SHORT_INT', 'SHORT_WORK_DUR', 'DATA'],
+ 'MetricType',
+ 'representing metric types'
+);
--- /dev/null
+/*
+ * 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 { useEnum } = require('./lib/use-enum');
+module.exports = useEnum(['public', 'private'], 'Visibility');
"build": "node scripts/build.js",
"build-release": "yarn install --immutable && node scripts/build.js release",
"test": "jest",
- "test-eslint-local-rules": "jest eslint-local-rules",
+ "test-eslint-local-rules": "jest -c eslint-local-rules/jest.config.js",
"format": "prettier --write --list-different \"src/main/js/**/*.{js,ts,tsx,css}\"",
"format-check": "prettier --list-different \"src/main/js/**/*.{js,ts,tsx,css}\"",
"lint": "eslint --ext js,ts,tsx --quiet src/main/js",
"ts-check": "tsc --noEmit",
"validate": "yarn dep-check && yarn lint && yarn ts-check && yarn format-check && yarn test",
"validate-ci": "yarn install --immutable && yarn dep-check && yarn test --coverage --maxWorkers=4 --ci",
- "check-ci": "yarn install --immutable && yarn ts-check && yarn format-check",
+ "check-ci": "yarn install --immutable && yarn ts-check && yarn format-check && yarn test-eslint-local-rules",
"update-cwes": "node scripts/update-cwes.js",
"dep-check": "node scripts/validate-package-json.js"
},
"path": "path-browserify"
},
"packageManager": "yarn@3.5.0"
-}
+}
\ No newline at end of file