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); } }); // Single-use codes must be caught too; fixture literals remain independent wire assertions. test('machine codes require enum members without banning ordinary text or Prisma selects', async () => { const eslint = new ESLint(); const filePath = 'src/main.ts'; for (const code of ['export function check(code: string) { return code === "one-off-code"; }', 'export const result = `MOEX_UNAVAILABLE`;', 'export const result = { code: "one-off-code" };', 'export const result = { "errorCode": "one-off-code" };', 'export const result = { code: `dynamic-${Date.now()}` };', 'export const result = "MOEX_UNAVAILABLE";', 'export const result = ["INSTRUMENT_ID_TYPE_FIGI"];', 'export const result = { OPERATION_TYPE_COUPON: "income" };']) { const [result] = await eslint.lintText(code, { filePath }); assert.equal(result.fatalErrorCount, 0, code); assert.ok(result.messages.some(({ ruleId }) => ruleId === 'no-restricted-syntax'), code); } for (const code of [ 'enum Code { Unavailable = "MOEX_UNAVAILABLE" } export const result = { code: Code.Unavailable };', 'export const select = { code: true, errorCode: true };', 'export const label = "Please try again"; export const key = "JWT_SECRET";', ]) { const [result] = await eslint.lintText(code, { filePath }); assert.equal(result.fatalErrorCount, 0, code); assert.ok(!result.messages.some(({ ruleId }) => ruleId === 'no-restricted-syntax'), code); } const [fixture] = await eslint.lintText('export const result = { code: "MOEX_UNAVAILABLE" };', { filePath: 'src/integrations/moex/moex.client.spec.ts' }); assert.ok(!fixture.messages.some(({ ruleId }) => ruleId === 'no-restricted-syntax')); const [comparison] = await eslint.lintText('enum Code { Ready = "ready" } export function check(code: Code) { return code === "ready"; }', { filePath }); assert.ok(comparison.messages.some(({ ruleId }) => ruleId === '@typescript-eslint/no-unsafe-enum-comparison')); });