Backend security / security (push) Successful in 8s
Backend verify / verify (push) Failing after 2m17s
Conventional commits / commits (pull_request) Successful in 31s
Backend security / security (pull_request) Successful in 8s
Backend verify / verify (pull_request) Failing after 1m56s
64 lines
3.1 KiB
JavaScript
64 lines
3.1 KiB
JavaScript
const { ESLint } = require('eslint');
|
|
const assert = require('node:assert/strict');
|
|
const { test } = require('node:test');
|
|
|
|
const eslint = new ESLint();
|
|
|
|
// Protect the quality gate's file scopes when configs or plugin versions change.
|
|
test('typed application code enforces async and unsafe-type checks', async () => {
|
|
const [result] = await eslint.lintText(
|
|
'export const unsafe: any = 1; Promise.resolve(unsafe);',
|
|
{ filePath: 'src/main.ts' },
|
|
);
|
|
const rules = new Set(result.messages.map(({ ruleId }) => ruleId));
|
|
assert.ok(rules.has('@typescript-eslint/no-explicit-any'));
|
|
assert.ok(rules.has('@typescript-eslint/no-floating-promises'));
|
|
});
|
|
|
|
test('framework and runtime rules reach their intended files', async () => {
|
|
const app = await eslint.calculateConfigForFile('src/main.ts');
|
|
const spec = await eslint.calculateConfigForFile('test/app.e2e-spec.ts');
|
|
const script = await eslint.calculateConfigForFile('scripts/generate-openapi.cjs');
|
|
const config = await eslint.calculateConfigForFile('eslint.config.mjs');
|
|
assert.equal(app.rules['@darraghor/nestjs-typed/validation-pipe-should-use-forbid-unknown'][0], 2);
|
|
assert.equal(spec.rules['jest/no-focused-tests'][0], 2);
|
|
assert.equal(app.rules['jest/no-focused-tests'], undefined);
|
|
assert.equal(app.languageOptions.globals.expect, undefined);
|
|
assert.equal(config.languageOptions.globals.require, 'off');
|
|
for (const profile of [app, spec, script, config]) {
|
|
assert.equal(profile.rules['n/no-deprecated-api'][0], 2);
|
|
assert.equal(profile.rules['security/detect-eval-with-expression'][0], 1);
|
|
assert.equal(profile.rules['regexp/no-super-linear-backtracking'][0], 2);
|
|
assert.equal(profile.rules['sonarjs/cognitive-complexity'][0], 2);
|
|
assert.equal(profile.rules['import-x/no-unresolved'][0], 2);
|
|
assert.equal(profile.rules['perfectionist/sort-imports'][0], 2);
|
|
assert.equal(profile.rules['@stylistic/semi'][0], 2);
|
|
}
|
|
});
|
|
|
|
test('focused tests are rejected and generated code is excluded', async () => {
|
|
const [result] = await eslint.lintText(
|
|
'it.only(\'example\', () => { expect(1).toBe(1); });',
|
|
{ filePath: 'test/app.e2e-spec.ts' },
|
|
);
|
|
assert.ok(result.messages.some(({ ruleId }) => ruleId === 'jest/no-focused-tests'));
|
|
assert.ok(await eslint.isPathIgnored('generated/prisma/client.ts'));
|
|
assert.ok(await eslint.isPathIgnored('dist/src/main.js'));
|
|
});
|
|
|
|
test('numeric literals require names, including previously ignored numbers and bigints', async () => {
|
|
const literals = [-60, -24, -10, -2, -1, 0, 1, 2, 10, 24, 60].map(String);
|
|
for (const literal of [...literals, ...literals.map((value) => `${value}n`)]) {
|
|
const [inline] = await eslint.lintText(
|
|
`export function value() { return ${literal}; }`,
|
|
{ filePath: 'src/main.ts' },
|
|
);
|
|
assert.ok(inline.messages.some(({ ruleId }) => ruleId === '@typescript-eslint/no-magic-numbers'), literal);
|
|
const [named] = await eslint.lintText(
|
|
`const boundary = ${literal}; export function value() { return boundary; }`,
|
|
{ filePath: 'src/main.ts' },
|
|
);
|
|
assert.ok(!named.messages.some(({ ruleId }) => ruleId === '@typescript-eslint/no-magic-numbers'), literal);
|
|
}
|
|
});
|