File size: 4,147 Bytes
2ecdf7d 5084a8e 2ecdf7d | 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 | const assert = require("assert");
const fs = require("fs");
const path = require("path");
const vm = require("vm");
const sandbox = { self: {}, setTimeout, clearTimeout, requestAnimationFrame: (callback) => setTimeout(callback, 0), cancelAnimationFrame: clearTimeout };
sandbox.self = sandbox;
for (const file of ["reader-contract.js", "reader-runtime.js", "reader-format-adapters.js"]) vm.runInNewContext(fs.readFileSync(path.join(__dirname, "../static", file), "utf8"), sandbox);
async function main() {
const events = [];
const runtime = sandbox.VoiceOfMLReaderRuntime.createReaderRuntime();
runtime.events.on("*", (_detail, type) => events.push(type));
assert.strictEqual(runtime.update("source", { url: "book" }), true);
assert.strictEqual(runtime.snapshot().source.url, "book");
let documentEvent;
runtime.events.on("state:document", (state) => { documentEvent = state; });
assert.strictEqual(runtime.update("document", { page: 7, restorationReady: true }), true);
assert.strictEqual(documentEvent.document.page, 7);
assert.strictEqual(documentEvent.document.restorationReady, true);
const delayed = runtime.schedule(() => { throw new Error("disposed timer fired"); }, 10000); runtime.cancel(delayed);
assert.strictEqual(runtime.updateFormat("pdf", { activeRenders: 1 }), true);
assert.strictEqual(runtime.snapshot().formats.pdf.activeRenders, 1);
const capability = runtime.negotiate({ mode: "pdf", extension: "pdf" });
assert.deepStrictEqual(JSON.parse(JSON.stringify(capability.features)), { toc: true, search: true, zoom: true, bookmarks: true, pagination: true, media: false });
const first = runtime.nextGeneration("navigation");
assert.strictEqual(runtime.currentGeneration("navigation"), first);
assert.strictEqual(runtime.isCurrent("navigation", first), true);
runtime.nextGeneration("navigation");
assert.strictEqual(runtime.isCurrent("navigation", first), false);
assert.strictEqual(runtime.currentGeneration("search"), 0);
const pdfGeneration = runtime.nextGeneration("pdf");
assert.strictEqual(runtime.currentGeneration("pdf"), pdfGeneration);
assert.strictEqual(runtime.currentGeneration("navigation"), first + 1);
assert.strictEqual(runtime.setStage("prepare"), true);
runtime.fail("READER_PARSE");
assert.strictEqual(runtime.state.lifecycle.phase, "failed");
assert.ok(events.includes("state:source") && events.includes("capability") && events.includes("generation") && events.includes("error"));
const calls = [];
runtime.track(() => calls.push("first")); runtime.track({ dispose: () => calls.push("second") }); runtime.dispose();
assert.deepStrictEqual(calls, ["second", "first"]); assert.strictEqual(runtime.state.lifecycle.phase, "disposed");
assert.strictEqual(runtime.currentGeneration("navigation"), first + 2);
assert.strictEqual(runtime.currentGeneration("pdf"), pdfGeneration + 1);
assert.strictEqual(runtime.update("source", { url: "late" }), false); assert.strictEqual(runtime.setPhase("ready"), false);
const registry = sandbox.VoiceOfMLReaderAdapters.createAdapterRegistry();
assert.throws(() => registry.register("bad", {}), /READER_ADAPTER_METHOD:bad:open/);
let finishOpen; const trace = [];
assert.deepStrictEqual(Array.from(sandbox.VoiceOfMLReaderAdapters.METHODS), ["open", "render", "restore", "dispose"]);
const adapter = registry.register("pdf", {
open: () => new Promise((resolve) => { finishOpen = () => { trace.push("open"); resolve("prepared"); }; }),
render: (value) => trace.push(`render:${value}`),
restore: (value) => trace.push(`restore:${value}`),
dispose: () => trace.push("dispose"),
});
assert.strictEqual(registry.activate("pdf"), adapter);
const opening = adapter.open();
adapter.restore("position");
finishOpen();
await adapter.render(await opening);
registry.dispose();
assert.deepStrictEqual(trace, ["restore:position", "open", "render:prepared", "dispose"]);
assert.throws(() => registry.register("pdf", adapter), /READER_ADAPTER_DUPLICATE/);
console.log("reader runtime contracts passed");
}
main().catch((error) => { console.error(error); process.exitCode = 1; });
|