as-test 1.0.16 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -0
- package/README.md +45 -4
- package/as-test.config.schema.json +5 -0
- package/assembly/__fuzz__/math.fuzz.ts +19 -0
- package/assembly/__fuzz__/string.fuzz.ts +31 -0
- package/assembly/index.ts +5 -5
- package/assembly/src/expectation.ts +93 -42
- package/assembly/util/format.ts +104 -0
- package/assembly/util/helpers.ts +7 -13
- package/assembly/util/json.ts +2 -2
- package/assembly/util/wipc.ts +15 -5
- package/bin/commands/clean-core.js +135 -0
- package/bin/commands/clean.js +51 -0
- package/bin/commands/init-core.js +33 -225
- package/bin/commands/run-core.js +433 -289
- package/bin/commands/web-runner-source.js +14 -700
- package/bin/commands/web-session.js +1144 -0
- package/bin/index.js +391 -78
- package/bin/types.js +1 -0
- package/bin/util.js +16 -1
- package/bin/wipc.js +7 -2
- package/lib/build/index.d.ts +1 -0
- package/lib/build/index.js +1116 -0
- package/lib/build/web-runner/client.d.ts +1 -0
- package/lib/build/web-runner/client.js +167 -0
- package/lib/build/web-runner/html.d.ts +1 -0
- package/lib/build/web-runner/html.js +201 -0
- package/lib/build/web-runner/worker.d.ts +1 -0
- package/lib/build/web-runner/worker.js +271 -0
- package/lib/src/index.ts +1266 -0
- package/package.json +14 -6
- package/transform/lib/mock.js +50 -27
|
@@ -188,7 +188,7 @@ async function runInteractiveOnboarding(options, face) {
|
|
|
188
188
|
},
|
|
189
189
|
{
|
|
190
190
|
value: "web",
|
|
191
|
-
label: "web (default runner: node .as-test/runners/default.web.js
|
|
191
|
+
label: "web (default runner: node .as-test/runners/default.web.js)",
|
|
192
192
|
},
|
|
193
193
|
], face, "wasi"));
|
|
194
194
|
if (options.target || onboardingMode == "quick") {
|
|
@@ -396,10 +396,6 @@ function printPlan(root, target, example, fuzzExample, install) {
|
|
|
396
396
|
path: ".as-test/runners/default.bindings.js",
|
|
397
397
|
isDir: false,
|
|
398
398
|
});
|
|
399
|
-
fileEntries.push({
|
|
400
|
-
path: ".as-test/runners/default.bindings.hooks.js",
|
|
401
|
-
isDir: false,
|
|
402
|
-
});
|
|
403
399
|
fileEntries.push({
|
|
404
400
|
path: ".as-test/runners/default.wasi.js",
|
|
405
401
|
isDir: false,
|
|
@@ -408,10 +404,6 @@ function printPlan(root, target, example, fuzzExample, install) {
|
|
|
408
404
|
path: ".as-test/runners/default.web.js",
|
|
409
405
|
isDir: false,
|
|
410
406
|
});
|
|
411
|
-
fileEntries.push({
|
|
412
|
-
path: ".as-test/runners/default.web.hooks.js",
|
|
413
|
-
isDir: false,
|
|
414
|
-
});
|
|
415
407
|
}
|
|
416
408
|
if (example != "none") {
|
|
417
409
|
fileEntries.push({
|
|
@@ -484,19 +476,28 @@ function applyInit(root, target, example, fuzzExample, force) {
|
|
|
484
476
|
runOptions: {
|
|
485
477
|
runtime: {
|
|
486
478
|
cmd: target == "wasi"
|
|
487
|
-
? "node .as-test/runners/default.wasi.js
|
|
479
|
+
? "node .as-test/runners/default.wasi.js"
|
|
488
480
|
: target == "bindings"
|
|
489
|
-
? "node .as-test/runners/default.bindings.js
|
|
490
|
-
: "node .as-test/runners/default.web.js
|
|
481
|
+
? "node .as-test/runners/default.bindings.js"
|
|
482
|
+
: "node .as-test/runners/default.web.js",
|
|
491
483
|
},
|
|
492
484
|
reporter: "default",
|
|
493
485
|
},
|
|
494
486
|
modes: target == "web"
|
|
495
487
|
? {
|
|
488
|
+
web: {
|
|
489
|
+
default: false,
|
|
490
|
+
runOptions: {
|
|
491
|
+
runtime: {
|
|
492
|
+
cmd: "node .as-test/runners/default.web.js",
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
496
|
"web-headless": {
|
|
497
|
+
default: false,
|
|
497
498
|
runOptions: {
|
|
498
499
|
runtime: {
|
|
499
|
-
cmd: "node .as-test/runners/default.web.js --headless
|
|
500
|
+
cmd: "node .as-test/runners/default.web.js --headless",
|
|
500
501
|
},
|
|
501
502
|
},
|
|
502
503
|
},
|
|
@@ -521,18 +522,10 @@ function applyInit(root, target, example, fuzzExample, force) {
|
|
|
521
522
|
const runnerPath = path.join(root, ".as-test/runners/default.bindings.js");
|
|
522
523
|
writeManagedFile(runnerPath, buildBindingsRunner(), force, summary, ".as-test/runners/default.bindings.js");
|
|
523
524
|
}
|
|
524
|
-
if (target == "wasi" || target == "bindings" || target == "web") {
|
|
525
|
-
const hooksPath = path.join(root, ".as-test/runners/default.bindings.hooks.js");
|
|
526
|
-
writeManagedFile(hooksPath, buildBindingsRunnerHooks(), force, summary, ".as-test/runners/default.bindings.hooks.js");
|
|
527
|
-
}
|
|
528
525
|
if (target == "wasi" || target == "bindings" || target == "web") {
|
|
529
526
|
const runnerPath = path.join(root, ".as-test/runners/default.web.js");
|
|
530
527
|
writeManagedFile(runnerPath, buildWebRunnerSource(), force, summary, ".as-test/runners/default.web.js");
|
|
531
528
|
}
|
|
532
|
-
if (target == "wasi" || target == "bindings" || target == "web") {
|
|
533
|
-
const hooksPath = path.join(root, ".as-test/runners/default.web.hooks.js");
|
|
534
|
-
writeManagedFile(hooksPath, buildWebRunnerHooks(), force, summary, ".as-test/runners/default.web.hooks.js");
|
|
535
|
-
}
|
|
536
529
|
const pkgPath = path.join(root, "package.json");
|
|
537
530
|
const pkg = existsSync(pkgPath)
|
|
538
531
|
? JSON.parse(readFileSync(pkgPath, "utf8"))
|
|
@@ -989,217 +982,32 @@ fuzz("basic string fuzzer", (value: string): bool => {
|
|
|
989
982
|
`;
|
|
990
983
|
}
|
|
991
984
|
function buildWasiRunner() {
|
|
992
|
-
return `import {
|
|
993
|
-
import { WASI } from "wasi";
|
|
985
|
+
return `import { instantiate } from "as-test/lib";
|
|
994
986
|
|
|
995
|
-
const
|
|
996
|
-
process.emitWarning = ((warning, ...args) => {
|
|
997
|
-
const type = typeof args[0] == "string" ? args[0] : "";
|
|
998
|
-
const name = typeof warning?.name == "string" ? warning.name : type;
|
|
999
|
-
const message =
|
|
1000
|
-
typeof warning == "string" ? warning : String(warning?.message ?? "");
|
|
1001
|
-
if (
|
|
1002
|
-
name == "ExperimentalWarning" &&
|
|
1003
|
-
message.includes("WASI is an experimental feature")
|
|
1004
|
-
) {
|
|
1005
|
-
return;
|
|
1006
|
-
}
|
|
1007
|
-
return originalEmitWarning(warning, ...args);
|
|
1008
|
-
});
|
|
1009
|
-
|
|
1010
|
-
const wasmPath = process.argv[2];
|
|
1011
|
-
if (!wasmPath) {
|
|
1012
|
-
process.stderr.write("usage: node ./.as-test/runners/default.wasi.js <file.wasm>\\n");
|
|
1013
|
-
process.exit(1);
|
|
1014
|
-
}
|
|
987
|
+
const imports = {};
|
|
1015
988
|
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
989
|
+
instantiate(imports)
|
|
990
|
+
.then((instance) => {
|
|
991
|
+
instance.exports.start?.();
|
|
992
|
+
// Add extra startup logic here when needed.
|
|
993
|
+
})
|
|
994
|
+
.catch((error) => {
|
|
995
|
+
throw new Error("Failed to run WASI module: " + String(error));
|
|
1022
996
|
});
|
|
1023
|
-
|
|
1024
|
-
const binary = readFileSync(wasmPath);
|
|
1025
|
-
const module = new WebAssembly.Module(binary);
|
|
1026
|
-
const instance = new WebAssembly.Instance(module, {
|
|
1027
|
-
env: {
|
|
1028
|
-
__as_test_request_fuzz_config() {
|
|
1029
|
-
return 0;
|
|
1030
|
-
},
|
|
1031
|
-
},
|
|
1032
|
-
wasi_snapshot_preview1: wasi.wasiImport,
|
|
1033
|
-
});
|
|
1034
|
-
wasi.start(instance);
|
|
1035
|
-
} catch (error) {
|
|
1036
|
-
process.stderr.write("failed to run WASI module: " + String(error) + "\\n");
|
|
1037
|
-
process.exit(1);
|
|
1038
|
-
}
|
|
1039
997
|
`;
|
|
1040
998
|
}
|
|
1041
999
|
function buildBindingsRunner() {
|
|
1042
|
-
return `import
|
|
1043
|
-
import path from "path";
|
|
1044
|
-
import { pathToFileURL } from "url";
|
|
1045
|
-
|
|
1046
|
-
const HOOKS_PATH = path.resolve(
|
|
1047
|
-
path.dirname(new URL(import.meta.url).pathname),
|
|
1048
|
-
"./default.bindings.hooks.js",
|
|
1049
|
-
);
|
|
1000
|
+
return `import { instantiate } from "as-test/lib";
|
|
1050
1001
|
|
|
1051
|
-
|
|
1052
|
-
const out = Buffer.alloc(length);
|
|
1053
|
-
let offset = 0;
|
|
1054
|
-
while (offset < length) {
|
|
1055
|
-
let read = 0;
|
|
1056
|
-
try {
|
|
1057
|
-
read = fs.readSync(0, out, offset, length - offset, null);
|
|
1058
|
-
} catch (error) {
|
|
1059
|
-
if (error && error.code === "EAGAIN") {
|
|
1060
|
-
continue;
|
|
1061
|
-
}
|
|
1062
|
-
throw error;
|
|
1063
|
-
}
|
|
1064
|
-
if (!read) break;
|
|
1065
|
-
offset += read;
|
|
1066
|
-
}
|
|
1067
|
-
const view = out.subarray(0, offset);
|
|
1068
|
-
return view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
function writeRaw(data) {
|
|
1072
|
-
const view = Buffer.from(data);
|
|
1073
|
-
fs.writeSync(1, view);
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
function createRunnerContext({ wasmPath, module, helperPath }) {
|
|
1077
|
-
return {
|
|
1078
|
-
wasmPath,
|
|
1079
|
-
helperPath,
|
|
1080
|
-
module,
|
|
1081
|
-
argv: process.argv.slice(2),
|
|
1082
|
-
env: process.env,
|
|
1083
|
-
readFrame(size) {
|
|
1084
|
-
return readExact(Number(size ?? 0));
|
|
1085
|
-
},
|
|
1086
|
-
writeFrame(data) {
|
|
1087
|
-
writeRaw(data);
|
|
1088
|
-
return true;
|
|
1089
|
-
},
|
|
1090
|
-
};
|
|
1091
|
-
}
|
|
1002
|
+
const imports = {};
|
|
1092
1003
|
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
};
|
|
1101
|
-
process.stdin.read = (size) => ctx.readFrame(size);
|
|
1102
|
-
return {};
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
function mergeImports(...groups) {
|
|
1106
|
-
const out = {};
|
|
1107
|
-
for (const group of groups) {
|
|
1108
|
-
if (!group || typeof group != "object") continue;
|
|
1109
|
-
for (const moduleName of Object.keys(group)) {
|
|
1110
|
-
out[moduleName] = Object.assign(out[moduleName] || {}, group[moduleName]);
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
return out;
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
async function loadRunnerHooks() {
|
|
1117
|
-
if (!fs.existsSync(HOOKS_PATH)) {
|
|
1118
|
-
return {
|
|
1119
|
-
createUserImports() {
|
|
1120
|
-
return {};
|
|
1121
|
-
},
|
|
1122
|
-
async runModule(_exports, _ctx) {},
|
|
1123
|
-
};
|
|
1124
|
-
}
|
|
1125
|
-
const mod = await import(pathToFileURL(HOOKS_PATH).href + "?t=" + Date.now());
|
|
1126
|
-
return {
|
|
1127
|
-
createUserImports:
|
|
1128
|
-
typeof mod.createUserImports == "function"
|
|
1129
|
-
? mod.createUserImports
|
|
1130
|
-
: () => ({}),
|
|
1131
|
-
runModule:
|
|
1132
|
-
typeof mod.runModule == "function" ? mod.runModule : async () => {},
|
|
1133
|
-
};
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
async function instantiateModule(ctx, hooks) {
|
|
1137
|
-
const helper = await import(pathToFileURL(ctx.helperPath).href);
|
|
1138
|
-
if (typeof helper.instantiate !== "function") {
|
|
1139
|
-
throw new Error("bindings helper missing instantiate export");
|
|
1140
|
-
}
|
|
1141
|
-
const imports = mergeImports(
|
|
1142
|
-
createAsTestImports(ctx),
|
|
1143
|
-
await hooks.createUserImports(ctx),
|
|
1144
|
-
);
|
|
1145
|
-
return helper.instantiate(ctx.module, imports);
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
const wasmPathArg = process.argv[2];
|
|
1149
|
-
if (!wasmPathArg) {
|
|
1150
|
-
process.stderr.write("usage: node ./.as-test/runners/default.bindings.js <file.wasm>\\n");
|
|
1151
|
-
process.exit(1);
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
const wasmPath = path.resolve(process.cwd(), wasmPathArg);
|
|
1155
|
-
const jsPath = wasmPath.replace(/\\.wasm$/, ".js");
|
|
1156
|
-
|
|
1157
|
-
try {
|
|
1158
|
-
const binary = fs.readFileSync(wasmPath);
|
|
1159
|
-
const module = new WebAssembly.Module(binary);
|
|
1160
|
-
const ctx = createRunnerContext({ wasmPath, module, helperPath: jsPath });
|
|
1161
|
-
const hooks = await loadRunnerHooks();
|
|
1162
|
-
const exports = await instantiateModule(ctx, hooks);
|
|
1163
|
-
await hooks.runModule(exports, ctx);
|
|
1164
|
-
} catch (error) {
|
|
1165
|
-
process.stderr.write("failed to run bindings module: " + String(error) + "\\n");
|
|
1166
|
-
process.exit(1);
|
|
1167
|
-
}
|
|
1168
|
-
`;
|
|
1169
|
-
}
|
|
1170
|
-
function buildBindingsRunnerHooks() {
|
|
1171
|
-
return `export function createUserImports(_ctx) {
|
|
1172
|
-
return {
|
|
1173
|
-
// env: {
|
|
1174
|
-
// now_ms: () => Date.now(),
|
|
1175
|
-
// },
|
|
1176
|
-
};
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
export async function runModule(_exports, _ctx) {
|
|
1180
|
-
// The generated bindings helper already calls exports._start().
|
|
1181
|
-
// Add extra startup calls here when your module exposes them.
|
|
1182
|
-
//
|
|
1183
|
-
// Example:
|
|
1184
|
-
// _exports.run?.();
|
|
1185
|
-
}
|
|
1186
|
-
`;
|
|
1187
|
-
}
|
|
1188
|
-
function buildWebRunnerHooks() {
|
|
1189
|
-
return `export function createUserImports(_ctx) {
|
|
1190
|
-
return {
|
|
1191
|
-
// env: {
|
|
1192
|
-
// now_ms: () => performance.now(),
|
|
1193
|
-
// },
|
|
1194
|
-
};
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
export async function runModule(_exports, _ctx) {
|
|
1198
|
-
// The generated bindings helper already calls exports._start().
|
|
1199
|
-
// Add extra startup calls here when your module exposes them.
|
|
1200
|
-
//
|
|
1201
|
-
// Example:
|
|
1202
|
-
// _exports.run?.();
|
|
1203
|
-
}
|
|
1004
|
+
instantiate(imports)
|
|
1005
|
+
.then((instance) => {
|
|
1006
|
+
instance.exports.start?.();
|
|
1007
|
+
// Add extra startup logic here when needed.
|
|
1008
|
+
})
|
|
1009
|
+
.catch((error) => {
|
|
1010
|
+
throw new Error("Failed to run bindings module: " + String(error));
|
|
1011
|
+
});
|
|
1204
1012
|
`;
|
|
1205
1013
|
}
|