Skip to content

Commit b3ca8de

Browse files
committed
WIP ES7 namespace export support
1 parent 40e98b7 commit b3ca8de

File tree

6 files changed

+130
-123
lines changed

6 files changed

+130
-123
lines changed

src/rules/namespace.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ module.exports = function (context) {
1414
if (imports.errors.length) {
1515
context.report({
1616
node: declaration.source,
17-
message: `Parse errors in imported module '${declaration.source.value}'.`,
17+
message: `Parse errors in imported module '${declaration.source.value}'.` + JSON.stringify(imports.errors),
1818
})
1919
return
2020
}

tests/files/deep-es7/a.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * as b from './b'

tests/files/deep-es7/b.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * as c from './c'

tests/files/deep-es7/c.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * as d from './d'

tests/files/deep-es7/d.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const e = "e"

tests/src/rules/namespace.js

+125-122
Original file line numberDiff line numberDiff line change
@@ -9,137 +9,140 @@ function error(name, namespace) {
99
return { message: `'${name}' not found in imported namespace '${namespace}'.` }
1010
}
1111

12-
13-
ruleTester.run('namespace', rule, {
14-
valid: [
15-
test({ code: "import * as foo from './empty-folder';"}),
16-
test({ code: 'import * as names from "./named-exports"; ' +
17-
'console.log((names.b).c); ' }),
18-
19-
test({ code: 'import * as names from "./named-exports"; ' +
20-
'console.log(names.a);' }),
21-
test({ code: 'import * as names from "./re-export-names"; ' +
22-
'console.log(names.foo);' }),
23-
test({ code: "import * as elements from './jsx';"
24-
, settings: { 'import/parse-options': { plugins: ['jsx'] }}}),
25-
test({ code: "import * as foo from './common';"
26-
, settings: { 'import/ignore': ['common'] } }),
27-
28-
// destructuring namespaces
29-
test({ code: 'import * as names from "./named-exports";' +
30-
'const { a } = names' }),
31-
test({ code: 'import * as names from "./named-exports";' +
32-
'const { d: c } = names' }),
33-
test({ code: 'import * as names from "./named-exports";' +
34-
'const { c } = foo\n' +
35-
' , { length } = "names"\n' +
36-
' , alt = names' }),
37-
// deep destructuring only cares about top level
38-
test({ code: 'import * as names from "./named-exports";' +
39-
'const { ExportedClass: { length } } = names' }),
40-
41-
// detect scope redefinition
42-
test({ code: 'import * as names from "./named-exports";' +
43-
'function b(names) { const { c } = names }' }),
44-
test({ code: 'import * as names from "./named-exports";' +
45-
'function b() { let names = null; const { c } = names }' }),
46-
test({ code: 'import * as names from "./named-exports";' +
47-
'const x = function names() { const { c } = names }' }),
48-
49-
50-
/////////
51-
// es7 //
52-
/////////
53-
test({ code: 'export * as names from "./named-exports"'
54-
, parser: 'babel-eslint' }),
55-
test({ code: 'export defport, * as names from "./named-exports"'
56-
, parser: 'babel-eslint' }),
57-
// non-existent is handled by no-unresolved
58-
test({ code: 'export * as names from "./does-not-exist"'
59-
, parser: 'babel-eslint' }),
60-
61-
///////////////////////
62-
// deep dereferences //
63-
///////////////////////
64-
65-
test({ code: 'import * as a from "./deep/a"; console.log(a.b.c.d.e)' }),
66-
test({ code: 'import * as a from "./deep/a"; console.log(a.b.c.d.e.f)' }),
67-
test({ code: 'import * as a from "./deep/a"; var {b:{c:{d:{e}}}} = a' }),
68-
],
69-
70-
invalid: [
71-
test({code: "import * as foo from './common';",
72-
errors: ["No exported names found in module './common'."]}),
73-
test({code: "import * as names from './default-export';",
74-
errors: ["No exported names found in module './default-export'."]}),
75-
76-
test({ code: "import * as names from './named-exports'; " +
77-
' console.log(names.c);'
78-
, errors: [error('c', 'names')] }),
79-
80-
test({ code: "import * as names from './named-exports';" +
81-
" console.log(names['a']);"
82-
, errors: 1 }),
83-
84-
// assignment warning (from no-reassign)
85-
test({ code: 'import * as foo from \'./bar\'; foo.foo = \'y\';'
86-
, errors: [{ message: 'Assignment to member of namespace \'foo\'.'}] }),
87-
test({ code: 'import * as foo from \'./bar\'; foo.x = \'y\';'
88-
, errors: 2 }),
89-
90-
// invalid destructuring
91-
test({ code: 'import * as names from "./named-exports";' +
92-
'const { c } = names'
93-
, errors: [{ type: 'Property' }] }),
94-
test({ code: 'import * as names from "./named-exports";' +
95-
'function b() { const { c } = names }'
96-
, errors: [{ type: 'Property' }] }),
97-
test({ code: 'import * as names from "./named-exports";' +
98-
'const { c: d } = names'
99-
, errors: [{ type: 'Property' }] }),
100-
test({ code: 'import * as names from "./named-exports";' +
101-
'const { c: { d } } = names'
102-
, errors: [{ type: 'Property' }] }),
103-
104-
/////////
105-
// es7 //
106-
/////////
107-
test({ code: 'export * as names from "./default-export"'
108-
, parser: 'babel-eslint'
109-
, errors: 1 }),
110-
test({ code: 'export defport, * as names from "./default-export"'
111-
, parser: 'babel-eslint'
112-
, errors: 1 }),
113-
114-
115-
// parse errors
12+
const valid = [
13+
test({ code: "import * as foo from './empty-folder';"}),
14+
test({ code: 'import * as names from "./named-exports"; ' +
15+
'console.log((names.b).c); ' }),
16+
17+
test({ code: 'import * as names from "./named-exports"; ' +
18+
'console.log(names.a);' }),
19+
test({ code: 'import * as names from "./re-export-names"; ' +
20+
'console.log(names.foo);' }),
21+
test({ code: "import * as elements from './jsx';"
22+
, settings: { 'import/parse-options': { plugins: ['jsx'] }}}),
23+
test({ code: "import * as foo from './common';"
24+
, settings: { 'import/ignore': ['common'] } }),
25+
26+
// destructuring namespaces
27+
test({ code: 'import * as names from "./named-exports";' +
28+
'const { a } = names' }),
29+
test({ code: 'import * as names from "./named-exports";' +
30+
'const { d: c } = names' }),
31+
test({ code: 'import * as names from "./named-exports";' +
32+
'const { c } = foo\n' +
33+
' , { length } = "names"\n' +
34+
' , alt = names' }),
35+
// deep destructuring only cares about top level
36+
test({ code: 'import * as names from "./named-exports";' +
37+
'const { ExportedClass: { length } } = names' }),
38+
39+
// detect scope redefinition
40+
test({ code: 'import * as names from "./named-exports";' +
41+
'function b(names) { const { c } = names }' }),
42+
test({ code: 'import * as names from "./named-exports";' +
43+
'function b() { let names = null; const { c } = names }' }),
44+
test({ code: 'import * as names from "./named-exports";' +
45+
'const x = function names() { const { c } = names }' }),
46+
47+
48+
/////////
49+
// es7 //
50+
/////////
51+
test({ code: 'export * as names from "./named-exports"'
52+
, parser: 'babel-eslint' }),
53+
test({ code: 'export defport, * as names from "./named-exports"'
54+
, parser: 'babel-eslint' }),
55+
// non-existent is handled by no-unresolved
56+
test({ code: 'export * as names from "./does-not-exist"'
57+
, parser: 'babel-eslint' }),
58+
]
59+
60+
const invalid = [
61+
test({code: "import * as foo from './common';",
62+
errors: ["No exported names found in module './common'."]}),
63+
test({code: "import * as names from './default-export';",
64+
errors: ["No exported names found in module './default-export'."]}),
65+
66+
test({ code: "import * as names from './named-exports'; " +
67+
' console.log(names.c);'
68+
, errors: [error('c', 'names')] }),
69+
70+
test({ code: "import * as names from './named-exports';" +
71+
" console.log(names['a']);"
72+
, errors: 1 }),
73+
74+
// assignment warning (from no-reassign)
75+
test({ code: 'import * as foo from \'./bar\'; foo.foo = \'y\';'
76+
, errors: [{ message: 'Assignment to member of namespace \'foo\'.'}] }),
77+
test({ code: 'import * as foo from \'./bar\'; foo.x = \'y\';'
78+
, errors: 2 }),
79+
80+
// invalid destructuring
81+
test({ code: 'import * as names from "./named-exports";' +
82+
'const { c } = names'
83+
, errors: [{ type: 'Property' }] }),
84+
test({ code: 'import * as names from "./named-exports";' +
85+
'function b() { const { c } = names }'
86+
, errors: [{ type: 'Property' }] }),
87+
test({ code: 'import * as names from "./named-exports";' +
88+
'const { c: d } = names'
89+
, errors: [{ type: 'Property' }] }),
90+
test({ code: 'import * as names from "./named-exports";' +
91+
'const { c: { d } } = names'
92+
, errors: [{ type: 'Property' }] }),
93+
94+
/////////
95+
// es7 //
96+
/////////
97+
test({ code: 'export * as names from "./default-export"'
98+
, parser: 'babel-eslint'
99+
, errors: 1 }),
100+
test({ code: 'export defport, * as names from "./default-export"'
101+
, parser: 'babel-eslint'
102+
, errors: 1 }),
103+
104+
105+
// parse errors
106+
test({
107+
code: "import * as namespace from './malformed.js';",
108+
errors: [{
109+
message: "Parse errors in imported module './malformed.js'.",
110+
type: 'Literal',
111+
}],
112+
}),
113+
114+
]
115+
116+
///////////////////////
117+
// deep dereferences //
118+
//////////////////////
119+
;[['deep', 'espree'], ['deep-es7', 'babel-eslint']].forEach(function ([folder, parser]) { // close over params
120+
valid.push(
121+
test({ parser, code: `import * as a from "./${folder}/a"; console.log(a.b.c.d.e)` }),
122+
test({ parser, code: `import * as a from "./${folder}/a"; console.log(a.b.c.d.e.f)` }),
123+
test({ parser, code: `import * as a from "./${folder}/a"; var {b:{c:{d:{e}}}} = a` }))
124+
125+
invalid.push(
116126
test({
117-
code: "import * as namespace from './malformed.js';",
118-
errors: [{
119-
message: "Parse errors in imported module './malformed.js'.",
120-
type: 'Literal',
121-
}],
122-
}),
123-
124-
125-
///////////////////////
126-
// deep dereferences //
127-
///////////////////////
128-
test({
129-
code: 'import * as a from "./deep/a"; console.log(a.b.e)',
127+
parser,
128+
code: `import * as a from "./${folder}/a"; console.log(a.b.e)`,
130129
errors: [ "'e' not found in deeply imported namespace 'a.b'." ],
131130
}),
132131
test({
133-
code: 'import * as a from "./deep/a"; console.log(a.b.c.e)',
132+
parser,
133+
code: `import * as a from "./${folder}/a"; console.log(a.b.c.e)`,
134134
errors: [ "'e' not found in deeply imported namespace 'a.b.c'." ],
135135
}),
136136
test({
137-
code: 'import * as a from "./deep/a"; var {b:{ e }} = a',
137+
parser,
138+
code: `import * as a from "./${folder}/a"; var {b:{ e }} = a`,
138139
errors: [ "'e' not found in deeply imported namespace 'a.b'." ],
139140
}),
140141
test({
141-
code: 'import * as a from "./deep/a"; var {b:{c:{ e }}} = a',
142+
parser,
143+
code: `import * as a from "./${folder}/a"; var {b:{c:{ e }}} = a`,
142144
errors: [ "'e' not found in deeply imported namespace 'a.b.c'." ],
143-
}),
144-
],
145+
}))
145146
})
147+
148+
ruleTester.run('namespace', rule, { valid, invalid })

0 commit comments

Comments
 (0)