@presolve/testing 0.1.0-alpha.8 → 0.2.0-beta.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@presolve/testing",
3
- "version": "0.1.0-alpha.8",
3
+ "version": "0.2.0-beta.1",
4
4
  "description": "Testing helpers for Presolve compiler products.",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "type": "module",
@@ -11,11 +11,14 @@
11
11
  },
12
12
  "publishConfig": {
13
13
  "access": "public",
14
- "tag": "alpha"
14
+ "tag": "beta"
15
15
  },
16
16
  "exports": {
17
17
  ".": "./src/index.js"
18
18
  },
19
+ "dependencies": {
20
+ "@presolve/vite": "0.2.0-beta.1"
21
+ },
19
22
  "scripts": {
20
23
  "test": "node test/smoke.mjs"
21
24
  }
package/src/index.js CHANGED
@@ -1,3 +1,7 @@
1
+ import { createPresolveVitePlugin } from "@presolve/vite";
2
+
3
+ export const PRESOLVE_TEST_INTEGRATION_SCHEMA_VERSION = 1;
4
+
1
5
  /** Compares caller-owned canonical byte sequences without interpretation. */
2
6
  export function equalCanonicalBytes(expected, actual) {
3
7
  if (!(expected instanceof Uint8Array) || !(actual instanceof Uint8Array)) return false;
@@ -10,3 +14,76 @@ export function declaredTest({ name, command, lane }) {
10
14
  if (!name || !command || !lane) throw new TypeError("declared test requires name, command, and lane");
11
15
  return Object.freeze({ name, command, lane });
12
16
  }
17
+
18
+ /**
19
+ * Creates the Vitest-facing Vite configuration for an already-published
20
+ * compiler product. The plugin remains the sole manifest validator; this
21
+ * package neither parses source nor evaluates compiler diagnostics.
22
+ */
23
+ export function createPresolveVitestConfig({ compilerProduct, readArtifact, fixtures = [] } = {}) {
24
+ return createTestIntegration({
25
+ runner: "vitest",
26
+ compilerProduct,
27
+ readArtifact,
28
+ fixtures,
29
+ });
30
+ }
31
+
32
+ /**
33
+ * Creates Playwright project metadata for an already-published application.
34
+ * The returned Vite plugin is for the caller's dev-server setup; Playwright
35
+ * receives only a validated origin and compiler publication identity.
36
+ */
37
+ export function createPresolvePlaywrightProject({
38
+ compilerProduct,
39
+ readArtifact,
40
+ baseURL,
41
+ fixtures = [],
42
+ } = {}) {
43
+ const integration = createTestIntegration({
44
+ runner: "playwright",
45
+ compilerProduct,
46
+ readArtifact,
47
+ fixtures,
48
+ });
49
+ if (typeof baseURL !== "string" || !isHttpOrigin(baseURL)) {
50
+ throw new TypeError("Presolve Playwright integration requires an absolute HTTP(S) origin baseURL");
51
+ }
52
+ return Object.freeze({
53
+ ...integration,
54
+ use: Object.freeze({ baseURL: new URL(baseURL).origin }),
55
+ });
56
+ }
57
+
58
+ function createTestIntegration({ runner, compilerProduct, readArtifact, fixtures }) {
59
+ if (!Array.isArray(fixtures)) {
60
+ throw new TypeError("Presolve test integration fixtures must be an array");
61
+ }
62
+ const vitePlugin = createPresolveVitePlugin({ compilerProduct, readArtifact });
63
+ return Object.freeze({
64
+ schemaVersion: PRESOLVE_TEST_INTEGRATION_SCHEMA_VERSION,
65
+ runner,
66
+ compiler: vitePlugin.api,
67
+ fixtures: Object.freeze(fixtures.map(normalizeFixture)),
68
+ vite: Object.freeze({ plugins: Object.freeze([vitePlugin]) }),
69
+ });
70
+ }
71
+
72
+ function normalizeFixture(fixture) {
73
+ if (!fixture || typeof fixture !== "object" || Array.isArray(fixture)
74
+ || typeof fixture.name !== "string" || !fixture.name
75
+ || typeof fixture.route !== "string" || !fixture.route.startsWith("/")) {
76
+ throw new TypeError("Presolve test fixtures require a non-empty name and absolute route");
77
+ }
78
+ return Object.freeze({ name: fixture.name, route: fixture.route });
79
+ }
80
+
81
+ function isHttpOrigin(value) {
82
+ try {
83
+ const url = new URL(value);
84
+ return (url.protocol === "http:" || url.protocol === "https:")
85
+ && url.pathname === "/" && !url.search && !url.hash;
86
+ } catch {
87
+ return false;
88
+ }
89
+ }
package/test/smoke.mjs CHANGED
@@ -1,6 +1,45 @@
1
- import { declaredTest, equalCanonicalBytes } from "../src/index.js";
1
+ import { createHash } from "node:crypto";
2
+ import {
3
+ createPresolvePlaywrightProject,
4
+ createPresolveVitestConfig,
5
+ declaredTest,
6
+ equalCanonicalBytes,
7
+ } from "../src/index.js";
2
8
 
3
9
  if (!equalCanonicalBytes(new Uint8Array([1, 2]), new Uint8Array([1, 2]))) throw new Error("equal bytes must compare");
4
10
  if (equalCanonicalBytes(new Uint8Array([1]), new Uint8Array([2]))) throw new Error("different bytes must not compare");
5
11
  const test = declaredTest({ name: "compiler", command: "cargo test -p presolve-compiler --lib", lane: "deterministic" });
6
12
  if (test.lane !== "deterministic" || !Object.isFrozen(test)) throw new Error("declared test metadata must be immutable");
13
+
14
+ const runtime = "export const runtime = 1;\n";
15
+ const vitest = createPresolveVitestConfig({
16
+ compilerProduct: {
17
+ manifest: {
18
+ schema_version: 1,
19
+ compiler_contract: "presolve-application-publication:1",
20
+ workspace_snapshot_id: "testing-fixture",
21
+ artifacts: [{ path: "runtime.js", digest: createHash("sha256").update(runtime).digest("hex") }],
22
+ },
23
+ },
24
+ readArtifact: () => runtime,
25
+ fixtures: [{ name: "home", route: "/" }],
26
+ });
27
+ if (vitest.runner !== "vitest" || vitest.vite.plugins.length !== 1 || vitest.fixtures[0].route !== "/") {
28
+ throw new Error("Vitest integration must preserve the compiler Vite plugin and declared route fixture");
29
+ }
30
+ const playwright = createPresolvePlaywrightProject({
31
+ compilerProduct: {
32
+ manifest: {
33
+ schema_version: 1,
34
+ compiler_contract: "presolve-application-publication:1",
35
+ workspace_snapshot_id: "testing-fixture",
36
+ artifacts: [{ path: "runtime.js", digest: createHash("sha256").update(runtime).digest("hex") }],
37
+ },
38
+ },
39
+ readArtifact: () => runtime,
40
+ baseURL: "http://127.0.0.1:4173/",
41
+ fixtures: [{ name: "home", route: "/" }],
42
+ });
43
+ if (playwright.runner !== "playwright" || playwright.use.baseURL !== "http://127.0.0.1:4173") {
44
+ throw new Error("Playwright integration must retain the caller-owned test origin");
45
+ }