Skip to content

Commit 22ea45c

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 22ea45c

File tree

1 file changed

+116
-37
lines changed

1 file changed

+116
-37
lines changed

tests/compiler.js

Lines changed: 116 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,107 @@ 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+
// Displaying the diffs in console for release fixtures isn't usually
186+
// meaningful, so release fixtures are compared as if --noDiff was passed.
187+
if (args.noDiff || mode === "release") {
188+
for (const extension of fixtureExtensions) {
189+
const filename = `${basename}.${mode}.${extension}`;
190+
const actual = (
191+
dummy.has(filename) &&
192+
dummy.get(filename).replace(/\r\n/g, "\n")
193+
);
194+
const expected = (
195+
fs.existsSync(filename) &&
196+
fs.readFileSync(filename, { encoding: "utf8" }).replace(/\r\n/g, "\n")
197+
);
198+
199+
// If a fixture/generated file is missing, false will be compared to a
200+
// string. If both are missing, nothing happens below (as it should).
201+
if (actual !== expected) {
202+
compareFixture.end(FAILURE);
203+
return prepareResult(FAILURE, "fixture mismatch");
204+
}
205+
}
206+
compareFixture.end(SUCCESS);
207+
return;
208+
}
209+
210+
let failed = false;
211+
212+
for (const extension of fixtureExtensions) {
213+
const filename = `${basename}.${mode}.${extension}`;
214+
const actualExists = dummy.has(filename);
215+
const expectedExists = fs.existsSync(filename);
216+
217+
if (!actualExists && !expectedExists) {
218+
// Neither exists, which is perfectly fine. Carry on.
219+
continue;
220+
} else if (actualExists != expectedExists) {
221+
const message = actualExists
222+
? `Fixture ${filename} is missing!`
223+
: `File ${filename} was not generated!`;
224+
225+
console.log(" " + stdoutColors.yellow(message));
226+
failed = true;
227+
continue;
228+
}
229+
230+
const actual = dummy.has(filename) && dummy.get(filename).replace(/\r\n/g, "\n");
231+
const expected = (
232+
fs.existsSync(filename) &&
233+
fs.readFileSync(filename, { encoding: "utf8" }).replace(/\r\n/g, "\n")
234+
);
235+
236+
const diffResult = diff(filename, expected, actual);
237+
if (diffResult !== null) {
238+
console.log(diffResult);
239+
failed = true;
240+
}
241+
}
242+
243+
if (failed) {
244+
compareFixture.end(FAILURE);
245+
return prepareResult(FAILURE, "fixture mismatch");
246+
}
247+
compareFixture.end(SUCCESS);
248+
}
249+
150250
if (config.features) {
151251
config.features.forEach(feature => {
152252
if (!features.includes(feature) && !features.includes("*")) {
@@ -176,15 +276,14 @@ async function runTest(basename) {
176276
{
177277
const cmd = [
178278
basename + ".ts",
179-
"--baseDir", basedir,
180279
"--debug",
181-
"--textFile" // -> stdout
280+
"--outFile", basename + ".debug.wasm",
281+
"--textFile", basename + ".debug.wat"
182282
];
183283
if (asc_flags) cmd.push(...asc_flags);
184-
cmd.push("--outFile", basename + ".debug.wasm");
185284
if (args.noColors) cmd.push("--noColors");
186285
const compileDebug = section("compile debug");
187-
const { error } = await asc.main(cmd, { stdout, stderr });
286+
const { error } = await asc.main(cmd, { stdout, stderr, writeFile });
188287

189288
let expectStderr = config.stderr;
190289
if (error) {
@@ -224,50 +323,28 @@ async function runTest(basename) {
224323
return prepareResult(SUCCESS);
225324
}
226325

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-
}
326+
const afterCompileResult = afterCompile("debug");
327+
if (afterCompileResult) return afterCompileResult;
250328
}
251329

252330
stdout.length = 0;
253331
stderr.length = 0;
254332

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

258336
// Build release
259337
{
260338
const cmd = [
261339
basename + ".ts",
262-
"--baseDir", basedir,
263-
"--outFile", // -> stdout
340+
"--outFile", basename + ".release.wasm",
341+
"--textFile", basename + ".release.wat",
264342
"-O"
265343
];
266344
if (asc_flags) cmd.push(...asc_flags);
267-
if (args.create) cmd.push("--textFile", basename + ".release.wat");
268345
if (args.noColors) cmd.push("--noColors");
269346
const compileRelease = section("compile release");
270-
const { error } = await asc.main(cmd, { stdout: stdout, stderr: stderr });
347+
const { error } = await asc.main(cmd, { stdout, stderr, writeFile });
271348

272349
if (error) {
273350
stderr.write("---\n");
@@ -278,15 +355,18 @@ async function runTest(basename) {
278355
}
279356
compileRelease.end(SUCCESS);
280357

358+
const afterCompileResult = afterCompile("release");
359+
if (afterCompileResult) return afterCompileResult;
360+
281361
if (missing_features.length) {
282362
console.log("- " + stdoutColors.yellow("instantiate SKIPPED") + ": " + missing_features.join(", ") + " not enabled\n");
283363
return prepareResult(SKIPPED, "feature not enabled: " + missing_features.join(", "));
284364
} else if (v8_flags) {
285365
v8.setFlagsFromString(v8_flags);
286366
}
287367

288-
const debugBuffer = fs.readFileSync(path.join(basedir, basename + ".debug.wasm"));
289-
const releaseBuffer = stdout.toBuffer();
368+
const debugBuffer = dummy.get(basename + ".debug.wasm");
369+
const releaseBuffer = dummy.get(basename + ".release.wasm");
290370
const instantiateDebug = section("instantiate debug");
291371
if (config.skipInstantiate) {
292372
instantiateDebug.end(SKIPPED);
@@ -313,7 +393,6 @@ async function runTest(basename) {
313393
if (asc_rtrace) {
314394
const cmd = [
315395
basename + ".ts",
316-
"--baseDir", basedir,
317396
"--outFile", // -> stdout
318397
"--debug",
319398
"--use", "ASC_RTRACE=1",

0 commit comments

Comments
 (0)