Skip to content

Commit 0ed6fe3

Browse files
ark120202Perryvw
authored andcommitted
Add test builder (#609)
* Add new test builder and convert few tests * Rename fn and mod to testFunction and testModule * Transform some more tests * Transform some more tests * Transform some more tests * Update require tests * Fix tests on node 8.5.0 * Change float precision in json test util * Transform some more tests * Revert "Change float precision in json test util" This reverts commit 90cc57f. * Transform some more tests * Move serialize to separate template functions * Rename some builder methods * numbers.spec.ts * Serialize NaN and Infinity test results * math.spec.ts * console.spec.ts * Merge array.spec.ts files * Move some math tests to lualib * Move around some lualib tests * Move numbers.spec.ts to lualib tests * Move inlining tests to other luaLibImport tests * Fix node 8 tests * Merge curry.spec.ts into functions.spec.ts * Fix object tests * Refactor array tests * Move custom decorator tests to separate directory * Merge tagged template literal and simple template literal tests * Update globalThis tests * Move and remove some tests from expressions.spec.ts * Move class-related tests to a directory * Move namespace tests from modules * Move modules tests to a subdirectory * Transform tagged template literals tests * Transform sourcemaps tests * Move string tests to lualib directory * Refactor spread.spec.ts * Refactor bindingpatterns.spec.ts * Merge and refactor destructuring tests * Fix expressions tests * Fix declared namespace function call test * Remove/move to other files tuples tests * Move transformers.spec.ts to subdirectory * Move some tests to printer subdirectory * Remove declarations.spec.ts * Split typechecking into instanceof and typeof * Rename lualib tests to builtins * Move parenthesis removal tests to printer subdirectory * Remove some translation tests * Move around assignments and expressions * Fix loading tests * enum.spec.ts * globalThis.spec.ts * Rearrange some enum tests * Refactor some tests * Fix enum tests * Remove todos for #663 * Move enum array index tests to array.spec.ts * Remove some translation tests * Fix nested namespace test * Fix as const cast creating diagnostics * Address feedback * Refactor new spread tests * Remove spreadAssignment translation test
1 parent c11ba34 commit 0ed6fe3

File tree

114 files changed

+5878
-7000
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+5878
-7000
lines changed

src/LuaTransformer.ts

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4552,7 +4552,7 @@ export class LuaTransformer {
45524552
return tstl.createNumericLiteral(Math[name], identifier);
45534553

45544554
default:
4555-
throw TSTLErrors.UnsupportedProperty("math", name, identifier);
4555+
throw TSTLErrors.UnsupportedProperty("Math", name, identifier);
45564556
}
45574557
}
45584558

@@ -4622,7 +4622,7 @@ export class LuaTransformer {
46224622
}
46234623

46244624
default:
4625-
throw TSTLErrors.UnsupportedProperty("math", expressionName, expression);
4625+
throw TSTLErrors.UnsupportedProperty("Math", expressionName, expression);
46264626
}
46274627
}
46284628

@@ -4872,11 +4872,7 @@ export class LuaTransformer {
48724872
tstl.createStringLiteral("char")
48734873
);
48744874
default:
4875-
throw TSTLErrors.UnsupportedForTarget(
4876-
`string property ${identifierString}`,
4877-
this.luaTarget,
4878-
identifier
4879-
);
4875+
throw TSTLErrors.UnsupportedProperty("String", identifierString, identifier);
48804876
}
48814877
}
48824878

@@ -4898,7 +4894,7 @@ export class LuaTransformer {
48984894
case "values":
48994895
return this.transformLuaLibFunction(LuaLibFeature.ObjectValues, expression, ...parameters);
49004896
default:
4901-
throw TSTLErrors.UnsupportedForTarget(`object property ${methodName}`, this.luaTarget, expression);
4897+
throw TSTLErrors.UnsupportedProperty("Object", methodName, expression);
49024898
}
49034899
}
49044900

@@ -4969,7 +4965,7 @@ export class LuaTransformer {
49694965
);
49704966
return tstl.createCallExpression(tstl.createIdentifier("print"), [debugTracebackCall]);
49714967
default:
4972-
throw TSTLErrors.UnsupportedForTarget(`console property ${methodName}`, this.luaTarget, expression);
4968+
throw TSTLErrors.UnsupportedProperty("console", methodName, expression);
49734969
}
49744970
}
49754971

