Skip to content

Commit 9480469

Browse files
authored
Small fixes for tests and CI (AssemblyScript#2722)
1 parent 382aabe commit 9480469

File tree

12 files changed

+333
-242
lines changed

12 files changed

+333
-242
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ jobs:
8383
env:
8484
ASC_FEATURES: threads,reference-types,gc,exception-handling
8585
run: |
86-
npm run test:compiler features/threads features/reference-types features/gc features/exception-handling
86+
npm run test:compiler features/threads features/reference-types features/gc features/exception-handling bindings/esm bindings/raw
8787
runtimes:
8888
name: "Runtimes"
8989
runs-on: ubuntu-latest

cli/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ export interface APIOptions {
165165
/** Reads a file from disk (or memory). */
166166
readFile?: (filename: string, baseDir: string) => (string | null) | Promise<string | null>;
167167
/** Writes a file to disk (or memory). */
168-
writeFile?: (filename: string, contents: Uint8Array, baseDir: string) => void | Promise<void>;
168+
writeFile?: (filename: string, contents: Uint8Array | string, baseDir: string) => void | Promise<void>;
169169
/** Lists all files within a directory. */
170170
listFiles?: (dirname: string, baseDir: string) => (string[] | null) | Promise<string[] | null>;
171171
/** Handler for diagnostic messages. */

tests/compiler.js

Lines changed: 123 additions & 43 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,15 +146,111 @@ 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("*")) {
153253
missing_features.push(feature);
154-
return; // from forEach
155254
}
156255
let featureConfig = featuresConfig[feature];
157256
if (featureConfig.asc_flags) {
@@ -166,13 +265,8 @@ async function runTest(basename) {
166265
if (v8_no_flags) v8_no_flags += " ";
167266
v8_no_flags += "--no-" + flag.substring(2);
168267
});
169-
v8.setFlagsFromString(v8_flags);
170268
}
171269
});
172-
if (missing_features.length) {
173-
console.log("- " + stdoutColors.yellow("feature SKIPPED") + " (" + missing_features.join(", ") + ")\n");
174-
return prepareResult(SKIPPED, "feature not enabled: " + missing_features.join(", "));
175-
}
176270
}
177271
if (config.asc_flags) {
178272
config.asc_flags.forEach(flag => { asc_flags.push(...flag.split(" ")); });
@@ -182,15 +276,14 @@ async function runTest(basename) {
182276
{
183277
const cmd = [
184278
basename + ".ts",
185-
"--baseDir", basedir,
186279
"--debug",
187-
"--textFile" // -> stdout
280+
"--outFile", basename + ".debug.wasm",
281+
"--textFile", basename + ".debug.wat"
188282
];
189283
if (asc_flags) cmd.push(...asc_flags);
190-
cmd.push("--outFile", basename + ".debug.wasm");
191284
if (args.noColors) cmd.push("--noColors");
192285
const compileDebug = section("compile debug");
193-
const { error } = await asc.main(cmd, { stdout, stderr });
286+
const { error } = await asc.main(cmd, { stdout, stderr, writeFile });
194287

195288
let expectStderr = config.stderr;
196289
if (error) {
@@ -230,50 +323,28 @@ async function runTest(basename) {
230323
return prepareResult(SUCCESS);
231324
}
232325

233-
const compareFixture = section("compare fixture");
234-
const actual = stdout.toString().replace(/\r\n/g, "\n");
235-
if (args.create) {
236-
fs.writeFileSync(path.join(basedir, basename + ".debug.wat"), actual, { encoding: "utf8" });
237-
console.log(" " + stdoutColors.yellow("Created fixture"));
238-
compareFixture.end(SKIPPED);
239-
} else {
240-
const expected = fs.readFileSync(path.join(basedir, basename + ".debug.wat"), { encoding: "utf8" }).replace(/\r\n/g, "\n");
241-
if (args.noDiff) {
242-
if (expected != actual) {
243-
compareFixture.end(FAILURE);
244-
return prepareResult(FAILURE, "fixture mismatch");
245-
}
246-
} else {
247-
let diffs = diff(basename + ".debug.wat", expected, actual);
248-
if (diffs !== null) {
249-
console.log(diffs);
250-
compareFixture.end(FAILURE);
251-
return prepareResult(FAILURE, "fixture mismatch");
252-
}
253-
}
254-
compareFixture.end(SUCCESS);
255-
}
326+
const afterCompileResult = afterCompile("debug");
327+
if (afterCompileResult) return afterCompileResult;
256328
}
257329

258330
stdout.length = 0;
259331
stderr.length = 0;
260332

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

264336
// Build release
265337
{
266338
const cmd = [
267339
basename + ".ts",
268-
"--baseDir", basedir,
269-
"--outFile", // -> stdout
340+
"--outFile", basename + ".release.wasm",
341+
"--textFile", basename + ".release.wat",
270342
"-O"
271343
];
272344
if (asc_flags) cmd.push(...asc_flags);
273-
if (args.create) cmd.push("--textFile", basename + ".release.wat");
274345
if (args.noColors) cmd.push("--noColors");
275346
const compileRelease = section("compile release");
276-
const { error } = await asc.main(cmd, { stdout: stdout, stderr: stderr });
347+
const { error } = await asc.main(cmd, { stdout, stderr, writeFile });
277348

278349
if (error) {
279350
stderr.write("---\n");
@@ -284,8 +355,18 @@ async function runTest(basename) {
284355
}
285356
compileRelease.end(SUCCESS);
286357

287-
const debugBuffer = fs.readFileSync(path.join(basedir, basename + ".debug.wasm"));
288-
const releaseBuffer = stdout.toBuffer();
358+
const afterCompileResult = afterCompile("release");
359+
if (afterCompileResult) return afterCompileResult;
360+
361+
if (missing_features.length) {
362+
console.log("- " + stdoutColors.yellow("instantiate SKIPPED") + ": " + missing_features.join(", ") + " not enabled\n");
363+
return prepareResult(SKIPPED, "feature not enabled: " + missing_features.join(", "));
364+
} else if (v8_flags) {
365+
v8.setFlagsFromString(v8_flags);
366+
}
367+
368+
const debugBuffer = dummy.get(basename + ".debug.wasm");
369+
const releaseBuffer = dummy.get(basename + ".release.wasm");
289370
const instantiateDebug = section("instantiate debug");
290371
if (config.skipInstantiate) {
291372
instantiateDebug.end(SKIPPED);
@@ -312,7 +393,6 @@ async function runTest(basename) {
312393
if (asc_rtrace) {
313394
const cmd = [
314395
basename + ".ts",
315-
"--baseDir", basedir,
316396
"--outFile", // -> stdout
317397
"--debug",
318398
"--use", "ASC_RTRACE=1",

0 commit comments

Comments
 (0)