|
| 1 | +import assert from "node:assert/strict" |
| 2 | +import { readFile } from "node:fs/promises" |
| 3 | +import { RUNTIME_CAPTURE_STATUS_SCHEMA, runtimeCaptureStatus } from "../packages/runtime-playground/src/public.js" |
| 4 | +import * as playgroundPublicApi from "../packages/runtime-playground/src/public.js" |
| 5 | +import type { CanonicalChangedFiles, WorkspacePatchArtifact } from "../packages/runtime-playground/src/artifacts.js" |
| 6 | +import type { RuntimeSnapshotArtifact } from "../packages/runtime-playground/src/runtime-snapshot.js" |
| 7 | + |
| 8 | +const snapshot: RuntimeSnapshotArtifact = { |
| 9 | + schema: "wp-codebox/wordpress-runtime-snapshot/v1", |
| 10 | + version: 1, |
| 11 | + id: "snapshot-1", |
| 12 | + createdAt: "2026-01-01T00:00:00.000Z", |
| 13 | + compatibility: { backend: "wordpress-playground", wordpressVersion: "6.9", phpVersion: "8.3" }, |
| 14 | + metadata: { |
| 15 | + runtime: { |
| 16 | + id: "runtime-1", |
| 17 | + backend: "wordpress-playground", |
| 18 | + status: "running", |
| 19 | + createdAt: "2026-01-01T00:00:00.000Z", |
| 20 | + environment: { kind: "wordpress", version: "6.9", phpVersion: "8.3" }, |
| 21 | + }, |
| 22 | + mounts: [], |
| 23 | + mountedInputs: [], |
| 24 | + activeTheme: "twentytwentyfive", |
| 25 | + activePlugins: ["example/example.php"], |
| 26 | + wpContentPath: "/wordpress/wp-content", |
| 27 | + }, |
| 28 | + database: { tables: [{ name: "wp_options", createSql: "CREATE TABLE wp_options (option_id int)", rows: [], rowCount: 0 }] }, |
| 29 | + files: [{ scope: "wp-content", path: "themes/twentytwentyfive/style.css", bytes: 12, sha256: "a".repeat(64), base64: "ZXhhbXBsZQ==" }], |
| 30 | + hashes: { database: { algorithm: "sha256", value: "b".repeat(64) }, files: { algorithm: "sha256", value: "c".repeat(64) } }, |
| 31 | +} |
| 32 | + |
| 33 | +const cleanChangedFiles: CanonicalChangedFiles = { schema: "wp-codebox/changed-files/v1", files: [] } |
| 34 | +const changedFiles: CanonicalChangedFiles = { |
| 35 | + schema: "wp-codebox/changed-files/v1", |
| 36 | + files: [ |
| 37 | + { path: "/tmp/site/wp-content/plugins/example/plugin.php", status: "added", mountIndex: 0, mountTarget: "/wordpress/wp-content/plugins/example", relativePath: "plugin.php", patchPath: "files/diffs/mount-0.patch" }, |
| 38 | + { path: "/tmp/site/wp-content/themes/theme/style.css", status: "modified", mountIndex: 1, mountTarget: "/wordpress/wp-content/themes/theme", relativePath: "style.css", patchPath: "files/diffs/mount-1.patch" }, |
| 39 | + { path: "/tmp/site/wp-content/themes/theme/old.css", status: "deleted", mountIndex: 1, mountTarget: "/wordpress/wp-content/themes/theme", relativePath: "old.css", patchPath: "files/diffs/mount-1.patch" }, |
| 40 | + ], |
| 41 | +} |
| 42 | + |
| 43 | +const clean = runtimeCaptureStatus({ snapshot, changedFiles: cleanChangedFiles }) |
| 44 | +assert.equal(clean.schema, RUNTIME_CAPTURE_STATUS_SCHEMA) |
| 45 | +assert.equal(clean.version, 1) |
| 46 | +assert.equal(clean.state, "clean") |
| 47 | +assert.equal(clean.resources?.databaseTables, 1) |
| 48 | +assert.equal(clean.resources?.wpContentFiles, 1) |
| 49 | +assert.deepEqual(clean.changes, { files: 0, added: 0, modified: 0, deleted: 0 }) |
| 50 | +assert.equal(clean.snapshotDigest?.algorithm, "sha256") |
| 51 | +assert.equal(clean.captureDigest?.algorithm, "sha256") |
| 52 | + |
| 53 | +const changed = runtimeCaptureStatus({ snapshot, changedFiles }) |
| 54 | +assert.equal(changed.state, "changed") |
| 55 | +assert.deepEqual(changed.changes, { files: 3, added: 1, modified: 1, deleted: 1 }) |
| 56 | + |
| 57 | +const unknown = runtimeCaptureStatus({ snapshot, limitations: ["No comparable baseline was provided."] }) |
| 58 | +assert.equal(unknown.state, "unknown") |
| 59 | +assert.deepEqual(unknown.limitations, ["No comparable baseline was provided."]) |
| 60 | +assert.equal(unknown.resources?.databaseTables, 1) |
| 61 | +assert.equal(unknown.snapshotDigest?.value, unknown.captureDigest?.value) |
| 62 | + |
| 63 | +const workspacePatch: Pick<WorkspacePatchArtifact, "summary" | "contentDigest" | "workspaces"> = { |
| 64 | + summary: { changed: true, files: 2, added: 1, modified: 1, deleted: 0 }, |
| 65 | + contentDigest: { algorithm: "sha256", inputs: ["files/changed-files.json", "files/patch.diff"], value: "d".repeat(64) }, |
| 66 | + workspaces: [ |
| 67 | + { mountIndex: 0, target: "/wordpress/wp-content/plugins/example", source: "/tmp/example", status: "changed", changed: true, patch: "files/diffs/mount-0.patch" }, |
| 68 | + ], |
| 69 | +} |
| 70 | +const workspaceChanged = runtimeCaptureStatus({ workspacePatch }) |
| 71 | +assert.equal(workspaceChanged.state, "changed") |
| 72 | +assert.equal(workspaceChanged.captureDigest?.value, "d".repeat(64)) |
| 73 | +assert.deepEqual(workspaceChanged.changes, { files: 2, added: 1, modified: 1, deleted: 0, workspaces: 1 }) |
| 74 | + |
| 75 | +const unsupported = runtimeCaptureStatus({ supported: false, diagnostics: [{ severity: "warning", code: "runtime-capture-unavailable", message: "Runtime capture is not available for this backend." }] }) |
| 76 | +assert.equal(unsupported.state, "unsupported") |
| 77 | +assert.deepEqual(unsupported.diagnostics, [{ severity: "warning", code: "runtime-capture-unavailable", message: "Runtime capture is not available for this backend." }]) |
| 78 | + |
| 79 | +assert.equal(typeof playgroundPublicApi.runtimeCaptureStatus, "function") |
| 80 | +assert.equal(playgroundPublicApi.RUNTIME_CAPTURE_STATUS_SCHEMA, "wp-codebox/runtime-capture-status/v1") |
| 81 | +assert.equal("buildRuntimeCaptureStatusForWordPressBuild" in playgroundPublicApi, false) |
| 82 | + |
| 83 | +for (const path of [ |
| 84 | + "packages/runtime-playground/src/runtime-capture-status.ts", |
| 85 | + "packages/runtime-playground/src/public.ts", |
| 86 | + "packages/runtime-playground/src/index.ts", |
| 87 | +]) { |
| 88 | + const source = await readFile(new URL(`../${path}`, import.meta.url), "utf8") |
| 89 | + assert.doesNotMatch(source, /WP Build|WordPress Build|paid|free|export gating/i, `${path} must stay product-agnostic`) |
| 90 | +} |
| 91 | + |
| 92 | +console.log("runtime capture status ok") |
0 commit comments