@hydranium/conformance 1.0.0-next.23 → 1.0.0-next.232

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 CHANGED
@@ -29,6 +29,19 @@ author, and that keeps checking you as the framework moves.
29
29
  - **A false-green guard in the fixture type.** `LanguageFixture` requires **both** a `valid` and an
30
30
  `invalid` model, so an "invalid" model that in fact parses clean fails the diagnostics checks
31
31
  instead of passing vacuously.
32
+ - **Server-side rendering, opt-in.** Supply `renderedDiagnostic: { locale, expected,
33
+ absentWithLocale }` on a fixture and the `/lsp` battery declares that locale at `initialize`,
34
+ then asserts the fragment appears — and, from `absentWithLocale`, that the untranslated fragment
35
+ DISAPPEARS with the locale and is present without it. It is opt-in because the framework ships no
36
+ catalogue and selects no locale, so a server that renders nothing is correct; and it is a PAIR
37
+ because "the message contains X" alone passes for a server whose English contains X. Omit
38
+ `absentWithLocale` and the control reports skipped rather than being quietly dropped.
39
+ - **Client sessions, on the data head.** The `/data` battery opens and writes every document as a
40
+ client session and holds the head to how sessions behave: a session writes and saves only what it
41
+ has open, ids are refused while live or reserved, a write answers with its document's
42
+ diagnostics, `text.dirty` follows the file, `text.hash` follows the text, and the release after the last close
43
+ reverts a document to what its save wrote, or drops it when it was never saved. See
44
+ [client sessions](../../docs/concepts/client-sessions.md).
32
45
 
33
46
  ## Install
34
47
 
@@ -51,8 +64,9 @@ package has no runtime dependencies of its own.
51
64
  | `./vitest` | Vitest adapter: `run{Data,Lsp,Glsp}Conformance`. |
52
65
  | `./jest` | Jest adapter: the same three entry points. |
53
66
 
