@rtif-sdk/test-kit 1.0.0 → 1.2.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.
@@ -3,11 +3,45 @@
3
3
  */
4
4
  import type { Document, Selection } from '@rtif-sdk/core';
5
5
  /**
6
- * Assert that two documents are structurally equal (ignoring block IDs).
6
+ * Options for `assertDocEqual`.
7
7
  */
8
- export declare function assertDocEqual(_actual: Document, _expected: Document): void;
8
+ export interface DocEqualOptions {
9
+ /**
10
+ * When true, block IDs must also match.
11
+ * Default: false (block IDs are ignored).
12
+ */
13
+ compareIds?: boolean;
14
+ }
15
+ /**
16
+ * Assert that two documents are structurally equal.
17
+ *
18
+ * By default, block IDs are ignored — only block content (type, spans, attrs)
19
+ * and document-level properties (version, meta) are compared.
20
+ * Pass `{ compareIds: true }` to also require matching block IDs.
21
+ *
22
+ * @param actual - The actual document
23
+ * @param expected - The expected document
24
+ * @param options - Comparison options
25
+ * @throws {Error} If the documents are not structurally equal
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * assertDocEqual(result.doc, expected);
30
+ * assertDocEqual(result.doc, expected, { compareIds: true });
31
+ * ```
32
+ */
33
+ export declare function assertDocEqual(actual: Document, expected: Document, options?: DocEqualOptions): void;
9
34
  /**
10
35
  * Assert that two selections are equal.
36
+ *
37
+ * @param actual - The actual selection
38
+ * @param expected - The expected selection
39
+ * @throws {Error} If the selections differ
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * assertSelectionEqual(engine.state.selection, sel(0, 5));
44
+ * ```
11
45
  */
12
46
  export declare function assertSelectionEqual(actual: Selection, expected: Selection): void;
13
47
  //# sourceMappingURL=assertions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,GAAG,IAAI,CAG3E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,GAAG,IAAI,CAUjF"}
1
+ {"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAe,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,QAAQ,EAChB,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,eAAe,GACxB,IAAI,CA8BN;AA2ED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,GAAG,IAAI,CAUjF"}
@@ -2,20 +2,151 @@
2
2
  * Custom test assertions for RTIF documents and selections.
3
3
  */
4
4
  /**
5
- * Assert that two documents are structurally equal (ignoring block IDs).
5
+ * Assert that two documents are structurally equal.
6
+ *
7
+ * By default, block IDs are ignored — only block content (type, spans, attrs)
8
+ * and document-level properties (version, meta) are compared.
9
+ * Pass `{ compareIds: true }` to also require matching block IDs.
10
+ *
11
+ * @param actual - The actual document
12
+ * @param expected - The expected document
13
+ * @param options - Comparison options
14
+ * @throws {Error} If the documents are not structurally equal
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * assertDocEqual(result.doc, expected);
19
+ * assertDocEqual(result.doc, expected, { compareIds: true });
20
+ * ```
6
21
  */
