Skip to content

Commit 8f3acbc

Browse files
committed
Compare WAT and bindings fixtures for both debug and release builds
This commit changes compiler tests such that WAT fixtures are compared in release builds as well. Moreover, the JS and (D)TS bindings are now compared as well, for both debug and release builds. These changes should ensure changes to Binaryen or bindings generation that affect the release WAT or JS/TS bindings respectively must update the broken compiler tests as well.
1 parent 7403509 commit 8f3acbc

File tree

1 file changed

+114
-37
lines changed

1 file changed

+114
-37
lines changed

tests/compiler.js

Lines changed: 114 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,11 @@ if (args.help) {
8080
const features = process.env.ASC_FEATURES ? process.env.ASC_FEATURES.split(",") : [];
8181
const featuresConfig = require("./features.json");
8282
const basedir = path.join(dirname, "compiler");
83+
process.chdir(basedir);
8384

8485
// Gets a list of all relevant tests
8586
function getTests() {
86-
let tests = glob.sync("**/!(_*).ts", { cwd: basedir })
87+
let tests = glob.sync("**/!(_*).ts")
8788
.map(name => name.replace(/\.ts$/, ""))
8889
.filter(name => !name.endsWith(".d") && !name.includes("node_modules"));
8990
if (argv.length) { // run matching tests only
@@ -134,6 +135,8 @@ async function runTest(basename) {
134135
const stdout = asc.createMemoryStream();
135136
const stderr = asc.createMemoryStream(chunk => process.stderr.write(chunk.toString().replace(/^(?!$)/mg, " ")));
136137
stderr.isTTY = true;
138+
const dummy = new Map();
139+
const writeFile = Map.prototype.set.bind(dummy);
137140
let asc_flags = [];
138141
let asc_rtrace = !!config.asc_rtrace;
139142
let v8_flags = "";
@@ -143,10 +146,105 @@ async function runTest(basename) {
143146
// Makes sure to reset the environment after
144147
function prepareResult(code, message = null) {
145148
if (v8_no_flags) v8.setFlagsFromString(v8_no_flags);
146-
if (!args.createBinary) fs.unlink(path.join(basedir, basename + ".debug.wasm"), err => { /* nop */ });
149+
// Delete the .wasm files in case the subsequent run doesn't specify the
150+
// --createBinary flag, thereby preventing confusion. Also, the .debug.wasm
151+
// file is used by the bindings/esm test.
152+
if (!args.createBinary) {
153+
fs.unlink(basename + ".debug.wasm", err => { /* nop */ });
154+
fs.unlink(basename + ".release.wasm", err => { /* nop */ });
155+
}
147156
return { code, message };
148157
}
149158

159+
function afterCompile(mode) {
160+
// The ESM bindings test requires the .wasm file to be present. The file is
161+
// promptly deleted after the test has completed, unless --createBinary is
162+
// specified.
163+
{
164+
const filename = `${basename}.${mode}.wasm`;
165+
fs.writeFileSync(filename, dummy.get(filename));
166+
}
167+
168+
const compareFixture = section("compare fixture");
169+
const fixtureExtensions = ["wat", "js", "d.ts"];
170+
171+
if (args.create) {
172+
for (const extension of fixtureExtensions) {
173+
const filename = `${basename}.${mode}.${extension}`;
174+
if (!dummy.has(filename)) {
175+
fs.unlink(filename, err => { /* nop */ });
176+
continue;
177+
}
178+
fs.writeFileSync(filename, dummy.get(filename));
179+
console.log(" " + stdoutColors.yellow(`Created fixture ${filename}`));
180+
}
181+
compareFixture.end(SKIPPED);
182+
return;
183+
}
184+
185+
if (args.noDiff) {
186+
for (const extension of fixtureExtensions) {
187+
const filename = `${basename}.${mode}.${extension}`;
188+
const actual = (
189+
dummy.has(filename) &&
190+
dummy.get(filename).replace(/\r\n/g, "\n")
191+
);
192+
const expected = (
193+
fs.existsSync(filename) &&
194+
fs.readFileSync(filename, { encoding: "utf8" }).replace(/\r\n/g, "\n")
195+
);
196+
197+
// If a fixture/generated file is missing, false will be compared to a
198+
// string. If both are missing, nothing happens below (as it should).
199+
if (actual !== expected) {
200+
compareFixture.end(FAILURE);
201+
return prepareResult(FAILURE, "fixture mismatch");
202+
}
203+
}
204+
compareFixture.end(SUCCESS);
205+
return;
206+
}
207+
208+
let failed = false;
209+
210+
for (const extension of fixtureExtensions) {
211+
const filename = `${basename}.${mode}.${extension}`;
212+
const actualExists = dummy.has(filename);
213+
const expectedExists = fs.existsSync(filename);
214+
215+
if (!actualExists && !expectedExists) {
216+
// Neither exists, which is perfectly fine. Carry on.
217+
continue;
218+
} else if (actualExists != expectedExists) {
219+
const message = actualExists
220+
? `Fixture ${filename} is missing!`
221+
: `File ${filename} was not generated!`;
222+
223+
console.log(" " + stdoutColors.yellow(message));
224+
failed = true;
225+
continue;
226+
}
227+
228+
const actual = dummy.has(filename) && dummy.get(filename).replace(/\r\n/g, "\n");
229+
const expected = (
230+
fs.existsSync(filename) &&
231+
fs.readFileSync(filename, { encoding: "utf8" }).replace(/\r\n/g, "\n")
232+
);
233+
234+
const diffResult = diff(filename, expected, actual);
235+
if (diffResult !== null) {
236+
console.log(diffResult);
237+
failed = true;
238+
}
239+
}
240+
241+
if (failed) {
242+
compareFixture.end(FAILURE);
243+
return prepareResult(FAILURE, "fixture mismatch");
244+
}
245+
compareFixture.end(SUCCESS);
246+
}
247+
150248
if (config.features) {
151249
config.features.forEach(feature => {
152250
if (!features.includes(feature) && !features.includes("*")) {
@@ -176,15 +274,14 @@ async function runTest(basename) {
176274
{
177275
const cmd = [
178276
basename + ".ts",
179-
"--baseDir", basedir,
180277
"--debug",
181-
"--textFile" // -> stdout
278+
"--outFile", basename + ".debug.wasm",
279+
"--textFile", basename + ".debug.wat"
182280
];
183281
if (asc_flags) cmd.push(...asc_flags);
184-
cmd.push("--outFile", basename + ".debug.wasm");
185282
if (args.noColors) cmd.push("--noColors");
186283
const compileDebug = section("compile debug");
187-
const { error } = await asc.main(cmd, { stdout, stderr });
284+
const { error } = await asc.main(cmd, { stdout, stderr, writeFile });
188285

189286
let expectStderr = config.stderr;
190287
if (error) {
@@ -224,50 +321,28 @@ async function runTest(basename) {
224321
return prepareResult(SUCCESS);
225322
}
226323

227-
const compareFixture = section("compare fixture");
228-
const actual = stdout.toString().replace(/\r\n/g, "\n");
229-
if (args.create) {
230-
fs.writeFileSync(path.join(basedir, basename + ".debug.wat"), actual, { encoding: "utf8" });
231-
console.log(" " + stdoutColors.yellow("Created fixture"));
232-
compareFixture.end(SKIPPED);
233-
} else {
234-
const expected = fs.readFileSync(path.join(basedir, basename + ".debug.wat"), { encoding: "utf8" }).replace(/\r\n/g, "\n");
235-
if (args.noDiff) {
236-
if (expected != actual) {
237-
compareFixture.end(FAILURE);
238-
return prepareResult(FAILURE, "fixture mismatch");
239-
}
240-
} else {
241-
let diffs = diff(basename + ".debug.wat", expected, actual);
242-
if (diffs !== null) {
243-
console.log(diffs);
244-
compareFixture.end(FAILURE);
245-
return prepareResult(FAILURE, "fixture mismatch");
246-
}
247-
}
248-
compareFixture.end(SUCCESS);
249-
}
324+
const afterCompileResult = afterCompile("debug");
325+
if (afterCompileResult) return afterCompileResult;
250326
}
251327

252328
stdout.length = 0;
253329
stderr.length = 0;
254330

255-
const gluePath = path.join(basedir, basename + ".js");
331+
const gluePath = basename + ".js";
256332
const glue = fs.existsSync(gluePath) ? await import(pathToFileURL(gluePath)) : {};
257333

258334
// Build release
259335
{
260336
const cmd = [
261337
basename + ".ts",
262-
"--baseDir", basedir,
263-
"--outFile", // -> stdout
338+
"--outFile", basename + ".release.wasm",
339+
"--textFile", basename + ".release.wat",
264340
"-O"
265341
];
266342
if (asc_flags) cmd.push(...asc_flags);
267-
if (args.create) cmd.push("--textFile", basename + ".release.wat");
268343
if (args.noColors) cmd.push("--noColors");
269344
const compileRelease = section("compile release");
270-
const { error } = await asc.main(cmd, { stdout: stdout, stderr: stderr });
345+
const { error } = await asc.main(cmd, { stdout, stderr, writeFile });
271346

272347
if (error) {
273348
stderr.write("---\n");
@@ -278,15 +353,18 @@ async function runTest(basename) {
278353
}
279354
compileRelease.end(SUCCESS);
280355

356+
const afterCompileResult = afterCompile("release");
357+
if (afterCompileResult) return afterCompileResult;
358+
281359
if (missing_features.length) {
282360
console.log("- " + stdoutColors.yellow("instantiate SKIPPED") + ": " + missing_features.join(", ") + " not enabled\n");
283361
return prepareResult(SKIPPED, "feature not enabled: " + missing_features.join(", "));
284362
} else if (v8_flags) {
285363
v8.setFlagsFromString(v8_flags);
286364
}
287365

288-
const debugBuffer = fs.readFileSync(path.join(basedir, basename + ".debug.wasm"));
289-
const releaseBuffer = stdout.toBuffer();
366+
const debugBuffer = dummy.get(basename + ".debug.wasm");
367+
const releaseBuffer = dummy.get(basename + ".release.wasm");
290368
const instantiateDebug = section("instantiate debug");
291369
if (config.skipInstantiate) {
292370
instantiateDebug.end(SKIPPED);
@@ -313,7 +391,6 @@ async function runTest(basename) {
313391
if (asc_rtrace) {
314392
const cmd = [
315393
basename + ".ts",
316-
"--baseDir", basedir,
317394
"--outFile", // -> stdout
318395
"--debug",
319396
"--use", "ASC_RTRACE=1",

0 commit comments

Comments
 (0)