@@ -4992,7 +4988,7 @@ export class LuaTransformer {
49924988
const functionIdentifier = tstl.createIdentifier(`__TS__SymbolRegistry${upperMethodName}`);
49934989
return tstl.createCallExpression(functionIdentifier, parameters, expression);
49944990
default:
4995-
throw TSTLErrors.UnsupportedForTarget(`symbol property ${methodName}`, this.luaTarget, expression);
4991+
throw TSTLErrors.UnsupportedProperty("Symbol", methodName, expression);
49964992
}
49974993
}
49984994

@@ -5008,7 +5004,7 @@ export class LuaTransformer {
50085004
case "isFinite":
50095005
return this.transformLuaLibFunction(LuaLibFeature.NumberIsFinite, expression, ...parameters);
50105006
default:
5011-
throw TSTLErrors.UnsupportedForTarget(`number property ${methodName}`, this.luaTarget, expression);
5007+
throw TSTLErrors.UnsupportedProperty("Number", methodName, expression);
50125008
}
50135009
}
50145010

@@ -5186,11 +5182,14 @@ export class LuaTransformer {
51865182
}
51875183

51885184
public transformAssertionExpression(expression: ts.AssertionExpression): ExpressionVisitResult {
5189-
this.validateFunctionAssignment(
5190-
expression,
5191-
this.checker.getTypeAtLocation(expression.expression),
5192-
this.checker.getTypeAtLocation(expression.type)
5193-
);
5185+
if (!ts.isConstTypeReference(expression.type)) {
5186+
this.validateFunctionAssignment(
5187+
expression,
5188+
this.checker.getTypeAtLocation(expression.expression),
5189+
this.checker.getTypeAtLocation(expression.type)
5190+
);
5191+
}
5192+
51945193
return this.transformExpression(expression.expression);
51955194
}
51965195

test/json.lua

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,15 @@ end
112112

113113

114114
local function encode_number(val)
115-
-- Check for NaN, -inf and inf
116-
if val ~= val or val <= -math.huge or val >= math.huge then
117-
error("unexpected number value '" .. tostring(val) .. "'")
115+
if val ~= val then
116+
return "NaN"
117+
elseif val == math.huge then
118+
return "Infinity"
119+
elseif val == -math.huge then
120+
return "-Infinity"
121+
else
122+
return string.format("%.17g", val)
118123
end
119-
return string.format("%.14g", val)
120124
end
121125

122126

@@ -139,6 +143,7 @@ encode = function(val, stack)
139143
end
140144

141145

146+
-- TODO: Since it supports NaN and Infinity it is considered a superset of JSON, so it probably should be renamed
142147
function JSONStringify(val)
143148
return ( encode(val) )
144149
end

