@coherent.js/tooling 1.0.0-rc.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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/lsp/analysis/coherent-analyzer.d.ts +93 -0
  4. package/dist/lsp/analysis/coherent-analyzer.d.ts.map +1 -0
  5. package/dist/lsp/analysis/coherent-analyzer.js +288 -0
  6. package/dist/lsp/analysis/coherent-analyzer.js.map +1 -0
  7. package/dist/lsp/analysis/element-validator.d.ts +45 -0
  8. package/dist/lsp/analysis/element-validator.d.ts.map +1 -0
  9. package/dist/lsp/analysis/element-validator.js +84 -0
  10. package/dist/lsp/analysis/element-validator.js.map +1 -0
  11. package/dist/lsp/analysis/nesting-validator.d.ts +49 -0
  12. package/dist/lsp/analysis/nesting-validator.d.ts.map +1 -0
  13. package/dist/lsp/analysis/nesting-validator.js +68 -0
  14. package/dist/lsp/analysis/nesting-validator.js.map +1 -0
  15. package/dist/lsp/data/element-attributes.d.ts +92 -0
  16. package/dist/lsp/data/element-attributes.d.ts.map +1 -0
  17. package/dist/lsp/data/element-attributes.generated.json +7085 -0
  18. package/dist/lsp/data/element-attributes.js +282 -0
  19. package/dist/lsp/data/element-attributes.js.map +1 -0
  20. package/dist/lsp/data/nesting-rules.d.ts +67 -0
  21. package/dist/lsp/data/nesting-rules.d.ts.map +1 -0
  22. package/dist/lsp/data/nesting-rules.js +240 -0
  23. package/dist/lsp/data/nesting-rules.js.map +1 -0
  24. package/dist/lsp/providers/code-actions.d.ts +15 -0
  25. package/dist/lsp/providers/code-actions.d.ts.map +1 -0
  26. package/dist/lsp/providers/code-actions.js +191 -0
  27. package/dist/lsp/providers/code-actions.js.map +1 -0
  28. package/dist/lsp/providers/completion.d.ts +15 -0
  29. package/dist/lsp/providers/completion.d.ts.map +1 -0
  30. package/dist/lsp/providers/completion.js +247 -0
  31. package/dist/lsp/providers/completion.js.map +1 -0
  32. package/dist/lsp/providers/diagnostics.d.ts +26 -0
  33. package/dist/lsp/providers/diagnostics.d.ts.map +1 -0
  34. package/dist/lsp/providers/diagnostics.js +143 -0
  35. package/dist/lsp/providers/diagnostics.js.map +1 -0
  36. package/dist/lsp/providers/hover.d.ts +15 -0
  37. package/dist/lsp/providers/hover.d.ts.map +1 -0
  38. package/dist/lsp/providers/hover.js +215 -0
  39. package/dist/lsp/providers/hover.js.map +1 -0
  40. package/dist/lsp/server.d.ts +17 -0
  41. package/dist/lsp/server.d.ts.map +1 -0
  42. package/dist/lsp/server.js +82 -0
  43. package/dist/lsp/server.js.map +1 -0
  44. package/dist/testing/index.js +746 -0
  45. package/dist/testing/index.js.map +7 -0
  46. package/dist/testing/matchers.js +246 -0
  47. package/dist/testing/matchers.js.map +7 -0
  48. package/dist/testing/test-renderer.js +254 -0
  49. package/dist/testing/test-renderer.js.map +7 -0
  50. package/dist/testing/test-utils.js +262 -0
  51. package/dist/testing/test-utils.js.map +7 -0
  52. package/package.json +96 -0
  53. package/types/testing/index.d.ts +404 -0
