All checks were successful
wai-quantum docs, course and locales / does this change touch it (pull_request) Successful in 6s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 9s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (pull_request) Successful in 8s
WAI energy receipts / does this change touch it (pull_request) Successful in 10s
wai-quantum for JavaScript / does this change touch it (pull_request) Successful in 7s
wai-quantum docs, course and locales / the Studio's words in every locale · linux (pull_request) Successful in 37s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (pull_request) Successful in 1m13s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (pull_request) Successful in 2m49s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 3m6s
wai-quantum for JavaScript / javascript · linux (pull_request) Successful in 3m7s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 5m7s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 6m33s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 8m31s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 9m6s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 10m53s
wai-quantum docs, course and locales / the course and the command line's languages · linux (pull_request) Successful in 12m23s
wai-quantum docs, course and locales / every command and snippet in the docs · linux (pull_request) Successful in 1h4m5s
wai/wai-quantum-js/ packs the job service's engine for WebAssembly (wai-web with its quantum_engine feature, the engine of wai-quantum 0.7.0) and its bindings as an ES module with its TypeScript declarations and no dependencies, for a page (init() fetches the .wasm beside the module) or for Node (init is given its bytes). The package keeps its own version line, as the Python package does. - build.sh: wai-web built for wasm32 with paths remapped (as the views build does), wasm-bindgen 0.2.127 (refused if it is not the version wai-web's lock file pins), package.json, README and the licence copied, the build refused if a local path is left in the bindings or the binary, then packed. - test/smoke.mjs, on the package unpacked: a job run with a fresh 32-byte key and its receipt verified with this engine's did:key; a forged result that does not verify; a program linted and drawn; a refused program with its diagnostic code (Q310). - test/install.mjs: the README's Node example, run in an empty app that installed the tarball with npm, the package found by name and its .wasm by the subpath it exports. - ci/check.sh runs them all and holds the tarball to the package's allow-list (the seven files and nothing else). - wai-quantum-js.yml runs ci/check.sh on Linux. wai-quantum-js-release.yml runs it on a wai-quantum-cli-v* tag and attaches the tarball and its SHA-256 to the release. Nothing is published to a registry from CI. On the M3 Ultra: the .wasm is 5,928,153 bytes, the tarball 2.26 MB, and every check passes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
56 lines
3 KiB
JavaScript
56 lines
3 KiB
JavaScript
// The package as an installer leaves it: its bindings and its WebAssembly, loaded in
|
|
// Node with nothing else installed.
|
|
//
|
|
// node wai/wai-quantum-js/test/smoke.mjs PACKAGE_DIR
|
|
//
|
|
// Prints one line per check and exits non-zero on the first that fails.
|
|
import assert from 'node:assert/strict';
|
|
import { randomBytes } from 'node:crypto';
|
|
import { readFile } from 'node:fs/promises';
|
|
import { join, resolve } from 'node:path';
|
|
import { pathToFileURL } from 'node:url';
|
|
|
|
const dir = resolve(process.argv[2] ?? '.');
|
|
const pkg = JSON.parse(await readFile(join(dir, 'package.json'), 'utf8'));
|
|
const wq = await import(pathToFileURL(join(dir, pkg.main)).href);
|
|
// In Node the module is given its WebAssembly's bytes; a page lets it fetch them.
|
|
await wq.default({ module_or_path: await readFile(join(dir, 'wai_quantum_bg.wasm')) });
|
|
console.log('node', process.versions.node, pkg.name, pkg.version);
|
|
|
|
const BELL = 'OPENQASM 3.0; qubit[2] q; bit[2] c; h q[0]; cx q[0], q[1]; c = measure q;';
|
|
|
|
// A job run with a fresh key, and its receipt checked.
|
|
const engine = new wq.QuantumEngine(randomBytes(32), 256);
|
|
const signer = engine.signer_did();
|
|
assert.match(signer, /^did:key:z6Mk/, signer);
|
|
const job = JSON.parse(engine.run(JSON.stringify({ qasm: BELL, shots: 1000, seed: 7 })));
|
|
assert.equal(job.status, 'done', JSON.stringify(job).slice(0, 400));
|
|
const counts = job.result.counts;
|
|
assert.ok(Object.keys(counts).length > 0 && Object.keys(counts).every((k) => k === '00' || k === '11'), JSON.stringify(counts));
|
|
const v = JSON.parse(wq.engine_verify(JSON.stringify(job)));
|
|
assert.equal(v.valid, true, JSON.stringify(v));
|
|
assert.equal(v.signer, signer, JSON.stringify(v));
|
|
console.log(`run and verify: ${job.method}, ${Object.values(counts).reduce((a, b) => a + b, 0)} shots, signed by this engine's key`);
|
|
|
|
// A result changed after it was sealed does not verify.
|
|
const forged = structuredClone(job);
|
|
const k = Object.keys(forged.result.counts)[0];
|
|
forged.result.counts[k] += 1;
|
|
assert.notEqual(JSON.parse(wq.engine_verify(JSON.stringify(forged))).valid, true);
|
|
console.log('a forged result does not verify');
|
|
|
|
// A program read and drawn.
|
|
const lint = JSON.parse(wq.engine_lint(BELL));
|
|
assert.equal(lint.ok, true, JSON.stringify(lint));
|
|
assert.equal(lint.qubits, 2, JSON.stringify(lint));
|
|
const drawn = JSON.parse(wq.engine_draw(BELL, 80));
|
|
assert.ok(typeof drawn.text === 'string' && drawn.text.trim().length > 0, JSON.stringify(drawn));
|
|
console.log(`lint and draw: ${lint.qubits} qubits, ${lint.gates} gates; drawn in ${drawn.text.trimEnd().split('\n').length} lines`);
|
|
|
|
// A program the engine refuses says why, with its diagnostic code.
|
|
const WHILE = 'OPENQASM 3.0; qubit[1] q; bit[1] c; c[0] = measure q[0]; while (c[0]) { x q[0]; c[0] = measure q[0]; }';
|
|
const refused = JSON.parse(engine.run(JSON.stringify({ qasm: WHILE, shots: 10 })));
|
|
assert.ok(typeof refused.error === 'string' && /^Q\d{3}$/.test(refused.code ?? ''), JSON.stringify(refused));
|
|
console.log(`a refused program says why: [${refused.code}] ${refused.meaning}`);
|
|
|
|
console.log('smoke: every check passed');
|