test/legacy-utils.ts

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari";
2+
import * as fs from "fs";
3+
import * as path from "path";
4+
import * as ts from "typescript";
5+
import * as tstl from "../src";
6+
import * as tsHelper from "../src/TSHelper";
7+
8+
export function transpileString(
9+
str: string | { [filename: string]: string },
10+
options: tstl.CompilerOptions = {},
11+
ignoreDiagnostics = true
12+
): string {
13+
const { diagnostics, file } = transpileStringResult(str, options);
14+
expect(file.lua).toBeDefined();
15+
16+
const errors = diagnostics.filter(d => !ignoreDiagnostics || d.source === "typescript-to-lua");
17+
expect(errors).not.toHaveDiagnostics();
18+
19+
return file.lua!.trim();
20+
}
21+
22+
export function transpileStringsAsProject(
23+
input: Record<string, string>,
24+
options: tstl.CompilerOptions = {}
25+
): tstl.TranspileResult {
26+
const optionsWithDefaults = {
27+
luaTarget: tstl.LuaTarget.Lua53,
28+
noHeader: true,
29+
skipLibCheck: true,
30+
target: ts.ScriptTarget.ESNext,
31+
lib: ["lib.esnext.d.ts"],
32+
experimentalDecorators: true,
33+
...options,
34+
};
35+
36+
return tstl.transpileVirtualProject(input, optionsWithDefaults);
37+
}
38+
39+
export function transpileStringResult(
40+
input: string | Record<string, string>,
41+
options: tstl.CompilerOptions = {}
42+
): Required<tstl.TranspileStringResult> {
43+
const { diagnostics, transpiledFiles } = transpileStringsAsProject(
44+
typeof input === "string" ? { "main.ts": input } : input,
45+
options
46+
);
47+
48+
const file = transpiledFiles.find(({ fileName }) => /\bmain\.[a-z]+$/.test(fileName));
49+
if (file === undefined) {
50+
throw new Error('Program should have a file named "main"');
51+
}
52+
53+
return { diagnostics, file };
54+
}
55+
56+
const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8");
57+
const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8") + "\n";
58+
export function executeLua(luaStr: string, withLib = true): any {
59+
luaStr = luaStr.replace(/require\("lualib_bundle"\)/g, lualibContent);
60+
if (withLib) {
61+
luaStr = minimalTestLib + luaStr;
62+
}
63+
64+
const L = lauxlib.luaL_newstate();
65+
lualib.luaL_openlibs(L);
66+
const status = lauxlib.luaL_dostring(L, to_luastring(luaStr));
67+
68+
if (status === lua.LUA_OK) {
69+
// Read the return value from stack depending on its type.
70+
if (lua.lua_isboolean(L, -1)) {
71+
return lua.lua_toboolean(L, -1);
72+
} else if (lua.lua_isnil(L, -1)) {
73+
return undefined;
74+
} else if (lua.lua_isnumber(L, -1)) {
75+
return lua.lua_tonumber(L, -1);
76+
} else if (lua.lua_isstring(L, -1)) {
77+
return lua.lua_tojsstring(L, -1);
78+
} else {
79+
throw new Error("Unsupported lua return type: " + to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))));
80+
}
81+
} else {
82+
// If the lua VM did not terminate with status code LUA_OK an error occurred.
83+
// Throw a JS error with the message, retrieved by reading a string from the stack.
84+
85+
// Filter control characters out of string which are in there because ????
86+
throw new Error("LUA ERROR: " + to_jsstring(lua.lua_tostring(L, -1).filter(c => c >= 20)));
87+
}
88+
}
89+
90+
export function transpileAndExecute(
91+
tsStr: string,
92+
compilerOptions?: tstl.CompilerOptions,
93+
luaHeader?: string,
94+
tsHeader?: string
95+
): any {
96+
const wrappedTsString = `${tsHeader ? tsHeader : ""}
97+
declare function JSONStringify(this: void, p: any): string;
98+
function __runTest(this: void): any {${tsStr}}`;
99+
100+
const lua = `${luaHeader ? luaHeader : ""}
101+
${transpileString(wrappedTsString, compilerOptions, false)}
102+
return __runTest();`;
103+
104+
return executeLua(lua);
105+
}
106+
107+
export function transpileAndExecuteProjectReturningMainExport(
108+
typeScriptFiles: Record<string, string>,
109+
exportName: string,
110+
options: tstl.CompilerOptions = {}
111+
): [any, string] {
112+
const mainFile = Object.keys(typeScriptFiles).find(typeScriptFileName => typeScriptFileName === "main.ts");
113+
if (!mainFile) {
114+
throw new Error("An entry point file needs to be specified. This should be called main.ts");
115+
}
116+
117+
const joinedTranspiledFiles = Object.keys(typeScriptFiles)
118+
.filter(typeScriptFileName => typeScriptFileName !== "main.ts")
119+
.map(typeScriptFileName => {
120+
const modulePath = tsHelper.getExportPath(typeScriptFileName, options);
121+
const tsCode = typeScriptFiles[typeScriptFileName];
122+
const luaCode = transpileString(tsCode, options);
123+
return `package.preload["${modulePath}"] = function()
124+
${luaCode}
125+
end`;
126+
})
127+
.join("\n");
128+
129+
const luaCode = `return (function()
130+
${joinedTranspiledFiles}
131+
${transpileString(typeScriptFiles[mainFile])}
132+
end)().${exportName}`;
133+
134+
try {
135+
return [executeLua(luaCode), luaCode];
136+
} catch (err) {
137+
throw new Error(`
138+
Encountered an error when executing the following Lua code:
139+
140+
${luaCode}
141+
142+
${err}
143+
`);
144+
}
145+
}
146+
147+
export function transpileExecuteAndReturnExport(
148+
tsStr: string,
149+
returnExport: string,
150+
compilerOptions?: tstl.CompilerOptions,
151+
luaHeader?: string
152+
): any {
153+
const wrappedTsString = `declare function JSONStringify(this: void, p: any): string;
154+
${tsStr}`;
155+
156+
const lua = `return (function()
157+
${luaHeader ? luaHeader : ""}
158+
${transpileString(wrappedTsString, compilerOptions, false)}
159+
end)().${returnExport}`;
160+
161+
return executeLua(lua);
162+
}

0 commit comments

Comments
 (0)