Eslint-plugin-sonarjs skips test rules because of the project working directory

Description

Summary

When linting an Angular application through Nx, certain SonarJS rules for Jest tests are not executed. As a result, the Nx lint target reports no linting errors, even though the same test file produces 19 errors when ESLint is invoked directly from the repository root.

Affected file:

<repository-root>/apps/<application>/src/app/<feature>/shared/validation/<test-file>.spec.ts

Reproduction

Run ESLint directly from the repository root:

pnpm exec eslint apps\<application>\src\app\<feature>\shared\validation\<test-file>.spec.ts

The result is:

✖ 19 problems (19 errors, 0 warnings)

The reported rules include:

sonarjs/parameterized-tests
sonarjs/no-duplicate-test-title

Examples:

224:16  error  Replace these 8 tests with a single Parameterized one
338:16  error  Rename this test title to make it unique within the suite
359:16  error  Replace these 3 tests with a single Parameterized one

Now run the Nx lint target:

nx run <application>:lint

No errors for the affected test file are reported.

The same behavior occurs when the Nx cache is disabled:

nx run <application>:lint --skip-nx-cache

Therefore, the Nx cache does not appear to be the cause.

Actual behavior

The lint target is inferred by the Nx ESLint plugin. The resolved target effectively executes:

eslint .

with the following working directory:

<repository-root>/apps/<application>

The direct ESLint command, however, is executed from:

<repository-root>

The ESLint configuration contains eslint-plugin-sonarjs, and the affected rules are enabled in both cases. Running eslint --print-config also shows both rules with severity 2 (error) in both execution contexts.

Suspected technical cause

The affected SonarJS rules do not only check whether they are enabled in the ESLint configuration. They also determine whether a supported test framework is active. For this purpose, SonarJS checks imports in the current file and dependencies declared in available package.json files.

The test file uses global Jest functions such as describe and it, but it does not explicitly import Jest. The Jest dependencies are declared in the package.json located at the repository root. There is no separate package.json in the application directory.

When ESLint is executed from the repository root, SonarJS can find the root-level Jest dependencies and correctly identifies Jest as the active test framework. When ESLint is executed by Nx, the working directory is restricted to the application directory. The dependency lookup stops at the application level and does not reach the repository root package.json.

Because the test file also contains no explicit Jest import, SonarJS does not detect an active test framework in the Nx execution context. The rule implementations consequently register no visitors and produce no diagnostics, even though the rules remain present and enabled in the effective ESLint configuration.

Expected behavior

The following commands should produce equivalent linting results:

nx run <application>:lint

and:

pnpm exec eslint apps\<application>

In particular, the Nx target should detect violations of:

sonarjs/parameterized-tests
sonarjs/no-duplicate-test-title

Hi @nicbre,

thanks for reporting this. This has been addressed here along with the similar problem described here. It will be released in the next ESLint plugin version.

Cheers