@cookshack/eslint-config 1.1.0 → 2.0.5
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/.build.yml +1 -1
- package/.husky/pre-commit +1 -0
- package/dist/index.cjs +424 -24
- package/dist/index.js +427 -28
- package/index.js +470 -27
- package/package.json +7 -3
- package/test/rules/narrowest-scope.js +571 -0
- package/test/rules/positive-vibes.js +34 -0
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
import { Linter } from 'eslint'
|
|
2
|
+
import { plugins, getPrintBuffer } from '../../index.js'
|
|
3
|
+
import { diffLines } from 'diff'
|
|
4
|
+
|
|
5
|
+
let linter, validCases, invalidCases, config
|
|
6
|
+
|
|
7
|
+
linter = new Linter()
|
|
8
|
+
validCases = []
|
|
9
|
+
invalidCases = []
|
|
10
|
+
|
|
11
|
+
config = [ { languageOptions: { ecmaVersion: 2025,
|
|
12
|
+
sourceType: 'module' },
|
|
13
|
+
plugins,
|
|
14
|
+
rules: { 'cookshack/narrowest-scope': 'error' } } ]
|
|
15
|
+
|
|
16
|
+
function pass(code, expected) {
|
|
17
|
+
validCases.push({ code, expected })
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function patch(expected, output) {
|
|
21
|
+
return diffLines(expected.trim(), output.trim()).flatMap(p => p.value.split('\n').filter(l => l).map(l => ({ ...p, line: l })))
|
|
22
|
+
.map(p => (p.removed ? '- ' : p.added ? '+ ' : ' ') + p.line).join('\n')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function _pass(tc) {
|
|
26
|
+
let messages, output
|
|
27
|
+
|
|
28
|
+
messages = linter.verify(tc.code, config)
|
|
29
|
+
output = getPrintBuffer()
|
|
30
|
+
if (messages.length > 0)
|
|
31
|
+
throw new Error('unexpected errors: ' + JSON.stringify(messages) + '\noutput:\n' + output)
|
|
32
|
+
if (tc.expected?.trim() == output.trim())
|
|
33
|
+
return
|
|
34
|
+
throw new Error('output mismatch:\n' + patch(tc.expected, output))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function _fail(tc) {
|
|
38
|
+
let messages, output
|
|
39
|
+
|
|
40
|
+
messages = linter.verify(tc.code, config)
|
|
41
|
+
output = getPrintBuffer()
|
|
42
|
+
if (messages.length == tc.errors.length) {
|
|
43
|
+
if (tc.expected?.trim() == output.trim())
|
|
44
|
+
return
|
|
45
|
+
throw new Error('output mismatch:\n' + patch(tc.expected, output))
|
|
46
|
+
}
|
|
47
|
+
throw new Error('expected ' + tc.errors.length + ' errors, got ' + messages.length + '\n' + JSON.stringify(messages, null, 2))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function fail(count, code, expected) {
|
|
51
|
+
let errors
|
|
52
|
+
|
|
53
|
+
errors = []
|
|
54
|
+
while (count > 0) {
|
|
55
|
+
errors.push({ messageId: 'tooBroad' })
|
|
56
|
+
count--
|
|
57
|
+
}
|
|
58
|
+
invalidCases.push({ code, errors, expected })
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
pass('if (g) { let x = 0; x++; console.log(x); }',
|
|
62
|
+
`SCOPE 1 GLOBAL pos 0
|
|
63
|
+
SCOPE 1.1 MODULE pos 0
|
|
64
|
+
SCOPE 1.1.1 BLOCK pos 7
|
|
65
|
+
LET x pos 13
|
|
66
|
+
WRITE x pos 13.4
|
|
67
|
+
READ x pos 20
|
|
68
|
+
WRITE x pos 20
|
|
69
|
+
READ x pos 37`)
|
|
70
|
+
|
|
71
|
+
pass('let x = 0; x++; console.log(x);',
|
|
72
|
+
`SCOPE 1 GLOBAL pos 0
|
|
73
|
+
SCOPE 1.1 MODULE pos 0
|
|
74
|
+
LET x pos 4
|
|
75
|
+
WRITE x pos 4.4
|
|
76
|
+
READ x pos 11
|
|
77
|
+
WRITE x pos 11
|
|
78
|
+
READ x pos 28`)
|
|
79
|
+
|
|
80
|
+
pass('{ let x = 0; if (x) console.log(1); }',
|
|
81
|
+
`SCOPE 1 GLOBAL pos 0
|
|
82
|
+
SCOPE 1.1 MODULE pos 0
|
|
83
|
+
SCOPE 1.1.1 BLOCK pos 0
|
|
84
|
+
LET x pos 6
|
|
85
|
+
WRITE x pos 6.4
|
|
86
|
+
READ x pos 17`)
|
|
87
|
+
|
|
88
|
+
pass('let x = 0; x++; let y = x; console.log(y);',
|
|
89
|
+
`SCOPE 1 GLOBAL pos 0
|
|
90
|
+
SCOPE 1.1 MODULE pos 0
|
|
91
|
+
LET x pos 4
|
|
92
|
+
WRITE x pos 4.4
|
|
93
|
+
READ x pos 11
|
|
94
|
+
WRITE x pos 11
|
|
95
|
+
READ x pos 19.6
|
|
96
|
+
LET y pos 20
|
|
97
|
+
WRITE y pos 20.4
|
|
98
|
+
READ y pos 39`)
|
|
99
|
+
|
|
100
|
+
pass('let x = 0; x++; let y = x + 1; console.log(y);',
|
|
101
|
+
`SCOPE 1 GLOBAL pos 0
|
|
102
|
+
SCOPE 1.1 MODULE pos 0
|
|
103
|
+
LET x pos 4
|
|
104
|
+
WRITE x pos 4.4
|
|
105
|
+
READ x pos 11
|
|
106
|
+
WRITE x pos 11
|
|
107
|
+
READ x pos 19.6
|
|
108
|
+
LET y pos 20
|
|
109
|
+
WRITE y pos 20.4
|
|
110
|
+
READ y pos 43`)
|
|
111
|
+
|
|
112
|
+
pass('function foo() { let x; x = 1; return x }',
|
|
113
|
+
`SCOPE 1 GLOBAL pos 0
|
|
114
|
+
SCOPE 1.1 MODULE pos 0
|
|
115
|
+
LET foo pos 9
|
|
116
|
+
SCOPE 1.1.1 FUNCTION pos 12 name foo
|
|
117
|
+
LET x pos 21
|
|
118
|
+
WRITE x pos 29.4
|
|
119
|
+
READ x pos 38`)
|
|
120
|
+
|
|
121
|
+
pass('for (let i = 0; i < 10; i++) { console.log(i) }',
|
|
122
|
+
`SCOPE 1 GLOBAL pos 0
|
|
123
|
+
SCOPE 1.1 MODULE pos 0
|
|
124
|
+
SCOPE 1.1.1 FOR pos 0
|
|
125
|
+
LET i pos 9
|
|
126
|
+
WRITE i pos 9.4
|
|
127
|
+
READ i pos 16
|
|
128
|
+
READ i pos 24
|
|
129
|
+
WRITE i pos 24
|
|
130
|
+
SCOPE 1.1.1.1 BLOCK pos 29
|
|
131
|
+
READ i C pos 43`)
|
|
132
|
+
|
|
133
|
+
pass('function outer() { let x; function inner() { x = 1 } return x }',
|
|
134
|
+
`SCOPE 1 GLOBAL pos 0
|
|
135
|
+
SCOPE 1.1 MODULE pos 0
|
|
136
|
+
LET outer pos 9
|
|
137
|
+
SCOPE 1.1.1 FUNCTION pos 14 name outer
|
|
138
|
+
LET x pos 23
|
|
139
|
+
LET inner pos 35
|
|
140
|
+
SCOPE 1.1.1.1 FUNCTION pos 40 name inner
|
|
141
|
+
WRITE x pos 50.4
|
|
142
|
+
READ x pos 60`)
|
|
143
|
+
|
|
144
|
+
pass('let x; function foo() { x = 1 } function bar() { return x }',
|
|
145
|
+
`SCOPE 1 GLOBAL pos 0
|
|
146
|
+
SCOPE 1.1 MODULE pos 0
|
|
147
|
+
LET x pos 4
|
|
148
|
+
LET foo pos 16
|
|
149
|
+
SCOPE 1.1.1 FUNCTION pos 19 name foo
|
|
150
|
+
WRITE x pos 29.4
|
|
151
|
+
LET bar pos 41
|
|
152
|
+
SCOPE 1.1.2 FUNCTION pos 44 name bar
|
|
153
|
+
READ x pos 56`)
|
|
154
|
+
|
|
155
|
+
pass(`
|
|
156
|
+
function f(s1, s2, otherwise) {
|
|
157
|
+
let a, s
|
|
158
|
+
|
|
159
|
+
a = []
|
|
160
|
+
s = s1
|
|
161
|
+
while (s) {
|
|
162
|
+
if (s.done)
|
|
163
|
+
break
|
|
164
|
+
a.push(s)
|
|
165
|
+
s = s.next
|
|
166
|
+
}
|
|
167
|
+
s = s2
|
|
168
|
+
while (s) {
|
|
169
|
+
if (s.done)
|
|
170
|
+
break
|
|
171
|
+
if (a.includes(s))
|
|
172
|
+
return s
|
|
173
|
+
s = s.next
|
|
174
|
+
}
|
|
175
|
+
return otherwise
|
|
176
|
+
}
|
|
177
|
+
`,
|
|
178
|
+
`SCOPE 1 GLOBAL pos 1
|
|
179
|
+
SCOPE 1.1 MODULE pos 1
|
|
180
|
+
LET f pos 10
|
|
181
|
+
SCOPE 1.1.1 FUNCTION pos 11 name f
|
|
182
|
+
LET s1 pos 12
|
|
183
|
+
LET s2 pos 16
|
|
184
|
+
LET otherwise pos 20
|
|
185
|
+
LET a pos 39
|
|
186
|
+
LET s pos 42
|
|
187
|
+
WRITE a pos 53.4
|
|
188
|
+
READ s1 pos 60
|
|
189
|
+
WRITE s pos 62.4
|
|
190
|
+
READ s pos 72
|
|
191
|
+
SCOPE 1.1.1.1 BLOCK pos 75
|
|
192
|
+
READ s C pos 85
|
|
193
|
+
READ a C pos 109
|
|
194
|
+
READ s C pos 116
|
|
195
|
+
READ s C pos 127
|
|
196
|
+
WRITE s C pos 133.4
|
|
197
|
+
READ s2 pos 144
|
|
198
|
+
WRITE s pos 146.4
|
|
199
|
+
READ s pos 156
|
|
200
|
+
SCOPE 1.1.1.2 BLOCK pos 159
|
|
201
|
+
READ s C pos 169
|
|
202
|
+
READ a C pos 197
|
|
203
|
+
READ s C pos 208
|
|
204
|
+
READ s B C pos 225
|
|
205
|
+
READ s C pos 235
|
|
206
|
+
WRITE s C pos 241.4
|
|
207
|
+
READ otherwise pos 255`)
|
|
208
|
+
|
|
209
|
+
pass('import { a } from \'a.js\'; { a.f() }',
|
|
210
|
+
`SCOPE 1 GLOBAL pos 0
|
|
211
|
+
SCOPE 1.1 MODULE pos 0
|
|
212
|
+
LET a pos 9
|
|
213
|
+
SCOPE 1.1.1 BLOCK pos 26
|
|
214
|
+
READ a pos 28`)
|
|
215
|
+
|
|
216
|
+
pass('function foo() { return 1 } function bar() { return foo() }',
|
|
217
|
+
`SCOPE 1 GLOBAL pos 0
|
|
218
|
+
SCOPE 1.1 MODULE pos 0
|
|
219
|
+
LET foo pos 9
|
|
220
|
+
SCOPE 1.1.1 FUNCTION pos 12 name foo
|
|
221
|
+
LET bar pos 37
|
|
222
|
+
SCOPE 1.1.2 FUNCTION pos 40 name bar
|
|
223
|
+
READ foo pos 52`)
|
|
224
|
+
|
|
225
|
+
pass(`
|
|
226
|
+
let tout
|
|
227
|
+
|
|
228
|
+
function update
|
|
229
|
+
(view) {
|
|
230
|
+
if (tout)
|
|
231
|
+
clearTimeout(tout)
|
|
232
|
+
tout = setTimeout(() => console.log('hi'), 10000)
|
|
233
|
+
}
|
|
234
|
+
`,
|
|
235
|
+
`SCOPE 1 GLOBAL pos 1
|
|
236
|
+
SCOPE 1.1 MODULE pos 1
|
|
237
|
+
LET tout pos 5
|
|
238
|
+
LET update pos 20
|
|
239
|
+
SCOPE 1.1.1 FUNCTION pos 26 name update
|
|
240
|
+
LET view pos 28
|
|
241
|
+
READ tout pos 42
|
|
242
|
+
READ tout B C pos 65
|
|
243
|
+
SCOPE 1.1.1.1 FUNCTION pos 91
|
|
244
|
+
WRITE tout pos 122.4`)
|
|
245
|
+
|
|
246
|
+
pass(`
|
|
247
|
+
function init
|
|
248
|
+
() {
|
|
249
|
+
let out2
|
|
250
|
+
|
|
251
|
+
function update
|
|
252
|
+
(view) {
|
|
253
|
+
if (out2)
|
|
254
|
+
clearTimeout(out2)
|
|
255
|
+
out2 = setTimeout(() => console.log('hi'), 10000)
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
`,
|
|
259
|
+
`SCOPE 1 GLOBAL pos 1
|
|
260
|
+
SCOPE 1.1 MODULE pos 1
|
|
261
|
+
LET init pos 10
|
|
262
|
+
SCOPE 1.1.1 FUNCTION pos 14 name init
|
|
263
|
+
LET out2 pos 26
|
|
264
|
+
LET update pos 43
|
|
265
|
+
SCOPE 1.1.1.1 FUNCTION pos 49 name update
|
|
266
|
+
LET view pos 53
|
|
267
|
+
READ out2 pos 69
|
|
268
|
+
READ out2 B C pos 94
|
|
269
|
+
SCOPE 1.1.1.1.1 FUNCTION pos 122
|
|
270
|
+
WRITE out2 pos 153.4`)
|
|
271
|
+
|
|
272
|
+
pass(`
|
|
273
|
+
function init
|
|
274
|
+
() {
|
|
275
|
+
let stopTimeout
|
|
276
|
+
|
|
277
|
+
function f() {
|
|
278
|
+
if (stopTimeout) {
|
|
279
|
+
clearTimeout(stopTimeout)
|
|
280
|
+
stopTimeout = 0
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
console.log('Again to stop')
|
|
284
|
+
stopTimeout = setTimeout(() => {
|
|
285
|
+
stopTimeout = 0
|
|
286
|
+
console.log('stop timed out')
|
|
287
|
+
}, 5000)
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return f
|
|
292
|
+
}
|
|
293
|
+
`,
|
|
294
|
+
`SCOPE 1 GLOBAL pos 1
|
|
295
|
+
SCOPE 1.1 MODULE pos 1
|
|
296
|
+
LET init pos 10
|
|
297
|
+
SCOPE 1.1.1 FUNCTION pos 14 name init
|
|
298
|
+
LET stopTimeout pos 26
|
|
299
|
+
LET f pos 50
|
|
300
|
+
SCOPE 1.1.1.1 FUNCTION pos 51 name f
|
|
301
|
+
READ stopTimeout pos 64
|
|
302
|
+
SCOPE 1.1.1.1.1 BLOCK pos 77
|
|
303
|
+
READ stopTimeout C pos 98
|
|
304
|
+
WRITE stopTimeout C pos 132.4
|
|
305
|
+
SCOPE 1.1.1.1.2 BLOCK pos 148
|
|
306
|
+
SCOPE 1.1.1.1.2.1 FUNCTION pos 216
|
|
307
|
+
WRITE stopTimeout C pos 247.4
|
|
308
|
+
WRITE stopTimeout C pos 300.4
|
|
309
|
+
READ f pos 321`)
|
|
310
|
+
|
|
311
|
+
pass('try { f() } catch (err) { console.log(err.message) }',
|
|
312
|
+
`SCOPE 1 GLOBAL pos 0
|
|
313
|
+
SCOPE 1.1 MODULE pos 0
|
|
314
|
+
SCOPE 1.1.1 BLOCK pos 4
|
|
315
|
+
SCOPE 1.1.2 CATCH pos 12
|
|
316
|
+
LET err pos 19
|
|
317
|
+
SCOPE 1.1.2.1 BLOCK pos 24
|
|
318
|
+
READ err pos 38`)
|
|
319
|
+
|
|
320
|
+
pass(`
|
|
321
|
+
class A extends B {
|
|
322
|
+
constructor
|
|
323
|
+
(name) {
|
|
324
|
+
super()
|
|
325
|
+
this.name = name
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
update
|
|
329
|
+
(state) {
|
|
330
|
+
if (state.docChanged)
|
|
331
|
+
console.log('yes')
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
g = f({ a() { return new A('eg') } })
|
|
336
|
+
`,
|
|
337
|
+
`SCOPE 1 GLOBAL pos 3
|
|
338
|
+
SCOPE 1.1 MODULE pos 3
|
|
339
|
+
LET A pos 9
|
|
340
|
+
SCOPE 1.1.1 CLASS pos 9 name A
|
|
341
|
+
LET A pos 9
|
|
342
|
+
SCOPE 1.1.1.1 FUNCTION pos 43 name constructor
|
|
343
|
+
LET name pos 44
|
|
344
|
+
READ name pos 84
|
|
345
|
+
SCOPE 1.1.1.2 FUNCTION pos 111 name update
|
|
346
|
+
LET state pos 112
|
|
347
|
+
READ state pos 131
|
|
348
|
+
SCOPE 1.1.2 FUNCTION pos 198 name a
|
|
349
|
+
READ A pos 214`)
|
|
350
|
+
|
|
351
|
+
pass(`
|
|
352
|
+
let clen
|
|
353
|
+
|
|
354
|
+
function parse
|
|
355
|
+
() {
|
|
356
|
+
if (maybe())
|
|
357
|
+
clen = get()
|
|
358
|
+
|
|
359
|
+
if (check(clen)) {
|
|
360
|
+
run()
|
|
361
|
+
clen = 0
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
`,
|
|
365
|
+
`SCOPE 1 GLOBAL pos 1
|
|
366
|
+
SCOPE 1.1 MODULE pos 1
|
|
367
|
+
LET clen pos 5
|
|
368
|
+
LET parse pos 20
|
|
369
|
+
SCOPE 1.1.1 FUNCTION pos 25 name parse
|
|
370
|
+
WRITE clen B C pos 62.4
|
|
371
|
+
READ clen pos 76
|
|
372
|
+
SCOPE 1.1.1.1 BLOCK pos 83
|
|
373
|
+
WRITE clen C pos 107.4`)
|
|
374
|
+
|
|
375
|
+
pass(`
|
|
376
|
+
function make
|
|
377
|
+
() {
|
|
378
|
+
let clen
|
|
379
|
+
|
|
380
|
+
function parse
|
|
381
|
+
() {
|
|
382
|
+
while (1) {
|
|
383
|
+
if (maybe())
|
|
384
|
+
clen = get()
|
|
385
|
+
|
|
386
|
+
if (check(clen)) {
|
|
387
|
+
run()
|
|
388
|
+
clen = undefined
|
|
389
|
+
}
|
|
390
|
+
else
|
|
391
|
+
break
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return 0
|
|
396
|
+
}
|
|
397
|
+
`,
|
|
398
|
+
`SCOPE 1 GLOBAL pos 1
|
|
399
|
+
SCOPE 1.1 MODULE pos 1
|
|
400
|
+
LET make pos 10
|
|
401
|
+
SCOPE 1.1.1 FUNCTION pos 14 name make
|
|
402
|
+
LET clen pos 26
|
|
403
|
+
LET parse pos 43
|
|
404
|
+
SCOPE 1.1.1.1 FUNCTION pos 48 name parse
|
|
405
|
+
SCOPE 1.1.1.1.1 BLOCK pos 70
|
|
406
|
+
WRITE clen B C pos 111.4
|
|
407
|
+
READ clen pos 129
|
|
408
|
+
SCOPE 1.1.1.1.1.1 BLOCK pos 136
|
|
409
|
+
READ undefined pos 167
|
|
410
|
+
WRITE clen C pos 176.4`)
|
|
411
|
+
|
|
412
|
+
pass(`
|
|
413
|
+
function initMouse
|
|
414
|
+
() {
|
|
415
|
+
let hover
|
|
416
|
+
|
|
417
|
+
function updateHover
|
|
418
|
+
() {
|
|
419
|
+
if (maybe()) {
|
|
420
|
+
hover = 1
|
|
421
|
+
}
|
|
422
|
+
else if (hover) {
|
|
423
|
+
hover = 0
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
`,
|
|
428
|
+
`SCOPE 1 GLOBAL pos 1
|
|
429
|
+
SCOPE 1.1 MODULE pos 1
|
|
430
|
+
LET initMouse pos 10
|
|
431
|
+
SCOPE 1.1.1 FUNCTION pos 19 name initMouse
|
|
432
|
+
LET hover pos 31
|
|
433
|
+
LET updateHover pos 49
|
|
434
|
+
SCOPE 1.1.1.1 FUNCTION pos 60 name updateHover
|
|
435
|
+
SCOPE 1.1.1.1.1 BLOCK pos 85
|
|
436
|
+
WRITE hover C pos 102.4
|
|
437
|
+
READ hover B C pos 122
|
|
438
|
+
SCOPE 1.1.1.1.2 BLOCK pos 129
|
|
439
|
+
WRITE hover C pos 146.4`)
|
|
440
|
+
|
|
441
|
+
pass(`
|
|
442
|
+
export let wexts
|
|
443
|
+
|
|
444
|
+
export
|
|
445
|
+
function init
|
|
446
|
+
() {
|
|
447
|
+
wexts = Mk.array
|
|
448
|
+
}
|
|
449
|
+
`,
|
|
450
|
+
`SCOPE 1 GLOBAL pos 1
|
|
451
|
+
SCOPE 1.1 MODULE pos 1
|
|
452
|
+
LET wexts pos 12
|
|
453
|
+
LET init pos 35
|
|
454
|
+
SCOPE 1.1.1 FUNCTION pos 39 name init
|
|
455
|
+
WRITE wexts pos 63.4`)
|
|
456
|
+
|
|
457
|
+
pass(`
|
|
458
|
+
let classCache
|
|
459
|
+
|
|
460
|
+
export
|
|
461
|
+
function add
|
|
462
|
+
() {
|
|
463
|
+
classCache = classCache || new Map()
|
|
464
|
+
}
|
|
465
|
+
`,
|
|
466
|
+
`SCOPE 1 GLOBAL pos 1
|
|
467
|
+
SCOPE 1.1 MODULE pos 1
|
|
468
|
+
LET classCache pos 5
|
|
469
|
+
LET add pos 33
|
|
470
|
+
SCOPE 1.1.1 FUNCTION pos 36 name add
|
|
471
|
+
READ classCache pos 57
|
|
472
|
+
READ Map pos 75
|
|
473
|
+
WRITE classCache pos 80.4`)
|
|
474
|
+
|
|
475
|
+
fail(1, 'let x = 1; function foo() { return x }',
|
|
476
|
+
`SCOPE 1 GLOBAL pos 0
|
|
477
|
+
SCOPE 1.1 MODULE pos 0
|
|
478
|
+
LET x pos 4
|
|
479
|
+
WRITE x pos 4.4
|
|
480
|
+
LET foo pos 20
|
|
481
|
+
SCOPE 1.1.1 FUNCTION pos 23 name foo
|
|
482
|
+
READ x pos 35`)
|
|
483
|
+
|
|
484
|
+
fail(1, 'let x; { let y = 1; x = y }',
|
|
485
|
+
`SCOPE 1 GLOBAL pos 0
|
|
486
|
+
SCOPE 1.1 MODULE pos 0
|
|
487
|
+
LET x pos 4
|
|
488
|
+
SCOPE 1.1.1 BLOCK pos 7
|
|
489
|
+
LET y pos 13
|
|
490
|
+
WRITE y pos 13.4
|
|
491
|
+
READ y pos 24
|
|
492
|
+
WRITE x pos 25.4`)
|
|
493
|
+
|
|
494
|
+
fail(2, `
|
|
495
|
+
function f
|
|
496
|
+
(a, b, otherwise) {
|
|
497
|
+
let c1, c2, ok
|
|
498
|
+
|
|
499
|
+
if (a)
|
|
500
|
+
ok = 4
|
|
501
|
+
else
|
|
502
|
+
ok = 1
|
|
503
|
+
|
|
504
|
+
if (b) {
|
|
505
|
+
c1 = 2
|
|
506
|
+
b.forEach(d => {
|
|
507
|
+
c1 += d
|
|
508
|
+
})
|
|
509
|
+
return c1
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
{
|
|
513
|
+
c2 = ok
|
|
514
|
+
c2 += ok * ok
|
|
515
|
+
if (c2 > 22)
|
|
516
|
+
return ok
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return otherwise
|
|
520
|
+
}
|
|
521
|
+
`,
|
|
522
|
+
`SCOPE 1 GLOBAL pos 1
|
|
523
|
+
SCOPE 1.1 MODULE pos 1
|
|
524
|
+
LET f pos 10
|
|
525
|
+
SCOPE 1.1.1 FUNCTION pos 11 name f
|
|
526
|
+
LET a pos 13
|
|
527
|
+
LET b pos 16
|
|
528
|
+
LET otherwise pos 19
|
|
529
|
+
LET c1 pos 38
|
|
530
|
+
LET c2 pos 42
|
|
531
|
+
LET ok pos 46
|
|
532
|
+
READ a pos 56
|
|
533
|
+
WRITE ok B C pos 69.4
|
|
534
|
+
WRITE ok B C pos 87.4
|
|
535
|
+
READ b pos 95
|
|
536
|
+
SCOPE 1.1.1.1 BLOCK pos 98
|
|
537
|
+
WRITE c1 pos 110.4
|
|
538
|
+
READ b pos 115
|
|
539
|
+
SCOPE 1.1.1.1.1 FUNCTION pos 125
|
|
540
|
+
LET d pos 125
|
|
541
|
+
READ d pos 144
|
|
542
|
+
WRITE c1 pos 145.4
|
|
543
|
+
READ c1 pos 164
|
|
544
|
+
SCOPE 1.1.1.2 BLOCK pos 174
|
|
545
|
+
READ ok pos 185
|
|
546
|
+
WRITE c2 pos 187.4
|
|
547
|
+
READ ok pos 198
|
|
548
|
+
READ ok pos 203
|
|
549
|
+
WRITE c2 pos 205.4
|
|
550
|
+
READ c2 pos 214
|
|
551
|
+
READ ok B C pos 236
|
|
552
|
+
READ otherwise pos 253`)
|
|
553
|
+
|
|
554
|
+
fail(1, 'let a; try { f() } catch (err) { a = err.message; console.log(a) }',
|
|
555
|
+
`SCOPE 1 GLOBAL pos 0
|
|
556
|
+
SCOPE 1.1 MODULE pos 0
|
|
557
|
+
LET a pos 4
|
|
558
|
+
SCOPE 1.1.1 BLOCK pos 11
|
|
559
|
+
SCOPE 1.1.2 CATCH pos 19
|
|
560
|
+
LET err pos 26
|
|
561
|
+
SCOPE 1.1.2.1 BLOCK pos 31
|
|
562
|
+
READ err pos 37
|
|
563
|
+
WRITE a pos 48.4
|
|
564
|
+
READ a pos 62`)
|
|
565
|
+
|
|
566
|
+
globalThis.describe('narrowest-scope', () => {
|
|
567
|
+
for (let tc of validCases)
|
|
568
|
+
globalThis.it(tc.code, () => _pass(tc))
|
|
569
|
+
for (let tc of invalidCases)
|
|
570
|
+
globalThis.it(tc.code, () => _fail(tc))
|
|
571
|
+
})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { RuleTester } from 'eslint'
|
|
2
|
+
import { plugins } from '../../index.js'
|
|
3
|
+
|
|
4
|
+
let ruleTester, validCases, invalidCases
|
|
5
|
+
|
|
6
|
+
ruleTester = new RuleTester()
|
|
7
|
+
validCases = []
|
|
8
|
+
invalidCases = []
|
|
9
|
+
|
|
10
|
+
function pass
|
|
11
|
+
(code) {
|
|
12
|
+
validCases.push({ code })
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function fail
|
|
16
|
+
(messageId, code) {
|
|
17
|
+
invalidCases.push({ code, errors: [ { messageId } ] })
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
pass('if (x) { }')
|
|
21
|
+
|
|
22
|
+
fail('positiveVibes', 'if (!x) { }')
|
|
23
|
+
|
|
24
|
+
fail('equality', 'if (x != y) { }')
|
|
25
|
+
|
|
26
|
+
fail('strictEquality', 'if (x !== y) { }')
|
|
27
|
+
|
|
28
|
+
fail('equality', 'function f(x, y) { return x != y }')
|
|
29
|
+
|
|
30
|
+
globalThis.describe('positive-vibes',
|
|
31
|
+
() => ruleTester.run('positive-vibes',
|
|
32
|
+
plugins.cookshack.rules['positive-vibes'],
|
|
33
|
+
{ valid: validCases,
|
|
34
|
+
invalid: invalidCases }))
|