forked from import-js/eslint-plugin-import
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnamed.js
233 lines (191 loc) · 6.83 KB
/
named.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
import { test, SYNTAX_CASES } from '../utils'
import { RuleTester } from 'eslint'
import { CASE_SENSITIVE_FS } from 'eslint-module-utils/resolve'
var ruleTester = new RuleTester()
, rule = require('rules/named')
function error(name, module) {
return { message: name + ' not found in \'' + module + '\''
, type: 'Identifier' }
}
ruleTester.run('named', rule, {
valid: [
test({ code: 'import "./malformed.js"' }),
test({code: 'import { foo } from "./bar"'}),
test({code: 'import { foo } from "./empty-module"'}),
test({code: 'import bar from "./bar.js"'}),
test({code: 'import bar, { foo } from "./bar.js"'}),
test({code: 'import {a, b, d} from "./named-exports"'}),
test({code: 'import {ExportedClass} from "./named-exports"'}),
test({code: 'import { ActionTypes } from "./qc"'}),
test({code: 'import {a, b, c, d} from "./re-export"'}),
test({ code: 'import { jsxFoo } from "./jsx/AnotherComponent"'
, settings: { 'import/resolve': { 'extensions': ['.js', '.jsx'] } } }),
// validate that eslint-disable-line silences this properly
test({code: 'import {a, b, d} from "./common"; ' +
'// eslint-disable-line named' }),
test({ code: 'import { foo, bar } from "./re-export-names"' }),
test({ code: 'import { foo, bar } from "./common"'
, settings: { 'import/ignore': ['common'] } }),
// ignore core modules by default
test({ code: 'import { foo } from "crypto"' }),
test({ code: 'import { zoob } from "a"' }),
test({ code: 'import { someThing } from "./test-module"' }),
// export tests
test({ code: 'export { foo } from "./bar"' }),
test({ code: 'export { foo as bar } from "./bar"' }),
test({ code: 'export { foo } from "./does-not-exist"' }),
// es7
test({
code: 'export bar, { foo } from "./bar"',
parser: 'babel-eslint',
}),
test({
code: 'import { foo, bar } from "./named-trampoline"',
parser: 'babel-eslint',
}),
// regression tests
test({ code: 'export { foo as bar }'}),
// destructured exports
test({ code: 'import { destructuredProp } from "./named-exports"' }),
test({ code: 'import { arrayKeyProp } from "./named-exports"' }),
test({ code: 'import { deepProp } from "./named-exports"' }),
test({ code: 'import { deepSparseElement } from "./named-exports"' }),
// flow types
test({
code: 'import type { MyType } from "./flowtypes"',
'parser': 'babel-eslint',
}),
// jsnext
test({
code: '/*jsnext*/ import { createStore } from "redux"',
settings: { 'import/ignore': [] },
}),
// should work without ignore
test({
code: '/*jsnext*/ import { createStore } from "redux"',
}),
// ignore is ignored if exports are found
test({ code: 'import { foo } from "es6-module"' }),
// issue #210: shameless self-reference
test({ code: 'import { me, soGreat } from "./narcissist"' }),
// issue #251: re-export default as named
test({ code: 'import { foo, bar, baz } from "./re-export-default"' }),
test({
code: 'import { common } from "./re-export-default"',
settings: { 'import/ignore': ['common'] },
}),
// ignore CJS by default. always ignore ignore list
test({ code: 'import {a, b, d} from "./common"' }),
test({
code: 'import { baz } from "./bar"',
settings: { 'import/ignore': ['bar'] },
}),
test({
code: 'import { common } from "./re-export-default"',
}),
...SYNTAX_CASES,
],
invalid: [
test({ code: 'import { somethingElse } from "./test-module"'
, errors: [ error('somethingElse', './test-module') ] }),
test({code: 'import { baz } from "./bar"',
errors: [error('baz', './bar')]}),
// test multiple
test({code: 'import { baz, bop } from "./bar"',
errors: [error('baz', './bar'), error('bop', './bar')]}),
test({code: 'import {a, b, c} from "./named-exports"',
errors: [error('c', './named-exports')]}),
test({code: 'import { a } from "./default-export"',
errors: [error('a', './default-export')]}),
test({code: 'import { ActionTypess } from "./qc"',
errors: [error('ActionTypess', './qc')]}),
test({code: 'import {a, b, c, d, e} from "./re-export"',
errors: [error('e', './re-export')]}),
test({
code: 'import { a } from "./re-export-names"',
options: [2, 'es6-only'],
errors: [error('a', './re-export-names')],
}),
// export tests
test({
code: 'export { bar } from "./bar"',
errors: ["bar not found in './bar'"],
}),
// es7
test({
code: 'export bar2, { bar } from "./bar"',
parser: 'babel-eslint',
errors: ["bar not found in './bar'"],
}),
test({
code: 'import { foo, bar, baz } from "./named-trampoline"',
parser: 'babel-eslint',
errors: ["baz not found in './named-trampoline'"],
}),
test({
code: 'import { baz } from "./broken-trampoline"',
parser: 'babel-eslint',
errors: ["baz not found via broken-trampoline.js -> named-exports.js"],
}),
// parse errors
// test({
// code: "import { a } from './test.coffee';",
// settings: { 'import/extensions': ['.js', '.coffee'] },
// errors: [{
// message: "Parse errors in imported module './test.coffee': Unexpected token > (1:20)",
// type: 'Literal',
// }],
// }),
// flow types
test({
code: 'import type { MissingType } from "./flowtypes"',
parser: 'babel-eslint',
errors: [{
message: "MissingType not found in './flowtypes'",
type: 'Identifier',
}],
}),
// jsnext
test({
code: '/*jsnext*/ import { createSnorlax } from "redux"',
settings: { 'import/ignore': [] },
errors: ["createSnorlax not found in 'redux'"],
}),
// should work without ignore
test({
code: '/*jsnext*/ import { createSnorlax } from "redux"',
errors: ["createSnorlax not found in 'redux'"],
}),
// ignore is ignored if exports are found
test({
code: 'import { baz } from "es6-module"',
errors: ["baz not found in 'es6-module'"],
}),
// issue #251
test({
code: 'import { foo, bar, bap } from "./re-export-default"',
errors: ["bap not found in './re-export-default'"],
}),
// #328: * exports do not include default
test({
code: 'import { default as barDefault } from "./re-export"',
errors: [`default not found in './re-export'`],
}),
],
})
// #311: import of mismatched case
if (!CASE_SENSITIVE_FS) {
ruleTester.run('named (path case-insensitivity)', rule, {
valid: [
test({
code: 'import { b } from "./Named-Exports"',
}),
],
invalid: [
test({
code: 'import { foo } from "./Named-Exports"',
errors: [`foo not found in './Named-Exports'`],
}),
],
})
}