js-style-kit 0.6.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +5 -0
  2. package/dist/bin/index.cjs +2 -1
  3. package/dist/bin/index.cjs.map +1 -1
  4. package/dist/index.d.ts +23 -7
  5. package/dist/index.js +135 -36
  6. package/dist/index.js.map +1 -1
  7. package/package.json +10 -7
  8. package/src/eslint/base/README.md +186 -0
  9. package/src/eslint/base/config.ts +37 -0
  10. package/src/eslint/base/rules.ts +444 -0
  11. package/src/eslint/base/types.ts +20 -0
  12. package/src/eslint/constants.ts +52 -0
  13. package/src/eslint/convex/README.md +30 -0
  14. package/src/eslint/convex/config.ts +34 -0
  15. package/src/eslint/convex/rules.ts +8 -0
  16. package/src/eslint/convex/types.ts +8 -0
  17. package/src/eslint/ignores.ts +34 -0
  18. package/src/eslint/import/README.md +397 -0
  19. package/src/eslint/import/config.ts +48 -0
  20. package/src/eslint/import/rules.ts +81 -0
  21. package/src/eslint/index.ts +273 -0
  22. package/src/eslint/jsdoc/README.md +399 -0
  23. package/src/eslint/jsdoc/config.ts +29 -0
  24. package/src/eslint/jsdoc/rules.ts +81 -0
  25. package/src/eslint/jsdoc/types.ts +56 -0
  26. package/src/eslint/nextjs/config.ts +25 -0
  27. package/src/eslint/nextjs/rules.ts +25 -0
  28. package/src/eslint/nextjs/types.ts +27 -0
  29. package/src/eslint/perfectionist/README.md +454 -0
  30. package/src/eslint/perfectionist/config.ts +25 -0
  31. package/src/eslint/perfectionist/rules.ts +39 -0
  32. package/src/eslint/prefer-arrow-function/config.ts +33 -0
  33. package/src/eslint/prefer-arrow-function/types.ts +13 -0
  34. package/src/eslint/process-custom-rules.ts +72 -0
  35. package/src/eslint/query/README.md +254 -0
  36. package/src/eslint/query/config.ts +27 -0
  37. package/src/eslint/query/rules.ts +11 -0
  38. package/src/eslint/query/types.ts +11 -0
  39. package/src/eslint/react/README.md +416 -0
  40. package/src/eslint/react/config.ts +65 -0
  41. package/src/eslint/react/rules.ts +188 -0
  42. package/src/eslint/react/types.ts +26 -0
  43. package/src/eslint/react-refresh/config.ts +28 -0
  44. package/src/eslint/react-refresh/rules.ts +48 -0
  45. package/src/eslint/storybook/README.md +424 -0
  46. package/src/eslint/storybook/config.ts +57 -0
  47. package/src/eslint/testing/README.md +436 -0
  48. package/src/eslint/testing/config.ts +99 -0
  49. package/src/eslint/testing/get-import-restrictions.ts +70 -0
  50. package/src/eslint/testing/jest-rules.ts +47 -0
  51. package/src/eslint/testing/vitest-rules.ts +42 -0
  52. package/src/eslint/turbo/README.md +380 -0
  53. package/src/eslint/turbo/config.ts +26 -0
  54. package/src/eslint/turbo/types.ts +7 -0
  55. package/src/eslint/types.ts +36 -0
  56. package/src/eslint/typescript/README.md +229 -0
  57. package/src/eslint/typescript/config.ts +48 -0
  58. package/src/eslint/typescript/rules.ts +137 -0
  59. package/src/eslint/typescript/types.ts +35 -0
  60. package/src/eslint/unicorn/README.md +497 -0
  61. package/src/eslint/unicorn/config.ts +36 -0
  62. package/src/eslint/unicorn/rules.ts +86 -0
  63. package/src/index.ts +3 -0
  64. package/src/modules.d.ts +5 -0
  65. package/src/prettier/README.md +413 -0
  66. package/src/prettier/index.ts +110 -0
  67. package/src/utils/is-type.ts +60 -0
