From d6c6a62557741031afaca8bb6029670a327ea11f Mon Sep 17 00:00:00 2001 From: robonen Date: Mon, 15 Jun 2026 16:54:50 +0700 Subject: [PATCH] chore(eslint): add shared tests preset and relax no-console A 'tests' preset exempts *.test/*.spec/*.bench files from the type-boundary rules (no-explicit-any, no-unused-vars, no-new-array, no-extraneous-class); base now allows intentional console.warn/error (stray console.log still flagged). --- configs/eslint/src/index.ts | 2 +- configs/eslint/src/presets/base.ts | 5 +++- configs/eslint/src/presets/index.ts | 1 + configs/eslint/src/presets/tests.ts | 39 +++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 configs/eslint/src/presets/tests.ts diff --git a/configs/eslint/src/index.ts b/configs/eslint/src/index.ts index 498a123..1786d35 100644 --- a/configs/eslint/src/index.ts +++ b/configs/eslint/src/index.ts @@ -2,7 +2,7 @@ export { compose } from './compose'; /* Presets */ -export { base, ignores, typescript, vue, vitest, imports, node, stylistic, regexp } from './presets'; +export { base, ignores, typescript, vue, vitest, tests, imports, node, stylistic, regexp } from './presets'; /* Types */ export type { diff --git a/configs/eslint/src/presets/base.ts b/configs/eslint/src/presets/base.ts index 4da972a..ae8479e 100644 --- a/configs/eslint/src/presets/base.ts +++ b/configs/eslint/src/presets/base.ts @@ -62,7 +62,10 @@ export const base: FlatConfigArray = [ rules: { /* ── eslint core ──────────────────────────────────────── */ eqeqeq: 'error', - 'no-console': 'warn', + /* Allow intentional `console.warn`/`console.error` — used for library dev + diagnostics (a11y/validation warnings, often `__DEV__`-guarded). Stray + `console.log`/`debug`/`info` are still flagged. */ + 'no-console': ['warn', { allow: ['warn', 'error'] }], 'no-debugger': 'error', 'no-eval': 'error', 'no-var': 'error', diff --git a/configs/eslint/src/presets/index.ts b/configs/eslint/src/presets/index.ts index dd29f3e..830dbb6 100644 --- a/configs/eslint/src/presets/index.ts +++ b/configs/eslint/src/presets/index.ts @@ -2,6 +2,7 @@ export { base, ignores } from './base'; export { typescript } from './typescript'; export { vue } from './vue'; export { vitest } from './vitest'; +export { tests } from './tests'; export { imports } from './imports'; export { node } from './node'; export { regexp } from './regexp'; diff --git a/configs/eslint/src/presets/tests.ts b/configs/eslint/src/presets/tests.ts new file mode 100644 index 0000000..9742dcd --- /dev/null +++ b/configs/eslint/src/presets/tests.ts @@ -0,0 +1,39 @@ +import type { FlatConfigArray } from '../types'; + +/** + * Relaxations for test, spec and benchmark files — the type-boundary carve-outs + * that test scaffolding legitimately needs, applied uniformly across every + * package. + * + * Tests stub globals (`(globalThis as any).x`), cast `vi.fn()` mocks, build + * throwaway fixtures and keep deliberate sink variables; benchmarks pre-size + * arrays with `new Array(n)`. The `vitest` preset already grants these for its + * own (`it`/`expect`) ruleset, but most packages don't adopt that preset (their + * tests use string `describe` titles), so this small overlay carries just the + * relaxations — no vitest-specific style rules — and is meant to be composed + * LAST so it wins over the `typescript`/`stylistic` presets for these files. + * + * Source `any` is unaffected: it stays at `warn` everywhere else. + */ +export const tests: FlatConfigArray = [ + { + name: 'robonen/tests', + files: [ + '**/*.{test,spec,bench}.{ts,tsx,cts,mts,js,jsx,cjs,mjs}', + '**/test/**/*.{ts,tsx,js,jsx}', + '**/__test__/**/*.{ts,tsx,js,jsx}', + '**/__tests__/**/*.{ts,tsx,js,jsx}', + ], + rules: { + /* Test scaffolding inspects/stubs untyped boundaries; `any` is idiomatic here. */ + '@typescript-eslint/no-explicit-any': 'off', + /* Sink variables, partially-used fixtures and `_`-less throwaways are fine in tests. */ + '@typescript-eslint/no-unused-vars': 'off', + 'no-unused-vars': 'off', + /* Benchmarks legitimately pre-size arrays (`new Array(n)`) for fixtures. */ + 'unicorn/no-new-array': 'off', + /* Empty mock/fixture classes (e.g. stubbing `class DeviceOrientationEvent {}`). */ + '@typescript-eslint/no-extraneous-class': 'off', + }, + }, +];