54
- Each named subpath also resolves as `@hydranium/conformance/lib/<name>`, so a consumer on classic
55
- `moduleResolution: "Node"` can reach it. The root barrel deliberately re-exports none of the slices.
67
+ Resolve the subpaths with [a resolver that reads `exports`](../../docs/adopting/requirements.md#a-resolver-that-reads-exports);
68
+ `"Node"` (node10) reaches none of them.
69
+ The root barrel deliberately re-exports none of the slices.
56
70
 
57
71
  ## Usage
58
72
 
@@ -65,12 +79,19 @@ Each takes `connect` plus `languages`:
65
79
  - **`connect`** returns a freshly wired driver and is called **once per check**, so checks cannot
66
80
  interfere; the kit disposes the driver afterwards. The data slice wants a server already ready; the
67
81
  LSP slice drives the `initialize` handshake itself, so `connect` must **not** pre-initialise; the
68
- GLSP slice drives `start()`.
69
- - **`languages`** is an array of `LanguageFixture`: `valid` and `invalid` (both read by every
70
- slice), plus two opt-ins — `edit` (data slice only: a replacement text and an `expect(root)`
71
- predicate, because only you know what "the edit landed" means for your grammar) and
72
- `completionPosition` (LSP slice only). A fixture's `uri` and `text` may be thunks, resolved after
73
- `connect`, which is how each check gets pristine input in a workspace `connect` just created.
82
+ GLSP slice drives `start()`. The data slice saves documents beside each fixture's `valid`, so its
83
+ `connect` should give each check a workspace the kit may write to and throw away.
84
+ - **`languages`** is an array of `LanguageFixture`: `valid` and `invalid` are required and read by
85
+ every slice; every other field is an opt-in whose checks report **skipped with a named reason**
86
+ when it is absent, so an opt-out stays distinguishable from lost coverage. Read the current set
87
+ off the `LanguageFixture` type, which says per field which slice reads it and what supplying it
88
+ claims — the two that carry the most are `edit` (a replacement text plus an `expect(root)`
89
+ predicate, because only you know what "the edit landed" means for your grammar) and `dependent`
90
+ (a document that references `valid`, which is what lets the data slice provoke a cascade; add
91
+ `breakingEdit`, a text for `valid` that breaks that reference, and the slice also checks who a
92
+ dependent's update event is credited to). A fixture's `uri` and `text` may be thunks, resolved
93
+ after `connect`, which is how each check gets pristine input in a workspace `connect` just
94
+ created.
74
95
 
75
96
  The GLSP slice is generic over your action type and takes `GlspFixture` per diagram type — the
76
97
  fixture builds the native actions and the kit matches responses by `kind`, so no `@eclipse-glsp/*`
@@ -87,9 +108,10 @@ among the framework's test layers, see [`docs/contributing/testing.md`](../../do
87
108
 
88
109
  ## Status
89
110
 
90
- Alpha — pre-v0, not yet published. The check batteries are being populated incrementally and the
91
- driver ports are not yet stable — a new check can turn a passing adopter red by design. See the
92
- [repository README](../../README.md) for the current status and known limitations.
111
+ Alpha — pre-v0, published as a `1.0.0-next` prerelease on every merge to `main`. The check batteries
112
+ are being populated incrementally and the driver ports are not yet stable — a new check can turn a
113
+ passing adopter red by design. See the [repository README](../../README.md) for the current status
114
+ and known limitations.
93
115
 
94
116
  ## License
95
117
 
@@ -7,28 +7,40 @@
7
7
  * SPDX-License-Identifier: MIT
8
8
  ********************************************************************************/
9
9
  import { type TransferDiagnostic, type TransferElement } from '@hydranium/protocol';
10
- import type { DataServerProtocol, TransferDocumentUpdatedEvent } from '@hydranium/protocol/data';
10
+ import type { DataServerProtocol, ReferenceServerProtocol, TransferDocumentsBuiltEvent, TransferDocumentUpdatedEvent } from '@hydranium/protocol/data';
11
11
  import { type Harness } from '@hydranium/protocol/testing';
12
12
  import type { ConformanceCheck } from '../conformance-suite.js';
13
13
  import { type LanguageFixture } from '../model.js';
14
14
  /**
15
15
  * The data-server driver port — a live, connected, READY data-server exposed
16
- * through its protocol-native proxy plus the captured client-side update
17
- * events. The kit names only `@hydranium/protocol` types, so a
16
+ * through its protocol-native proxy plus the captured client-side
17
+ * notifications. The kit names only `@hydranium/protocol` types, so a
18
18
  * `DataServerHarness` satisfies the port structurally (it has `proxy` +
19
- * `events` + `dispose`) with NO adapter. `extends Harness` gives the kit the
19
+ * `events`, `builds` and `dispose`) with NO adapter. `extends Harness` gives the kit the
20
20
  * universal `dispose()` teardown.
21
21
  *
22
- * The kit seeds documents purely through the proxy: `updateModelDocument` is
23
- * an upsert (it creates a cold URI from the payload, not just modifies an
24
- * existing one), so the slice needs no services-level open hook. The adopter
25
- * only has to stand the server up READY in its `connect` — see
26
- * {@link DataConformanceOptions.connect}.
22
+ * The kit seeds documents purely through the proxy, as client sessions: it
23
+ * registers one with `createSession`, opens the document, or creates it with
24
+ * `createModelDocument` when there is no file to open, and writes it. So the
25
+ * head under test must implement sessions, and the slice needs no
26
+ * services-level open hook. The adopter only has to stand the server up READY
27
+ * in its `connect` — see {@link DataConformanceOptions.connect}.
27
28
  */
28
29
  export interface DataConformanceDriver<TTransfer extends TransferElement, TDiagnostic extends TransferDiagnostic = TransferDiagnostic> extends Harness {
29
30
  readonly proxy: DataServerProtocol<TTransfer, TDiagnostic>;
30
- /** Captured `onDocumentUpdated` events, append order — the subscription check's observation target. */
31
+ /** Captured `onDocumentUpdated` events, in append order. */
31
32
  readonly events: ReadonlyArray<TransferDocumentUpdatedEvent<TTransfer, TDiagnostic>>;
33
+ /** Captured `onDocumentsBuilt` events, append order — the cascade check's observation target. */
34
+ readonly builds: ReadonlyArray<TransferDocumentsBuiltEvent>;
35
+ /**
36
+ * The opt-in reference surface, when the head serves it.
37
+ *
38
+ * Separate from {@link proxy} because `ReferenceServerProtocol` is NOT part
39
+ * of `DataServerProtocol` — a head may serve documents and no references at
40
+ * all. Absent means the reference check reports skipped with a named reason
41
+ * rather than failing a head that never claimed the surface.
42
+ */
43
+ readonly references?: ReferenceServerProtocol;
32
44
  }
33
45
  /** Options for `runDataConformance`. */
34
46
  export interface DataConformanceOptions<TTransfer extends TransferElement, TDiagnostic extends TransferDiagnostic = TransferDiagnostic> {
@@ -37,6 +49,10 @@ export interface DataConformanceOptions<TTransfer extends TransferElement, TDiag
37
49
  * once per check for isolation; the kit disposes it after the check. The
38
50
  * adopter must initialise the workspace before returning, so `waitForReady`
39
51
  * resolves rather than hanging.
52
+ *
53
+ * Some checks save documents beside each fixture's `valid`, and nothing in
54
+ * the protocol deletes a file, so give each check a workspace the kit may
55
+ * write to and throw away.
40
56
  */
41
57
  readonly connect: () => DataConformanceDriver<TTransfer, TDiagnostic> | Promise<DataConformanceDriver<TTransfer, TDiagnostic>>;
42
58
  /** Per-language fixtures; the grammar-bearing checks run once per language. */
@@ -52,6 +68,13 @@ export interface DataConformanceOptions<TTransfer extends TransferElement, TDiag
52
68
  * from "never implemented" without the adopter saying which it is.
53
69
  */
54
70
  readonly expectsProjects?: boolean;
71
+ /**
72
+ * Open another connection to the same server as `driver`, for the check
73
+ * that a connection's sessions end with it while the server lives on. That
74
+ * check disposes `driver` and needs its `dispose` to close the connection as
75
+ * the server sees it. Absent, the check reports skipped.
76
+ */
77
+ readonly attach?: (driver: DataConformanceDriver<TTransfer, TDiagnostic>) => DataConformanceDriver<TTransfer, TDiagnostic> | Promise<DataConformanceDriver<TTransfer, TDiagnostic>>;
55
78
  /** Suite title override. Default `'conformance: data-server'`. */
56
79
  readonly suiteTitle?: string;
57
80
  }
@@ -62,7 +85,7 @@ export interface DataConformanceOptions<TTransfer extends TransferElement, TDiag
62
85
  * unit tests; adopters call `runDataConformance`.
63
86
  *
64
87
  * `LanguageFixture.edit` is read HERE and nowhere else in the kit, and is
65
- * optional: its two checks report skipped when it is absent. See
88
+ * optional: every check that needs one reports skipped when it is absent. See
66
89
  * {@link LanguageFixture} for which slice reads which field.
67
90
  */
68
91
  export declare function buildDataChecks<TTransfer extends TransferElement, TDiagnostic extends TransferDiagnostic = TransferDiagnostic>(options: DataConformanceOptions<TTransfer, TDiagnostic>): ConformanceCheck[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAWlF,OAAO,EAAoB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtG,OAAO,KAAK,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AACjG,OAAO,EAAE,KAAK,OAAO,EAAW,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,KAAK,eAAe,EAAiC,MAAM,aAAa,CAAC;AAElF;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,qBAAqB,CACnC,SAAS,SAAS,eAAe,EACjC,WAAW,SAAS,kBAAkB,GAAG,kBAAkB,CAC5D,SAAQ,OAAO;IACd,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC3D,uGAAuG;IACvG,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,4BAA4B,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;CACvF;AAED,wCAAwC;AACxC,MAAM,WAAW,sBAAsB,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,SAAS,kBAAkB,GAAG,kBAAkB;IACnI;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,qBAAqB,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IAC/H,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IACnD;;;;;;;;;OASG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,kEAAkE;IAClE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC/B;AAeD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,SAAS,kBAAkB,GAAG,kBAAkB,EAC3H,OAAO,EAAE,sBAAsB,CAAC,SAAS,EAAE,WAAW,CAAC,GACvD,gBAAgB,EAAE,CAsMpB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAWlF,OAAO,EAWJ,KAAK,kBAAkB,EACvB,KAAK,eAAe,EAEtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACT,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,4BAA4B,EAC9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,OAAO,EAAW,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,KAAK,eAAe,EAAiC,MAAM,aAAa,CAAC;AAElF;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,qBAAqB,CACnC,SAAS,SAAS,eAAe,EACjC,WAAW,SAAS,kBAAkB,GAAG,kBAAkB,CAC5D,SAAQ,OAAO;IACd,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC3D,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,4BAA4B,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IACrF,iGAAiG;IACjG,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,2BAA2B,CAAC,CAAC;IAC5D;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,uBAAuB,CAAC;CAChD;AAED,wCAAwC;AACxC,MAAM,WAAW,sBAAsB,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,SAAS,kBAAkB,GAAG,kBAAkB;IACnI;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,qBAAqB,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IAC/H,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IACnD;;;;;;;;;OASG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CACf,MAAM,EAAE,qBAAqB,CAAC,SAAS,EAAE,WAAW,CAAC,KACnD,qBAAqB,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IAC5G,kEAAkE;IAClE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC/B;AA6HD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,SAAS,SAAS,eAAe,EAAE,WAAW,SAAS,kBAAkB,GAAG,kBAAkB,EAC3H,OAAO,EAAE,sBAAsB,CAAC,SAAS,EAAE,WAAW,CAAC,GACvD,gBAAgB,EAAE,CAq8BpB"}