js-style-kit 0.6.0 → 0.7.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.
- package/README.md +5 -0
- package/dist/index.d.ts +11 -5
- package/dist/index.js +48 -77
- package/dist/index.js.map +1 -1
- package/package.json +36 -33
- package/src/eslint/base/README.md +186 -0
- package/src/eslint/base/config.ts +37 -0
- package/src/eslint/base/rules.ts +444 -0
- package/src/eslint/base/types.ts +20 -0
- package/src/eslint/constants.ts +52 -0
- package/src/eslint/convex/README.md +30 -0
- package/src/eslint/convex/config.ts +34 -0
- package/src/eslint/convex/rules.ts +8 -0
- package/src/eslint/convex/types.ts +8 -0
- package/src/eslint/ignores.ts +31 -0
- package/src/eslint/import/README.md +397 -0
- package/src/eslint/import/config.ts +48 -0
- package/src/eslint/import/rules.ts +81 -0
- package/src/eslint/index.ts +259 -0
- package/src/eslint/jsdoc/README.md +399 -0
- package/src/eslint/jsdoc/config.ts +29 -0
- package/src/eslint/jsdoc/rules.ts +81 -0
- package/src/eslint/jsdoc/types.ts +56 -0
- package/src/eslint/nextjs/config.ts +25 -0
- package/src/eslint/nextjs/rules.ts +25 -0
- package/src/eslint/nextjs/types.ts +27 -0
- package/src/eslint/perfectionist/README.md +454 -0
- package/src/eslint/perfectionist/config.ts +25 -0
- package/src/eslint/perfectionist/rules.ts +39 -0
- package/src/eslint/prefer-arrow-function/config.ts +33 -0
- package/src/eslint/prefer-arrow-function/types.ts +13 -0
- package/src/eslint/process-custom-rules.ts +72 -0
- package/src/eslint/query/README.md +254 -0
- package/src/eslint/query/config.ts +27 -0
- package/src/eslint/query/rules.ts +11 -0
- package/src/eslint/query/types.ts +11 -0
- package/src/eslint/react/README.md +416 -0
- package/src/eslint/react/config.ts +65 -0
- package/src/eslint/react/rules.ts +188 -0
- package/src/eslint/react/types.ts +26 -0
- package/src/eslint/react-refresh/config.ts +28 -0
- package/src/eslint/react-refresh/rules.ts +48 -0
- package/src/eslint/storybook/README.md +424 -0
- package/src/eslint/storybook/config.ts +57 -0
- package/src/eslint/testing/README.md +436 -0
- package/src/eslint/testing/config.ts +90 -0
- package/src/eslint/testing/jest-rules.ts +47 -0
- package/src/eslint/testing/vitest-rules.ts +42 -0
- package/src/eslint/turbo/README.md +380 -0
- package/src/eslint/turbo/config.ts +26 -0
- package/src/eslint/turbo/types.ts +7 -0
- package/src/eslint/types.ts +29 -0
- package/src/eslint/typescript/README.md +229 -0
- package/src/eslint/typescript/config.ts +48 -0
- package/src/eslint/typescript/rules.ts +137 -0
- package/src/eslint/typescript/types.ts +35 -0
- package/src/eslint/unicorn/README.md +497 -0
- package/src/eslint/unicorn/config.ts +36 -0
- package/src/eslint/unicorn/rules.ts +86 -0
- package/src/index.ts +3 -0
- package/src/modules.d.ts +5 -0
- package/src/prettier/README.md +413 -0
- package/src/prettier/index.ts +110 -0
- 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,90 @@
|
|
|
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 { jestRules } from "./jest-rules.js";
|
|
8
|
+
import { vitestRules } from "./vitest-rules.js";
|
|
9
|
+
|
|
10
|
+
export interface TestingConfig {
|
|
11
|
+
filenamePattern?: "spec" | "test";
|
|
12
|
+
files?: string[];
|
|
13
|
+
formattingRules?: boolean;
|
|
14
|
+
framework?: "bun" | "jest" | "node" | "vitest";
|
|
15
|
+
itOrTest?: "it" | "test";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates an ESLint configuration object for testing.
|
|
20
|
+
*
|
|
21
|
+
* @param options - Configuration options
|
|
22
|
+
* @param options.files - Files to include in the configuration
|
|
23
|
+
* @param options.filenamePattern - ".test" or ".spec" filename pattern
|
|
24
|
+
* @param options.itOrTest - "it" or "test"
|
|
25
|
+
* @param options.framework - "jest" or "vitest"
|
|
26
|
+
* @param options.formattingRules - Whether to include formatting rules like padding around blocks
|
|
27
|
+
* @param customRules - Optional object containing custom rules to override or add to the testing configuration.
|
|
28
|
+
* @returns ESLint configuration object
|
|
29
|
+
*/
|
|
30
|
+
export const testingConfig = (
|
|
31
|
+
{
|
|
32
|
+
filenamePattern,
|
|
33
|
+
files,
|
|
34
|
+
formattingRules,
|
|
35
|
+
framework,
|
|
36
|
+
itOrTest,
|
|
37
|
+
}: TestingConfig = {
|
|
38
|
+
filenamePattern: "test",
|
|
39
|
+
formattingRules: true,
|
|
40
|
+
framework: "vitest",
|
|
41
|
+
itOrTest: "test",
|
|
42
|
+
},
|
|
43
|
+
customRules?: Record<string, EslintRuleConfig>,
|
|
44
|
+
): EslintConfigObject => ({
|
|
45
|
+
files: files ?? ["**/*.{test,spec}.{ts,tsx,js,jsx}"],
|
|
46
|
+
languageOptions: {
|
|
47
|
+
globals:
|
|
48
|
+
framework === "vitest" ?
|
|
49
|
+
{ ...vitest.environments.env.globals }
|
|
50
|
+
: jest.environments.globals.globals,
|
|
51
|
+
},
|
|
52
|
+
name: configNames.testing,
|
|
53
|
+
plugins: {
|
|
54
|
+
jest,
|
|
55
|
+
vitest,
|
|
56
|
+
},
|
|
57
|
+
rules: {
|
|
58
|
+
// jest doesn't have a file name rule, so we'll use this one for both
|
|
59
|
+
"@typescript-eslint/unbound-method": "off",
|
|
60
|
+
"vitest/consistent-test-filename": [
|
|
61
|
+
"warn",
|
|
62
|
+
{
|
|
63
|
+
allTestPattern: ".*\\.(test|spec)\\.[tj]sx?$",
|
|
64
|
+
pattern: `.*\\.${filenamePattern}\\.[tj]sx?$`,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
...(framework === "vitest" ? vitestRules(itOrTest) : jestRules(itOrTest)),
|
|
68
|
+
...(formattingRules ?
|
|
69
|
+
{
|
|
70
|
+
"jest/padding-around-after-all-blocks": "warn",
|
|
71
|
+
"jest/padding-around-after-each-blocks": "warn",
|
|
72
|
+
"jest/padding-around-before-all-blocks": "warn",
|
|
73
|
+
"jest/padding-around-before-each-blocks": "warn",
|
|
74
|
+
"jest/padding-around-describe-blocks": "warn",
|
|
75
|
+
"jest/padding-around-expect-groups": "warn",
|
|
76
|
+
"jest/padding-around-test-blocks": "warn",
|
|
77
|
+
}
|
|
78
|
+
: {}),
|
|
79
|
+
...(customRules ?? {}),
|
|
80
|
+
},
|
|
81
|
+
...(framework !== "jest" && framework !== "vitest" ?
|
|
82
|
+
{
|
|
83
|
+
settings: {
|
|
84
|
+
jest: {
|
|
85
|
+
globalPackage: framework === "node" ? "node:test" : "bun:test",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
: {}),
|
|
90
|
+
});
|
|
@@ -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
|
+
});
|