@adobe/data-testing 0.10.21 → 0.10.22
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/README.md +42 -25
- package/dist/conformance/adapt-spec.d.ts +1 -6
- package/dist/conformance/adapt-spec.js +2 -0
- package/dist/conformance/adapt-spec.js.map +1 -1
- package/dist/conformance/build-double.js +22 -18
- package/dist/conformance/build-double.js.map +1 -1
- package/dist/conformance/build-double.test.d.ts +1 -0
- package/dist/conformance/build-double.test.js +30 -0
- package/dist/conformance/build-double.test.js.map +1 -0
- package/dist/conformance/check-feature.d.ts +5 -0
- package/dist/conformance/check-feature.js +50 -0
- package/dist/conformance/check-feature.js.map +1 -0
- package/dist/conformance/check-spec.d.ts +4 -0
- package/dist/conformance/check-spec.js +20 -0
- package/dist/conformance/check-spec.js.map +1 -0
- package/dist/conformance/feature-types.d.ts +2 -2
- package/dist/conformance/implementation.d.ts +41 -0
- package/dist/conformance/implementation.js +11 -0
- package/dist/conformance/implementation.js.map +1 -0
- package/dist/conformance/manifest.type-test.d.ts +122 -0
- package/dist/conformance/manifest.type-test.js +96 -0
- package/dist/conformance/manifest.type-test.js.map +1 -0
- package/dist/conformance/public.d.ts +7 -1
- package/dist/conformance/public.js +8 -3
- package/dist/conformance/public.js.map +1 -1
- package/dist/conformance/run-actions.d.ts +1 -0
- package/dist/conformance/run-actions.js +1 -1
- package/dist/conformance/run-actions.js.map +1 -1
- package/dist/conformance/run-feature.d.ts +1 -1
- package/dist/conformance/run-feature.js +26 -15
- package/dist/conformance/run-feature.js.map +1 -1
- package/dist/conformance/run-spec.d.ts +2 -2
- package/dist/conformance/run-spec.js +5 -9
- package/dist/conformance/run-spec.js.map +1 -1
- package/dist/conformance/run-systems.d.ts +33 -0
- package/dist/conformance/run-systems.js +126 -0
- package/dist/conformance/run-systems.js.map +1 -0
- package/dist/conformance/spec.d.ts +22 -0
- package/dist/conformance/spec.js +9 -0
- package/dist/conformance/spec.js.map +1 -0
- package/dist/conformance/state-matches.d.ts +14 -0
- package/dist/conformance/state-matches.js +3 -0
- package/dist/conformance/state-matches.js.map +1 -0
- package/dist/conformance/systems-types.d.ts +41 -0
- package/dist/conformance/systems-types.js +2 -0
- package/dist/conformance/systems-types.js.map +1 -0
- package/dist/conformance/systems.test.d.ts +1 -0
- package/dist/conformance/systems.test.js +125 -0
- package/dist/conformance/systems.test.js.map +1 -0
- package/dist/conformance/systems.type-test.d.ts +30 -0
- package/dist/conformance/systems.type-test.js +33 -0
- package/dist/conformance/systems.type-test.js.map +1 -0
- package/dist/conformance/with-no-op.d.ts +5 -0
- package/dist/conformance/with-no-op.js +14 -0
- package/dist/conformance/with-no-op.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.type-test.js","sourceRoot":"","sources":["../../src/conformance/manifest.type-test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { spec, type Spec } from "./spec.js";
|
|
2
|
+
export { implementation, type Implementation } from "./implementation.js";
|
|
3
|
+
export { checkSpec } from "./check-spec.js";
|
|
4
|
+
export { checkFeature } from "./check-feature.js";
|
|
5
|
+
export type { StateMatches } from "./state-matches.js";
|
|
6
|
+
export type { FrameCases, SystemCases } from "./systems-types.js";
|
|
7
|
+
export { runSystems, type SystemRunConfig } from "./run-systems.js";
|
|
2
8
|
export type { Responses, SpecCase, SpecCases, SpecDerivationCase, SpecDerivations, CaseModule, } from "./feature-types.js";
|
|
3
9
|
export type { Effects, ServiceCall } from "./types.js";
|
|
4
10
|
export { adaptCases } from "./adapt-spec.js";
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
-
// The conformance manifest API — the standard surface. `
|
|
3
|
-
// manifest
|
|
4
|
-
|
|
2
|
+
// The conformance manifest API — the standard surface. `spec` builds a feature's pure
|
|
3
|
+
// spec manifest and `checkSpec` runs it; `implementation` pairs the spec with its ECS
|
|
4
|
+
// build and `checkFeature` runs that. `StateMatches` pins State to the data schemas.
|
|
5
|
+
export { spec } from "./spec.js";
|
|
6
|
+
export { implementation } from "./implementation.js";
|
|
7
|
+
export { checkSpec } from "./check-spec.js";
|
|
8
|
+
export { checkFeature } from "./check-feature.js";
|
|
9
|
+
export { runSystems } from "./run-systems.js";
|
|
5
10
|
// The escape hatch — the lower-level runners, for a feature whose ecs conformance needs
|
|
6
11
|
// per-surface `seedContext` or a custom concurrency/db (e.g. a user-scoped `userId`); it
|
|
7
12
|
// feeds them from its manifest with `adaptCases`. Ordinary features use `checkFeature`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../src/conformance/public.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../src/conformance/public.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,sFAAsF;AACtF,sFAAsF;AACtF,qFAAqF;AACrF,OAAO,EAAE,IAAI,EAAa,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAuB,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AAWpE,wFAAwF;AACxF,yFAAyF;AACzF,wFAAwF;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAA6B,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,YAAY,EAA0B,MAAM,oBAAoB,CAAC;AAG1E,yFAAyF;AACzF,uDAAuD;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -11,5 +11,6 @@ export interface ActionRunConfig<Db, Store, State> {
|
|
|
11
11
|
readonly initial?: State;
|
|
12
12
|
readonly seedContext?: (db: Db, before: State, args: unknown) => void;
|
|
13
13
|
readonly match?: MatchOptions;
|
|
14
|
+
readonly kind?: string;
|
|
14
15
|
}
|
|
15
16
|
export declare function runActions<Db, Store extends SchemaSource, State>(config: ActionRunConfig<Db, Store, State>): void;
|
|
@@ -14,7 +14,7 @@ export function runActions(config) {
|
|
|
14
14
|
const paired = transitions.get(name);
|
|
15
15
|
if (!paired)
|
|
16
16
|
continue; // action with no transition (e.g. a streaming port) — not conformed here
|
|
17
|
-
describe(`${name} action conforms`, () => {
|
|
17
|
+
describe(`${name} ${config.kind ?? "action"} conforms`, () => {
|
|
18
18
|
for (const testCase of paired.cases) {
|
|
19
19
|
it(testCase.name, async () => {
|
|
20
20
|
const { services, input, calls } = splitAndRecordServices(testCase.args);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-actions.js","sourceRoot":"","sources":["../../src/conformance/run-actions.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"run-actions.js","sourceRoot":"","sources":["../../src/conformance/run-actions.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AA0BxC,gFAAgF;AAChF,2EAA2E;AAC3E,MAAM,UAAU,UAAU,CAAwC,MAAyC;IACzG,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC5D,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACzD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM;YAAE,SAAS,CAAC,yEAAyE;QAChG,QAAQ,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,IAAI,QAAQ,WAAW,EAAE,GAAG,EAAE;YAC3D,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBACpC,EAAE,CAAC,QAAQ,CAAC,IAAc,EAAE,KAAK,IAAI,EAAE;oBACrC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,sBAAsB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;oBACzE,qDAAqD;oBACrD,MAAM,MAAM,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,GAAI,QAAQ,CAAC,MAAiB,EAAW,CAAC;oBACtF,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;oBACrE,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;oBAChD,4EAA4E;oBAC5E,2EAA2E;oBAC3E,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;oBAC5D,MAAM,IAAI,GAAG,MAAsD,CAAC;oBACpE,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;wBAClC,MAAM,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAuB,CAAC,CAAC;wBAC3E,OAAO;oBACT,CAAC;oBACD,MAAM,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;oBACrB,6DAA6D;oBAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBAC/B,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,MAAgB,EAAE,QAAQ,CAAC,KAAe,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;oBACpG,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAgB,CAAC,CAAC;gBAClD,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
|
@@ -19,9 +19,9 @@ export interface FeatureRunConfig<State, StoreT, Db extends {
|
|
|
19
19
|
readonly computedPlugin?: Database.Plugin;
|
|
20
20
|
readonly projection: Projection<StoreT, State>;
|
|
21
21
|
readonly hydrate?: readonly string[];
|
|
22
|
+
readonly services?: Readonly<Record<string, () => object>>;
|
|
22
23
|
readonly match?: MatchOptions;
|
|
23
24
|
readonly ops?: {
|
|
24
|
-
readonly transactions?: Record<string, unknown>;
|
|
25
25
|
readonly actions?: Record<string, unknown>;
|
|
26
26
|
readonly computeds?: Record<string, unknown>;
|
|
27
27
|
};
|
|
@@ -1,46 +1,57 @@
|
|
|
1
1
|
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
2
|
import { describe, it } from "vitest";
|
|
3
3
|
import { Database, Store } from "@adobe/data/ecs";
|
|
4
|
-
import { runTransactions } from "./run-transactions.js";
|
|
5
4
|
import { runActions } from "./run-actions.js";
|
|
6
5
|
import { runComputeds } from "./run-computeds.js";
|
|
7
6
|
import { expectAfter } from "./expect-after.js";
|
|
7
|
+
import { discoverTransitions, discoverDerivations, discoverOps } from "./discover.js";
|
|
8
|
+
const pick = (source, names) => Object.fromEntries([...source].filter(([name]) => names.has(name)));
|
|
8
9
|
export function runFeature(config) {
|
|
9
10
|
const initial = config.state.create();
|
|
10
11
|
const { fromState, toState, toData } = config.projection;
|
|
11
12
|
const facets = config.plugin;
|
|
13
|
+
const computedFacets = config.computedPlugin;
|
|
12
14
|
// A plugin carries the schema facets, so `Store.create` / `Database.create`
|
|
13
15
|
// accept it; the resulting store/db is the projection's `StoreT`/`Db`.
|
|
14
16
|
const makeStore = () => Store.create(config.plugin);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
const baseServices = () => Object.fromEntries(Object.entries(config.services ?? {}).map(([name, create]) => [name, create()]));
|
|
18
|
+
const transitions = discoverTransitions(config.transitions);
|
|
19
|
+
const derivations = discoverDerivations(config.transitions);
|
|
20
|
+
const actions = discoverOps(config.ops?.actions ?? facets.actions);
|
|
21
|
+
const computeds = discoverOps(config.ops?.computeds ?? computedFacets?.computed ?? {});
|
|
22
|
+
const byAction = new Set([...transitions.keys()].filter((name) => actions.has(name)));
|
|
23
|
+
const missing = [
|
|
24
|
+
...[...transitions.keys()].filter((name) => !byAction.has(name)),
|
|
25
|
+
...[...derivations.keys()].filter((name) => !computeds.has(name)),
|
|
26
|
+
];
|
|
27
|
+
if (missing.length > 0) {
|
|
28
|
+
describe("every spec op has an implementation", () => {
|
|
29
|
+
for (const name of missing) {
|
|
30
|
+
it(name, () => {
|
|
31
|
+
throw new Error(`spec op "${name}" has no same-named ${derivations.has(name) ? "computed" : "action"}`);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
24
36
|
runActions({
|
|
25
|
-
makeDb: (services) => Database.toSystemDatabase(Database.create(config.plugin, { services })),
|
|
37
|
+
makeDb: (services) => Database.toSystemDatabase(Database.create(config.plugin, { services: { ...baseServices(), ...services } })),
|
|
26
38
|
store: (db) => db.store,
|
|
27
39
|
fromState,
|
|
28
40
|
toState,
|
|
29
41
|
initial,
|
|
30
42
|
transitions: config.transitions,
|
|
31
|
-
actions:
|
|
43
|
+
actions: pick(actions, byAction),
|
|
32
44
|
match: config.match,
|
|
33
45
|
});
|
|
34
46
|
if (config.computedPlugin) {
|
|
35
|
-
const computedFacets = config.computedPlugin;
|
|
36
47
|
runComputeds({
|
|
37
|
-
makeDb: () => Database.toSystemDatabase(Database.create(config.computedPlugin)),
|
|
48
|
+
makeDb: () => Database.toSystemDatabase(Database.create(config.computedPlugin, { services: baseServices() })),
|
|
38
49
|
store: (db) => db.store,
|
|
39
50
|
fromState,
|
|
40
51
|
toData,
|
|
41
52
|
initial,
|
|
42
53
|
derivations: config.transitions,
|
|
43
|
-
computeds:
|
|
54
|
+
computeds: Object.fromEntries(computeds),
|
|
44
55
|
hydrate: config.hydrate,
|
|
45
56
|
match: config.match,
|
|
46
57
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-feature.js","sourceRoot":"","sources":["../../src/conformance/run-feature.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAGlD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"run-feature.js","sourceRoot":"","sources":["../../src/conformance/run-feature.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Schema } from "@adobe/data/schema";
|
|
2
2
|
import type { MatchOptions } from "../match/match.js";
|
|
3
3
|
export interface SpecRunConfig {
|
|
4
4
|
readonly state?: {
|
|
@@ -6,7 +6,7 @@ export interface SpecRunConfig {
|
|
|
6
6
|
};
|
|
7
7
|
readonly transitions: Record<string, Record<string, unknown>>;
|
|
8
8
|
readonly match?: MatchOptions;
|
|
9
|
-
readonly
|
|
9
|
+
readonly schemas?: Readonly<Record<string, Schema>>;
|
|
10
10
|
readonly label?: (path: string, fnName: string | undefined) => string;
|
|
11
11
|
}
|
|
12
12
|
export declare const runSpec: (config: SpecRunConfig) => void;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
2
|
import { describe, it } from "vitest";
|
|
3
|
-
import { Store } from "@adobe/data/ecs";
|
|
4
3
|
import { assert } from "../match/assert.js";
|
|
5
4
|
import { expectAfter } from "./expect-after.js";
|
|
6
5
|
import { expectThrows } from "./expect-throws.js";
|
|
@@ -19,12 +18,9 @@ const isDerivationCase = (c) => typeof c === "object" && c !== null && "value" i
|
|
|
19
18
|
// "No test suite found" — so we register a single no-op so empty discovery is a
|
|
20
19
|
// valid outcome, not an error.
|
|
21
20
|
export const runSpec = (config) => {
|
|
22
|
-
// Reference fields are found from schemas; without
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
const schemaSource = config.plugin
|
|
26
|
-
? { componentSchemas: Store.create(config.plugin).componentSchemas }
|
|
27
|
-
: { componentSchemas: {} };
|
|
21
|
+
// Reference fields are found from schemas; without them only map keys (an id by
|
|
22
|
+
// construction) refify.
|
|
23
|
+
const schemaSource = { componentSchemas: config.schemas ?? {} };
|
|
28
24
|
const suites = [];
|
|
29
25
|
for (const [path, module] of Object.entries(config.transitions)) {
|
|
30
26
|
const exportNames = Object.keys(module);
|
|
@@ -88,8 +84,8 @@ export const runSpec = (config) => {
|
|
|
88
84
|
}
|
|
89
85
|
const result = (await suite.fn(before, args));
|
|
90
86
|
// The pure transform mints its own spec-ids, so compare up to an
|
|
91
|
-
// id-bijection too (entity map keys always; reference fields when
|
|
92
|
-
// `
|
|
87
|
+
// id-bijection too (entity map keys always; reference fields when
|
|
88
|
+
// `schemas` are given).
|
|
93
89
|
expectAfter({ ...before, ...result }, before, tc.after, schemaSource, config.match);
|
|
94
90
|
expectEffects(calls, tc.effects);
|
|
95
91
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-spec.js","sourceRoot":"","sources":["../../src/conformance/run-spec.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"run-spec.js","sourceRoot":"","sources":["../../src/conformance/run-spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Entity } from "@adobe/data/ecs";
|
|
2
|
+
import type { MatchOptions } from "../match/match.js";
|
|
3
|
+
import type { SchemaSource } from "./refify.js";
|
|
4
|
+
import type { Effects } from "./types.js";
|
|
5
|
+
type SystemFn = () => void | Promise<void>;
|
|
6
|
+
export type SystemDatabase<StoreT> = {
|
|
7
|
+
readonly store: StoreT;
|
|
8
|
+
readonly system: {
|
|
9
|
+
readonly order: readonly (readonly string[])[];
|
|
10
|
+
readonly functions: Readonly<Record<string, SystemFn | null | undefined>>;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export type SystemCase = {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly before: object;
|
|
16
|
+
readonly args?: unknown;
|
|
17
|
+
readonly after?: object;
|
|
18
|
+
readonly effects?: Effects<Record<string, unknown>>;
|
|
19
|
+
readonly throws?: true | string;
|
|
20
|
+
};
|
|
21
|
+
export interface SystemRunConfig<State, StoreT> {
|
|
22
|
+
readonly makeDb: (services: Record<string, object>) => SystemDatabase<StoreT>;
|
|
23
|
+
readonly fromState: (store: StoreT, state: State) => ReadonlyMap<unknown, Entity> | void;
|
|
24
|
+
readonly toState: (store: StoreT) => State;
|
|
25
|
+
readonly initial: State;
|
|
26
|
+
readonly systems: Record<string, Record<string, unknown>>;
|
|
27
|
+
readonly frameCases: () => readonly SystemCase[];
|
|
28
|
+
readonly args: Readonly<Record<string, (db: SystemDatabase<StoreT>, value: unknown) => void>>;
|
|
29
|
+
readonly unmodelled: Readonly<Record<string, string>>;
|
|
30
|
+
readonly match?: MatchOptions;
|
|
31
|
+
}
|
|
32
|
+
export declare function runSystems<State, StoreT extends SchemaSource>(config: SystemRunConfig<State, StoreT>): void;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
import { describe, it } from "vitest";
|
|
3
|
+
import { matches } from "../match/match.js";
|
|
4
|
+
import { discoverTransitions } from "./discover.js";
|
|
5
|
+
import { expectAfter } from "./expect-after.js";
|
|
6
|
+
import { expectThrows } from "./expect-throws.js";
|
|
7
|
+
import { resolveArgs } from "./resolve-args.js";
|
|
8
|
+
import { resolver } from "./resolve.js";
|
|
9
|
+
import { recordArgServices, splitAndRecordServices, expectEffects } from "./record-effects.js";
|
|
10
|
+
const SCHEDULER = "schedulerSystem";
|
|
11
|
+
// Write the case's data args into the store; services already arrived as doubles.
|
|
12
|
+
const writeArgs = (db, input, writers) => {
|
|
13
|
+
for (const [key, value] of Object.entries(input))
|
|
14
|
+
writers[key]?.(db, value);
|
|
15
|
+
};
|
|
16
|
+
// Conform a real-time feature's systems. Each spec system function conforms by running
|
|
17
|
+
// just the same-named ECS system on a seeded store. Each frame case conforms twice:
|
|
18
|
+
// the paired spec functions folded in `db.system.order` must give `after`, and so must
|
|
19
|
+
// one real frame. The order comes only from the systems' `schedule` declarations.
|
|
20
|
+
// Unmodelled systems are skipped on both sides and listed as skipped tests.
|
|
21
|
+
export function runSystems(config) {
|
|
22
|
+
const systems = discoverTransitions(config.systems);
|
|
23
|
+
const unmodelled = new Set(Object.keys(config.unmodelled));
|
|
24
|
+
const order = config.makeDb({}).system.order;
|
|
25
|
+
const orderNames = order.flat().filter((name) => name !== SCHEDULER);
|
|
26
|
+
const unaccounted = orderNames.filter((name) => !systems.has(name) && !unmodelled.has(name));
|
|
27
|
+
const unknown = [...systems.keys()].filter((name) => !orderNames.includes(name));
|
|
28
|
+
if (unaccounted.length > 0 || unknown.length > 0) {
|
|
29
|
+
describe("every system is modelled or declared unmodelled", () => {
|
|
30
|
+
for (const name of unaccounted) {
|
|
31
|
+
it(name, () => {
|
|
32
|
+
throw new Error(`system "${name}" has no spec function and is not declared unmodelled`);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
for (const name of unknown) {
|
|
36
|
+
it(name, () => {
|
|
37
|
+
throw new Error(`spec system "${name}" names no ECS system`);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
for (const [name, reason] of Object.entries(config.unmodelled)) {
|
|
43
|
+
describe(`${name} system`, () => {
|
|
44
|
+
it.skip(`unmodelled — ${reason}`, () => { });
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const seed = (testCase) => {
|
|
48
|
+
const { services, input, calls } = splitAndRecordServices(testCase.args);
|
|
49
|
+
const before = { ...config.initial, ...testCase.before };
|
|
50
|
+
const db = config.makeDb(services);
|
|
51
|
+
return { db, before, input, calls, resolve: resolver(config.fromState(db.store, before)) };
|
|
52
|
+
};
|
|
53
|
+
const expectCase = (db, before, testCase, calls) => {
|
|
54
|
+
expectAfter(config.toState(db.store), before, testCase.after ?? {}, db.store, config.match);
|
|
55
|
+
expectEffects(calls, testCase.effects);
|
|
56
|
+
};
|
|
57
|
+
for (const [name, paired] of systems) {
|
|
58
|
+
describe(`${name} system conforms`, () => {
|
|
59
|
+
for (const raw of paired.cases) {
|
|
60
|
+
const testCase = raw;
|
|
61
|
+
it(testCase.name, async () => {
|
|
62
|
+
const { db, before, input, calls, resolve } = seed(testCase);
|
|
63
|
+
writeArgs(db, resolveArgs(input, paired.argsSchema, resolve), config.args);
|
|
64
|
+
const fn = db.system.functions[name];
|
|
65
|
+
if (typeof fn !== "function")
|
|
66
|
+
throw new Error(`system "${name}" is init-only; declare it unmodelled`);
|
|
67
|
+
if (testCase.throws !== undefined) {
|
|
68
|
+
await expectThrows(() => fn(), testCase.throws);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
await fn();
|
|
72
|
+
expectCase(db, before, testCase, calls);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const frameCases = config.frameCases();
|
|
78
|
+
if (frameCases.length === 0)
|
|
79
|
+
return;
|
|
80
|
+
// The modelled systems of each tier, in the order the scheduler runs them.
|
|
81
|
+
const tiers = order.map((tier) => tier.filter((name) => name !== SCHEDULER && systems.has(name)));
|
|
82
|
+
// Fold the paired spec functions over a tier's systems in the given order.
|
|
83
|
+
const foldTier = async (state, names, args) => {
|
|
84
|
+
let next = state;
|
|
85
|
+
for (const name of names)
|
|
86
|
+
next = { ...next, ...(await systems.get(name).fn(next, args)) };
|
|
87
|
+
return next;
|
|
88
|
+
};
|
|
89
|
+
describe("frame conforms", () => {
|
|
90
|
+
frameCases.forEach((named, index) => {
|
|
91
|
+
const fresh = () => config.frameCases()[index];
|
|
92
|
+
it(`${named.name} (spec systems in schedule order)`, async () => {
|
|
93
|
+
const testCase = fresh();
|
|
94
|
+
const { args, calls } = recordArgServices(testCase.args);
|
|
95
|
+
const before = { ...config.initial, ...testCase.before };
|
|
96
|
+
let state = before;
|
|
97
|
+
for (const tier of tiers) {
|
|
98
|
+
const forward = await foldTier(state, tier, args);
|
|
99
|
+
if (tier.length > 1) {
|
|
100
|
+
// Systems sharing a tier have no declared order, so they must commute.
|
|
101
|
+
const reverse = await foldTier(state, [...tier].reverse(), recordArgServices(fresh().args).args);
|
|
102
|
+
if (!matches(forward, reverse, config.match)) {
|
|
103
|
+
throw new Error(`systems ${tier.join(", ")} share a tier but don't commute; declare before/after`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
state = forward;
|
|
107
|
+
}
|
|
108
|
+
const store = config.makeDb({}).store;
|
|
109
|
+
expectAfter(state, before, testCase.after ?? {}, store, config.match);
|
|
110
|
+
expectEffects(calls, testCase.effects);
|
|
111
|
+
});
|
|
112
|
+
it(`${named.name} (one ECS frame)`, async () => {
|
|
113
|
+
const testCase = fresh();
|
|
114
|
+
const { db, before, input, calls, resolve } = seed(testCase);
|
|
115
|
+
writeArgs(db, resolveArgs(input, undefined, resolve), config.args);
|
|
116
|
+
for (const tier of db.system.order) {
|
|
117
|
+
await Promise.all(tier
|
|
118
|
+
.filter((name) => name !== SCHEDULER && !unmodelled.has(name))
|
|
119
|
+
.map((name) => db.system.functions[name]?.()));
|
|
120
|
+
}
|
|
121
|
+
expectCase(db, before, testCase, calls);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=run-systems.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-systems.js","sourceRoot":"","sources":["../../src/conformance/run-systems.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Schema } from "@adobe/data/schema";
|
|
2
|
+
import type { MatchOptions } from "../match/match.js";
|
|
3
|
+
import type { CaseModule, RequiredServices } from "./feature-types.js";
|
|
4
|
+
import type { SpecSystems } from "./systems-types.js";
|
|
5
|
+
type AnyFn = (...args: never[]) => unknown;
|
|
6
|
+
export interface Spec<State extends object, Fns extends Record<string, AnyFn>, Cases extends object, Sys = {}> {
|
|
7
|
+
readonly state: {
|
|
8
|
+
create(): State;
|
|
9
|
+
readonly samples?: readonly State[];
|
|
10
|
+
};
|
|
11
|
+
readonly fns: Fns;
|
|
12
|
+
readonly cases: Cases;
|
|
13
|
+
readonly services?: Readonly<Record<string, () => object>>;
|
|
14
|
+
readonly schemas?: Readonly<Record<string, Schema>>;
|
|
15
|
+
readonly match?: MatchOptions;
|
|
16
|
+
readonly systems?: SpecSystems<State, Sys>;
|
|
17
|
+
}
|
|
18
|
+
export declare const spec: <State extends object, Fns extends Record<string, AnyFn>, C extends { readonly [K in keyof Fns]: CaseModule<State, Fns[K]>; }, Sys extends Record<string, AnyFn> = {}>(manifest: Omit<Spec<State, Fns, C, Sys>, "services"> & RequiredServices<Fns & Sys> & ([Exclude<keyof C, keyof Fns>] extends [never] ? unknown : {
|
|
19
|
+
readonly __casesError: "a case module names something that is not a conformed fn";
|
|
20
|
+
readonly extra: Exclude<keyof C, keyof Fns>;
|
|
21
|
+
})) => Spec<State, Fns, C, Sys>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Author a feature's spec manifest. A typed identity that arms the compile-time guards:
|
|
2
|
+
// • `cases` coverage — a module for every fn (missing → error), none for a non-fn.
|
|
3
|
+
// • `services` requiredness — exactly the injected-service keys the fns and systems declare.
|
|
4
|
+
// • `systems.cases` coverage — a module for every system function.
|
|
5
|
+
export const spec = (manifest) =>
|
|
6
|
+
// Runtime invariant the checker can't see: the constrained param IS this Spec (the
|
|
7
|
+
// requiredness factors are compile-only phantoms with no runtime shape).
|
|
8
|
+
manifest;
|
|
9
|
+
//# sourceMappingURL=spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/conformance/spec.ts"],"names":[],"mappings":"AAmCA,wFAAwF;AACxF,qFAAqF;AACrF,+FAA+F;AAC/F,qEAAqE;AACrE,MAAM,CAAC,MAAM,IAAI,GAAG,CAMlB,QAIyI,EAC/G,EAAE;AAC5B,mFAAmF;AACnF,yEAAyE;AACzE,QAA+C,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type SingletonKeys<S> = {
|
|
2
|
+
[K in keyof S]: S[K] extends ReadonlyMap<unknown, unknown> ? never : K;
|
|
3
|
+
}[keyof S];
|
|
4
|
+
type EntityValueKeys<S> = {
|
|
5
|
+
[K in keyof S]: S[K] extends ReadonlyMap<unknown, infer V> ? keyof V : never;
|
|
6
|
+
}[keyof S];
|
|
7
|
+
export type StateMatches<S, Resources, Components> = [Exclude<SingletonKeys<S>, keyof Resources>] extends [never] ? [Exclude<EntityValueKeys<S>, keyof Components>] extends [never] ? true : {
|
|
8
|
+
readonly __stateError: "an entity value key is not a component";
|
|
9
|
+
readonly keys: Exclude<EntityValueKeys<S>, keyof Components>;
|
|
10
|
+
} : {
|
|
11
|
+
readonly __stateError: "a singleton key is not a resource";
|
|
12
|
+
readonly keys: Exclude<SingletonKeys<S>, keyof Resources>;
|
|
13
|
+
};
|
|
14
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-matches.js","sourceRoot":"","sources":["../../src/conformance/state-matches.ts"],"names":[],"mappings":"AAAA,uDAAuD"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Database } from "@adobe/data/ecs";
|
|
2
|
+
import type { UnionToIntersection } from "@adobe/data/types";
|
|
3
|
+
import type { ArgsOf, DataArgKeys, SpecCases } from "./feature-types.js";
|
|
4
|
+
type AnyFn = (...args: never[]) => unknown;
|
|
5
|
+
export type FrameArgs<Sys> = UnionToIntersection<{
|
|
6
|
+
[K in keyof Sys]: [ArgsOf<Sys[K]>] extends [void] ? {} : ArgsOf<Sys[K]>;
|
|
7
|
+
}[keyof Sys]>;
|
|
8
|
+
export type FrameCases<State, Sys> = SpecCases<State, (state: State, args: FrameArgs<Sys>) => Partial<State>>;
|
|
9
|
+
export type SystemCases<State, Sys> = {
|
|
10
|
+
readonly [K in keyof Sys]: SpecCases<State, Sys[K] & AnyFn>;
|
|
11
|
+
};
|
|
12
|
+
export type NoOpCase<State, Sys> = {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly before: Partial<State>;
|
|
15
|
+
} & ([
|
|
16
|
+
DataArgKeys<FrameArgs<Sys>>
|
|
17
|
+
] extends [never] ? {
|
|
18
|
+
readonly args?: undefined;
|
|
19
|
+
} : {
|
|
20
|
+
readonly args: Pick<FrameArgs<Sys>, DataArgKeys<FrameArgs<Sys>>>;
|
|
21
|
+
});
|
|
22
|
+
export type SpecSystems<State, Sys> = {
|
|
23
|
+
readonly fns: Sys;
|
|
24
|
+
readonly cases: SystemCases<State, Sys>;
|
|
25
|
+
readonly noOp?: readonly NoOpCase<State, Sys>[];
|
|
26
|
+
};
|
|
27
|
+
export type SystemKeys<PL extends Database.Plugin> = Exclude<Extract<keyof Database.Plugin.ToSystemDatabase<PL>["system"]["functions"], string>, "schedulerSystem">;
|
|
28
|
+
export type FrameArgWriters<PL extends Database.Plugin, Sys> = {
|
|
29
|
+
readonly [K in DataArgKeys<FrameArgs<Sys>>]-?: (db: Database.Plugin.ToSystemDatabase<PL>, value: FrameArgs<Sys>[K]) => void;
|
|
30
|
+
};
|
|
31
|
+
export type SystemsExact<Modelled, Unmodelled, All> = [Exclude<All, Modelled | Unmodelled>] extends [never] ? [Exclude<Modelled | Unmodelled, All>] extends [never] ? [Extract<Modelled, Unmodelled>] extends [never] ? unknown : {
|
|
32
|
+
readonly __systemsError: "a system is both modelled and unmodelled";
|
|
33
|
+
readonly both: Extract<Modelled, Unmodelled>;
|
|
34
|
+
} : {
|
|
35
|
+
readonly __systemsError: "names a system the ECS does not have";
|
|
36
|
+
readonly unknown: Exclude<Modelled | Unmodelled, All>;
|
|
37
|
+
} : {
|
|
38
|
+
readonly __systemsError: "a system is neither modelled nor unmodelled";
|
|
39
|
+
readonly missing: Exclude<All, Modelled | Unmodelled>;
|
|
40
|
+
};
|
|
41
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systems-types.js","sourceRoot":"","sources":["../../src/conformance/systems-types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|