Skip to content

Commit 9081fff

Browse files
committed
Refactor modules.spec.ts
1 parent a0fd091 commit 9081fff

3 files changed

Lines changed: 167 additions & 163 deletions

File tree

src/LuaPrinter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export class LuaPrinter {
141141
}
142142

143143
public print(file: lua.File): SourceNode {
144-
let header = "";
144+
let header = file.trivia;
145145

146146
if (!this.options.noHeader) {
147147
header += "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n";
Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`Import module names with invalid lua identifier characters ("_̀ः٠‿"): local identifier 1`] = `"______300_903_660_203F"`;
3+
exports[`import local identifier generation (".dot"): local identifier 1`] = `"_____2Edot"`;
44

5-
exports[`Import module names with invalid lua identifier characters ("dollar$"): local identifier 1`] = `"____dollar_24"`;
5+
exports[`import local identifier generation ("_̀ः٠‿"): local identifier 1`] = `"______300_903_660_203F"`;
66

7-
exports[`Import module names with invalid lua identifier characters ("hash#"): local identifier 1`] = `"____hash_23"`;
7+
exports[`import local identifier generation ("dollar$"): local identifier 1`] = `"____dollar_24"`;
88

9-
exports[`Import module names with invalid lua identifier characters ("ke-bab"): local identifier 1`] = `"____ke_2Dbab"`;
9+
exports[`import local identifier generation ("hash#"): local identifier 1`] = `"____hash_23"`;
1010

11-
exports[`Import module names with invalid lua identifier characters ("s p a c e"): local identifier 1`] = `"____s_20p_20a_20c_20e"`;
11+
exports[`import local identifier generation ("ke-bab"): local identifier 1`] = `"____ke_2Dbab"`;
1212

13-
exports[`Import module names with invalid lua identifier characters ("singlequote'"): local identifier 1`] = `"____singlequote_27"`;
13+
exports[`import local identifier generation ("s p a c e"): local identifier 1`] = `"____s_20p_20a_20c_20e"`;
1414

15-
exports[`Import module names with invalid lua identifier characters ("ɥɣɎɌͼƛಠ"): local identifier 1`] = `"_____265_263_24E_24C_37C_19B_CA0"`;
15+
exports[`import local identifier generation ("singlequote'"): local identifier 1`] = `"____singlequote_27"`;
16+
17+
exports[`import local identifier generation ("ɥɣɎɌͼƛಠ"): local identifier 1`] = `"_____265_263_24E_24C_37C_19B_CA0"`;

test/unit/modules.spec.ts

Lines changed: 157 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,51 @@
11
import * as ts from "typescript";
22
import * as util from "../util";
33

4-
describe("module import/export elision", () => {
5-
const moduleDeclaration = `
6-
declare module "module" {
7-
export type Type = string;
8-
export declare const value: string;
9-
}
10-
`;
11-
12-
const expectToElideImport: util.TapCallback = builder => {
13-
builder.addExtraFile("module.d.ts", moduleDeclaration).setOptions({ module: ts.ModuleKind.CommonJS });
14-
expect(builder.getLuaExecutionResult()).not.toBeInstanceOf(util.ExecutionError);
15-
};
16-
17-
test("should elide named type imports", () => {
18-
util.testModule`
19-
import { Type } from "module";
20-
const foo: Type = "bar";
21-
`.tap(expectToElideImport);
22-
});
23-
24-
test("should elide named value imports used only as a type", () => {
4+
describe("export default", () => {
5+
test("literal", () => {
256
util.testModule`
26-
import { value } from "module";
27-
const foo: typeof value = "bar";
28-
`.tap(expectToElideImport);
29-
});
30-
31-
test("should elide namespace imports with unused values", () => {
32-
util.testModule`
33-
import * as module from "module";
34-
const foo: module.Type = "bar";
35-
`.tap(expectToElideImport);
7+
export default true;
8+
`.expectToEqual({ default: true });
369
});
3710

38-
test("should elide `import =` declarations", () => {
11+
test("class", () => {
3912
util.testModule`
40-
import module = require("module");
41-
const foo: module.Type = "bar";
42-
`.tap(expectToElideImport);
13+
export default class Default {}
14+
const d = new Default();
15+
export const result = d.constructor.name;
16+
`
17+
.setReturnExport("result")
18+
.expectToMatchJsResult();
4319
});
4420

45-
test("should elide type exports", () => {
21+
test("function", () => {
4622
util.testModule`
47-
(globalThis as any).foo = true;
48-
type foo = boolean;
49-
export { foo };
50-
`.expectToEqual([]);
23+
export default function defaultFunction() {
24+
return true;
25+
}
26+
export const result = defaultFunction();
27+
`
28+
.setReturnExport("result")
29+
.expectToMatchJsResult();
5130
});
5231
});
5332

54-
test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"])(
55-
"Import module names with invalid lua identifier characters (%p)",
56-
name => {
57-
util.testBundle`
58-
import { foo } from "./${name}";
59-
export { foo };
60-
`
61-
.addExtraFile(`${name}.ts`, "export const foo = true;")
62-
.expectToEqual({ foo: true })
63-
.tap(builder => {
64-
const identifier = builder.getMainLuaCodeChunk().match(/local (.+) = require\(/)?.[1];
65-
expect(identifier).toMatchSnapshot("local identifier");
66-
});
67-
}
68-
);
69-
70-
test.each(["export default value;", "export { value as default };"])("Export Default From (%p)", exportStatement => {
33+
test("export { value as default }", () => {
7134
util.testBundle`
72-
export { default } from "./module";
73-
`
74-
.addExtraFile(
75-
"module.ts",
76-
`
77-
export const value = true;
78-
${exportStatement};
79-
`
80-
)
81-
.expectToEqual({ default: true });
35+
const value = true;
36+
export { value as default };
37+
`.expectToEqual({ default: true });
8238
});
8339

84-
test("Default Import and Export Expression", () => {
40+
test("export { default } from '...'", () => {
8541
util.testBundle`
86-
import defaultExport from "./module";
87-
export const value = defaultExport;
42+
export { default } from "./module";
8843
`
89-
.addExtraFile("module.ts", "export default 1 + 2 + 3;")
90-
.expectToEqual({ value: 6 });
44+
.addExtraFile("module.ts", "export default true;")
45+
.expectToEqual({ default: true });
9146
});
9247

93-
test("Import and Export Assignment", () => {
48+
test("import = and export =", () => {
9449
util.testBundle`
9550
import m = require("./module");
9651
export const value = m;
@@ -134,95 +89,142 @@ test("Mixed Exports, Default and Namespace Import", () => {
13489
.expectToEqual({ value: 6 });
13590
});
13691

137-
test("Export Default Function", () => {
138-
util.testBundle`
139-
import defaultExport from "./module";
140-
export const value = defaultExport();
141-
`
142-
.addExtraFile("module.ts", "export default function() { return true; }")
143-
.expectToEqual({ value: true });
144-
});
145-
146-
const reassignmentTestCases = [
147-
"x = 1",
148-
"x++",
149-
"(x = 1)",
150-
"[x] = [1]",
151-
"[[x]] = [[1]]",
152-
"({ x } = { x: 1 })",
153-
"({ y: x } = { y: 1 })",
154-
"({ x = 1 } = { x: undefined })",
155-
];
156-
157-
test.each(reassignmentTestCases)("export specifier with reassignment afterwards (%p)", reassignment => {
158-
util.testModule`
159-
let x = 0;
160-
export { x };
161-
${reassignment};
162-
`.expectToMatchJsResult();
163-
});
92+
describe("export live bindings", () => {
93+
const reassignmentTestCases = [
94+
"x = 1",
95+
"x++",
96+
"(x = 1)",
97+
"[x] = [1]",
98+
"[[x]] = [[1]]",
99+
"({ x } = { x: 1 })",
100+
"({ y: x } = { y: 1 })",
101+
"({ x = 1 } = { x: undefined })",
102+
];
103+
104+
// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/926
105+
test.each(reassignmentTestCases.filter(c => !c.includes(" } = { x: ")))("export variable (%p)", reassignment => {
106+
util.testModule`
107+
export let x = 0;
108+
${reassignment};
109+
`.expectToMatchJsResult();
110+
});
164111

165-
test.each(reassignmentTestCases)("export specifier fork (%p)", reassignment => {
166-
util.testModule`
167-
let x = 0;
168-
export { x as a };
169-
export { x as b };
170-
${reassignment};
171-
`.expectToMatchJsResult();
172-
});
112+
test.each(reassignmentTestCases)("export variable as a binding (%p)", reassignment => {
113+
util.testModule`
114+
let x = 0;
115+
export { x };
116+
${reassignment};
117+
`.expectToMatchJsResult();
118+
});
173119

174-
test("does not export shadowed identifiers", () => {
175-
util.testModule`
176-
export let a = 1;
177-
{ let a = 2; a = 3 };
178-
`.expectToMatchJsResult();
179-
});
120+
test.each(reassignmentTestCases)("export variable with multiple bindings (%p)", reassignment => {
121+
util.testModule`
122+
let x = 0;
123+
export { x as a };
124+
export { x as b };
125+
${reassignment};
126+
`.expectToMatchJsResult();
127+
});
180128

181-
test("export as specifier shouldn't effect local vars", () => {
182-
util.testModule`
183-
let x = false;
184-
export { x as a };
185-
let a = 5;
186-
a = 6;
187-
`.expectToMatchJsResult();
188-
});
129+
// Can't be added to reassignmentTestCases because of https://github.com/microsoft/TypeScript/issues/35881
130+
test("export variable (for in loop)", () => {
131+
util.testModule`
132+
export let foo = '';
133+
for (foo in { x: true }) {}
134+
`
135+
.setReturnExport("foo")
136+
.expectToMatchJsResult();
137+
});
189138

190-
test("export modified in for in loop", () => {
191-
util.testModule`
192-
export let foo = '';
193-
for (foo in { x: true }) {}
194-
`
195-
.setReturnExport("foo")
196-
.expectToMatchJsResult();
197-
});
139+
test("export variable as a binding (for in loop)", () => {
140+
util.testModule`
141+
let foo = '';
142+
export { foo as bar };
143+
for (foo in { x: true }) {}
144+
`
145+
.setReturnExport("bar")
146+
.expectToEqual("x");
147+
});
198148

199-
test("export dependency modified in for in loop", () => {
200-
util.testModule`
201-
let foo = '';
202-
export { foo as bar };
203-
for (foo in { x: true }) {}
204-
`
205-
.setReturnExport("bar")
206-
.expectToEqual("x");
207-
});
149+
test("does not update shadowed names", () => {
150+
util.testModule`
151+
export let a = 1;
152+
{ let a = 2; a = 3 };
153+
`.expectToMatchJsResult();
154+
});
208155

209-
test("export default class with future reference", () => {
210-
util.testModule`
211-
export default class Default {}
212-
const d = new Default();
213-
export const result = d.constructor.name;
214-
`
215-
.setReturnExport("result")
216-
.expectToMatchJsResult();
156+
test("renamed export specifier shouldn't effect local vars", () => {
157+
util.testModule`
158+
let x = false;
159+
export { x as a };
160+
let a = 5;
161+
a = 6;
162+
`.expectToMatchJsResult();
163+
});
217164
});
218165

219-
test("export default function with future reference", () => {
220-
util.testModule`
221-
export default function defaultFunction() {
222-
return true;
166+
describe("import and export elision", () => {
167+
const moduleDeclaration = `
168+
declare module "module" {
169+
export type Type = string;
170+
export declare const value: string;
223171
}
224-
export const result = defaultFunction();
225-
`
226-
.setReturnExport("result")
227-
.expectToMatchJsResult();
172+
`;
173+
174+
const expectToElideImport: util.TapCallback = builder => {
175+
builder.addExtraFile("module.d.ts", moduleDeclaration).setOptions({ module: ts.ModuleKind.CommonJS });
176+
expect(builder.getLuaExecutionResult()).not.toBeInstanceOf(util.ExecutionError);
177+
};
178+
179+
test("should elide named type imports", () => {
180+
util.testModule`
181+
import { Type } from "module";
182+
const foo: Type = "bar";
183+
`.tap(expectToElideImport);
184+
});
185+
186+
test("should elide named value imports used only as a type", () => {
187+
util.testModule`
188+
import { value } from "module";
189+
const foo: typeof value = "bar";
190+
`.tap(expectToElideImport);
191+
});
192+
193+
test("should elide namespace imports with unused values", () => {
194+
util.testModule`
195+
import * as module from "module";
196+
const foo: module.Type = "bar";
197+
`.tap(expectToElideImport);
198+
});
199+
200+
test("should elide `import =` declarations", () => {
201+
util.testModule`
202+
import module = require("module");
203+
const foo: module.Type = "bar";
204+
`.tap(expectToElideImport);
205+
});
206+
207+
test("should elide type exports", () => {
208+
util.testModule`
209+
(globalThis as any).foo = true;
210+
type foo = boolean;
211+
export { foo };
212+
`.expectToEqual([]);
213+
});
228214
});
215+
216+
test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌͼƛಠ", "_̀ः٠‿", ".dot"])(
217+
"import local identifier generation (%p)",
218+
name => {
219+
util.testBundle`
220+
import { foo } from "./${name}";
221+
export { foo };
222+
`
223+
.addExtraFile(`${name}.ts`, "export const foo = true;")
224+
.expectToEqual({ foo: true })
225+
.tap(builder => {
226+
const identifier = builder.getMainLuaCodeChunk().match(/local (.+) = require\(/)?.[1];
227+
expect(identifier).toMatchSnapshot("local identifier");
228+
});
229+
}
230+
);

0 commit comments

Comments
 (0)