@eigeninteractive/testkit 0.5.1 → 0.6.0
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/dist/contract-cli.d.ts +1 -2
- package/dist/contract-cli.js +21 -22
- package/dist/contract-cli.js.map +1 -1
- package/dist/contract-command-aCqO5CyJ.js +542 -0
- package/dist/contract-command-aCqO5CyJ.js.map +1 -0
- package/dist/index.d.ts +159 -8
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -55
- package/dist/index.js.map +1 -1
- package/dist/inspect-cli.d.ts +1 -16
- package/dist/inspect-cli.js +169 -153
- package/dist/inspect-cli.js.map +1 -1
- package/dist/local-state-CnO-Oi-R.js +467 -0
- package/dist/local-state-CnO-Oi-R.js.map +1 -0
- package/dist/local-state.d.ts +188 -224
- package/dist/local-state.d.ts.map +1 -0
- package/dist/local-state.js +2 -11
- package/package.json +10 -9
- package/src/contract-cli.ts +29 -0
- package/src/contract-command.ts +78 -0
- package/src/game-contract.ts +205 -0
- package/src/index.ts +53 -0
- package/src/inspect-cli.ts +231 -0
- package/{dist/kernel-scenarios.d.ts → src/kernel-scenarios.ts} +41 -5
- package/src/local-state.ts +638 -0
- package/src/twin-fixtures.ts +533 -0
- package/dist/chunk-BQIY636F.js +0 -483
- package/dist/chunk-BQIY636F.js.map +0 -1
- package/dist/chunk-YJE4AGHJ.js +0 -391
- package/dist/chunk-YJE4AGHJ.js.map +0 -1
- package/dist/contract-command.d.ts +0 -13
- package/dist/game-contract.d.ts +0 -58
- package/dist/local-state.js.map +0 -1
- package/dist/twin-fixtures.d.ts +0 -145
package/dist/twin-fixtures.d.ts
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Twin-drift fixture runner: the TS half of the shared JSON fixtures that
|
|
3
|
-
* keep a version unit's TS and Dart `GameRules` twins in sync. The JSON
|
|
4
|
-
* fixture format is shared verbatim with the Dart runner
|
|
5
|
-
* (`lib/testing/twin_fixtures.dart`): one file, two consumers.
|
|
6
|
-
*
|
|
7
|
-
* One fixture file per concern lives beside the version units at
|
|
8
|
-
* `<fixturesRoot>/v<N>/*.json` and is consumed by BOTH sides: this module
|
|
9
|
-
* runs each case against the TS unit (schemas + `applyAction` +
|
|
10
|
-
* `computeObservation` + the two predicates), while the Dart runner runs the
|
|
11
|
-
* same file against the Dart twin (generated payload parsing,
|
|
12
|
-
* `isValidAction`, `previewAction`, predicate twins). A behavioral divergence
|
|
13
|
-
* then fails one side's CI instead of degrading UX in production.
|
|
14
|
-
*
|
|
15
|
-
* ## Fixture file format
|
|
16
|
-
*
|
|
17
|
-
* ```jsonc
|
|
18
|
-
* {
|
|
19
|
-
* "schemaVersion": 1,
|
|
20
|
-
* "cases": [
|
|
21
|
-
* {
|
|
22
|
-
* "kind": "action",
|
|
23
|
-
* "name": "seat 0 marks an empty cell",
|
|
24
|
-
* "config": {},
|
|
25
|
-
* "state": { ... }, // TS: applyAction input
|
|
26
|
-
* "obs": { ... }, // Dart-only; defaults to `state`
|
|
27
|
-
* "pending": [0],
|
|
28
|
-
* "playerIndex": 0,
|
|
29
|
-
* "participantCount": 2, // optional, default 2
|
|
30
|
-
* "rngSeed": "any string", // optional, default "twin-fixtures"
|
|
31
|
-
* "action": { ... },
|
|
32
|
-
* "expected": {
|
|
33
|
-
* "valid": true, // false ⇒ TS IllegalMoveError,
|
|
34
|
-
* // Dart isValidAction false
|
|
35
|
-
* "state": { ... }, // optional, TS envelope.state
|
|
36
|
-
* "pending": [1], // optional, TS envelope.pendingPlayers
|
|
37
|
-
* "outcome": [ ... ], // optional, TS envelope.outcome
|
|
38
|
-
* // (null asserts the game is ongoing)
|
|
39
|
-
* "observation": { ... } // optional, the actor's post-action
|
|
40
|
-
* // view: TS computeObservation slice
|
|
41
|
-
* // data; Dart previewAction (when the
|
|
42
|
-
* // game implements optimism)
|
|
43
|
-
* }
|
|
44
|
-
* },
|
|
45
|
-
* { "kind": "playerLimits", "name": "...", "config": {},
|
|
46
|
-
* "expected": { "minPlayers": 2, "maxPlayers": 2 } },
|
|
47
|
-
* { "kind": "ratingPool", "name": "...", "access": "public",
|
|
48
|
-
* "minPlayers": 2, "maxPlayers": 2, "config": {}, "expected": "blitz" },
|
|
49
|
-
* { "kind": "botSeatable", "name": "...", "gameConfig": {},
|
|
50
|
-
* "botConfig": {}, "expected": false }
|
|
51
|
-
* ]
|
|
52
|
-
* }
|
|
53
|
-
* ```
|
|
54
|
-
*
|
|
55
|
-
* The `state`/`obs` split exists for hidden-info games (a seat's observation
|
|
56
|
-
* is not the state); perfect-info games omit `obs`. `expected.observation` is
|
|
57
|
-
* the shared behavioral anchor: the TS side must project the post-action
|
|
58
|
-
* state to it, and a Dart `previewAction` that returns non-null must predict
|
|
59
|
-
* it, so the two sides are compared through one recorded value.
|
|
60
|
-
*
|
|
61
|
-
* Wire it up in a game-owned test file running under plain-Node vitest:
|
|
62
|
-
*
|
|
63
|
-
* ```ts
|
|
64
|
-
* import { twinFixtureTests } from "@eigeninteractive/testkit";
|
|
65
|
-
* import gameModule from "../src/module/index.js";
|
|
66
|
-
*
|
|
67
|
-
* twinFixtureTests(gameModule, new URL("../src/module/fixtures/", import.meta.url));
|
|
68
|
-
* ```
|
|
69
|
-
*/
|
|
70
|
-
import { type GameAccess, type GameModule, type GameRules, type Json, type JsonObject, type OutcomeEntry } from "@eigeninteractive/rules";
|
|
71
|
-
/** One fixture file: cases targeting one `schemaVersion` unit. */
|
|
72
|
-
export interface TwinFixtureFile {
|
|
73
|
-
schemaVersion: number;
|
|
74
|
-
cases: TwinFixtureCase[];
|
|
75
|
-
}
|
|
76
|
-
/** A game-action case: exercises schemas, `applyAction`, and (through
|
|
77
|
-
* `expected.observation`) `computeObservation` for the acting seat. */
|
|
78
|
-
export interface ActionCase {
|
|
79
|
-
kind: "action";
|
|
80
|
-
name: string;
|
|
81
|
-
config: JsonObject;
|
|
82
|
-
state: JsonObject;
|
|
83
|
-
/** Dart-side observation payload; unused here (defaults to `state`). */
|
|
84
|
-
obs?: JsonObject;
|
|
85
|
-
pending: number[];
|
|
86
|
-
playerIndex: number;
|
|
87
|
-
participantCount?: number;
|
|
88
|
-
rngSeed?: string;
|
|
89
|
-
action: JsonObject;
|
|
90
|
-
expected: {
|
|
91
|
-
valid: boolean;
|
|
92
|
-
state?: JsonObject;
|
|
93
|
-
pending?: number[];
|
|
94
|
-
outcome?: OutcomeEntry[] | null;
|
|
95
|
-
observation?: JsonObject;
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
/** A `ratingPool` predicate case. Omitted timing fields mean null. */
|
|
99
|
-
export interface RatingPoolCase {
|
|
100
|
-
kind: "ratingPool";
|
|
101
|
-
name: string;
|
|
102
|
-
access: GameAccess;
|
|
103
|
-
turnSeconds?: number | null;
|
|
104
|
-
budgetSeconds?: number | null;
|
|
105
|
-
incrementSeconds?: number | null;
|
|
106
|
-
minPlayers: number;
|
|
107
|
-
maxPlayers: number;
|
|
108
|
-
config: JsonObject;
|
|
109
|
-
expected: string | null;
|
|
110
|
-
}
|
|
111
|
-
/** A `playerLimits` case: the seats one config may be played with. */
|
|
112
|
-
export interface PlayerLimitsCase {
|
|
113
|
-
kind: "playerLimits";
|
|
114
|
-
name: string;
|
|
115
|
-
config: JsonObject;
|
|
116
|
-
expected: {
|
|
117
|
-
minPlayers: number;
|
|
118
|
-
maxPlayers: number;
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
/** A `botSeatable` predicate case. */
|
|
122
|
-
export interface BotSeatableCase {
|
|
123
|
-
kind: "botSeatable";
|
|
124
|
-
name: string;
|
|
125
|
-
gameConfig: JsonObject;
|
|
126
|
-
botConfig: JsonObject;
|
|
127
|
-
expected: boolean;
|
|
128
|
-
}
|
|
129
|
-
export type TwinFixtureCase = ActionCase | PlayerLimitsCase | RatingPoolCase | BotSeatableCase;
|
|
130
|
-
/** Validate one fixture file's parsed JSON, or throw naming the offending
|
|
131
|
-
* file, case, and field. Exported so a repo can lint its fixtures without
|
|
132
|
-
* running them. */
|
|
133
|
-
export declare function parseTwinFixtureFile(path: string, json: unknown): TwinFixtureFile;
|
|
134
|
-
/** Run one fixture case against a rules unit, returning failure descriptions
|
|
135
|
-
* (empty ⇒ the case passes). Pure; the file-reading test registrar is
|
|
136
|
-
* {@link twinFixtureTests}. */
|
|
137
|
-
export declare function evaluateTwinCase(rules: GameRules, kase: TwinFixtureCase): string[];
|
|
138
|
-
/** Register one vitest test per fixture case found under `fixturesRoot`
|
|
139
|
-
* (layout: `<root>/v<N>/*.json`). Call at the top level of a test module
|
|
140
|
-
* running in a Node environment. */
|
|
141
|
-
export declare function twinFixtureTests(gameModule: GameModule, fixturesRoot: string | URL): void;
|
|
142
|
-
/** Structural JSON equality. Object keys with `undefined` values count as
|
|
143
|
-
* absent (matching how schema libraries model optional fields); array order
|
|
144
|
-
* matters. */
|
|
145
|
-
export declare function deepEquals(a: Json | undefined, b: Json | undefined): boolean;
|