| name | test-rule |
| description | Write and run tests for a SonarJS rule. Use when working on rule tests, writing test fixtures, or running unit tests for a specific rule. |
Running Tests
npx tsx --test packages/analysis/src/jsts/rules/S1234/**/*.test.ts
Replace S1234 with the actual rule number. Do not run the full test suite (npm run bridge:test) — it takes too long.
RuleTester Selection
| RuleTester | Use When |
|---|
DefaultParserRuleTester | Pure JavaScript rules, no TypeScript syntax |
NoTypeCheckingRuleTester | JS/TS rules that don't need type information |
RuleTester | Rules requiring TypeScript type information |
RuleTester with @babel/eslint-parser | Legacy JavaScript or Babel-specific syntax (e.g. Flow types, decorator proposals) |
Comment-Based Tests (preferred)
Test files are named *.fixture.* (e.g., cb.fixture.js, cb.fixture.ts) and live in the rule folder.
Basic Syntax
some.clean.code();
some.faulty.code();
The // ^^^^^^ underline marks the primary location (optional but recommended).
With Quick Fixes
some.faulty.code();
For ESLint fixes (not suggestions), use ! suffix: [[qf1!]]. ESLint fixes must not have a fix@ comment.
Secondary Locations
context.report({
node,
message: toEncodedMessage(message, [secondaryNode], ['secondary message']),
});
In fixture:
primary.node();
secondary.node();
Arrow direction: < means secondary is after primary; > means secondary is before primary.
Line Reference Modifiers
some.faulty.code();
some.faulty.code();
some.faulty.code();
Rule Options in Tests
Add a cb.options.json file in the rule folder:
[7, { "ignoreIIFE": true }]
Package.json Dependency Testing
process.chdir(__dirname);
ESLint RuleTester Format
For rules needing TypeScript type checking:
import { RuleTester } from '../../../tests/tools/testers/rule-tester.js';
const ruleTester = new RuleTester();
ruleTester.run('rule-name', rule, {
valid: [{ code: 'valid code here' }],
invalid: [
{
code: 'invalid code here',
errors: [{ messageId: 'errorKey' }],
},
],
});
Quick Fix Operation Syntax
| Syntax | Effect |
|---|
// edit@qf [[sc=1;ec=5]] {{text}} | Replace column 1–5 with text |
// edit@qf {{whole line replacement}} | Replace entire line |
// add@qf {{new line content}} | Add new line after issue line |
// del@qf | Delete the line |
// add@qf@+1 {{content}} | Add after line+1 |
Multiple Issues / Multiple Quick Fixes
code();
code();