eslint-plugin-ts-data-forge 0.1.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 (45) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +57 -0
  3. package/package.json +74 -0
  4. package/src/index.mts +7 -0
  5. package/src/plugin.mts +9 -0
  6. package/src/rule-types.mts +326 -0
  7. package/src/rules/ast-utils.mts +169 -0
  8. package/src/rules/branded-number-types.mts +47 -0
  9. package/src/rules/constants.mts +1 -0
  10. package/src/rules/import-utils.mts +152 -0
  11. package/src/rules/index.mts +1 -0
  12. package/src/rules/no-unnecessary-type-guard.mts +515 -0
  13. package/src/rules/no-unnecessary-type-guard.test.mts +368 -0
  14. package/src/rules/prefer-arr-is-array.mts +98 -0
  15. package/src/rules/prefer-arr-is-array.test.mts +62 -0
  16. package/src/rules/prefer-arr-is-bounded-length-array.mts +143 -0
  17. package/src/rules/prefer-arr-is-bounded-length-array.test.mts +154 -0
  18. package/src/rules/prefer-arr-is-fixed-length-array.mts +149 -0
  19. package/src/rules/prefer-arr-is-fixed-length-array.test.mts +214 -0
  20. package/src/rules/prefer-arr-is-max-length-array.mts +141 -0
  21. package/src/rules/prefer-arr-is-max-length-array.test.mts +188 -0
  22. package/src/rules/prefer-arr-is-min-length-array.mts +141 -0
  23. package/src/rules/prefer-arr-is-min-length-array.test.mts +202 -0
  24. package/src/rules/prefer-arr-is-non-empty.mts +131 -0
  25. package/src/rules/prefer-arr-is-non-empty.test.mts +90 -0
  26. package/src/rules/prefer-arr-sum.mts +269 -0
  27. package/src/rules/prefer-arr-sum.test.mts +171 -0
  28. package/src/rules/prefer-as-int.mts +131 -0
  29. package/src/rules/prefer-as-int.test.mts +267 -0
  30. package/src/rules/prefer-canonical-array-slicing.mts +800 -0
  31. package/src/rules/prefer-canonical-array-slicing.test.mts +588 -0
  32. package/src/rules/prefer-comparison-over-nullish-guard.mts +141 -0
  33. package/src/rules/prefer-comparison-over-nullish-guard.test.mts +171 -0
  34. package/src/rules/prefer-is-non-null-object.mts +145 -0
  35. package/src/rules/prefer-is-non-null-object.test.mts +156 -0
  36. package/src/rules/prefer-is-record-and-has-key.mts +156 -0
  37. package/src/rules/prefer-is-record-and-has-key.test.mts +217 -0
  38. package/src/rules/prefer-num-safe-parse-float.mts +166 -0
  39. package/src/rules/prefer-num-safe-parse-float.test.mts +163 -0
  40. package/src/rules/prefer-num-safe-parse-int.mts +166 -0
  41. package/src/rules/prefer-num-safe-parse-int.test.mts +137 -0
  42. package/src/rules/prefer-range-for-loop.mts +179 -0
  43. package/src/rules/prefer-range-for-loop.test.mts +156 -0
  44. package/src/rules/rules.mts +36 -0
  45. package/src/types.mts +4 -0
