Skip to content

Commit f4673a8

Browse files
committed
Refactor @forRange annotation tests
1 parent 4997d61 commit f4673a8

1 file changed

Lines changed: 96 additions & 97 deletions

File tree

test/unit/decorators/forRange.spec.ts

Lines changed: 96 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -2,107 +2,106 @@ import * as ts from "typescript";
22
import { InvalidForRangeCall } from "../../../src/transformation/utils/errors";
33
import * as util from "../../util";
44

5+
const createForRangeDeclaration = (args = "i: number, j: number, k?: number", returns = "number[]") => `
6+
/** @forRange */
7+
declare function luaRange(${args}): ${returns};
8+
`;
9+
510
test.each([
6-
{ args: [1, 10], expectResult: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] },
7-
{ args: [1, 10, 2], expectResult: [1, 3, 5, 7, 9] },
8-
{ args: [10, 1, -1], expectResult: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] },
9-
{ args: [10, 1, -2], expectResult: [10, 8, 6, 4, 2] },
10-
])("@forRange loop", ({ args, expectResult }) => {
11-
const tsHeader = "/** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[];";
12-
const code = `
13-
const results: number[] = [];
11+
{ args: [1, 10], results: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] },
12+
{ args: [1, 10, 2], results: [1, 3, 5, 7, 9] },
13+
{ args: [10, 1, -1], results: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] },
14+
{ args: [10, 1, -2], results: [10, 8, 6, 4, 2] },
15+
])("usage in for...of loop", ({ args, results }) => {
16+
util.testModule`
17+
${createForRangeDeclaration()}
18+
export const results: number[] = [];
19+
1420
for (const i of luaRange(${args})) {
1521
results.push(i);
1622
}
17-
return JSONStringify(results);`;
18-
19-
const result = util.transpileAndExecute(code, undefined, undefined, tsHeader);
20-
expect(JSON.parse(result)).toEqual(expectResult);
21-
});
22-
23-
test("invalid non-ambient @forRange function", () => {
24-
const code = `
25-
/** @forRange **/ function luaRange(i: number, j: number, k?: number): number[] { return []; }
26-
for (const i of luaRange(1, 10, 2)) {}`;
27-
28-
expect(() => util.transpileString(code)).toThrow(
29-
InvalidForRangeCall(
30-
ts.createEmptyStatement(),
31-
"@forRange function can only be used as an iterable in a for...of loop."
32-
).message
33-
);
34-
});
35-
36-
test.each([[1], [1, 2, 3, 4]])("invalid @forRange argument count", args => {
37-
const code = `
38-
/** @forRange **/ declare function luaRange(...args: number[]): number[] { return []; }
39-
for (const i of luaRange(${args})) {}`;
40-
41-
expect(() => util.transpileString(code)).toThrow(
42-
InvalidForRangeCall(ts.createEmptyStatement(), "@forRange function must take 2 or 3 arguments.").message
43-
);
44-
});
45-
46-
test("invalid @forRange control variable", () => {
47-
const code = `
48-
/** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[];
49-
let i: number;
50-
for (i of luaRange(1, 10, 2)) {}`;
51-
52-
expect(() => util.transpileString(code)).toThrow(
53-
InvalidForRangeCall(ts.createEmptyStatement(), "@forRange loop must declare its own control variable.").message
54-
);
23+
`
24+
.setReturnExport("results")
25+
.expectToEqual(results);
5526
});
5627

57-
test("invalid @forRange argument type", () => {
58-
const code = `
59-
/** @forRange **/ declare function luaRange(i: string, j: number): number[] { return []; }
60-
for (const i of luaRange("foo", 2)) {}`;
61-
62-
expect(() => util.transpileString(code)).toThrow(
63-
InvalidForRangeCall(ts.createEmptyStatement(), "@forRange arguments must be number types.").message
64-
);
65-
});
66-
67-
test("invalid @forRange destructuring", () => {
68-
const code = `
69-
/** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[][];
70-
for (const [i] of luaRange(1, 10, 2)) {}`;
71-
72-
expect(() => util.transpileString(code)).toThrow(
73-
InvalidForRangeCall(ts.createEmptyStatement(), "@forRange loop cannot use destructuring.").message
74-
);
75-
});
76-
77-
test("invalid @forRange return type", () => {
78-
const code = `
79-
/** @forRange **/ declare function luaRange(i: number, j: number, k?: number): string[];
80-
for (const i of luaRange(1, 10)) {}`;
81-
82-
expect(() => util.transpileString(code)).toThrow(
83-
InvalidForRangeCall(
84-
ts.createEmptyStatement(),
85-
"@forRange function must return Iterable<number> or Array<number>."
86-
).message
87-
);
88-
});
89-
90-
test.each([
91-
"const range = luaRange(1, 10);",
92-
"console.log(luaRange);",
93-
"luaRange.call(null, 0, 0, 0);",
94-
"let array = [0, luaRange, 1];",
95-
"const call: any; call(luaRange);",
96-
"for (const i of [...luaRange(1, 10)]) {}",
97-
])("invalid @forRange reference (%p)", statement => {
98-
const code = `
99-
/** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[];
100-
${statement}`;
101-
102-
expect(() => util.transpileString(code)).toThrow(
103-
InvalidForRangeCall(
104-
ts.createEmptyStatement(),
105-
"@forRange function can only be used as an iterable in a for...of loop."
106-
).message
107-
);
28+
describe("invalid usage", () => {
29+
test("non-ambient declaration", () => {
30+
util.testModule`
31+
/** @forRange */
32+
function luaRange() {}
33+
`.expectToHaveDiagnosticOfError(
34+
InvalidForRangeCall(
35+
ts.createEmptyStatement(),
36+
"@forRange function can only be used as an iterable in a for...of loop."
37+
)
38+
);
39+
});
40+
41+
test.each([[1], [1, 2, 3, 4]])("argument count", args => {
42+
util.testModule`
43+
${createForRangeDeclaration("...args: number[]")}
44+
for (const i of luaRange(${args})) {}
45+
`.expectToHaveDiagnosticOfError(
46+
InvalidForRangeCall(ts.createEmptyStatement(), "@forRange function must take 2 or 3 arguments.")
47+
);
48+
});
49+
50+
test("non-declared loop variable", () => {
51+
util.testModule`
52+
${createForRangeDeclaration()}
53+
let i: number;
54+
for (i of luaRange(1, 10, 2)) {}
55+
`.expectToHaveDiagnosticOfError(
56+
InvalidForRangeCall(ts.createEmptyStatement(), "@forRange loop must declare its own control variable.")
57+
);
58+
});
59+
60+
test("argument types", () => {
61+
util.testModule`
62+
${createForRangeDeclaration("i: string, j: number")}
63+
for (const i of luaRange("foo", 2)) {}
64+
`.expectToHaveDiagnosticOfError(
65+
InvalidForRangeCall(ts.createEmptyStatement(), "@forRange arguments must be number types.")
66+
);
67+
});
68+
69+
test("variable destructuring", () => {
70+
util.testModule`
71+
${createForRangeDeclaration(undefined, "number[][]")}
72+
for (const [i] of luaRange(1, 10, 2)) {}
73+
`.expectToHaveDiagnosticOfError(
74+
InvalidForRangeCall(ts.createEmptyStatement(), "@forRange loop cannot use destructuring.")
75+
);
76+
});
77+
78+
test("return type", () => {
79+
util.testModule`
80+
${createForRangeDeclaration(undefined, "string[]")}
81+
for (const i of luaRange(1, 10)) {}
82+
`.expectToHaveDiagnosticOfError(
83+
InvalidForRangeCall(
84+
ts.createEmptyStatement(),
85+
"@forRange function must return Iterable<number> or Array<number>."
86+
)
87+
);
88+
});
89+
90+
test.each([
91+
"const range = luaRange(1, 10);",
92+
"luaRange.call(null, 0, 0, 0);",
93+
"let array = [0, luaRange, 1];",
94+
"const call = undefined as any; call(luaRange);",
95+
"for (const i of [...luaRange(1, 10)]) {}",
96+
])("reference (%p)", statement => {
97+
util.testModule`
98+
${createForRangeDeclaration()}
99+
${statement}
100+
`.expectToHaveDiagnosticOfError(
101+
InvalidForRangeCall(
102+
ts.createEmptyStatement(),
103+
"@forRange function can only be used as an iterable in a for...of loop."
104+
)
105+
);
106+
});
108107
});

0 commit comments

Comments
 (0)