Skip to content

Commit 1d79e1d

Browse files
authored
update sonarjs rules (#3953)
1 parent 4da9ad7 commit 1d79e1d

6 files changed

Lines changed: 265 additions & 24 deletions

File tree

eslint.config.js

Lines changed: 248 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -409,38 +409,276 @@ export default defineConfig([
409409
'react-x/prefer-use-state-lazy-initialization': 1,
410410

411411
// SonarJS rules
412-
// https://github.com/SonarSource/eslint-plugin-sonarjs#rules
413-
'sonarjs/no-all-duplicated-branches': 1,
414-
'sonarjs/no-element-overwrite': 1,
415-
'sonarjs/no-empty-collection': 1,
416-
'sonarjs/no-extra-arguments': 0,
417-
'sonarjs/no-identical-conditions': 1,
418-
'sonarjs/no-identical-expressions': 1,
419-
'sonarjs/no-ignored-return': 1,
420-
'sonarjs/no-use-of-empty-return-value': 1,
421-
'sonarjs/non-existent-operator': 1,
412+
// https://github.com/SonarSource/SonarJS/blob/master/packages/jsts/src/rules/README.md#rules
413+
'sonarjs/anchor-precedence': 1,
414+
'sonarjs/argument-type': 1,
415+
'sonarjs/arguments-order': 1,
416+
'sonarjs/arguments-usage': 1,
417+
'sonarjs/array-callback-without-return': 1,
418+
'sonarjs/array-constructor': 1,
419+
'sonarjs/arrow-function-convention': 0,
420+
'sonarjs/assertions-in-tests': 1,
421+
'sonarjs/aws-apigateway-public-api': 0,
422+
'sonarjs/aws-ec2-rds-dms-public': 0,
423+
'sonarjs/aws-ec2-unencrypted-ebs-volume': 0,
424+
'sonarjs/aws-efs-unencrypted': 0,
425+
'sonarjs/aws-iam-all-privileges': 0,
426+
'sonarjs/aws-iam-all-resources-accessible': 0,
427+
'sonarjs/aws-iam-privilege-escalation': 0,
428+
'sonarjs/aws-iam-public-access': 0,
429+
'sonarjs/aws-opensearchservice-domain': 0,
430+
'sonarjs/aws-rds-unencrypted-databases': 0,
431+
'sonarjs/aws-restricted-ip-admin-access': 0,
432+
'sonarjs/aws-s3-bucket-granted-access': 0,
433+
'sonarjs/aws-s3-bucket-insecure-http': 0,
434+
'sonarjs/aws-s3-bucket-public-access': 0,
435+
'sonarjs/aws-s3-bucket-server-encryption': 0,
436+
'sonarjs/aws-s3-bucket-versioning': 0,
437+
'sonarjs/aws-sagemaker-unencrypted-notebook': 0,
438+
'sonarjs/aws-sns-unencrypted-topics': 0,
439+
'sonarjs/aws-sqs-unencrypted-queue': 0,
440+
'sonarjs/bitwise-operators': 1,
441+
'sonarjs/block-scoped-var': 1,
442+
'sonarjs/bool-param-default': 0,
443+
'sonarjs/call-argument-line': 1,
444+
'sonarjs/certificate-transparency': 1,
445+
'sonarjs/chai-determinate-assertion': 1,
446+
'sonarjs/class-name': 1,
447+
'sonarjs/class-prototype': 1,
448+
'sonarjs/code-eval': 1,
422449
'sonarjs/cognitive-complexity': 0,
450+
'sonarjs/comma-or-logical-or-case': 1,
451+
'sonarjs/comment-regex': 1,
452+
'sonarjs/concise-regex': 1,
453+
'sonarjs/conditional-indentation': 1,
454+
'sonarjs/confidential-information-logging': 1,
455+
'sonarjs/constructor-for-side-effects': 1,
456+
'sonarjs/content-length': 1,
457+
'sonarjs/content-security-policy': 1,
458+
'sonarjs/cookie-no-httponly': 1,
459+
'sonarjs/cookies': 1,
460+
'sonarjs/cors': 1,
461+
'sonarjs/csrf': 1,
462+
'sonarjs/cyclomatic-complexity': 0,
463+
'sonarjs/declarations-in-global-scope': 0,
464+
'sonarjs/deprecation': 0,
465+
'sonarjs/destructuring-assignment-syntax': 1,
466+
'sonarjs/different-types-comparison': 0,
467+
'sonarjs/disabled-auto-escaping': 1,
468+
'sonarjs/disabled-resource-integrity': 1,
469+
'sonarjs/disabled-timeout': 1,
470+
'sonarjs/dns-prefetching': 1,
471+
'sonarjs/duplicates-in-character-class': 1,
472+
'sonarjs/dynamically-constructed-templates': 1,
423473
'sonarjs/elseif-without-else': 0,
474+
'sonarjs/empty-string-repetition': 1,
475+
'sonarjs/encryption': 1,
476+
'sonarjs/encryption-secure-mode': 1,
477+
'sonarjs/enforce-trailing-comma': 0,
478+
'sonarjs/existing-groups': 1,
479+
'sonarjs/expression-complexity': 0,
480+
'sonarjs/file-header': 0,
481+
'sonarjs/file-name-differ-from-class': 1,
482+
'sonarjs/file-permissions': 1,
483+
'sonarjs/file-uploads': 1,
484+
'sonarjs/fixme-tag': 1,
485+
'sonarjs/for-in': 1,
486+
'sonarjs/for-loop-increment-sign': 1,
487+
'sonarjs/frame-ancestors': 1,
488+
'sonarjs/function-inside-loop': 1,
489+
'sonarjs/function-name': 0,
490+
'sonarjs/function-return-type': 0,
491+
'sonarjs/future-reserved-words': 1,
492+
'sonarjs/generator-without-yield': 1,
493+
'sonarjs/hardcoded-secret-signatures': 1,
494+
'sonarjs/hashing': 1,
495+
'sonarjs/hidden-files': 1,
496+
'sonarjs/in-operator-type-error': 1,
497+
'sonarjs/inconsistent-function-call': 1,
498+
'sonarjs/index-of-compare-to-positive-number': 1,
499+
'sonarjs/insecure-cookie': 1,
500+
'sonarjs/insecure-jwt-token': 1,
501+
'sonarjs/inverted-assertion-arguments': 1,
502+
'sonarjs/jsx-no-leaked-render': 1,
503+
'sonarjs/label-position': 1,
504+
'sonarjs/link-with-target-blank': 1,
505+
'sonarjs/max-lines': 0,
506+
'sonarjs/max-lines-per-function': 0,
424507
'sonarjs/max-switch-cases': 0,
508+
'sonarjs/max-union-size': 0,
509+
'sonarjs/misplaced-loop-counter': 1,
510+
'sonarjs/nested-control-flow': 0,
511+
'sonarjs/new-operator-misuse': 1,
512+
'sonarjs/no-all-duplicated-branches': 1,
513+
'sonarjs/no-alphabetical-sort': 1,
514+
'sonarjs/no-angular-bypass-sanitization': 1,
515+
'sonarjs/no-array-delete': 1,
516+
'sonarjs/no-associative-arrays': 1,
517+
'sonarjs/no-async-constructor': 1,
518+
'sonarjs/no-built-in-override': 1,
519+
'sonarjs/no-case-label-in-switch': 1,
520+
'sonarjs/no-clear-text-protocols': 1,
521+
'sonarjs/no-code-after-done': 1,
425522
'sonarjs/no-collapsible-if': 1,
426523
'sonarjs/no-collection-size-mischeck': 1,
524+
'sonarjs/no-commented-code': 1,
525+
'sonarjs/no-control-regex': 1,
526+
'sonarjs/no-dead-store': 1,
527+
'sonarjs/no-delete-var': 1,
528+
'sonarjs/no-duplicate-in-composite': 1,
427529
'sonarjs/no-duplicate-string': 0,
428530
'sonarjs/no-duplicated-branches': 1,
531+
'sonarjs/no-element-overwrite': 1,
532+
'sonarjs/no-empty-after-reluctant': 1,
533+
'sonarjs/no-empty-alternatives': 1,
534+
'sonarjs/no-empty-character-class': 1,
535+
'sonarjs/no-empty-collection': 1,
536+
'sonarjs/no-empty-group': 1,
537+
'sonarjs/no-empty-test-file': 1,
538+
'sonarjs/no-equals-in-for-termination': 1,
539+
'sonarjs/no-exclusive-tests': 1,
540+
'sonarjs/no-extra-arguments': 0,
541+
'sonarjs/no-fallthrough': 1,
542+
'sonarjs/no-for-in-iterable': 1,
543+
'sonarjs/no-function-declaration-in-block': 1,
544+
'sonarjs/no-global-this': 1,
545+
'sonarjs/no-globals-shadowing': 1,
429546
'sonarjs/no-gratuitous-expressions': 1,
547+
'sonarjs/no-hardcoded-ip': 1,
548+
'sonarjs/no-hardcoded-passwords': 1,
549+
'sonarjs/no-hardcoded-secrets': 1,
550+
'sonarjs/no-hook-setter-in-body': 1,
551+
'sonarjs/no-identical-conditions': 1,
552+
'sonarjs/no-identical-expressions': 1,
430553
'sonarjs/no-identical-functions': 1,
554+
'sonarjs/no-ignored-exceptions': 1,
555+
'sonarjs/no-ignored-return': 1,
556+
'sonarjs/no-implicit-dependencies': 1,
557+
'sonarjs/no-implicit-global': 1,
558+
'sonarjs/no-in-misuse': 1,
559+
'sonarjs/no-incomplete-assertions': 1,
560+
'sonarjs/no-inconsistent-returns': 0,
561+
'sonarjs/no-incorrect-string-concat': 1,
562+
'sonarjs/no-internal-api-use': 1,
563+
'sonarjs/no-intrusive-permissions': 1,
564+
'sonarjs/no-invalid-regexp': 1,
565+
'sonarjs/no-invariant-returns': 1,
431566
'sonarjs/no-inverted-boolean-check': 1,
567+
'sonarjs/no-ip-forward': 1,
568+
'sonarjs/no-labels': 1,
569+
'sonarjs/no-literal-call': 1,
570+
'sonarjs/no-mime-sniff': 1,
571+
'sonarjs/no-misleading-array-reverse': 1,
572+
'sonarjs/no-misleading-character-class': 1,
573+
'sonarjs/no-mixed-content': 1,
574+
'sonarjs/no-nested-assignment': 1,
575+
'sonarjs/no-nested-conditional': 0,
576+
'sonarjs/no-nested-functions': 0,
577+
'sonarjs/no-nested-incdec': 1,
432578
'sonarjs/no-nested-switch': 1,
433579
'sonarjs/no-nested-template-literals': 1,
580+
'sonarjs/no-os-command-from-path': 1,
581+
'sonarjs/no-parameter-reassignment': 1,
582+
'sonarjs/no-primitive-wrappers': 1,
583+
'sonarjs/no-redundant-assignments': 1,
434584
'sonarjs/no-redundant-boolean': 1,
435585
'sonarjs/no-redundant-jump': 1,
586+
'sonarjs/no-redundant-optional': 1,
587+
'sonarjs/no-redundant-parentheses': 1,
588+
'sonarjs/no-reference-error': 0,
589+
'sonarjs/no-referrer-policy': 1,
590+
'sonarjs/no-regex-spaces': 1,
591+
'sonarjs/no-require-or-define': 1,
592+
'sonarjs/no-return-type-any': 1,
593+
'sonarjs/no-same-argument-assert': 1,
436594
'sonarjs/no-same-line-conditional': 1,
595+
'sonarjs/no-selector-parameter': 0,
596+
'sonarjs/no-skipped-tests': 1,
437597
'sonarjs/no-small-switch': 1,
598+
'sonarjs/no-sonar-comments': 1,
599+
'sonarjs/no-tab': 1,
600+
'sonarjs/no-table-as-layout': 1,
601+
'sonarjs/no-try-promise': 1,
602+
'sonarjs/no-undefined-argument': 1,
603+
'sonarjs/no-undefined-assignment': 0,
604+
'sonarjs/no-unenclosed-multiline-block': 1,
605+
'sonarjs/no-uniq-key': 1,
606+
'sonarjs/no-unsafe-unzip': 1,
607+
'sonarjs/no-unthrown-error': 1,
438608
'sonarjs/no-unused-collection': 1,
609+
'sonarjs/no-unused-function-argument': 1,
610+
'sonarjs/no-unused-vars': 1,
611+
'sonarjs/no-use-of-empty-return-value': 1,
439612
'sonarjs/no-useless-catch': 1,
613+
'sonarjs/no-useless-increment': 1,
614+
'sonarjs/no-useless-intersection': 1,
615+
'sonarjs/no-useless-react-setstate': 1,
616+
'sonarjs/no-variable-usage-before-declaration': 1,
617+
'sonarjs/no-vue-bypass-sanitization': 1,
618+
'sonarjs/no-weak-cipher': 1,
619+
'sonarjs/no-weak-keys': 1,
620+
'sonarjs/no-wildcard-import': 0,
621+
'sonarjs/non-existent-operator': 1,
622+
'sonarjs/non-number-in-arithmetic-expression': 1,
623+
'sonarjs/null-dereference': 1,
624+
'sonarjs/object-alt-content': 1,
625+
'sonarjs/operation-returning-nan': 1,
626+
'sonarjs/os-command': 1,
627+
'sonarjs/post-message': 1,
628+
'sonarjs/prefer-default-last': 1,
440629
'sonarjs/prefer-immediate-return': 1,
441630
'sonarjs/prefer-object-literal': 1,
631+
'sonarjs/prefer-promise-shorthand': 1,
632+
'sonarjs/prefer-read-only-props': 0,
633+
'sonarjs/prefer-regexp-exec': 1,
442634
'sonarjs/prefer-single-boolean-return': 1,
635+
'sonarjs/prefer-type-guard': 1,
443636
'sonarjs/prefer-while': 1,
637+
'sonarjs/process-argv': 1,
638+
'sonarjs/production-debug': 1,
639+
'sonarjs/pseudo-random': 0,
640+
'sonarjs/public-static-readonly': 1,
641+
'sonarjs/publicly-writable-directories': 1,
642+
'sonarjs/reduce-initial-value': 1,
643+
'sonarjs/redundant-type-aliases': 0,
644+
'sonarjs/regex-complexity': 1,
645+
'sonarjs/regular-expr': 1,
646+
'sonarjs/review-blockchain-mnemonic': 1,
647+
'sonarjs/session-regeneration': 1,
648+
'sonarjs/shorthand-property-grouping': 0,
649+
'sonarjs/single-char-in-character-classes': 1,
650+
'sonarjs/single-character-alternation': 1,
651+
'sonarjs/slow-regex': 1,
652+
'sonarjs/sockets': 1,
653+
'sonarjs/sql-queries': 1,
654+
'sonarjs/stable-tests': 1,
655+
'sonarjs/standard-input': 1,
656+
'sonarjs/stateful-regex': 1,
657+
'sonarjs/strict-transport-security': 1,
658+
'sonarjs/strings-comparison': 1,
659+
'sonarjs/super-invocation': 1,
660+
'sonarjs/table-header': 1,
661+
'sonarjs/table-header-reference': 1,
662+
'sonarjs/test-check-exception': 1,
663+
'sonarjs/todo-tag': 0,
664+
'sonarjs/too-many-break-or-continue-in-loop': 0,
665+
'sonarjs/unicode-aware-regex': 1,
666+
'sonarjs/unused-import': 1,
667+
'sonarjs/unused-named-groups': 1,
668+
'sonarjs/unverified-certificate': 1,
669+
'sonarjs/unverified-hostname': 1,
670+
'sonarjs/updated-const-var': 1,
671+
'sonarjs/updated-loop-counter': 0,
672+
'sonarjs/use-type-alias': 1,
673+
'sonarjs/useless-string-operation': 1,
674+
'sonarjs/values-not-convertible-to-numbers': 1,
675+
'sonarjs/variable-name': 1,
676+
'sonarjs/void-use': 1,
677+
'sonarjs/weak-ssl': 1,
678+
'sonarjs/web-sql-database': 1,
679+
'sonarjs/x-powered-by': 1,
680+
'sonarjs/xml-parser-xxe': 1,
681+
'sonarjs/xpath': 1,
444682

445683
// @typescript-eslint/eslint-plugin rules
446684
// https://typescript-eslint.io/rules/#supported-rules

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
"eslint-plugin-jest-dom": "^5.5.0",
7171
"eslint-plugin-react": "^7.37.5",
7272
"eslint-plugin-react-hooks": "^7.0.1",
73-
"eslint-plugin-sonarjs": "^3.0.5",
73+
"eslint-plugin-sonarjs": "^3.0.6",
7474
"eslint-plugin-testing-library": "^7.13.5",
7575
"jspdf": "^4.0.0",
7676
"jspdf-autotable": "^5.0.2",

src/DataGrid.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
596596
previousRowIdx < rows.length
597597
) {
598598
const step = sign(rowIdx - previousRowIdx);
599-
for (let i = previousRowIdx + step; i !== rowIdx; i += step) {
599+
for (let i = previousRowIdx + step; i < rowIdx; i += step) {
600600
const row = rows[i];
601601
if (isRowSelectionDisabled?.(row) === true) continue;
602602
if (checked) {

src/GroupRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function GroupedRow<R, SR>({
4141
gridRowStart,
4242
groupBy,
4343
toggleGroup,
44-
isRowSelectionDisabled,
44+
isRowSelectionDisabled: _isRowSelectionDisabled,
4545
...props
4646
}: GroupRowRendererProps<R, SR>) {
4747
// Select is always the first column

test/browser/keyboardNavigation.test.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@ import { getSelectedCell, setup, tabIntoGrid, testCount, validateCellPosition }
66

77
type Row = undefined;
88

9-
const rows: readonly Row[] = new Array(100);
9+
const rows: readonly Row[] = Array.from({ length: 100 });
1010
const topSummaryRows: readonly Row[] = [undefined];
1111
const bottomSummaryRows: readonly Row[] = [undefined, undefined];
1212

13-
const columns = [
13+
const columns: readonly Column<Row, Row>[] = [
1414
SelectColumn,
1515
{ key: 'col2', name: 'col2' },
1616
{ key: 'col3', name: 'col3' },
1717
{ key: 'col4', name: 'col4' },
1818
{ key: 'col5', name: 'col5' },
1919
{ key: 'col6', name: 'col6' },
2020
{ key: 'col7', name: 'col7' }
21-
] as const satisfies Column<Row, Row>[];
21+
];
2222

2323
test('keyboard navigation', async () => {
2424
await setup({ columns, rows, topSummaryRows, bottomSummaryRows }, true);
@@ -122,7 +122,7 @@ test('arrow and tab navigation', async () => {
122122
});
123123

124124
test('grid enter/exit', async () => {
125-
await setup({ columns, rows: new Array(5), bottomSummaryRows }, true);
125+
await setup<Row, Row>({ columns, rows: Array.from({ length: 5 }), bottomSummaryRows }, true);
126126

127127
const beforeButton = page.getByRole('button', { name: 'Before' });
128128
const afterButton = page.getByRole('button', { name: 'After' });
@@ -164,7 +164,7 @@ test('grid enter/exit', async () => {
164164
});
165165

166166
test('navigation with focusable cell renderer', async () => {
167-
await setup({ columns, rows: new Array(1), bottomSummaryRows }, true);
167+
await setup<Row, Row>({ columns, rows: Array.from({ length: 1 }), bottomSummaryRows }, true);
168168
await tabIntoGrid();
169169
await userEvent.keyboard('{arrowdown}');
170170
await validateCellPosition(0, 1);
@@ -205,7 +205,10 @@ test('navigation when header and summary rows have focusable elements', async ()
205205
}
206206
];
207207

208-
await setup({ columns, rows: new Array(2), bottomSummaryRows: [1, 2] }, true);
208+
await setup<Row, number>(
209+
{ columns, rows: Array.from({ length: 2 }), bottomSummaryRows: [1, 2] },
210+
true
211+
);
209212
await tabIntoGrid();
210213

211214
// should set focus on the header filter
@@ -320,7 +323,7 @@ test('reset selected cell when row is removed', async () => {
320323
});
321324

322325
test('should not change the left and right arrow behavior for right to left languages', async () => {
323-
await setup({ rows, columns, direction: 'rtl' }, true);
326+
await setup<Row, Row>({ columns, rows, direction: 'rtl' }, true);
324327
await tabIntoGrid();
325328
await validateCellPosition(0, 0);
326329
await userEvent.tab();

test/browser/virtualization.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ function setupGrid(
1010
frozenColumnCount = 0,
1111
summaryRowCount = 0
1212
) {
13-
const columns: Column<unknown>[] = [];
14-
const rows = new Array(rowCount);
15-
const topSummaryRows = new Array(summaryRowCount).fill(null);
16-
const bottomSummaryRows = new Array(summaryRowCount).fill(null);
13+
const columns: Column<unknown, null>[] = [];
14+
const rows = Array.from({ length: rowCount });
15+
const topSummaryRows = Array.from({ length: summaryRowCount }, () => null);
16+
const bottomSummaryRows = Array.from({ length: summaryRowCount }, () => null);
1717

1818
for (let i = 0; i < columnCount; i++) {
1919
const key = String(i);

0 commit comments

Comments
 (0)