mirror of
https://github.com/encounter/jco.git
synced 2026-03-30 11:18:26 -07:00
154 lines
4.7 KiB
JavaScript
154 lines
4.7 KiB
JavaScript
import { dirname, join, resolve } from "node:path";
|
|
import { execArgv } from "node:process";
|
|
import { deepStrictEqual, ok, strictEqual, fail } from "node:assert";
|
|
import { mkdir, readFile, rm, symlink, writeFile } from "node:fs/promises";
|
|
|
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
import puppeteer from "puppeteer";
|
|
|
|
import {
|
|
exec,
|
|
jcoPath,
|
|
getTmpDir,
|
|
setupAsyncTest,
|
|
startTestWebServer,
|
|
loadTestPage,
|
|
} from "./helpers.js";
|
|
|
|
const multiMemory = execArgv.includes("--experimental-wasm-multi-memory")
|
|
? ["--multi-memory"]
|
|
: [];
|
|
|
|
const AsyncFunction = (async () => {}).constructor;
|
|
|
|
export async function asyncBrowserTest(_fixtures) {
|
|
suite("Async", () => {
|
|
var tmpDir;
|
|
var outDir;
|
|
var outFile;
|
|
|
|
suiteSetup(async function () {
|
|
tmpDir = await getTmpDir();
|
|
outDir = resolve(tmpDir, "out-component-dir");
|
|
outFile = resolve(tmpDir, "out-component-file");
|
|
|
|
const modulesDir = resolve(tmpDir, "node_modules", "@bytecodealliance");
|
|
await mkdir(modulesDir, { recursive: true });
|
|
await symlink(
|
|
fileURLToPath(new URL("../packages/preview2-shim", import.meta.url)),
|
|
resolve(modulesDir, "preview2-shim"),
|
|
"dir",
|
|
);
|
|
});
|
|
|
|
suiteTeardown(async function () {
|
|
try {
|
|
await rm(tmpDir, { recursive: true });
|
|
} catch {}
|
|
});
|
|
|
|
teardown(async function () {
|
|
try {
|
|
await rm(outDir, { recursive: true });
|
|
await rm(outFile);
|
|
} catch {}
|
|
});
|
|
|
|
if (typeof WebAssembly?.Suspending === "function") {
|
|
test("Transpile async (browser, JSPI)", async () => {
|
|
const componentName = "async-call";
|
|
const {
|
|
instance,
|
|
cleanup: componentCleanup,
|
|
outputDir,
|
|
} = await setupAsyncTest({
|
|
asyncMode: "jspi",
|
|
component: {
|
|
name: "async_call",
|
|
path: resolve("test/fixtures/components/async_call.component.wasm"),
|
|
imports: {
|
|
"something:test/test-interface": {
|
|
callAsync: async () => "called async",
|
|
callSync: () => "called sync",
|
|
},
|
|
},
|
|
},
|
|
jco: {
|
|
transpile: {
|
|
extraArgs: {
|
|
asyncImports: ["something:test/test-interface#call-async"],
|
|
asyncExports: ["run-async"],
|
|
},
|
|
},
|
|
},
|
|
});
|
|
const moduleName = componentName.toLowerCase().replaceAll("-", "_");
|
|
const moduleRelPath = `${moduleName}/${moduleName}.js`;
|
|
|
|
strictEqual(
|
|
instance.runSync instanceof AsyncFunction,
|
|
false,
|
|
"runSync() should be a sync function",
|
|
);
|
|
strictEqual(
|
|
instance.runAsync instanceof AsyncFunction,
|
|
true,
|
|
"runAsync() should be an async function",
|
|
);
|
|
|
|
// Start a test web server
|
|
const {
|
|
server,
|
|
serverPort,
|
|
cleanup: webServerCleanup,
|
|
} = await startTestWebServer({
|
|
routes: [
|
|
// NOTE: the goal here is to serve relative paths via the browser hash
|
|
//
|
|
// (1) browser visits test page (served by test web server)
|
|
// (2) browser requests component itself by looking at URL hash fragment
|
|
// (i.e. "#transpiled:async_call/async_call.js" -> , "/transpiled/async_call/async_call.js")
|
|
// (i.e. "/transpiled/async_call/async_call.js" -> file read of /tmp/xxxxxx/async_call/async_call.js)
|
|
{
|
|
urlPrefix: "/transpiled/",
|
|
basePathURL: pathToFileURL(`${outputDir}/`),
|
|
},
|
|
// Serve all other files (ex. the initial HTML for the page)
|
|
{ basePathURL: import.meta.url },
|
|
],
|
|
});
|
|
|
|
// Start a browser to visit the test server
|
|
const browser = await puppeteer.launch({
|
|
args: [
|
|
"--enable-experimental-webassembly-jspi",
|
|
"--flag-switches-begin",
|
|
"--enable-features=WebAssemblyExperimentalJSPI",
|
|
"--flag-switches-end",
|
|
],
|
|
});
|
|
|
|
// Load the test page in the browser, which will trigger tests against
|
|
// the component and/or related browser polyfills
|
|
const {
|
|
page,
|
|
output: { json },
|
|
} = await loadTestPage({
|
|
browser,
|
|
serverPort,
|
|
path: "fixtures/browser/test-pages/something__test.async.html",
|
|
hash: `transpiled:${moduleRelPath}`,
|
|
});
|
|
|
|
// Check the output expected to be returned from handle of the
|
|
// guest export (this depends on the component)
|
|
deepStrictEqual(json, { responseText: "callAsync" });
|
|
|
|
await browser.close();
|
|
await webServerCleanup();
|
|
await componentCleanup();
|
|
});
|
|
}
|
|
});
|
|
}
|