-
Notifications
You must be signed in to change notification settings - Fork 70
/
Copy pathasync.browser.js
153 lines (137 loc) · 4.74 KB
/
async.browser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
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();
});
}
});
}