Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epidemian
GitHub Repository: epidemian/eslint-plugin-import
Path: blob/main/tests/src/rules/extensions.js
829 views
1
import { RuleTester } from 'eslint';
2
import rule from 'rules/extensions';
3
import { getTSParsers, test, testFilePath } from '../utils';
4
5
const ruleTester = new RuleTester();
6
7
ruleTester.run('extensions', rule, {
8
valid: [
9
test({ code: 'import a from "@/a"' }),
10
test({ code: 'import a from "a"' }),
11
test({ code: 'import dot from "./file.with.dot"' }),
12
test({
13
code: 'import a from "a/index.js"',
14
options: [ 'always' ],
15
}),
16
test({
17
code: 'import dot from "./file.with.dot.js"',
18
options: [ 'always' ],
19
}),
20
test({
21
code: [
22
'import a from "a"',
23
'import packageConfig from "./package.json"',
24
].join('\n'),
25
options: [ { json: 'always', js: 'never' } ],
26
}),
27
test({
28
code: [
29
'import lib from "./bar"',
30
'import component from "./bar.jsx"',
31
'import data from "./bar.json"',
32
].join('\n'),
33
options: [ 'never' ],
34
settings: { 'import/resolve': { 'extensions': [ '.js', '.jsx', '.json' ] } },
35
}),
36
37
test({
38
code: [
39
'import bar from "./bar"',
40
'import barjson from "./bar.json"',
41
'import barhbs from "./bar.hbs"',
42
].join('\n'),
43
options: [ 'always', { js: 'never', jsx: 'never' } ],
44
settings: { 'import/resolve': { 'extensions': [ '.js', '.jsx', '.json', '.hbs' ] } },
45
}),
46
47
test({
48
code: [
49
'import bar from "./bar.js"',
50
'import pack from "./package"',
51
].join('\n'),
52
options: [ 'never', { js: 'always', json: 'never' } ],
53
settings: { 'import/resolve': { 'extensions': [ '.js', '.json' ] } },
54
}),
55
56
// unresolved (#271/#295)
57
test({ code: 'import path from "path"' }),
58
test({ code: 'import path from "path"', options: [ 'never' ] }),
59
test({ code: 'import path from "path"', options: [ 'always' ] }),
60
test({ code: 'import thing from "./fake-file.js"', options: [ 'always' ] }),
61
test({ code: 'import thing from "non-package"', options: [ 'never' ] }),
62
63
test({
64
code: `
65
import foo from './foo.js'
66
import bar from './bar.json'
67
import Component from './Component.jsx'
68
import express from 'express'
69
`,
70
options: [ 'ignorePackages' ],
71
}),
72
73
test({
74
code: `
75
import foo from './foo.js'
76
import bar from './bar.json'
77
import Component from './Component.jsx'
78
import express from 'express'
79
`,
80
options: [ 'always', { ignorePackages: true } ],
81
}),
82
83
test({
84
code: `
85
import foo from './foo'
86
import bar from './bar'
87
import Component from './Component'
88
import express from 'express'
89
`,
90
options: [ 'never', { ignorePackages: true } ],
91
}),
92
93
test({
94
code: 'import exceljs from "exceljs"',
95
options: [ 'always', { js: 'never', jsx: 'never' } ],
96
filename: testFilePath('./internal-modules/plugins/plugin.js'),
97
settings: {
98
'import/resolver': {
99
'node': { 'extensions': [ '.js', '.jsx', '.json' ] },
100
'webpack': { 'config': 'webpack.empty.config.js' },
101
},
102
},
103
}),
104
105
// export (#964)
106
test({
107
code: [
108
'export { foo } from "./foo.js"',
109
'let bar; export { bar }',
110
].join('\n'),
111
options: [ 'always' ],
112
}),
113
test({
114
code: [
115
'export { foo } from "./foo"',
116
'let bar; export { bar }',
117
].join('\n'),
118
options: [ 'never' ],
119
}),
120
121
// Root packages should be ignored and they are names not files
122
test({
123
code: [
124
'import lib from "pkg.js"',
125
'import lib2 from "pgk/package"',
126
'import lib3 from "@name/pkg.js"',
127
].join('\n'),
128
options: [ 'never' ],
129
}),
130
131
// Query strings.
132
test({
133
code: 'import bare from "./foo?a=True.ext"',
134
options: [ 'never' ],
135
}),
136
test({
137
code: 'import bare from "./foo.js?a=True"',
138
options: [ 'always' ],
139
}),
140
141
test({
142
code: [
143
'import lib from "pkg"',
144
'import lib2 from "pgk/package.js"',
145
'import lib3 from "@name/pkg"',
146
].join('\n'),
147
options: [ 'always' ],
148
}),
149
],
150
151
invalid: [
152
test({
153
code: 'import a from "a/index.js"',
154
errors: [ {
155
message: 'Unexpected use of file extension "js" for "a/index.js"',
156
line: 1,
157
column: 15,
158
} ],
159
}),
160
test({
161
code: 'import dot from "./file.with.dot"',
162
options: [ 'always' ],
163
errors: [
164
{
165
message: 'Missing file extension "js" for "./file.with.dot"',
166
line: 1,
167
column: 17,
168
},
169
],
170
}),
171
test({
172
code: [
173
'import a from "a/index.js"',
174
'import packageConfig from "./package"',
175
].join('\n'),
176
options: [ { json: 'always', js: 'never' } ],
177
settings: { 'import/resolve': { 'extensions': [ '.js', '.json' ] } },
178
errors: [
179
{
180
message: 'Unexpected use of file extension "js" for "a/index.js"',
181
line: 1,
182
column: 15,
183
},
184
{
185
message: 'Missing file extension "json" for "./package"',
186
line: 2,
187
column: 27,
188
},
189
],
190
}),
191
test({
192
code: [
193
'import lib from "./bar.js"',
194
'import component from "./bar.jsx"',
195
'import data from "./bar.json"',
196
].join('\n'),
197
options: [ 'never' ],
198
settings: { 'import/resolve': { 'extensions': [ '.js', '.jsx', '.json' ] } },
199
errors: [
200
{
201
message: 'Unexpected use of file extension "js" for "./bar.js"',
202
line: 1,
203
column: 17,
204
},
205
],
206
}),
207
test({
208
code: [
209
'import lib from "./bar.js"',
210
'import component from "./bar.jsx"',
211
'import data from "./bar.json"',
212
].join('\n'),
213
options: [ { json: 'always', js: 'never', jsx: 'never' } ],
214
settings: { 'import/resolve': { 'extensions': [ '.js', '.jsx', '.json' ] } },
215
errors: [
216
{
217
message: 'Unexpected use of file extension "js" for "./bar.js"',
218
line: 1,
219
column: 17,
220
},
221
],
222
}),
223
// extension resolve order (#583/#965)
224
test({
225
code: [
226
'import component from "./bar.jsx"',
227
'import data from "./bar.json"',
228
].join('\n'),
229
options: [ { json: 'always', js: 'never', jsx: 'never' } ],
230
settings: { 'import/resolve': { 'extensions': [ '.jsx', '.json', '.js' ] } },
231
errors: [
232
{
233
message: 'Unexpected use of file extension "jsx" for "./bar.jsx"',
234
line: 1,
235
column: 23,
236
},
237
],
238
}),
239
test({
240
code: 'import "./bar.coffee"',
241
errors: [
242
{
243
message: 'Unexpected use of file extension "coffee" for "./bar.coffee"',
244
line: 1,
245
column: 8,
246
},
247
],
248
options: ['never', { js: 'always', jsx: 'always' }],
249
settings: { 'import/resolve': { 'extensions': ['.coffee', '.js'] } },
250
}),
251
252
test({
253
code: [
254
'import barjs from "./bar.js"',
255
'import barjson from "./bar.json"',
256
'import barnone from "./bar"',
257
].join('\n'),
258
options: [ 'always', { json: 'always', js: 'never', jsx: 'never' } ],
259
settings: { 'import/resolve': { 'extensions': [ '.js', '.jsx', '.json' ] } },
260
errors: [
261
{
262
message: 'Unexpected use of file extension "js" for "./bar.js"',
263
line: 1,
264
column: 19,
265
},
266
],
267
}),
268
269
test({
270
code: [
271
'import barjs from "./bar.js"',
272
'import barjson from "./bar.json"',
273
'import barnone from "./bar"',
274
].join('\n'),
275
options: [ 'never', { json: 'always', js: 'never', jsx: 'never' } ],
276
settings: { 'import/resolve': { 'extensions': [ '.js', '.jsx', '.json' ] } },
277
errors: [
278
{
279
message: 'Unexpected use of file extension "js" for "./bar.js"',
280
line: 1,
281
column: 19,
282
},
283
],
284
}),
285
286
// unresolved (#271/#295)
287
test({
288
code: 'import thing from "./fake-file.js"',
289
options: [ 'never' ],
290
errors: [
291
{
292
message: 'Unexpected use of file extension "js" for "./fake-file.js"',
293
line: 1,
294
column: 19,
295
},
296
],
297
}),
298
test({
299
code: 'import thing from "non-package/test"',
300
options: [ 'always' ],
301
errors: [
302
{
303
message: 'Missing file extension for "non-package/test"',
304
line: 1,
305
column: 19,
306
},
307
],
308
}),
309
310
test({
311
code: 'import thing from "@name/pkg/test"',
312
options: [ 'always' ],
313
errors: [
314
{
315
message: 'Missing file extension for "@name/pkg/test"',
316
line: 1,
317
column: 19,
318
},
319
],
320
}),
321
322
test({
323
code: 'import thing from "@name/pkg/test.js"',
324
options: [ 'never' ],
325
errors: [
326
{
327
message: 'Unexpected use of file extension "js" for "@name/pkg/test.js"',
328
line: 1,
329
column: 19,
330
},
331
],
332
}),
333
334
335
test({
336
code: `
337
import foo from './foo.js'
338
import bar from './bar.json'
339
import Component from './Component'
340
import baz from 'foo/baz'
341
import baw from '@scoped/baw/import'
342
import chart from '@/configs/chart'
343
import express from 'express'
344
`,
345
options: [ 'always', { ignorePackages: true } ],
346
errors: [
347
{
348
message: 'Missing file extension for "./Component"',
349
line: 4,
350
column: 31,
351
},
352
{
353
message: 'Missing file extension for "@/configs/chart"',
354
line: 7,
355
column: 27,
356
},
357
],
358
}),
359
360
test({
361
code: `
362
import foo from './foo.js'
363
import bar from './bar.json'
364
import Component from './Component'
365
import baz from 'foo/baz'
366
import baw from '@scoped/baw/import'
367
import chart from '@/configs/chart'
368
import express from 'express'
369
`,
370
options: [ 'ignorePackages' ],
371
errors: [
372
{
373
message: 'Missing file extension for "./Component"',
374
line: 4,
375
column: 31,
376
},
377
{
378
message: 'Missing file extension for "@/configs/chart"',
379
line: 7,
380
column: 27,
381
},
382
],
383
}),
384
385
test({
386
code: `
387
import foo from './foo.js'
388
import bar from './bar.json'
389
import Component from './Component.jsx'
390
import express from 'express'
391
`,
392
errors: [
393
{
394
message: 'Unexpected use of file extension "js" for "./foo.js"',
395
line: 2,
396
column: 25,
397
}, {
398
message: 'Unexpected use of file extension "jsx" for "./Component.jsx"',
399
line: 4,
400
column: 31,
401
},
402
],
403
options: [ 'never', { ignorePackages: true } ],
404
}),
405
406
test({
407
code: `
408
import foo from './foo.js'
409
import bar from './bar.json'
410
import Component from './Component.jsx'
411
`,
412
errors: [
413
{
414
message: 'Unexpected use of file extension "jsx" for "./Component.jsx"',
415
line: 4,
416
column: 31,
417
},
418
],
419
options: [ 'always', { pattern: { jsx: 'never' } } ],
420
}),
421
422
// export (#964)
423
test({
424
code: [
425
'export { foo } from "./foo"',
426
'let bar; export { bar }',
427
].join('\n'),
428
options: [ 'always' ],
429
errors: [
430
{
431
message: 'Missing file extension for "./foo"',
432
line: 1,
433
column: 21,
434
},
435
],
436
}),
437
test({
438
code: [
439
'export { foo } from "./foo.js"',
440
'let bar; export { bar }',
441
].join('\n'),
442
options: [ 'never' ],
443
errors: [
444
{
445
message: 'Unexpected use of file extension "js" for "./foo.js"',
446
line: 1,
447
column: 21,
448
},
449
],
450
}),
451
452
// Query strings.
453
test({
454
code: 'import withExtension from "./foo.js?a=True"',
455
options: [ 'never' ],
456
errors: [
457
{
458
message: 'Unexpected use of file extension "js" for "./foo.js?a=True"',
459
line: 1,
460
column: 27,
461
},
462
],
463
}),
464
test({
465
code: 'import withoutExtension from "./foo?a=True.ext"',
466
options: [ 'always' ],
467
errors: [
468
{
469
message: 'Missing file extension for "./foo?a=True.ext"',
470
line: 1,
471
column: 30,
472
},
473
],
474
}),
475
// require (#1230)
476
test({
477
code: [
478
'const { foo } = require("./foo")',
479
'export { foo }',
480
].join('\n'),
481
options: [ 'always' ],
482
errors: [
483
{
484
message: 'Missing file extension for "./foo"',
485
line: 1,
486
column: 25,
487
},
488
],
489
}),
490
test({
491
code: [
492
'const { foo } = require("./foo.js")',
493
'export { foo }',
494
].join('\n'),
495
options: [ 'never' ],
496
errors: [
497
{
498
message: 'Unexpected use of file extension "js" for "./foo.js"',
499
line: 1,
500
column: 25,
501
},
502
],
503
}),
504
505
// export { } from
506
test({
507
code: 'export { foo } from "./foo"',
508
options: [ 'always' ],
509
errors: [
510
{
511
message: 'Missing file extension for "./foo"',
512
line: 1,
513
column: 21,
514
},
515
],
516
}),
517
test({
518
code: `
519
import foo from "@/ImNotAScopedModule";
520
import chart from '@/configs/chart';
521
`,
522
options: ['always'],
523
errors: [
524
{
525
message: 'Missing file extension for "@/ImNotAScopedModule"',
526
line: 2,
527
},
528
{
529
message: 'Missing file extension for "@/configs/chart"',
530
line: 3,
531
},
532
],
533
}),
534
test({
535
code: 'export { foo } from "./foo.js"',
536
options: [ 'never' ],
537
errors: [
538
{
539
message: 'Unexpected use of file extension "js" for "./foo.js"',
540
line: 1,
541
column: 21,
542
},
543
],
544
}),
545
546
// export * from
547
test({
548
code: 'export * from "./foo"',
549
options: [ 'always' ],
550
errors: [
551
{
552
message: 'Missing file extension for "./foo"',
553
line: 1,
554
column: 15,
555
},
556
],
557
}),
558
test({
559
code: 'export * from "./foo.js"',
560
options: [ 'never' ],
561
errors: [
562
{
563
message: 'Unexpected use of file extension "js" for "./foo.js"',
564
line: 1,
565
column: 15,
566
},
567
],
568
}),
569
test({
570
code: 'import foo from "@/ImNotAScopedModule.js"',
571
options: ['never'],
572
errors: [
573
{
574
message: 'Unexpected use of file extension "js" for "@/ImNotAScopedModule.js"',
575
line: 1,
576
},
577
],
578
}),
579
test({
580
code: `
581
import _ from 'lodash';
582
import m from '@test-scope/some-module/index.js';
583
584
import bar from './bar';
585
`,
586
options: ['never'],
587
settings: {
588
'import/resolver': 'webpack',
589
'import/external-module-folders': ['node_modules', 'symlinked-module'],
590
},
591
errors: [
592
{
593
message: 'Unexpected use of file extension "js" for "@test-scope/some-module/index.js"',
594
line: 3,
595
},
596
],
597
}),
598
],
599
});
600
601
describe('TypeScript', () => {
602
getTSParsers()
603
// Type-only imports were added in TypeScript ESTree 2.23.0
604
.filter((parser) => parser !== require.resolve('typescript-eslint-parser'))
605
.forEach((parser) => {
606
ruleTester.run(`${parser}: extensions ignore type-only`, rule, {
607
valid: [
608
test({
609
code: 'import type T from "./typescript-declare";',
610
options: [
611
'always',
612
{ ts: 'never', tsx: 'never', js: 'never', jsx: 'never' },
613
],
614
parser,
615
}),
616
],
617
invalid: [
618
test({
619
code: 'import T from "./typescript-declare";',
620
errors: ['Missing file extension for "./typescript-declare"'],
621
options: [
622
'always',
623
{ ts: 'never', tsx: 'never', js: 'never', jsx: 'never' },
624
],
625
parser,
626
}),
627
],
628
});
629
});
630
});
631
632