@@ -0,0 +1,436 @@
1
+ # Testing Configuration
2
+
3
+ Comprehensive testing support with rules for Vitest, Jest, Bun, and Node.js test runners.
4
+
5
+ [← Back to main README](../../../README.md)
6
+
7
+ ## Overview
8
+
9
+ Testing support is **disabled by default** and provides:
10
+
11
+ - Framework-specific test rules (Vitest, Jest, Bun, Node.js)
12
+ - Test file naming conventions
13
+ - Test style consistency (`it` vs `test`)
14
+ - Optional formatting rules for test block padding
15
+
16
+ ## Quick Start
17
+
18
+ ```js
19
+ import { eslintConfig } from "js-style-kit";
20
+
21
+ export default eslintConfig({
22
+ testing: true, // Enable with defaults (Vitest)
23
+ });
24
+ ```
25
+
26
+ ## Configuration Options
27
+
28
+ ### Basic Enable
29
+
30
+ ```js
31
+ testing: true, // Vitest + ".test" files + "test" style + formatting
32
+ ```
33
+
34
+ ### Framework-Specific
35
+
36
+ ```js
37
+ testing: {
38
+ framework: "vitest", // "vitest" | "jest" | "bun" | "node"
39
+ filenamePattern: "test", // "test" | "spec"
40
+ itOrTest: "test", // "test" | "it"
41
+ formattingRules: true, // Enable padding rules
42
+ }
43
+ ```
44
+
45
+ ### Custom Files
46
+
47
+ ```js
48
+ testing: {
49
+ framework: "jest",
50
+ files: ["**/__tests__/**/*.ts", "**/*.test.ts"],
51
+ }
52
+ ```
53
+
54
+ ## Framework Options
55
+
56
+ ### Vitest (Default)
57
+
58
+ ```js
59
+ export default eslintConfig({
60
+ testing: { framework: "vitest" },
61
+ });
62
+ ```
63
+
64
+ **Includes:**
65
+
66
+ - ✅ Vitest-specific rules and globals
67
+ - ✅ Test assertion best practices
68
+ - ✅ Hook usage validation
69
+
70
+ ### Jest
71
+
72
+ ```js
73
+ export default eslintConfig({
74
+ testing: { framework: "jest" },
75
+ });
76
+ ```
77
+
78
+ **Includes:**
79
+
80
+ - ✅ Jest-specific rules and globals
81
+ - ✅ All Jest best practices
82
+ - ✅ Snapshot testing support
83
+
84
+ ### Bun
85
+
86
+ ```js
87
+ export default eslintConfig({
88
+ testing: { framework: "bun" },
89
+ });
90
+ ```
91
+
92
+ **Includes:**
93
+
94
+ - ✅ Bun test runner support
95
+ - ✅ Uses `bun:test` global package
96
+ - ✅ Jest-compatible rules
97
+
98
+ ### Node.js
99
+
100
+ ```js
101
+ export default eslintConfig({
102
+ testing: { framework: "node" },
103
+ });
104
+ ```
105
+
106
+ **Includes:**
107
+
108
+ - ✅ Node.js native test runner
109
+ - ✅ Uses `node:test` global package
110
+ - ✅ Jest-compatible rules
111
+
112
+ ## Filename Patterns
113
+
114
+ Control test file naming conventions:
115
+
116
+ ### .test files (Default)
117
+
118
+ ```js
119
+ testing: {
120
+ filenamePattern: "test", // Enforces .test.ts, .test.tsx, etc.
121
+ }
122
+ ```
123
+
124
+ **Valid:**
125
+
126
+ - ✅ `user.test.ts`
127
+ - ✅ `components/button.test.tsx`
128
+ - ❌ `user.spec.ts` (warning)
129
+
130
+ ### .spec files
131
+
132
+ ```js
133
+ testing: {
134
+ filenamePattern: "spec", // Enforces .spec.ts, .spec.tsx, etc.
135
+ }
136
+ ```
137
+
138
+ **Valid:**
139
+
140
+ - ✅ `user.spec.ts`
141
+ - ✅ `components/button.spec.tsx`
142
+ - ❌ `user.test.ts` (warning)
143
+
144
+ ## Test Style
145
+
146
+ Choose between `it` and `test` function names:
147
+
148
+ ### "test" Style (Default)
149
+
150
+ ```js
151
+ testing: {
152
+ itOrTest: "test",
153
+ }
154
+ ```
155
+
156
+ ```js
157
+ // ✅ Good
158
+ test("adds two numbers", () => {
159
+ expect(add(1, 2)).toBe(3);
160
+ });
161
+
162
+ // ❌ Bad
163
+ it("adds two numbers", () => {
164
+ expect(add(1, 2)).toBe(3);
165
+ });
166
+ ```
167
+
168
+ ### "it" Style
169
+
170
+ ```js
171
+ testing: {
172
+ itOrTest: "it",
173
+ }
174
+ ```
175
+
176
+ ```js
177
+ // ✅ Good
178
+ it("should add two numbers", () => {
179
+ expect(add(1, 2)).toBe(3);
180
+ });
181
+
182
+ // ❌ Bad
183
+ test("should add two numbers", () => {
184
+ expect(add(1, 2)).toBe(3);
185
+ });
186
+ ```
187
+
188
+ ## Formatting Rules
189
+
190
+ Control padding around test blocks for better readability:
191
+
192
+ ### Enabled (Default)
193
+
194
+ ```js
195
+ testing: {
196
+ formattingRules: true,
197
+ }
198
+ ```
199
+
200
+ ```js
201
+ // ✅ Good - proper spacing
202
+ describe("Calculator", () => {
203
+ let calculator;
204
+
205
+ beforeEach(() => {
206
+ calculator = new Calculator();
207
+ });
208
+
209
+ afterEach(() => {
210
+ calculator.reset();
211
+ });
212
+
213
+ describe("addition", () => {
214
+ test("adds positive numbers", () => {
215
+ expect(calculator.add(2, 3)).toBe(5);
216
+ });
217
+
218
+ test("adds negative numbers", () => {
219
+ expect(calculator.add(-2, -3)).toBe(-5);
220
+ });
221
+ });
222
+ });
223
+
224
+ // ❌ Bad - no spacing
225
+ describe("Calculator", () => {
226
+ let calculator;
227
+ beforeEach(() => {
228
+ calculator = new Calculator();
229
+ });
230
+ afterEach(() => {
231
+ calculator.reset();
232
+ });
233
+ describe("addition", () => {
234
+ test("adds positive numbers", () => {
235
+ expect(calculator.add(2, 3)).toBe(5);
236
+ });
237
+ test("adds negative numbers", () => {
238
+ expect(calculator.add(-2, -3)).toBe(-5);
239
+ });
240
+ });
241
+ });
242
+ ```
243
+
244
+ ### Disabled
245
+
246
+ ```js
247
+ testing: {
248
+ formattingRules: false, // No padding requirements
249
+ }
250
+ ```
251
+
252
+ ## Key Rules
253
+
254
+ ### Test Structure
255
+
256
+ - **`vitest/consistent-test-filename`** - Enforces consistent file naming
257
+ - **`vitest/consistent-test-it`** / **`jest/consistent-test-it`** - Enforces `it` or `test`
258
+ - **`vitest/no-identical-title`** / **`jest/no-identical-title`** - Prevents duplicate test names
259
+
260
+ ### Assertions
261
+
262
+ - **`vitest/expect-expect`** / **`jest/expect-expect`** - Ensures tests have assertions
263
+ - **`vitest/no-conditional-expect`** / **`jest/no-conditional-expect`** - No conditional assertions
264
+ - **`vitest/valid-expect`** / **`jest/valid-expect`** - Validates expect usage
265
+
266
+ ### Best Practices
267
+
268
+ - **`vitest/prefer-to-be`** / **`jest/prefer-to-be`** - Use `toBe()` for primitives
269
+ - **`vitest/prefer-to-be-truthy`** / **`jest/prefer-to-be-truthy`** - Use `toBeTruthy()`/`toBeFalsy()`
270
+ - **`vitest/no-disabled-tests`** / **`jest/no-disabled-tests`** - Warns on `.skip` and `.only`
271
+
272
+ ### TypeScript Integration
273
+
274
+ When TypeScript is enabled:
275
+
276
+ - **`@typescript-eslint/unbound-method`** is disabled (conflicts with test mocking)
277
+
278
+ ## Examples
279
+
280
+ ### Vitest + TypeScript
281
+
282
+ ```js
283
+ export default eslintConfig({
284
+ typescript: true,
285
+ testing: {
286
+ framework: "vitest",
287
+ filenamePattern: "test",
288
+ itOrTest: "test",
289
+ },
290
+ });
291
+ ```
292
+
293
+ ```ts
294
+ // user.test.ts
295
+ import { describe, test, expect } from "vitest";
296
+ import { createUser } from "./user";
297
+
298
+ describe("createUser", () => {
299
+ test("creates a user with valid data", () => {
300
+ const user = createUser({ name: "Alice", age: 30 });
301
+ expect(user).toEqual({ name: "Alice", age: 30 });
302
+ });
303
+
304
+ test("throws on invalid age", () => {
305
+ expect(() => createUser({ name: "Bob", age: -1 })).toThrow();
306
+ });
307
+ });
308
+ ```
309
+
310
+ ### Jest + Spec Files
311
+
312
+ ```js
313
+ export default eslintConfig({
314
+ testing: {
315
+ framework: "jest",
316
+ filenamePattern: "spec",
317
+ itOrTest: "it",
318
+ },
319
+ });
320
+ ```
321
+
322
+ ```ts
323
+ // user.spec.ts
324
+ describe("User", () => {
325
+ it("should create a user", () => {
326
+ const user = new User("Alice");
327
+ expect(user.name).toBe("Alice");
328
+ });
329
+ });
330
+ ```
331
+
332
+ ### Bun Tests
333
+
334
+ ```js
335
+ export default eslintConfig({
336
+ testing: {
337
+ framework: "bun",
338
+ },
339
+ });
340
+ ```
341
+
342
+ ```ts
343
+ // math.test.ts
344
+ import { test, expect } from "bun:test";
345
+
346
+ test("adds numbers", () => {
347
+ expect(1 + 2).toBe(3);
348
+ });
349
+ ```
350
+
351
+ ### Node.js Tests
352
+
353
+ ```js
354
+ export default eslintConfig({
355
+ testing: {
356
+ framework: "node",
357
+ },
358
+ });
359
+ ```
360
+
361
+ ```ts
362
+ // math.test.ts
363
+ import { test } from "node:test";
364
+ import assert from "node:assert";
365
+
366
+ test("adds numbers", () => {
367
+ assert.strictEqual(1 + 2, 3);
368
+ });
369
+ ```
370
+
371
+ ## Customization
372
+
373
+ Override specific testing rules:
374
+
375
+ ```js
376
+ export default eslintConfig({
377
+ testing: { framework: "vitest" },
378
+ rules: {
379
+ // Allow .only for debugging
380
+ "vitest/no-disabled-tests": "off",
381
+
382
+ // Stricter test naming
383
+ "vitest/consistent-test-filename": "error",
384
+
385
+ // Disable padding rules
386
+ "jest/padding-around-test-blocks": "off",
387
+ },
388
+ });
389
+ ```
390
+
391
+ ## Common Patterns
392
+
393
+ ### Monorepo with Multiple Test Runners
394
+
395
+ ```js
396
+ export default eslintConfig({
397
+ testing: { framework: "vitest" },
398
+ overrides: [
399
+ {
400
+ files: ["packages/legacy/**/*.test.ts"],
401
+ rules: {
402
+ // Use Jest rules for legacy package
403
+ },
404
+ },
405
+ ],
406
+ });
407
+ ```
408
+
409
+ ### React Component Testing
410
+
411
+ ```js
412
+ export default eslintConfig({
413
+ typescript: true,
414
+ react: true,
415
+ testing: {
416
+ framework: "vitest",
417
+ files: ["**/*.test.{ts,tsx}"],
418
+ },
419
+ });
420
+ ```
421
+
422
+ ## Related Configurations
423
+
424
+ - [TypeScript](../typescript/README.md) - TypeScript configuration
425
+ - [React](../react/README.md) - React component testing
426
+ - [Base](../base/README.md) - Base ESLint rules
427
+
428
+ ## Learn More
429
+
430
+ - [Vitest](https://vitest.dev/)
431
+ - [Jest](https://jestjs.io/)
432
+ - [Bun Test](https://bun.sh/docs/cli/test)
433
+ - [Node.js Test Runner](https://nodejs.org/api/test.html)
434
+ - [eslint-plugin-vitest](https://github.com/vitest-dev/eslint-plugin-vitest)
435
+ - [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest)
436
+ - [Main README](../../../README.md)
@@ -0,0 +1,99 @@
1
+ import jest from "eslint-plugin-jest";
2
+ import vitest from "eslint-plugin-vitest";
3
+
4
+ import type { EslintConfigObject, EslintRuleConfig } from "../types.js";
5
+
6
+ import { configNames } from "../constants.js";
7
+ import { getImportRestrictions } from "./get-import-restrictions.js";
8
+ import { jestRules } from "./jest-rules.js";
9
+ import { vitestRules } from "./vitest-rules.js";
10
+
11
+ export interface TestingConfig {
12
+ filenamePattern?: "spec" | "test";
13
+ files?: string[];
14
+ formattingRules?: boolean;
15
+ framework?: "bun" | "jest" | "node" | "vitest";
16
+ /**
17
+ * Whether to enforce imports from the correct testing framework.
18
+ * Uses the built-in ESLint `no-restricted-imports` rule.
19
+ *
20
+ * @default true
21
+ */
22
+ importRestrictions?: boolean;
23
+ itOrTest?: "it" | "test";
24
+ typescript?: boolean;
25
+ }
26
+
27
+ /**
28
+ * Creates an ESLint configuration object for testing.
29
+ *
30
+ * @param options - Configuration options
31
+ * @param options.files - Files to include in the configuration
32
+ * @param options.filenamePattern - ".test" or ".spec" filename pattern
33
+ * @param options.itOrTest - "it" or "test"
34
+ * @param options.framework - "jest" or "vitest" or "bun" or "node"
35
+ * @param options.formattingRules - Whether to include formatting rules like padding around blocks
36
+ * @param options.importRestrictions - Whether to enforce imports from the correct testing framework
37
+ * @param options.typescript - Whether the user is using TypeScript
38
+ * @param customRules - Optional object containing custom rules to override or add to the testing configuration.
39
+ * @returns ESLint configuration object
40
+ */
41
+ export const testingConfig = (
42
+ {
43
+ filenamePattern = "test",
44
+ files,
45
+ formattingRules = true,
46
+ framework = "vitest",
47
+ importRestrictions = true,
48
+ itOrTest = "test",
49
+ typescript = true,
50
+ }: TestingConfig = {},
51
+ customRules?: Record<string, EslintRuleConfig>,
52
+ ): EslintConfigObject => ({
53
+ files: files ?? ["**/*.{test,spec}.{ts,tsx,js,jsx}"],
54
+ languageOptions: {
55
+ globals:
56
+ framework === "vitest" ?
57
+ { ...vitest.environments.env.globals }
58
+ : jest.environments.globals.globals,
59
+ },
60
+ name: configNames.testing,
61
+ plugins: {
62
+ jest,
63
+ vitest,
64
+ },
65
+ rules: {
66
+ ...(typescript ? { "@typescript-eslint/unbound-method": "off" } : {}),
67
+ // jest doesn't have a file name rule, so we'll use this one for both
68
+ "vitest/consistent-test-filename": [
69
+ "warn",
70
+ {
71
+ allTestPattern: ".*\\.(test|spec)\\.[tj]sx?$",
72
+ pattern: `.*\\.${filenamePattern}\\.[tj]sx?$`,
73
+ },
74
+ ],
75
+ ...(framework === "vitest" ? vitestRules(itOrTest) : jestRules(itOrTest)),
76
+ ...(formattingRules ?
77
+ {
78
+ "jest/padding-around-after-all-blocks": "warn",
79
+ "jest/padding-around-after-each-blocks": "warn",
80
+ "jest/padding-around-before-all-blocks": "warn",
81
+ "jest/padding-around-before-each-blocks": "warn",
82
+ "jest/padding-around-describe-blocks": "warn",
83
+ "jest/padding-around-expect-groups": "warn",
84
+ "jest/padding-around-test-blocks": "warn",
85
+ }
86
+ : {}),
87
+ ...(importRestrictions ? getImportRestrictions(framework) : {}),
88
+ ...(customRules ?? {}),
89
+ },
90
+ ...(framework !== "jest" && framework !== "vitest" ?
91
+ {
92
+ settings: {
93
+ jest: {
94
+ globalPackage: framework === "node" ? "node:test" : "bun:test",
95
+ },
96
+ },
97
+ }
98
+ : {}),
99
+ });
@@ -0,0 +1,70 @@
1
+ import type { EslintRuleConfig } from "../types.js";
2
+
3
+ const commonTestImports = [
4
+ "describe",
5
+ "it",
6
+ "test",
7
+ "expect",
8
+ "beforeAll",
9
+ "beforeEach",
10
+ "afterAll",
11
+ "afterEach",
12
+ "vi",
13
+ "mock",
14
+ "spyOn",
15
+ ];
16
+
17
+ const frameworkConfig = {
18
+ bun: {
19
+ allowed: "'bun:test'",
20
+ restricted: ["vitest", "jest", "@jest/globals", "node:test"],
21
+ },
22
+ jest: {
23
+ allowed: "'jest' or '@jest/globals'",
24
+ restricted: ["vitest", "bun:test", "node:test"],
25
+ },
26
+ node: {
27
+ allowed: "'node:test'",
28
+ restricted: ["vitest", "jest", "@jest/globals", "bun:test"],
29
+ },
30
+ vitest: {
31
+ allowed: "'vitest'",
32
+ restricted: ["jest", "@jest/globals", "bun:test", "node:test"],
33
+ },
34
+ } as const;
35
+
36
+ /**
37
+ * Generates the error message for restricted imports.
38
+ *
39
+ * @param allowedFramework - The allowed framework(s) for imports
40
+ * @returns The formatted error message
41
+ */
42
+ const getRestrictionMessage = (allowedFramework: string): string =>
43
+ `This project is setup to use ${allowedFramework} for testing. Importing from other testing frameworks is not allowed. Change this setting in eslint.config.js under testing.framework`;
44
+
45
+ /**
46
+ * Returns import restriction rules based on the testing framework.
47
+ * Prevents importing from the wrong testing framework.
48
+ *
49
+ * @param framework - The testing framework being used
50
+ * @returns ESLint rules object with import restrictions
51
+ */
52
+ export const getImportRestrictions = (
53
+ framework: "bun" | "jest" | "node" | "vitest",
54
+ ): Record<string, EslintRuleConfig> => {
55
+ const config = frameworkConfig[framework];
56
+ const message = getRestrictionMessage(config.allowed);
57
+
58
+ return {
59
+ "no-restricted-imports": [
60
+ "warn",
61
+ {
62
+ paths: config.restricted.map((name) => ({
63
+ importNames: commonTestImports,
64
+ message,
65
+ name,
66
+ })),
67
+ },
68
+ ],
69
+ };
70
+ };
@@ -0,0 +1,47 @@
1
+ import type { EslintRuleConfig } from "../types.js";
2
+
3
+ type JestRules = Record<`jest/${string}`, EslintRuleConfig>;
4
+
5
+ /**
6
+ * Creates an object containing the ESLint rules for jest.
7
+ *
8
+ * @param itOrTest - "it" or "test"
9
+ * @returns An object containing the ESLint rules for jest.
10
+ */
11
+ export const jestRules = (itOrTest: "it" | "test" = "test"): JestRules => ({
12
+ "jest/consistent-test-it": [
13
+ "warn",
14
+ { fn: itOrTest, withinDescribe: itOrTest },
15
+ ],
16
+ "jest/expect-expect": "warn",
17
+ "jest/no-commented-out-tests": "warn",
18
+ "jest/no-conditional-expect": "warn",
19
+ "jest/no-conditional-in-test": "warn",
20
+ "jest/no-disabled-tests": "warn",
21
+ "jest/no-duplicate-hooks": "warn",
22
+ "jest/no-focused-tests": "warn",
23
+ "jest/no-identical-title": "warn",
24
+ "jest/no-interpolation-in-snapshots": "warn",
25
+ "jest/no-large-snapshots": ["warn", { inlineMaxSize: 50, maxSize: 100 }],
26
+ "jest/no-mocks-import": "warn", // Discourage manually importing from __mocks__
27
+ "jest/no-standalone-expect": "warn",
28
+ "jest/no-test-prefixes": "warn", // Prefer .only and .skip over f and x
29
+ "jest/no-test-return-statement": "warn",
30
+ "jest/prefer-comparison-matcher": "warn",
31
+ "jest/prefer-equality-matcher": "warn",
32
+ "jest/prefer-expect-resolves": "warn",
33
+ "jest/prefer-hooks-in-order": "warn",
34
+ "jest/prefer-hooks-on-top": "warn",
35
+ "jest/prefer-lowercase-title": ["warn", { ignoreTopLevelDescribe: true }],
36
+ "jest/prefer-snapshot-hint": "warn",
37
+ "jest/prefer-spy-on": "warn",
38
+ "jest/prefer-strict-equal": "warn",
39
+ "jest/prefer-to-be": "warn",
40
+ "jest/prefer-to-contain": "warn",
41
+ "jest/prefer-to-have-length": "warn",
42
+ "jest/require-top-level-describe": "warn",
43
+ "jest/valid-describe-callback": "warn",
44
+ "jest/valid-expect": "warn",
45
+ "jest/valid-expect-in-promise": "warn",
46
+ "jest/valid-title": "warn",
47
+ });
@@ -0,0 +1,42 @@
1
+ import type { EslintRuleConfig } from "../types.js";
2
+
3
+ type VitestRules = Record<`vitest/${string}`, EslintRuleConfig>;
4
+
5
+ /**
6
+ * Creates an object containing the ESLint rules for vitest.
7
+ *
8
+ * @param itOrTest - "it" or "test"
9
+ * @returns An object containing the ESLint rules for vitest.
10
+ */
11
+ export const vitestRules = (itOrTest: "it" | "test" = "test"): VitestRules => ({
12
+ "vitest/consistent-test-it": [
13
+ "warn",
14
+ { fn: itOrTest, withinDescribe: itOrTest },
15
+ ],
16
+ "vitest/expect-expect": "warn",
17
+ "vitest/no-commented-out-tests": "warn",
18
+ "vitest/no-conditional-in-test": "warn",
19
+ "vitest/no-disabled-tests": "warn",
20
+ "vitest/no-duplicate-hooks": "warn",
21
+ "vitest/no-focused-tests": "warn",
22
+ "vitest/no-identical-title": "warn",
23
+ "vitest/no-import-node-test": "warn",
24
+ "vitest/no-interpolation-in-snapshots": "warn", // Avoid dynamic snapshots
25
+ "vitest/no-large-snapshots": ["warn", { inlineMaxSize: 50, maxSize: 100 }], // Keep snapshots manageable
26
+ "vitest/no-standalone-expect": "warn",
27
+ "vitest/no-test-return-statement": "warn", // Tests shouldn't return values
28
+ "vitest/prefer-comparison-matcher": "warn", // Use comparison matchers
29
+ "vitest/prefer-equality-matcher": "warn", // Use equality matchers
30
+ "vitest/prefer-hooks-in-order": "warn", // Keep hooks in a predictable order
31
+ "vitest/prefer-hooks-on-top": "warn", // Keep hooks organized
32
+ "vitest/prefer-lowercase-title": ["warn", { ignoreTopLevelDescribe: true }], // Consistent casing
33
+ "vitest/prefer-strict-equal": "warn", // Prefer .toStrictEqual() over .toEqual()
34
+ "vitest/prefer-to-be": "warn", // Use .toBe() for primitives
35
+ "vitest/prefer-to-contain": "warn", // Use .toContain() for array/string includes
36
+ "vitest/prefer-to-have-length": "warn", // Use .toHaveLength() for checking length
37
+ "vitest/require-local-test-context-for-concurrent-snapshots": "warn",
38
+ "vitest/require-top-level-describe": "warn", // Group tests in describe blocks
39
+ "vitest/valid-describe-callback": "warn",
40
+ "vitest/valid-expect": "warn",
41
+ "vitest/valid-title": "warn",
42
+ });