177 lines
5.3 KiB
JavaScript
177 lines
5.3 KiB
JavaScript
const textDecoder = new TextDecoder();
|
|
const textEncoder = new TextEncoder();
|
|
const linuxCncParameterScratchFiles = ["rs274ngc.var", "rs274ngc.var.new", "rs274ngc.var.bak"];
|
|
|
|
export function createBrowserSmokeHarness(result) {
|
|
const sectionResults = [];
|
|
const near = (actual, expected) => Math.abs(actual - expected) < 1e-6;
|
|
const waitFor = async (predicate, message) => {
|
|
for (let i = 0; i < 50; i += 1) {
|
|
if (predicate()) {
|
|
return;
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
}
|
|
throw new Error(message);
|
|
};
|
|
const runSection = async (name, action) => {
|
|
const sectionNumber = sectionResults.length + 1;
|
|
result.textContent = `running: ${sectionNumber}: ${name}`;
|
|
try {
|
|
await action();
|
|
sectionResults.push(name);
|
|
} catch (error) {
|
|
const detail = error && error.stack ? error.stack : error;
|
|
throw new Error(`section "${name}" failed: ${detail}`);
|
|
}
|
|
};
|
|
const completedMessage = () => `browser wasm smoke passed (${sectionResults.length} sections)`;
|
|
const browserHasOpfs = () => navigator.storage && navigator.storage.getDirectory;
|
|
const expectEvent = (events, predicate, message) => {
|
|
if (!events.some(predicate)) {
|
|
throw new Error(message);
|
|
}
|
|
};
|
|
const expectNoEvent = (events, predicate, message) => {
|
|
if (events.some(predicate)) {
|
|
throw new Error(message);
|
|
}
|
|
};
|
|
const expectText = (actual, expected, message) => {
|
|
if (actual !== expected) {
|
|
throw new Error(message);
|
|
}
|
|
};
|
|
const expectIncludes = (actual, expected, message) => {
|
|
if (!actual.includes(expected)) {
|
|
throw new Error(message);
|
|
}
|
|
};
|
|
const expectFileList = (actual, expected, message) => {
|
|
if (
|
|
actual.length !== expected.length ||
|
|
expected.some((entry) => !actual.includes(entry))
|
|
) {
|
|
throw new Error(`${message}: ${actual.join(",")}`);
|
|
}
|
|
};
|
|
const expectErrorContaining = async (action, expectedText, message) => {
|
|
try {
|
|
await action();
|
|
throw new Error(message);
|
|
} catch (error) {
|
|
if (!String(error?.message ?? error).includes(expectedText)) {
|
|
throw error;
|
|
}
|
|
}
|
|
};
|
|
const expectMissingOpfsFile = async (action, message) => {
|
|
try {
|
|
await action();
|
|
throw new Error(message);
|
|
} catch (error) {
|
|
if (error?.name !== "NotFoundError") {
|
|
throw error;
|
|
}
|
|
}
|
|
};
|
|
const expectMissingWasmPath = (action, message) => {
|
|
try {
|
|
action();
|
|
throw new Error(message);
|
|
} catch (error) {
|
|
if (error?.errno !== 44) {
|
|
throw error;
|
|
}
|
|
}
|
|
};
|
|
const expectWasmFilesMissing = (fs, paths, messageForPath) => {
|
|
for (const wasmPath of paths) {
|
|
expectMissingWasmPath(
|
|
() => fs.readFile(wasmPath),
|
|
messageForPath(wasmPath),
|
|
);
|
|
}
|
|
};
|
|
const decodeBytes = (bytes) => textDecoder.decode(bytes);
|
|
const encodeText = (text) => textEncoder.encode(text);
|
|
const readOpfsText = async (simulator, path) => decodeBytes(await simulator.fs.opfs.readFile(path));
|
|
const readWasmText = (simulator, path) => decodeBytes(simulator.fs.module.FS.readFile(path));
|
|
const writeWasmText = (simulator, path, text) => simulator.fs.module.FS.writeFile(path, encodeText(text));
|
|
const removeWasmPathIfExists = (simulator, path) => {
|
|
try {
|
|
simulator.fs.module.FS.unlink(path);
|
|
} catch (error) {
|
|
if (error?.errno !== 44) {
|
|
throw error;
|
|
}
|
|
}
|
|
};
|
|
const expectOpfsText = async (simulator, path, expected, message) => {
|
|
expectText(await readOpfsText(simulator, path), expected, message);
|
|
};
|
|
const expectWasmText = (simulator, path, expected, message) => {
|
|
expectText(readWasmText(simulator, path), expected, message);
|
|
};
|
|
const expectOpfsExists = async (simulator, path, message) => {
|
|
if (!(await simulator.fs.opfs.exists(path))) {
|
|
throw new Error(message);
|
|
}
|
|
};
|
|
const expectOpfsMissing = async (simulator, path, message) => {
|
|
if (await simulator.fs.opfs.exists(path)) {
|
|
throw new Error(message);
|
|
}
|
|
};
|
|
const expectOpfsFileStat = async (simulator, path, expectedSize, message) => {
|
|
const stat = await simulator.fs.opfs.stat(path);
|
|
if (stat.kind !== "file" || stat.size !== expectedSize) {
|
|
throw new Error(message);
|
|
}
|
|
};
|
|
const expectOpfsDirectoryStat = async (simulator, path, message) => {
|
|
const stat = await simulator.fs.opfs.stat(path);
|
|
if (stat.kind !== "directory" || stat.size !== null) {
|
|
throw new Error(message);
|
|
}
|
|
};
|
|
const expectLinuxCncParameterScratchMissing = (simulator, messageForPath) => {
|
|
for (const parameterPath of linuxCncParameterScratchFiles) {
|
|
expectMissingWasmPath(
|
|
() => simulator.fs.module.FS.stat(parameterPath),
|
|
messageForPath(parameterPath),
|
|
);
|
|
}
|
|
};
|
|
|
|
return {
|
|
browserHasOpfs,
|
|
completedMessage,
|
|
decodeBytes,
|
|
encodeText,
|
|
expectErrorContaining,
|
|
expectEvent,
|
|
expectFileList,
|
|
expectIncludes,
|
|
expectLinuxCncParameterScratchMissing,
|
|
expectMissingOpfsFile,
|
|
expectMissingWasmPath,
|
|
expectNoEvent,
|
|
expectOpfsDirectoryStat,
|
|
expectOpfsExists,
|
|
expectOpfsFileStat,
|
|
expectOpfsMissing,
|
|
expectOpfsText,
|
|
expectText,
|
|
expectWasmFilesMissing,
|
|
expectWasmText,
|
|
near,
|
|
readOpfsText,
|
|
readWasmText,
|
|
removeWasmPathIfExists,
|
|
runSection,
|
|
waitFor,
|
|
writeWasmText,
|
|
};
|
|
}
|