@@ -0,0 +1,267 @@
1
+ import parser from '@typescript-eslint/parser';
2
+ import { RuleTester } from '@typescript-eslint/rule-tester';
3
+ import dedent from 'dedent';
4
+ import { preferAsInt } from './prefer-as-int.mjs';
5
+
6
+ const tester = new RuleTester({
7
+ languageOptions: {
8
+ parser,
9
+ parserOptions: {
10
+ ecmaVersion: 2020,
11
+ sourceType: 'module',
12
+ projectService: {
13
+ allowDefaultProject: ['*.ts*'],
14
+ },
15
+ tsconfigRootDir: `${import.meta.dirname}/../..`,
16
+ },
17
+ },
18
+ });
19
+
20
+ describe('prefer-as-int', () => {
21
+ tester.run('prefer-as-int', preferAsInt, {
22
+ valid: [
23
+ {
24
+ name: 'ignores non-Int assertions',
25
+ code: dedent`
26
+ const n = 1;
27
+ const result = n as number;
28
+ `,
29
+ },
30
+ ],
31
+ invalid: [
32
+ ...([
33
+ {
34
+ name: 'replaces as Int with asInt import',
35
+ code: dedent`
36
+ const n = 1;
37
+ const result = n as Int;
38
+ `,
39
+ output: dedent`
40
+ import { asInt } from 'ts-data-forge';
41
+ const n = 1;
42
+ const result = asInt(n);
43
+ `,
44
+ errors: [{ messageId: 'useBrandedNumberCastFunction' }],
45
+ },
46
+ {
47
+ name: 'replaces as Int with asInt import when other imports exist',
48
+ code: dedent`
49
+ import { noop } from './noop.mjs';
50
+
51
+ const n = 1;
52
+ noop(n as Int);
53
+ `,
54
+ output: dedent`
55
+ import { asInt } from 'ts-data-forge';
56
+ import { noop } from './noop.mjs';
57
+
58
+ const n = 1;
59
+ noop(asInt(n));
60
+ `,
61
+ errors: [{ messageId: 'useBrandedNumberCastFunction' }],
62
+ },
63
+ {
64
+ name: 'replaces multiple as Int with asInt imports',
65
+ code: dedent`
66
+ const n = 1;
67
+ const result = n as Int;
68
+ const another = (n + 1) as Int;
69
+ `,
70
+ output: dedent`
71
+ import { asInt } from 'ts-data-forge';
72
+ const n = 1;
73
+ const result = asInt(n);
74
+ const another = asInt(n + 1);
75
+ `,
76
+ errors: [
77
+ { messageId: 'useBrandedNumberCastFunction' },
78
+ { messageId: 'useBrandedNumberCastFunction' },
79
+ ],
80
+ },
81
+ // {
82
+ // name: 'replaces as Int with asInt import with another disabled line',
83
+ // code: dedent`
84
+ // const n = 1;
85
+
86
+ // // eslint-disable-next-line
87
+ // const result = n as Int;
88
+
89
+ // const another = (n + 1) as Int;
90
+ // `,
91
+ // output: dedent`
92
+ // import { asInt } from 'ts-data-forge';
93
+ // const n = 1;
94
+
95
+ // // eslint-disable-next-line
96
+ // const result = n as Int;
97
+
98
+ // const another = asInt(n + 1);
99
+ // `,
100
+ // errors: [{ messageId: 'useBrandedNumberCastFunction' }],
101
+ // },
102
+ ] as const),
103
+
104
+ ...([
105
+ {
106
+ name: 'keeps existing asInt import',
107
+ code: dedent`
108
+ import { asInt } from 'ts-data-forge';
109
+
110
+ const n = 1;
111
+ const result = n as Int;
112
+ `,
113
+ output: dedent`
114
+ import { asInt } from 'ts-data-forge';
115
+
116
+ const n = 1;
117
+ const result = asInt(n);
118
+ `,
119
+ errors: [{ messageId: 'useBrandedNumberCastFunction' }],
120
+ },
121
+ {
122
+ name: 'keeps existing asInt import when other imports exist',
123
+ code: dedent`
124
+ import { noop } from './noop.mjs';
125
+ import { asInt } from 'ts-data-forge';
126
+
127
+ const n = 1;
128
+ noop(n as Int);
129
+ `,
130
+ output: dedent`
131
+ import { noop } from './noop.mjs';
132
+ import { asInt } from 'ts-data-forge';
133
+
134
+ const n = 1;
135
+ noop(asInt(n));
136
+ `,
137
+ errors: [{ messageId: 'useBrandedNumberCastFunction' }],
138
+ },
139
+ ] as const),
140
+
141
+ ...([
142
+ {
143
+ name: 'adds import even if ts-data-forge import exists',
144
+ code: dedent`
145
+ import { isNonNullObject } from 'ts-data-forge';
146
+
147
+ const n = 1;
148
+ const result = n as Int;
149
+ `,
150
+ output: dedent`
151
+ import { asInt } from 'ts-data-forge';
152
+ import { isNonNullObject } from 'ts-data-forge';
153
+
154
+ const n = 1;
155
+ const result = asInt(n);
156
+ `,
157
+ errors: [{ messageId: 'useBrandedNumberCastFunction' }],
158
+ },
159
+ {
160
+ name: 'adds import even if ts-data-forge import exists (with other imports)',
161
+ code: dedent`
162
+ import { noop } from './noop.mjs';
163
+ import { isNonNullObject } from 'ts-data-forge';
164
+
165
+ const n = 1;
166
+ const result = n as Int;
167
+ `,
168
+ output: dedent`
169
+ import { asInt } from 'ts-data-forge';
170
+ import { noop } from './noop.mjs';
171
+ import { isNonNullObject } from 'ts-data-forge';
172
+
173
+ const n = 1;
174
+ const result = asInt(n);
175
+ `,
176
+ errors: [{ messageId: 'useBrandedNumberCastFunction' }],
177
+ },
178
+ ] as const),
179
+ ],
180
+ });
181
+
182
+ // Test cases for other branded number types
183
+ tester.run('prefer-as-int (other types)', preferAsInt, {
184
+ valid: [],
185
+ invalid: [
186
+ {
187
+ name: 'replaces as Uint32 with asUint32',
188
+ code: dedent`
189
+ const n = 1;
190
+ const result = n as Uint32;
191
+ `,
192
+ output: dedent`
193
+ import { asUint32 } from 'ts-data-forge';
194
+ const n = 1;
195
+ const result = asUint32(n);
196
+ `,
197
+ errors: [{ messageId: 'useBrandedNumberCastFunction' }],
198
+ },
199
+ {
200
+ name: 'replaces as SafeInt with asSafeInt',
201
+ code: dedent`
202
+ const n = 1;
203
+ const result = n as SafeInt;
204
+ `,
205
+ output: dedent`
206
+ import { asSafeInt } from 'ts-data-forge';
207
+ const n = 1;
208
+ const result = asSafeInt(n);
209
+ `,
210
+ errors: [{ messageId: 'useBrandedNumberCastFunction' }],
211
+ },
212
+ {
213
+ name: 'replaces as PositiveInt with asPositiveInt',
214
+ code: dedent`
215
+ const n = 1;
216
+ const result = n as PositiveInt;
217
+ `,
218
+ output: dedent`
219
+ import { asPositiveInt } from 'ts-data-forge';
220
+ const n = 1;
221
+ const result = asPositiveInt(n);
222
+ `,
223
+ errors: [{ messageId: 'useBrandedNumberCastFunction' }],
224
+ },
225
+ {
226
+ name: 'replaces multiple different branded types',
227
+ code: dedent`
228
+ const n = 1;
229
+ const a = n as Int;
230
+ const b = n as Uint32;
231
+ const c = n as SafeInt;
232
+ `,
233
+ output: [
234
+ dedent`
235
+ import { asInt } from 'ts-data-forge';
236
+ const n = 1;
237
+ const a = asInt(n);
238
+ const b = n as Uint32;
239
+ const c = n as SafeInt;
240
+ `,
241
+ dedent`
242
+ import { asUint32 } from 'ts-data-forge';
243
+ import { asInt } from 'ts-data-forge';
244
+ const n = 1;
245
+ const a = asInt(n);
246
+ const b = asUint32(n);
247
+ const c = n as SafeInt;
248
+ `,
249
+ dedent`
250
+ import { asSafeInt } from 'ts-data-forge';
251
+ import { asUint32 } from 'ts-data-forge';
252
+ import { asInt } from 'ts-data-forge';
253
+ const n = 1;
254
+ const a = asInt(n);
255
+ const b = asUint32(n);
256
+ const c = asSafeInt(n);
257
+ `,
258
+ ],
259
+ errors: [
260
+ { messageId: 'useBrandedNumberCastFunction' },
261
+ { messageId: 'useBrandedNumberCastFunction' },
262
+ { messageId: 'useBrandedNumberCastFunction' },
263
+ ],
264
+ },
265
+ ],
266
+ });
267
+ }, 20000);