Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epidemian
GitHub Repository: epidemian/eslint-plugin-import
Path: blob/main/tests/src/rules/export.js
829 views
1
import { test, testFilePath, SYNTAX_CASES, getTSParsers, testVersion } from '../utils';
2
3
import { RuleTester } from 'eslint';
4
import eslintPkg from 'eslint/package.json';
5
import semver from 'semver';
6
7
const ruleTester = new RuleTester();
8
const rule = require('rules/export');
9
10
ruleTester.run('export', rule, {
11
valid: [].concat(
12
test({ code: 'import "./malformed.js"' }),
13
14
// default
15
test({ code: 'var foo = "foo"; export default foo;' }),
16
test({ code: 'export var foo = "foo"; export var bar = "bar";' }),
17
test({ code: 'export var foo = "foo", bar = "bar";' }),
18
test({ code: 'export var { foo, bar } = object;' }),
19
test({ code: 'export var [ foo, bar ] = array;' }),
20
test({ code: 'let foo; export { foo, foo as bar }' }),
21
test({ code: 'let bar; export { bar }; export * from "./export-all"' }),
22
test({ code: 'export * from "./export-all"' }),
23
test({ code: 'export * from "./does-not-exist"' }),
24
25
// #328: "export * from" does not export a default
26
test({ code: 'export default foo; export * from "./bar"' }),
27
28
...SYNTAX_CASES,
29
30
test({
31
code: `
32
import * as A from './named-export-collision/a';
33
import * as B from './named-export-collision/b';
34
35
export { A, B };
36
`,
37
}),
38
testVersion('>= 6', () => ({
39
code: `
40
export * as A from './named-export-collision/a';
41
export * as B from './named-export-collision/b';
42
`,
43
parserOptions: {
44
ecmaVersion: 2020,
45
},
46
})) || [],
47
),
48
49
invalid: [
50
// multiple defaults
51
// test({
52
// code: 'export default foo; export default bar',
53
// errors: ['Multiple default exports.', 'Multiple default exports.'],
54
// }),
55
// test({
56
// code: 'export default function foo() {}; ' +
57
// 'export default function bar() {}',
58
// errors: ['Multiple default exports.', 'Multiple default exports.'],
59
// }),
60
61
// test({
62
// code: 'export function foo() {}; ' +
63
// 'export { bar as foo }',
64
// errors: ['Parsing error: Duplicate export \'foo\''],
65
// }),
66
// test({
67
// code: 'export {foo}; export {foo};',
68
// errors: ['Parsing error: Duplicate export \'foo\''],
69
// }),
70
// test({
71
// code: 'export {foo}; export {bar as foo};',
72
// errors: ['Parsing error: Duplicate export \'foo\''],
73
// }),
74
// test({
75
// code: 'export var foo = "foo"; export var foo = "bar";',
76
// errors: ['Parsing error: Duplicate export \'foo\''],
77
// }),
78
// test({
79
// code: 'export var foo = "foo", foo = "bar";',
80
// errors: ['Parsing error: Duplicate export \'foo\''],
81
// }),
82
test({
83
code: 'let foo; export { foo }; export * from "./export-all"',
84
errors: ['Multiple exports of name \'foo\'.',
85
'Multiple exports of name \'foo\'.'],
86
}),
87
// test({ code: 'export * from "./default-export"'
88
// , errors: [{ message: 'No named exports found in module ' +
89
// '\'./default-export\'.'
90
// , type: 'Literal' }] }),
91
92
// note: Espree bump to Acorn 4+ changed this test's error message.
93
// `npm up` first if it's failing.
94
test({
95
code: 'export * from "./malformed.js"',
96
errors: [{
97
message: "Parse errors in imported module './malformed.js': 'return' outside of function (1:1)",
98
type: 'Literal',
99
}],
100
}),
101
102
// test({
103
// code: 'export var { foo, bar } = object; export var foo = "bar"',
104
// errors: ['Parsing error: Duplicate export \'foo\''],
105
// }),
106
// test({
107
// code: 'export var { bar: { foo } } = object; export var foo = "bar"',
108
// errors: ['Parsing error: Duplicate export \'foo\''],
109
// }),
110
// test({
111
// code: 'export var [ foo, bar ] = array; export var bar = "baz"',
112
// errors: ['Parsing error: Duplicate export \'bar\''],
113
// }),
114
// test({
115
// code: 'export var [ foo, /*sparse*/, { bar } ] = array; export var bar = "baz"',
116
// errors: ['Parsing error: Duplicate export \'bar\''],
117
// }),
118
119
120
// #328: "export * from" does not export a default
121
test({
122
code: 'export * from "./default-export"',
123
errors: [`No named exports found in module './default-export'.`],
124
}),
125
],
126
});
127
128
129
context('TypeScript', function () {
130
getTSParsers().forEach((parser) => {
131
const parserConfig = {
132
parser,
133
settings: {
134
'import/parsers': { [parser]: ['.ts'] },
135
'import/resolver': { 'eslint-import-resolver-typescript': true },
136
},
137
};
138
139
ruleTester.run('export', rule, {
140
valid: [
141
// type/value name clash
142
test(Object.assign({
143
code: `
144
export const Foo = 1;
145
export type Foo = number;
146
`,
147
}, parserConfig)),
148
test(Object.assign({
149
code: `
150
export const Foo = 1;
151
export interface Foo {}
152
`,
153
}, parserConfig)),
154
155
test(Object.assign({
156
code: `
157
export function fff(a: string);
158
export function fff(a: number);
159
`,
160
}, parserConfig)),
161
162
test(Object.assign({
163
code: `
164
export function fff(a: string);
165
export function fff(a: number);
166
export function fff(a: string|number) {};
167
`,
168
}, parserConfig)),
169
170
// namespace
171
test(Object.assign({
172
code: `
173
export const Bar = 1;
174
export namespace Foo {
175
export const Bar = 1;
176
}
177
`,
178
}, parserConfig)),
179
test(Object.assign({
180
code: `
181
export type Bar = string;
182
export namespace Foo {
183
export type Bar = string;
184
}
185
`,
186
}, parserConfig)),
187
test(Object.assign({
188
code: `
189
export const Bar = 1;
190
export type Bar = string;
191
export namespace Foo {
192
export const Bar = 1;
193
export type Bar = string;
194
}
195
`,
196
}, parserConfig)),
197
test(Object.assign({
198
code: `
199
export namespace Foo {
200
export const Foo = 1;
201
export namespace Bar {
202
export const Foo = 2;
203
}
204
export namespace Baz {
205
export const Foo = 3;
206
}
207
}
208
`,
209
}, parserConfig)),
210
test(Object.assign({
211
code: 'export * from "./file1.ts"',
212
filename: testFilePath('typescript-d-ts/file-2.ts'),
213
}, parserConfig)),
214
215
...(semver.satisfies(eslintPkg.version, '< 6') ? [] : [
216
test({
217
code: `
218
export * as A from './named-export-collision/a';
219
export * as B from './named-export-collision/b';
220
`,
221
parser,
222
}),
223
]),
224
225
// Exports in ambient modules
226
test(Object.assign({
227
code: `
228
declare module "a" {
229
const Foo = 1;
230
export {Foo as default};
231
}
232
declare module "b" {
233
const Bar = 2;
234
export {Bar as default};
235
}
236
`,
237
}, parserConfig)),
238
test(Object.assign({
239
code: `
240
declare module "a" {
241
const Foo = 1;
242
export {Foo as default};
243
}
244
const Bar = 2;
245
export {Bar as default};
246
`,
247
}, parserConfig)),
248
249
...(semver.satisfies(process.version, '< 8') && semver.satisfies(eslintPkg.version, '< 6') ? [] : test({
250
...parserConfig,
251
code: `
252
export * from './module';
253
`,
254
filename: testFilePath('export-star-4/index.js'),
255
settings: {
256
...parserConfig.settings,
257
'import/extensions': ['.js', '.ts', '.jsx'],
258
},
259
})),
260
],
261
invalid: [
262
// type/value name clash
263
test(Object.assign({
264
code: `
265
export type Foo = string;
266
export type Foo = number;
267
`,
268
errors: [
269
{
270
message: `Multiple exports of name 'Foo'.`,
271
line: 2,
272
},
273
{
274
message: `Multiple exports of name 'Foo'.`,
275
line: 3,
276
},
277
],
278
}, parserConfig)),
279
280
// namespace
281
test(Object.assign({
282
code: `
283
export const a = 1
284
export namespace Foo {
285
export const a = 2;
286
export const a = 3;
287
}
288
`,
289
errors: [
290
{
291
message: `Multiple exports of name 'a'.`,
292
line: 4,
293
},
294
{
295
message: `Multiple exports of name 'a'.`,
296
line: 5,
297
},
298
],
299
}, parserConfig)),
300
test(Object.assign({
301
code: `
302
declare module 'foo' {
303
const Foo = 1;
304
export default Foo;
305
export default Foo;
306
}
307
`,
308
errors: [
309
{
310
message: 'Multiple default exports.',
311
line: 4,
312
},
313
{
314
message: 'Multiple default exports.',
315
line: 5,
316
},
317
],
318
}, parserConfig)),
319
test(Object.assign({
320
code: `
321
export namespace Foo {
322
export namespace Bar {
323
export const Foo = 1;
324
export const Foo = 2;
325
}
326
export namespace Baz {
327
export const Bar = 3;
328
export const Bar = 4;
329
}
330
}
331
`,
332
errors: [
333
{
334
message: `Multiple exports of name 'Foo'.`,
335
line: 4,
336
},
337
{
338
message: `Multiple exports of name 'Foo'.`,
339
line: 5,
340
},
341
{
342
message: `Multiple exports of name 'Bar'.`,
343
line: 8,
344
},
345
{
346
message: `Multiple exports of name 'Bar'.`,
347
line: 9,
348
},
349
],
350
}, parserConfig)),
351
352
// Exports in ambient modules
353
test(Object.assign({
354
code: `
355
declare module "a" {
356
const Foo = 1;
357
export {Foo as default};
358
}
359
const Bar = 2;
360
export {Bar as default};
361
const Baz = 3;
362
export {Baz as default};
363
`,
364
errors: [
365
{
366
message: 'Multiple default exports.',
367
line: 7,
368
},
369
{
370
message: 'Multiple default exports.',
371
line: 9,
372
},
373
],
374
}, parserConfig)),
375
],
376
});
377
});
378
});
379
380