@@ -0,0 +1,404 @@
1
+ /**
2
+ * Coherent.js Testing Utilities TypeScript Definitions
3
+ * @module @coherent.js/testing
4
+ */
5
+
6
+ import type { CoherentNode, CoherentElement, CoherentComponent, ComponentProps } from '@coherent.js/core';
7
+
8
+ // ============================================================================
9
+ // Test Renderer Types
10
+ // ============================================================================
11
+
12
+ /**
13
+ * Render options for test utilities
14
+ */
15
+ export interface RenderOptions {
16
+ /** Wrapper component */
17
+ wrapper?: CoherentComponent;
18
+ /** Context values to provide */
19
+ context?: Record<string, unknown>;
20
+ /** Props to pass to component */
21
+ props?: Record<string, unknown>;
22
+ /** Initial state */
23
+ initialState?: Record<string, unknown>;
24
+ }
25
+
26
+ /**
27
+ * Result from rendering a component
28
+ */
29
+ export interface RenderResult {
30
+ /** Rendered HTML string */
31
+ html: string;
32
+ /** The rendered element structure */
33
+ element: CoherentElement;
34
+ /** Container element (if DOM is available) */
35
+ container: HTMLElement | null;
36
+ /** Re-render with new props */
37
+ rerender(props?: Record<string, unknown>): void;
38
+ /** Unmount and cleanup */
39
+ unmount(): void;
40
+ /** Debug output */
41
+ debug(): void;
42
+ /** Query helpers */
43
+ getByText(text: string | RegExp): Element | null;
44
+ getByTestId(testId: string): Element | null;
45
+ getAllByText(text: string | RegExp): Element[];
46
+ }
47
+
48
+ /**
49
+ * Test renderer class
50
+ */
51
+ export class TestRenderer {
52
+ /** Render a component */
53
+ render(component: CoherentNode, options?: RenderOptions): RenderResult;
54
+
55
+ /** Render a component asynchronously */
56
+ renderAsync(component: CoherentNode, options?: RenderOptions): Promise<RenderResult>;
57
+
58
+ /** Shallow render (no children) */
59
+ shallow(component: CoherentNode): RenderResult;
60
+
61
+ /** Cleanup all renders */
62
+ cleanup(): void;
63
+ }
64
+
65
+ /**
66
+ * Render a component for testing
67
+ */
68
+ export function renderComponent(
69
+ component: CoherentComponent | CoherentNode,
70
+ props?: Record<string, unknown>
71
+ ): RenderResult;
72
+
73
+ /**
74
+ * Render a component asynchronously
75
+ */
76
+ export function renderComponentAsync(
77
+ component: CoherentNode,
78
+ options?: RenderOptions
79
+ ): Promise<RenderResult>;
80
+
81
+ /**
82
+ * Create a new test renderer instance
83
+ */
84
+ export function createTestRenderer(): TestRenderer;
85
+
86
+ /**
87
+ * Shallow render a component
88
+ */
89
+ export function shallowRender(component: CoherentNode): RenderResult;
90
+
91
+ /**
92
+ * Render a node to HTML string
93
+ */
94
+ export function renderToString(node: CoherentNode): string;
95
+
96
+ // ============================================================================
97
+ // Custom Matchers for Coherent.js
98
+ // ============================================================================
99
+
100
+ /**
101
+ * Coherent.js-specific test matchers
102
+ */
103
+ export interface CoherentMatchers<R = unknown> {
104
+ // Element structure matchers
105
+ /** Assert element has specific tag name */
106
+ toHaveTag(tagName: string): R;
107
+ /** Assert element contains text */
108
+ toHaveText(text: string): R;
109
+ /** Assert element has attribute (optionally with value) */
110
+ toHaveAttribute(name: string, value?: string): R;
111
+ /** Assert element has CSS class */
112
+ toHaveClassName(className: string): R;
113
+ /** Assert element has children (optionally specific count) */
114
+ toHaveChildren(count?: number): R;
115
+
116
+ // Component matchers
117
+ /** Assert component renders an element with tag */
118
+ toRenderElement(tagName: string): R;
119
+ /** Assert component renders text content */
120
+ toRenderText(text: string): R;
121
+ /** Assert component matches snapshot */
122
+ toMatchComponentSnapshot(): R;
123
+
124
+ // Hydration matchers
125
+ /** Assert hydration completes without mismatch */
126
+ toHydrateWithoutMismatch(): R;
127
+ /** Assert hydrated component has specific state */
128
+ toHaveState(state: Record<string, unknown>): R;
129
+
130
+ // Accessibility matchers
131
+ /** Assert element has accessible name */
132
+ toHaveAccessibleName(name: string): R;
133
+ /** Assert element has ARIA role */
134
+ toHaveRole(role: string): R;
135
+ }
136
+
137
+ // ============================================================================
138
+ // Test Utilities
139
+ // ============================================================================
140
+
141
+ /**
142
+ * Event simulation options
143
+ */
144
+ export interface EventOptions {
145
+ bubbles?: boolean;
146
+ cancelable?: boolean;
147
+ composed?: boolean;
148
+ [key: string]: unknown;
149
+ }
150
+
151
+ /**
152
+ * Fire DOM events on elements
153
+ */
154
+ export const fireEvent: {
155
+ /** Fire any event */
156
+ (element: Element, event: Event): boolean;
157
+ /** Fire click event */
158
+ click(element: Element, options?: EventOptions): boolean;
159
+ /** Fire change event */
160
+ change(element: Element, options?: EventOptions & { target?: { value?: unknown } }): boolean;
161
+ /** Fire input event */
162
+ input(element: Element, options?: EventOptions & { target?: { value?: unknown } }): boolean;
163
+ /** Fire submit event */
164
+ submit(element: Element, options?: EventOptions): boolean;
165
+ /** Fire keydown event */
166
+ keyDown(element: Element, options?: EventOptions & { key?: string; code?: string }): boolean;
167
+ /** Fire keyup event */
168
+ keyUp(element: Element, options?: EventOptions & { key?: string; code?: string }): boolean;
169
+ /** Fire focus event */
170
+ focus(element: Element, options?: EventOptions): boolean;
171
+ /** Fire blur event */
172
+ blur(element: Element, options?: EventOptions): boolean;
173
+ /** Fire mouseenter event */
174
+ mouseEnter(element: Element, options?: EventOptions): boolean;
175
+ /** Fire mouseleave event */
176
+ mouseLeave(element: Element, options?: EventOptions): boolean;
177
+ [key: string]: unknown;
178
+ };
179
+
180
+ /**
181
+ * Wait options
182
+ */
183
+ export interface WaitOptions {
184
+ /** Timeout in ms */
185
+ timeout?: number;
186
+ /** Check interval in ms */
187
+ interval?: number;
188
+ }
189
+
190
+ /**
191
+ * Wait for a condition to be true
192
+ */
193
+ export function waitFor<T>(
194
+ callback: () => T | Promise<T>,
195
+ options?: WaitOptions
196
+ ): Promise<T>;
197
+
198
+ /**
199
+ * Wait for an element to appear
200
+ */
201
+ export function waitForElement(selector: string, options?: WaitOptions): Promise<Element>;
202
+
203
+ /**
204
+ * Wait for an element to be removed
205
+ */
206
+ export function waitForElementToBeRemoved(
207
+ selector: string | Element,
208
+ options?: WaitOptions
209
+ ): Promise<void>;
210
+
211
+ /**
212
+ * Run a callback and flush pending state updates
213
+ */
214
+ export function act<T>(callback: () => T | Promise<T>): Promise<T>;
215
+
216
+ // ============================================================================
217
+ // Mock Utilities
218
+ // ============================================================================
219
+
220
+ /**
221
+ * Mock function interface
222
+ */
223
+ export interface Mock<T extends (...args: unknown[]) => unknown = (...args: unknown[]) => unknown> {
224
+ (...args: Parameters<T>): ReturnType<T>;
225
+ mock: {
226
+ calls: Parameters<T>[];
227
+ results: Array<{ type: 'return' | 'throw'; value: unknown }>;
228
+ instances: unknown[];
229
+ };
230
+ mockClear(): void;
231
+ mockReset(): void;
232
+ mockRestore(): void;
233
+ mockImplementation(fn: T): this;
234
+ mockReturnValue(value: ReturnType<T>): this;
235
+ mockReturnValueOnce(value: ReturnType<T>): this;
236
+ mockResolvedValue(value: ReturnType<T> extends Promise<infer U> ? U : never): this;
237
+ mockRejectedValue(error: unknown): this;
238
+ }
239
+
240
+ /**
241
+ * Create a mock function
242
+ */
243
+ export function createMock<T extends (...args: unknown[]) => unknown>(
244
+ implementation?: T
245
+ ): Mock<T>;
246
+
247
+ /**
248
+ * Create a spy on an object method
249
+ */
250
+ export function createSpy<T extends (...args: unknown[]) => unknown>(
251
+ object: object,
252
+ method: string
253
+ ): Mock<T>;
254
+
255
+ /**
256
+ * Mock a component
257
+ */
258
+ export function mockComponent<P extends ComponentProps = ComponentProps>(
259
+ name: string,
260
+ render?: (props: P) => CoherentNode
261
+ ): CoherentComponent<P>;
262
+
263
+ /**
264
+ * Create test state with reset capability
265
+ */
266
+ export function createTestState<T extends Record<string, unknown>>(
267
+ initial: T
268
+ ): {
269
+ getState: () => T;
270
+ setState: (updates: Partial<T>) => void;
271
+ reset: () => void;
272
+ };
273
+
274
+ /**
275
+ * Cleanup all mocks and rendered components
276
+ */
277
+ export function cleanup(): void;
278
+
279
+ // ============================================================================
280
+ // Query Utilities
281
+ // ============================================================================
282
+
283
+ /**
284
+ * Query helper interface
285
+ */
286
+ export interface Within {
287
+ getByText(text: string | RegExp): Element;
288
+ getByRole(role: string, options?: { name?: string | RegExp }): Element;
289
+ getByLabelText(text: string | RegExp): Element;
290
+ getByPlaceholderText(text: string | RegExp): Element;
291
+ getByTestId(testId: string): Element;
292
+ queryByText(text: string | RegExp): Element | null;
293
+ queryByRole(role: string, options?: { name?: string | RegExp }): Element | null;
294
+ queryAllByText(text: string | RegExp): Element[];
295
+ findByText(text: string | RegExp): Promise<Element>;
296
+ findAllByText(text: string | RegExp): Promise<Element[]>;
297
+ }
298
+
299
+ /**
300
+ * Create query helpers scoped to an element
301
+ */
302
+ export function within(element: Element): Within;
303
+
304
+ /**
305
+ * Global screen queries (document.body)
306
+ */
307
+ export const screen: Within;
308
+
309
+ /**
310
+ * User event simulation
311
+ */
312
+ export const userEvent: {
313
+ click(element: Element): Promise<void>;
314
+ dblClick(element: Element): Promise<void>;
315
+ type(element: Element, text: string, options?: { delay?: number }): Promise<void>;
316
+ clear(element: Element): Promise<void>;
317
+ selectOptions(element: Element, values: string | string[]): Promise<void>;
318
+ tab(options?: { shift?: boolean }): Promise<void>;
319
+ hover(element: Element): Promise<void>;
320
+ unhover(element: Element): Promise<void>;
321
+ upload(element: Element, files: File | File[]): Promise<void>;
322
+ paste(element: Element, text: string): Promise<void>;
323
+ };
324
+
325
+ // ============================================================================
326
+ // Assertion Utilities
327
+ // ============================================================================
328
+
329
+ /**
330
+ * Assert element structure matches expected
331
+ */
332
+ export function assertElementStructure(
333
+ element: CoherentElement,
334
+ expected: Partial<CoherentElement>
335
+ ): void;
336
+
337
+ /**
338
+ * Standard assertions
339
+ */
340
+ export const assertions: {
341
+ assertElement(element: unknown): asserts element is Element;
342
+ assertHTMLElement(element: unknown): asserts element is HTMLElement;
343
+ assertInDocument(element: Element | null): asserts element is Element;
344
+ assertVisible(element: Element): void;
345
+ assertHasAttribute(element: Element, attr: string): void;
346
+ assertHasClass(element: Element, className: string): void;
347
+ };
348
+
349
+ // ============================================================================
350
+ // DOM Matchers (for Vitest/Jest)
351
+ // ============================================================================
352
+
353
+ /**
354
+ * Custom DOM matchers
355
+ */
356
+ export interface CustomMatchers<R = void> {
357
+ toHaveHTML(html: string): R;
358
+ toContainHTML(html: string): R;
359
+ toHaveTextContent(text: string | RegExp): R;
360
+ toHaveAttribute(attr: string, value?: string): R;
361
+ toHaveClass(className: string): R;
362
+ toBeInTheDocument(): R;
363
+ toBeVisible(): R;
364
+ toBeDisabled(): R;
365
+ toBeEnabled(): R;
366
+ toHaveValue(value: unknown): R;
367
+ toHaveStyle(style: Record<string, unknown>): R;
368
+ toHaveFocus(): R;
369
+ toBeChecked(): R;
370
+ toBeValid(): R;
371
+ toBeInvalid(): R;
372
+ }
373
+
374
+ /**
375
+ * Custom matchers object
376
+ */
377
+ export const customMatchers: CustomMatchers;
378
+
379
+ /**
380
+ * Extend test framework expect
381
+ */
382
+ export function extendExpect(matchers: Record<string, (...args: unknown[]) => unknown>): void;
383
+
384
+ // ============================================================================
385
+ // Vitest/Jest Module Extensions
386
+ // ============================================================================
387
+
388
+ // Extend Vitest matchers
389
+ declare module 'vitest' {
390
+ interface Assertion<T = unknown> extends CoherentMatchers<T>, CustomMatchers<T> {}
391
+ interface AsymmetricMatchersContaining extends CoherentMatchers, CustomMatchers {}
392
+ }
393
+
394
+ // Extend Jest matchers (for users using Jest)
395
+ declare global {
396
+ namespace Vi {
397
+ interface Matchers<R = void> extends CustomMatchers<R>, CoherentMatchers<R> {}
398
+ interface AsymmetricMatchers extends CustomMatchers, CoherentMatchers {}
399
+ }
400
+ namespace jest {
401
+ interface Matchers<R = void> extends CustomMatchers<R>, CoherentMatchers<R> {}
402
+ interface Expect extends CustomMatchers, CoherentMatchers {}
403
+ }
404
+ }