7
- export function assertDocEqual(_actual, _expected) {
8
- // TODO: Implement deep structural comparison
9
- throw new Error('assertDocEqual() not yet implemented');
22
+ export function assertDocEqual(actual, expected, options) {
23
+ const compareIds = options?.compareIds ?? false;
24
+ // Version
25
+ if (actual.version !== expected.version) {
26
+ throw new Error(`Document version mismatch: got ${String(actual.version)}, expected ${String(expected.version)}`);
27
+ }
28
+ // Block count
29
+ if (actual.blocks.length !== expected.blocks.length) {
30
+ throw new Error(`Block count mismatch: got ${String(actual.blocks.length)}, expected ${String(expected.blocks.length)}`);
31
+ }
32
+ // Blocks
33
+ for (let i = 0; i < expected.blocks.length; i++) {
34
+ const aBlock = actual.blocks[i];
35
+ const eBlock = expected.blocks[i];
36
+ assertBlockEqual(aBlock, eBlock, i, compareIds);
37
+ }
38
+ // Meta
39
+ if (!deepEqual(actual.meta, expected.meta)) {
40
+ throw new Error(`Document meta mismatch:\n got: ${JSON.stringify(actual.meta)}\n expected: ${JSON.stringify(expected.meta)}`);
41
+ }
42
+ }
43
+ /**
44
+ * Assert that two blocks are structurally equal.
45
+ */
46
+ function assertBlockEqual(actual, expected, index, compareIds) {
47
+ const prefix = `Block[${String(index)}]`;
48
+ // ID (optional)
49
+ if (compareIds && actual.id !== expected.id) {
50
+ throw new Error(`${prefix} id mismatch: got "${actual.id}", expected "${expected.id}"`);
51
+ }
52
+ // Type
53
+ if (actual.type !== expected.type) {
54
+ throw new Error(`${prefix} type mismatch: got "${actual.type}", expected "${expected.type}"`);
55
+ }
56
+ // Span count
57
+ if (actual.spans.length !== expected.spans.length) {
58
+ throw new Error(`${prefix} span count mismatch: got ${String(actual.spans.length)}, expected ${String(expected.spans.length)}\n` +
59
+ ` got: ${JSON.stringify(actual.spans)}\n` +
60
+ ` expected: ${JSON.stringify(expected.spans)}`);
61
+ }
62
+ // Spans
63
+ for (let j = 0; j < expected.spans.length; j++) {
64
+ const aSpan = actual.spans[j];
65
+ const eSpan = expected.spans[j];
66
+ assertSpanEqual(aSpan, eSpan, index, j);
67
+ }
68
+ // Attrs
69
+ if (!deepEqual(normalizeAttrs(actual.attrs), normalizeAttrs(expected.attrs))) {
70
+ throw new Error(`${prefix} attrs mismatch:\n got: ${JSON.stringify(actual.attrs)}\n expected: ${JSON.stringify(expected.attrs)}`);
71
+ }
72
+ }
73
+ /**
74
+ * Assert that two spans are structurally equal.
75
+ */
76
+ function assertSpanEqual(actual, expected, blockIndex, spanIndex) {
77
+ const prefix = `Block[${String(blockIndex)}].Span[${String(spanIndex)}]`;
78
+ if (actual.text !== expected.text) {
79
+ throw new Error(`${prefix} text mismatch: got "${actual.text}", expected "${expected.text}"`);
80
+ }
81
+ if (!marksDeepEqual(actual.marks, expected.marks)) {
82
+ throw new Error(`${prefix} marks mismatch:\n got: ${JSON.stringify(actual.marks)}\n expected: ${JSON.stringify(expected.marks)}`);
83
+ }
10
84
  }
11
85
  /**
12
86
  * Assert that two selections are equal.
87
+ *
88
+ * @param actual - The actual selection
89
+ * @param expected - The expected selection
90
+ * @throws {Error} If the selections differ
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * assertSelectionEqual(engine.state.selection, sel(0, 5));
95
+ * ```
13
96
  */
14
97
  export function assertSelectionEqual(actual, expected) {
15
98
  if (actual.anchor.offset !== expected.anchor.offset ||
16
99
  actual.focus.offset !== expected.focus.offset) {
17
- throw new Error(`Selection mismatch: got (${actual.anchor.offset}, ${actual.focus.offset}), ` +
18
- `expected (${expected.anchor.offset}, ${expected.focus.offset})`);
100
+ throw new Error(`Selection mismatch: got (${String(actual.anchor.offset)}, ${String(actual.focus.offset)}), ` +
101
+ `expected (${String(expected.anchor.offset)}, ${String(expected.focus.offset)})`);
102
+ }
103
+ }
104
+ // ---------------------------------------------------------------------------
105
+ // Internal helpers
106
+ // ---------------------------------------------------------------------------
107
+ /**
108
+ * Normalize attrs: treat undefined and empty object as equivalent (both → undefined).
109
+ */
110
+ function normalizeAttrs(attrs) {
111
+ if (attrs === undefined)
112
+ return undefined;
113
+ if (Object.keys(attrs).length === 0)
114
+ return undefined;
115
+ return attrs;
116
+ }
117
+ /**
118
+ * Compare marks with RTIF semantics: undefined and {} are equal.
119
+ */
120
+ function marksDeepEqual(a, b) {
121
+ const aNorm = a === undefined || Object.keys(a).length === 0 ? undefined : a;
122
+ const bNorm = b === undefined || Object.keys(b).length === 0 ? undefined : b;
123
+ return deepEqual(aNorm, bNorm);
124
+ }
125
+ /**
126
+ * Simple deep equality for JSON-serializable values.
127
+ */
128
+ function deepEqual(a, b) {
129
+ if (a === b)
130
+ return true;
131
+ if (a === null || b === null)
132
+ return false;
133
+ if (a === undefined || b === undefined)
134
+ return false;
135
+ if (typeof a !== typeof b)
136
+ return false;
137
+ if (typeof a === 'object' && typeof b === 'object') {
138
+ const aObj = a;
139
+ const bObj = b;
140
+ const aKeys = Object.keys(aObj);
141
+ const bKeys = Object.keys(bObj);
142
+ if (aKeys.length !== bKeys.length)
143
+ return false;
144
+ for (const key of aKeys) {
145
+ if (!deepEqual(aObj[key], bObj[key]))
146
+ return false;
147
+ }
148
+ return true;
19
149
  }
150
+ return false;
20
151
  }
21
152
  //# sourceMappingURL=assertions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"assertions.js","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAAiB,EAAE,SAAmB;IACnE,6CAA6C;IAC7C,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,QAAmB;IACzE,IACE,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC,MAAM;QAC/C,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,KAAK,CAAC,MAAM,EAC7C,CAAC;QACD,MAAM,IAAI,KAAK,CACb,4BAA4B,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK;YAC3E,aAAa,QAAQ,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CACnE,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"assertions.js","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"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"}
@@ -1,25 +1,214 @@
1
1
  /**
2
- * Fluent document builders for tests.
3
- * See SPEC.md Appendix C for usage examples.
2
+ * Fluent document builders and fixture factories for RTIF tests.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { doc, span, sel, emptyDoc, textDoc } from '@rtif-sdk/test-kit';
7
+ *
8
+ * // Plain text block
9
+ * const d1 = doc().block('Hello').build();
10
+ *
11
+ * // Block with formatted spans
12
+ * const d2 = doc()
13
+ * .block(span('Hello '), span('world', { bold: true }), span('!'))
14
+ * .build();
15
+ *
16
+ * // Block with type, attrs, and custom ID
17
+ * const d3 = doc()
18
+ * .block('Title').type('heading').attrs({ level: 1 }).id('h1')
19
+ * .block('Body text')
20
+ * .meta({ title: 'My Doc' })
21
+ * .build();
22
+ *
23
+ * // Common fixtures
24
+ * const empty = emptyDoc();
25
+ * const simple = textDoc('hello');
26
+ * ```
4
27
  */
5
28
  import type { Document, Selection } from '@rtif-sdk/core';
6
- /** Builder for constructing test documents fluently */
29
+ /**
30
+ * Input type for span content in `block()`.
31
+ * A plain string creates an unmarked span; a `SpanDef` carries marks.
32
+ */
33
+ export type SpanInput = string | SpanDef;
34
+ /**
35
+ * A span definition with text and optional marks.
36
+ * Created via the `span()` helper.
37
+ */
38
+ export interface SpanDef {
39
+ readonly text: string;
40
+ readonly marks?: Record<string, unknown>;
41
+ }
42
+ /**
43
+ * Create a span definition with text and optional marks.
44
+ *
45
+ * @param text - The span text content
46
+ * @param marks - Optional formatting marks
47
+ * @returns A SpanDef for use in `DocumentBuilder.block()`
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * span('hello') // plain text
52
+ * span('bold', { bold: true }) // bold text
53
+ * span('link', { link: { href: '…' }}) // link
54
+ * ```
55
+ */
56
+ export declare function span(text: string, marks?: Record<string, unknown>): SpanDef;
57
+ /** Builder for constructing test documents fluently. */
7
58
  export declare class DocumentBuilder {
8
- private blocks;
59
+ private _blocks;
60
+ private _meta?;
9
61
  private nextId;
10
62
  /**
11
- * Add a block with plain text, or text with marks.
63
+ * Add a block with one or more spans.
64
+ *
65
+ * When called with a single string, creates a plain text block.
66
+ * When called with `SpanInput` values (strings and/or `span()` results),
67
+ * each input becomes a span in the block.
68
+ *
69
+ * @param inputs - One or more span inputs (strings or SpanDefs)
70
+ * @returns The builder for chaining
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * doc().block('Hello') // plain text
75
+ * doc().block(span('Hello '), span('world', { bold: true })) // mixed
76
+ * doc().block('plain ', span('bold', { bold: true }), ' more') // strings + spans
77
+ * ```
78
+ */
79
+ block(...inputs: SpanInput[]): this;
80
+ /**
81
+ * Set the block type on the last added block.
82
+ *
83
+ * @param blockType - The block type string (e.g., 'heading', 'code_block')
84
+ * @returns The builder for chaining
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * doc().block('Title').type('heading').build()
89
+ * ```
90
+ */
91
+ type(blockType: string): this;
92
+ /**
93
+ * Set block-level attributes on the last added block.
94
+ *
95
+ * @param blockAttrs - The attributes to set
96
+ * @returns The builder for chaining
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * doc().block('Title').type('heading').attrs({ level: 2 }).build()
101
+ * ```
102
+ */
103
+ attrs(blockAttrs: Record<string, unknown>): this;
104
+ /**
105
+ * Set a custom ID on the last added block.
12
106
  *
13
- * Usage:
14
- * doc().block("Hello")
15
- * doc().block("Hello ", { bold: "world" })
107
+ * @param blockId - The block ID
108
+ * @returns The builder for chaining
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * doc().block('Hello').id('custom-id').build()
113
+ * ```
114
+ */
115
+ id(blockId: string): this;
116
+ /**
117
+ * Set document-level metadata.
118
+ *
119
+ * @param docMeta - The metadata key-value pairs
120
+ * @returns The builder for chaining
121
+ *
122
+ * @example
123
+ * ```ts
124
+ * doc().block('Hello').meta({ title: 'My Doc', lang: 'en' }).build()
125
+ * ```
126
+ */
127
+ meta(docMeta: Record<string, unknown>): this;
128
+ /**
129
+ * Build the final Document.
130
+ *
131
+ * @returns A valid RTIF Document
16
132
  */
17
- block(text: string, _marks?: Record<string, string>): this;
18
- /** Build the final Document */
19
133
  build(): Document;
20
134
  }
21
- /** Create a new DocumentBuilder */
135
+ /**
136
+ * Create a new DocumentBuilder.
137
+ *
138
+ * @returns A fresh DocumentBuilder
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * const d = doc().block('Hello').block('World').build();
143
+ * ```
144
+ */
22
145
  export declare function doc(): DocumentBuilder;
23
- /** Create a Selection from anchor and focus offsets */
146
+ /**
147
+ * Create a Selection from anchor and focus offsets.
148
+ *
149
+ * @param anchor - Anchor offset
150
+ * @param focus - Focus offset
151
+ * @returns A Selection object
152
+ *
153
+ * @example
154
+ * ```ts
155
+ * sel(0, 5) // forward selection
156
+ * sel(5, 5) // collapsed cursor at offset 5
157
+ * sel(10, 5) // backward selection
158
+ * ```
159
+ */
24
160
  export declare function sel(anchor: number, focus: number): Selection;
161
+ /**
162
+ * Create an empty document with a single empty block.
163
+ *
164
+ * @param blockId - Optional block ID (default: 'b1')
165
+ * @returns A Document with one empty text block
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * const d = emptyDoc();
170
+ * // { version: 1, blocks: [{ id: 'b1', type: 'text', spans: [{ text: '' }] }] }
171
+ * ```
172
+ */
173
+ export declare function emptyDoc(blockId?: string): Document;
174
+ /**
175
+ * Create a document with a single text block.
176
+ *
177
+ * @param text - The block text content
178
+ * @param blockId - Optional block ID (default: 'b1')
179
+ * @returns A Document with one text block
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * const d = textDoc('hello');
184
+ * const d2 = textDoc('hello', 'custom-id');
185
+ * ```
186
+ */
187
+ export declare function textDoc(text: string, blockId?: string): Document;
188
+ /**
189
+ * Create a document with multiple text blocks.
190
+ *
191
+ * @param texts - Array of text strings, one per block
192
+ * @returns A Document with blocks 'b1', 'b2', etc.
193
+ *
194
+ * @example
195
+ * ```ts
196
+ * const d = multiBlockDoc('hello', 'world');
197
+ * // Two blocks: b1="hello", b2="world"
198
+ * ```
199
+ */
200
+ export declare function multiBlockDoc(...texts: string[]): Document;
201
+ /**
202
+ * Extract plain text from a document, joining blocks with newlines.
203
+ *
204
+ * @param document - The RTIF document
205
+ * @returns Plain text representation
206
+ *
207
+ * @example
208
+ * ```ts
209
+ * const text = docText(engine.state.doc);
210
+ * // "hello\nworld"
211
+ * ```
212
+ */
213
+ export declare function docText(document: Document): string;
25
214
  //# sourceMappingURL=builders.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../src/builders.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAS,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEjE,uDAAuD;AACvD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAAK;IAEnB;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAW1D,+BAA+B;IAC/B,KAAK,IAAI,QAAQ;CAUlB;AAED,mCAAmC;AACnC,wBAAgB,GAAG,IAAI,eAAe,CAErC;AAED,uDAAuD;AACvD,wBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAK5D"}
1
+ {"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../src/builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAe,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzC;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAK3E;AAED,wDAAwD;AACxD,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,KAAK,CAAC,CAA0B;IACxC,OAAO,CAAC,MAAM,CAAK;IAEnB;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI;IAyBnC;;;;;;;;;;OAUG;IACH,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAS7B;;;;;;;;;;OAUG;IACH,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAShD;;;;;;;;;;OAUG;IACH,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IASzB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAK5C;;;;OAIG;IACH,KAAK,IAAI,QAAQ;CAclB;AAED;;;;;;;;;GASG;AACH,wBAAgB,GAAG,IAAI,eAAe,CAErC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAK5D;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,OAAO,SAAO,GAAG,QAAQ,CAKjD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,SAAO,GAAG,QAAQ,CAK9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,QAAQ,CAY1D;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAIlD"}
package/dist/builders.js CHANGED
@@ -1,49 +1,302 @@
1
1
  /**
2
- * Fluent document builders for tests.
3
- * See SPEC.md Appendix C for usage examples.
2
+ * Fluent document builders and fixture factories for RTIF tests.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { doc, span, sel, emptyDoc, textDoc } from '@rtif-sdk/test-kit';
7
+ *
8
+ * // Plain text block
9
+ * const d1 = doc().block('Hello').build();
10
+ *
11
+ * // Block with formatted spans
12
+ * const d2 = doc()
13
+ * .block(span('Hello '), span('world', { bold: true }), span('!'))
14
+ * .build();
15
+ *
16
+ * // Block with type, attrs, and custom ID
17
+ * const d3 = doc()
18
+ * .block('Title').type('heading').attrs({ level: 1 }).id('h1')
19
+ * .block('Body text')
20
+ * .meta({ title: 'My Doc' })
21
+ * .build();
22
+ *
23
+ * // Common fixtures
24
+ * const empty = emptyDoc();
25
+ * const simple = textDoc('hello');
26
+ * ```
4
27
  */
5
- /** Builder for constructing test documents fluently */
28
+ /**
29
+ * Create a span definition with text and optional marks.
30
+ *
31
+ * @param text - The span text content
32
+ * @param marks - Optional formatting marks
33
+ * @returns A SpanDef for use in `DocumentBuilder.block()`
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * span('hello') // plain text
38
+ * span('bold', { bold: true }) // bold text
39
+ * span('link', { link: { href: '…' }}) // link
40
+ * ```
41
+ */
42
+ export function span(text, marks) {
43
+ if (marks !== undefined) {
44
+ return { text, marks };
45
+ }
46
+ return { text };
47
+ }
48
+ /** Builder for constructing test documents fluently. */
6
49
  export class DocumentBuilder {
7
- blocks = [];
50
+ _blocks = [];
51
+ _meta;
8
52
  nextId = 1;
9
53
  /**
10
- * Add a block with plain text, or text with marks.
54
+ * Add a block with one or more spans.
55
+ *
56
+ * When called with a single string, creates a plain text block.
57
+ * When called with `SpanInput` values (strings and/or `span()` results),
58
+ * each input becomes a span in the block.
11
59
  *
12
- * Usage:
13
- * doc().block("Hello")
14
- * doc().block("Hello ", { bold: "world" })
60
+ * @param inputs - One or more span inputs (strings or SpanDefs)
61
+ * @returns The builder for chaining
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * doc().block('Hello') // plain text
66
+ * doc().block(span('Hello '), span('world', { bold: true })) // mixed
67
+ * doc().block('plain ', span('bold', { bold: true }), ' more') // strings + spans
68
+ * ```
15
69
  */
16
- block(text, _marks) {
17
- // TODO: Implement mark parsing from the shorthand format
18
- // For now, creates a simple single-span block
19
- this.blocks.push({
70
+ block(...inputs) {
71
+ const spans = inputs.map((input) => {
72
+ if (typeof input === 'string') {
73
+ return { text: input };
74
+ }
75
+ const s = { text: input.text };
76
+ if (input.marks !== undefined) {
77
+ s.marks = { ...input.marks };
78
+ }
79
+ return s;
80
+ });
81
+ // Default to an empty span if no inputs provided
82
+ if (spans.length === 0) {
83
+ spans.push({ text: '' });
84
+ }
85
+ this._blocks.push({
20
86
  id: `b${this.nextId++}`,
21
87
  type: 'text',
22
- spans: [{ text }],
88
+ spans,
23
89
  });
24
90
  return this;
25
91
  }
26
- /** Build the final Document */
92
+ /**
93
+ * Set the block type on the last added block.
94
+ *
95
+ * @param blockType - The block type string (e.g., 'heading', 'code_block')
96
+ * @returns The builder for chaining
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * doc().block('Title').type('heading').build()
101
+ * ```
102
+ */
103
+ type(blockType) {
104
+ const last = this._blocks[this._blocks.length - 1];
105
+ if (!last) {
106
+ throw new Error('type() must be called after block()');
107
+ }
108
+ last.type = blockType;
109
+ return this;
110
+ }
111
+ /**
112
+ * Set block-level attributes on the last added block.
113
+ *
114
+ * @param blockAttrs - The attributes to set
115
+ * @returns The builder for chaining
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * doc().block('Title').type('heading').attrs({ level: 2 }).build()
120
+ * ```
121
+ */
122
+ attrs(blockAttrs) {
123
+ const last = this._blocks[this._blocks.length - 1];
124
+ if (!last) {
125
+ throw new Error('attrs() must be called after block()');
126
+ }
127
+ last.attrs = { ...blockAttrs };
128
+ return this;
129
+ }
130
+ /**
131
+ * Set a custom ID on the last added block.
132
+ *
133
+ * @param blockId - The block ID
134
+ * @returns The builder for chaining
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * doc().block('Hello').id('custom-id').build()
139
+ * ```
140
+ */
141
+ id(blockId) {
142
+ const last = this._blocks[this._blocks.length - 1];
143
+ if (!last) {
144
+ throw new Error('id() must be called after block()');
145
+ }
146
+ last.id = blockId;
147
+ return this;
148
+ }
149
+ /**
150
+ * Set document-level metadata.
151
+ *
152
+ * @param docMeta - The metadata key-value pairs
153
+ * @returns The builder for chaining
154
+ *
155
+ * @example
156
+ * ```ts
157
+ * doc().block('Hello').meta({ title: 'My Doc', lang: 'en' }).build()
158
+ * ```
159
+ */
160
+ meta(docMeta) {
161
+ this._meta = { ...docMeta };
162
+ return this;
163
+ }
164
+ /**
165
+ * Build the final Document.
166
+ *
167
+ * @returns A valid RTIF Document
168
+ */
27
169
  build() {
28
- if (this.blocks.length === 0) {
29
- this.blocks.push({
170
+ if (this._blocks.length === 0) {
171
+ this._blocks.push({
30
172
  id: 'b1',
31
173
  type: 'text',
32
174
  spans: [{ text: '' }],
33
175
  });
34
176
  }
35
- return { version: 1, blocks: this.blocks };
177
+ const result = { version: 1, blocks: this._blocks };
178
+ if (this._meta !== undefined) {
179
+ result.meta = this._meta;
180
+ }
181
+ return result;
36
182
  }
37
183
  }
38
- /** Create a new DocumentBuilder */
184
+ /**
185
+ * Create a new DocumentBuilder.
186
+ *
187
+ * @returns A fresh DocumentBuilder
188
+ *
189
+ * @example
190
+ * ```ts
191
+ * const d = doc().block('Hello').block('World').build();
192
+ * ```
193
+ */
39
194
  export function doc() {
40
195
  return new DocumentBuilder();
41
196
  }
42
- /** Create a Selection from anchor and focus offsets */
197
+ /**
198
+ * Create a Selection from anchor and focus offsets.
199
+ *
200
+ * @param anchor - Anchor offset
201
+ * @param focus - Focus offset
202
+ * @returns A Selection object
203
+ *
204
+ * @example
205
+ * ```ts
206
+ * sel(0, 5) // forward selection
207
+ * sel(5, 5) // collapsed cursor at offset 5
208
+ * sel(10, 5) // backward selection
209
+ * ```
210
+ */
43
211
  export function sel(anchor, focus) {
44
212
  return {
45
213
  anchor: { offset: anchor },
46
214
  focus: { offset: focus },
47
215
  };
48
216
  }
217
+ // ---------------------------------------------------------------------------
218
+ // Common Fixtures
219
+ // ---------------------------------------------------------------------------
220
+ /**
221
+ * Create an empty document with a single empty block.
222
+ *
223
+ * @param blockId - Optional block ID (default: 'b1')
224
+ * @returns A Document with one empty text block
225
+ *
226
+ * @example
227
+ * ```ts
228
+ * const d = emptyDoc();
229
+ * // { version: 1, blocks: [{ id: 'b1', type: 'text', spans: [{ text: '' }] }] }
230
+ * ```
231
+ */
232
+ export function emptyDoc(blockId = 'b1') {
233
+ return {
234
+ version: 1,
235
+ blocks: [{ id: blockId, type: 'text', spans: [{ text: '' }] }],
236
+ };
237
+ }
238
+ /**
239
+ * Create a document with a single text block.
240
+ *
241
+ * @param text - The block text content
242
+ * @param blockId - Optional block ID (default: 'b1')
243
+ * @returns A Document with one text block
244
+ *
245
+ * @example
246
+ * ```ts
247
+ * const d = textDoc('hello');
248
+ * const d2 = textDoc('hello', 'custom-id');
249
+ * ```
250
+ */
251
+ export function textDoc(text, blockId = 'b1') {
252
+ return {
253
+ version: 1,
254
+ blocks: [{ id: blockId, type: 'text', spans: [{ text }] }],
255
+ };
256
+ }
257
+ /**
258
+ * Create a document with multiple text blocks.
259
+ *
260
+ * @param texts - Array of text strings, one per block
261
+ * @returns A Document with blocks 'b1', 'b2', etc.
262
+ *
263
+ * @example
264
+ * ```ts
265
+ * const d = multiBlockDoc('hello', 'world');
266
+ * // Two blocks: b1="hello", b2="world"
267
+ * ```
268
+ */
269
+ export function multiBlockDoc(...texts) {
270
+ if (texts.length === 0) {
271
+ return emptyDoc();
272
+ }
273
+ return {
274
+ version: 1,
275
+ blocks: texts.map((text, i) => ({
276
+ id: `b${i + 1}`,
277
+ type: 'text',
278
+ spans: [{ text }],
279
+ })),
280
+ };
281
+ }
282
+ // ---------------------------------------------------------------------------
283
+ // Helpers
284
+ // ---------------------------------------------------------------------------
285
+ /**
286
+ * Extract plain text from a document, joining blocks with newlines.
287
+ *
288
+ * @param document - The RTIF document
289
+ * @returns Plain text representation
290
+ *
291
+ * @example
292
+ * ```ts
293
+ * const text = docText(engine.state.doc);
294
+ * // "hello\nworld"
295
+ * ```
296
+ */
297
+ export function docText(document) {
298
+ return document.blocks
299
+ .map((b) => b.spans.map((s) => s.text).join(''))
300
+ .join('\n');
301
+ }
49
302
  //# sourceMappingURL=builders.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"builders.js","sourceRoot":"","sources":["../src/builders.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,uDAAuD;AACvD,MAAM,OAAO,eAAe;IAClB,MAAM,GAAY,EAAE,CAAC;IACrB,MAAM,GAAG,CAAC,CAAC;IAEnB;;;;;;OAMG;IACH,KAAK,CAAC,IAAY,EAAE,MAA+B;QACjD,yDAAyD;QACzD,8CAA8C;QAC9C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,EAAE,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE;YACvB,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;SAClB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+BAA+B;IAC/B,KAAK;QACH,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;aACtB,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IAC7C,CAAC;CACF;AAED,mCAAmC;AACnC,MAAM,UAAU,GAAG;IACjB,OAAO,IAAI,eAAe,EAAE,CAAC;AAC/B,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,GAAG,CAAC,MAAc,EAAE,KAAa;IAC/C,OAAO;QACL,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;QAC1B,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;KACzB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"builders.js","sourceRoot":"","sources":["../src/builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAmBH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,KAA+B;IAChE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC;AAED,wDAAwD;AACxD,MAAM,OAAO,eAAe;IAClB,OAAO,GAAY,EAAE,CAAC;IACtB,KAAK,CAA2B;IAChC,MAAM,GAAG,CAAC,CAAC;IAEnB;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,GAAG,MAAmB;QAC1B,MAAM,KAAK,GAAW,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;YACzB,CAAC;YACD,MAAM,CAAC,GAAS,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;YACrC,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC9B,CAAC,CAAC,KAAK,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;QAEH,iDAAiD;QACjD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3B,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,EAAE,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE;YACvB,IAAI,EAAE,MAAM;YACZ,KAAK;SACN,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;OAUG;IACH,IAAI,CAAC,SAAiB;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,UAAmC;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,UAAU,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;OAUG;IACH,EAAE,CAAC,OAAe;QAChB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;OAUG;IACH,IAAI,CAAC,OAAgC;QACnC,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;gBAChB,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;aACtB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,MAAM,GAAa,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;QAC9D,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QAC3B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,GAAG;IACjB,OAAO,IAAI,eAAe,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,GAAG,CAAC,MAAc,EAAE,KAAa;IAC/C,OAAO;QACL,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;QAC1B,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;KACzB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAO,GAAG,IAAI;IACrC,OAAO;QACL,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,OAAO,GAAG,IAAI;IAClD,OAAO;QACL,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;KAC3D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,GAAG,KAAe;IAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,QAAQ,EAAE,CAAC;IACpB,CAAC;IACD,OAAO;QACL,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9B,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE;YACf,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;SAClB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,OAAO,CAAC,QAAkB;IACxC,OAAO,QAAQ,CAAC,MAAM;SACnB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SAC/C,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
- export { doc, sel, DocumentBuilder } from './builders.js';
1
+ export { doc, sel, span, DocumentBuilder, emptyDoc, textDoc, multiBlockDoc, docText, } from './builders.js';
2
+ export type { SpanInput, SpanDef } from './builders.js';
2
3
  export { assertDocEqual, assertSelectionEqual } from './assertions.js';
4
+ export type { DocEqualOptions } from './assertions.js';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,GAAG,EACH,GAAG,EACH,IAAI,EACJ,eAAe,EACf,QAAQ,EACR,OAAO,EACP,aAAa,EACb,OAAO,GACR,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAGxD,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvE,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
- export { doc, sel, DocumentBuilder } from './builders.js';
1
+ // Builders
2
+ export { doc, sel, span, DocumentBuilder, emptyDoc, textDoc, multiBlockDoc, docText, } from './builders.js';
3
+ // Assertions
2
4
  export { assertDocEqual, assertSelectionEqual } from './assertions.js';
3
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,WAAW;AACX,OAAO,EACL,GAAG,EACH,GAAG,EACH,IAAI,EACJ,eAAe,EACf,QAAQ,EACR,OAAO,EACP,aAAa,EACb,OAAO,GACR,MAAM,eAAe,CAAC;AAGvB,aAAa;AACb,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rtif-sdk/test-kit",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "RTIF shared test utilities, builders, and assertions",
5
5
  "author": "coryrobinson42@gmail.com",
6
6
  "type": "module",
@@ -12,10 +12,19 @@
12
12
  "import": "./dist/index.js"
13
13
  }
14
14
  },
15
- "files": ["dist"],
15
+ "files": [
16
+ "dist"
17
+ ],
16
18
  "sideEffects": false,
17
- "engines": { "node": ">=20.0.0" },
18
- "keywords": ["rtif", "test-utilities", "rich-text", "editor-testing"],
19
+ "engines": {
20
+ "node": ">=20.0.0"
21
+ },
22
+ "keywords": [
23
+ "rtif",
24
+ "test-utilities",
25
+ "rich-text",
26
+ "editor-testing"
27
+ ],
19
28
  "scripts": {
20
29
  "build": "tsc --build tsconfig.build.json",
21
30
  "test": "vitest run",