wyreframe 0.1.0 → 0.1.5

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 (58) hide show
  1. package/LICENSE +692 -0
  2. package/README.md +65 -5
  3. package/package.json +8 -7
  4. package/src/index.ts +425 -0
  5. package/src/renderer/Renderer.gen.tsx +49 -0
  6. package/src/renderer/Renderer.mjs +41 -1
  7. package/src/renderer/Renderer.res +78 -0
  8. package/src/parser/Core/__tests__/Bounds_test.mjs +0 -326
  9. package/src/parser/Core/__tests__/Bounds_test.res +0 -412
  10. package/src/parser/Core/__tests__/Grid_test.mjs +0 -322
  11. package/src/parser/Core/__tests__/Grid_test.res +0 -319
  12. package/src/parser/Core/__tests__/Types_test.mjs +0 -614
  13. package/src/parser/Core/__tests__/Types_test.res +0 -650
  14. package/src/parser/Detector/__tests__/BoxTracer_test.mjs +0 -70
  15. package/src/parser/Detector/__tests__/BoxTracer_test.res +0 -92
  16. package/src/parser/Detector/__tests__/HierarchyBuilder_test.mjs +0 -489
  17. package/src/parser/Detector/__tests__/HierarchyBuilder_test.res +0 -849
  18. package/src/parser/Detector/__tests__/ShapeDetector_test.mjs +0 -377
  19. package/src/parser/Detector/__tests__/ShapeDetector_test.res +0 -563
  20. package/src/parser/Interactions/__tests__/InteractionMerger_test.mjs +0 -576
  21. package/src/parser/Interactions/__tests__/InteractionMerger_test.res +0 -646
  22. package/src/parser/Scanner/__tests__/Grid_manual.mjs +0 -214
  23. package/src/parser/Scanner/__tests__/Grid_manual.res +0 -141
  24. package/src/parser/Semantic/Elements/__tests__/ButtonParser_test.mjs +0 -189
  25. package/src/parser/Semantic/Elements/__tests__/ButtonParser_test.res +0 -257
  26. package/src/parser/Semantic/Elements/__tests__/CheckboxParser_test.mjs +0 -202
  27. package/src/parser/Semantic/Elements/__tests__/CheckboxParser_test.res +0 -250
  28. package/src/parser/Semantic/Elements/__tests__/CodeTextParser_manual.mjs +0 -293
  29. package/src/parser/Semantic/Elements/__tests__/CodeTextParser_manual.res +0 -134
  30. package/src/parser/Semantic/Elements/__tests__/InputParser_test.mjs +0 -253
  31. package/src/parser/Semantic/Elements/__tests__/InputParser_test.res +0 -304
  32. package/src/parser/Semantic/Elements/__tests__/LinkParser_test.mjs +0 -289
  33. package/src/parser/Semantic/Elements/__tests__/LinkParser_test.res +0 -402
  34. package/src/parser/Semantic/Elements/__tests__/TextParser_test.mjs +0 -149
  35. package/src/parser/Semantic/Elements/__tests__/TextParser_test.res +0 -167
  36. package/src/parser/Semantic/__tests__/ASTBuilder_test.mjs +0 -187
  37. package/src/parser/Semantic/__tests__/ASTBuilder_test.res +0 -192
  38. package/src/parser/Semantic/__tests__/ParserRegistry_test.mjs +0 -154
  39. package/src/parser/Semantic/__tests__/ParserRegistry_test.res +0 -191
  40. package/src/parser/Semantic/__tests__/SemanticParser_integration_test.mjs +0 -768
  41. package/src/parser/Semantic/__tests__/SemanticParser_integration_test.res +0 -1069
  42. package/src/parser/Semantic/__tests__/SemanticParser_manual.mjs +0 -1329
  43. package/src/parser/Semantic/__tests__/SemanticParser_manual.res +0 -544
  44. package/src/parser/__tests__/GridScanner_integration.test.mjs +0 -632
  45. package/src/parser/__tests__/GridScanner_integration.test.res +0 -816
  46. package/src/parser/__tests__/Performance.test.mjs +0 -244
  47. package/src/parser/__tests__/Performance.test.res +0 -371
  48. package/src/parser/__tests__/PerformanceFixtures.mjs +0 -200
  49. package/src/parser/__tests__/PerformanceFixtures.res +0 -284
  50. package/src/parser/__tests__/WyreframeParser_integration.test.mjs +0 -770
  51. package/src/parser/__tests__/WyreframeParser_integration.test.res +0 -1008
  52. package/src/parser/__tests__/fixtures/alignment-test.txt +0 -9
  53. package/src/parser/__tests__/fixtures/all-elements.txt +0 -16
  54. package/src/parser/__tests__/fixtures/login-scene.txt +0 -17
  55. package/src/parser/__tests__/fixtures/multi-scene.txt +0 -25
  56. package/src/parser/__tests__/fixtures/nested-boxes.txt +0 -15
  57. package/src/parser/__tests__/fixtures/simple-box.txt +0 -5
  58. package/src/parser/__tests__/fixtures/with-dividers.txt +0 -14
@@ -1,768 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Parser from "../../Parser.mjs";
4
- import * as Vitest from "rescript-vitest/src/Vitest.mjs";
5
-
6
- function collectAllElements(elements) {
7
- return elements.flatMap(el => {
8
- if (el.TAG === "Box") {
9
- return [el].concat(collectAllElements(el.children));
10
- } else {
11
- return [el];
12
- }
13
- });
14
- }
15
-
16
- function hasElement(elements, predicate) {
17
- let allElements = collectAllElements(elements);
18
- return allElements.some(predicate);
19
- }
20
-
21
- Vitest.describe("SemanticParser Integration - Login Scene", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
22
- Vitest.test("SP-01: parses complete login scene with all elements", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
23
- let ast = Parser.parse(`
24
- @scene: login
25
- @title: Login Page
26
-
27
- +--Login----------------+
28
- | |
29
- | * Welcome |
30
- | |
31
- | Email: #email |
32
- | |
33
- | Password: #password |
34
- | |
35
- | [ Login ] |
36
- | |
37
- +-----------------------+
38
- `);
39
- if (ast.TAG === "Ok") {
40
- let ast$1 = ast._0;
41
- t.expect(ast$1.scenes.length).toBe(1);
42
- let scene = ast$1.scenes[0];
43
- t.expect(scene.id).toBe("login");
44
- t.expect(scene.title).toBe("Login Page");
45
- let emphasisFound = hasElement(scene.elements, el => {
46
- if (el.TAG === "Text" && el.emphasis) {
47
- return el.content.includes("Welcome");
48
- } else {
49
- return false;
50
- }
51
- });
52
- t.expect(emphasisFound).toBe(true);
53
- let emailInputFound = hasElement(scene.elements, el => {
54
- if (el.TAG === "Input") {
55
- return el.id === "email";
56
- } else {
57
- return false;
58
- }
59
- });
60
- t.expect(emailInputFound).toBe(true);
61
- let passwordInputFound = hasElement(scene.elements, el => {
62
- if (el.TAG === "Input") {
63
- return el.id === "password";
64
- } else {
65
- return false;
66
- }
67
- });
68
- t.expect(passwordInputFound).toBe(true);
69
- let loginButtonFound = hasElement(scene.elements, el => {
70
- if (el.TAG === "Button") {
71
- return el.text === "Login";
72
- } else {
73
- return false;
74
- }
75
- });
76
- t.expect(loginButtonFound).toBe(true);
77
- return t.expect(scene.elements.length).toBeGreaterThan(0);
78
- }
79
- console.error(ast._0);
80
- t.expect(true).toBe(false);
81
- });
82
- Vitest.test("SP-01a: login scene elements have correct positions", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
83
- let ast = Parser.parse(`
84
- @scene: login
85
-
86
- +--Login---+
87
- | #email |
88
- | [ OK ] |
89
- +----------+
90
- `);
91
- if (ast.TAG !== "Ok") {
92
- return t.expect(true).toBe(false);
93
- }
94
- let scene = ast._0.scenes[0];
95
- scene.elements.forEach(el => {
96
- switch (el.TAG) {
97
- case "Button" :
98
- case "Input" :
99
- break;
100
- default:
101
- return;
102
- }
103
- let position = el.position;
104
- t.expect(position.row).toBeGreaterThanOrEqual(0);
105
- t.expect(position.col).toBeGreaterThanOrEqual(0);
106
- });
107
- });
108
- });
109
-
110
- Vitest.describe("SemanticParser Integration - Multiple Scenes", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
111
- Vitest.test("SP-02: parses multiple scenes separated by dividers", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
112
- let ast = Parser.parse(`
113
- @scene: home
114
- @title: Home Screen
115
-
116
- +----------+
117
- | Home |
118
- +----------+
119
-
120
- ---
121
-
122
- @scene: settings
123
- @title: Settings Screen
124
-
125
- +--------------+
126
- | Settings |
127
- +--------------+
128
- `);
129
- if (ast.TAG === "Ok") {
130
- let ast$1 = ast._0;
131
- t.expect(ast$1.scenes.length).toBe(2);
132
- let homeScene = ast$1.scenes[0];
133
- t.expect(homeScene.id).toBe("home");
134
- t.expect(homeScene.title).toBe("Home Screen");
135
- let settingsScene = ast$1.scenes[1];
136
- t.expect(settingsScene.id).toBe("settings");
137
- t.expect(settingsScene.title).toBe("Settings Screen");
138
- return t.expect(homeScene.id).not.toBe(settingsScene.id);
139
- }
140
- console.error(ast._0);
141
- t.expect(true).toBe(false);
142
- });
143
- Vitest.test("SP-02a: handles three or more scenes", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
144
- let ast = Parser.parse(`
145
- @scene: one
146
- +----+
147
- | 1 |
148
- +----+
149
-
150
- ---
151
-
152
- @scene: two
153
- +----+
154
- | 2 |
155
- +----+
156
-
157
- ---
158
-
159
- @scene: three
160
- +----+
161
- | 3 |
162
- +----+
163
- `);
164
- if (ast.TAG !== "Ok") {
165
- return t.expect(true).toBe(false);
166
- }
167
- let ast$1 = ast._0;
168
- t.expect(ast$1.scenes.length).toBe(3);
169
- t.expect(ast$1.scenes[0].id).toBe("one");
170
- t.expect(ast$1.scenes[1].id).toBe("two");
171
- t.expect(ast$1.scenes[2].id).toBe("three");
172
- });
173
- });
174
-
175
- Vitest.describe("SemanticParser Integration - Nested Boxes", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
176
- Vitest.test("SP-03: parses nested box hierarchy correctly", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
177
- let ast = Parser.parse(`
178
- @scene: nested
179
-
180
- +--Outer-------------+
181
- | |
182
- | +--Inner-------+ |
183
- | | | |
184
- | | [ Button ] | |
185
- | | | |
186
- | +--------------+ |
187
- | |
188
- +--------------------+
189
- `);
190
- if (ast.TAG === "Ok") {
191
- let scene = ast._0.scenes[0];
192
- let outerBox = scene.elements.find(el => {
193
- if (el.TAG !== "Box") {
194
- return false;
195
- }
196
- let match = el.name;
197
- return match === "Outer";
198
- });
199
- if (outerBox === undefined) {
200
- return t.expect(true).toBe(false);
201
- }
202
- if (outerBox.TAG !== "Box") {
203
- return t.expect(true).toBe(false);
204
- }
205
- let children = outerBox.children;
206
- t.expect(outerBox.name).toBe("Outer");
207
- t.expect(children.length).toBeGreaterThan(0);
208
- let hasInnerBox = children.some(child => {
209
- if (child.TAG !== "Box") {
210
- return false;
211
- }
212
- let match = child.name;
213
- return match === "Inner";
214
- });
215
- return t.expect(hasInnerBox).toBe(true);
216
- }
217
- console.error(ast._0);
218
- t.expect(true).toBe(false);
219
- });
220
- Vitest.test("SP-03a: handles three-level nesting", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
221
- let ast = Parser.parse(`
222
- @scene: deep
223
-
224
- +--Level1---------------+
225
- | |
226
- | +--Level2-----------+ |
227
- | | | |
228
- | | +--Level3------+ | |
229
- | | | [ OK ] | | |
230
- | | +--------------+ | |
231
- | | | |
232
- | +-------------------+ |
233
- | |
234
- +-----------------------+
235
- `);
236
- if (ast.TAG !== "Ok") {
237
- return t.expect(true).toBe(false);
238
- }
239
- let scene = ast._0.scenes[0];
240
- let hasLevel1 = scene.elements.some(el => {
241
- if (el.TAG !== "Box") {
242
- return false;
243
- }
244
- let n = el.name;
245
- if (n !== undefined) {
246
- return n.includes("Level1");
247
- } else {
248
- return false;
249
- }
250
- });
251
- t.expect(hasLevel1).toBe(true);
252
- });
253
- });
254
-
255
- Vitest.describe("SemanticParser Integration - Dividers", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
256
- Vitest.test("SP-04: detects horizontal dividers within boxes", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
257
- let ast = Parser.parse(`
258
- @scene: sections
259
-
260
- +------------------+
261
- | Section 1 |
262
- | |
263
- +==================+
264
- | Section 2 |
265
- | |
266
- +------------------+
267
- `);
268
- if (ast.TAG === "Ok") {
269
- let scene = ast._0.scenes[0];
270
- scene.elements.some(el => el.TAG === "Divider");
271
- return t.expect(scene.elements.length).toBeGreaterThan(0);
272
- }
273
- console.error(ast._0);
274
- t.expect(true).toBe(false);
275
- });
276
- Vitest.test("SP-04a: handles multiple dividers in one box", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
277
- let ast = Parser.parse(`
278
- @scene: multi
279
-
280
- +----------+
281
- | Part 1 |
282
- +==========+
283
- | Part 2 |
284
- +==========+
285
- | Part 3 |
286
- +----------+
287
- `);
288
- if (ast.TAG !== "Ok") {
289
- return t.expect(true).toBe(false);
290
- }
291
- let ast$1 = ast._0;
292
- t.expect(ast$1.scenes.length).toBe(1);
293
- let scene = ast$1.scenes[0];
294
- t.expect(scene.elements.length).toBeGreaterThan(0);
295
- });
296
- });
297
-
298
- Vitest.describe("SemanticParser Integration - All Element Types", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => Vitest.test("SP-05: recognizes all supported element types in one scene", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
299
- let ast = Parser.parse(`
300
- @scene: alltypes
301
-
302
- +----------------------+
303
- | * Emphasis Text |
304
- | |
305
- | Plain Text |
306
- | |
307
- | [ Button ] |
308
- | |
309
- | #input |
310
- | |
311
- | "Link Text" |
312
- | |
313
- | [x] Checked Box |
314
- | |
315
- | [ ] Unchecked Box |
316
- +----------------------+
317
- `);
318
- if (ast.TAG === "Ok") {
319
- let scene = ast._0.scenes[0];
320
- let hasEmphasis = scene.elements.some(el => {
321
- if (el.TAG === "Text") {
322
- return el.emphasis;
323
- } else {
324
- return false;
325
- }
326
- });
327
- t.expect(hasEmphasis).toBe(true);
328
- let hasPlainText = scene.elements.some(el => {
329
- if (el.TAG === "Text") {
330
- return !el.emphasis;
331
- } else {
332
- return false;
333
- }
334
- });
335
- t.expect(hasPlainText).toBe(true);
336
- let hasButton = scene.elements.some(el => el.TAG === "Button");
337
- t.expect(hasButton).toBe(true);
338
- let hasInput = scene.elements.some(el => el.TAG === "Input");
339
- t.expect(hasInput).toBe(true);
340
- let hasLink = scene.elements.some(el => el.TAG === "Link");
341
- t.expect(hasLink).toBe(true);
342
- let hasCheckedBox = scene.elements.some(el => {
343
- if (el.TAG === "Checkbox") {
344
- return el.checked;
345
- } else {
346
- return false;
347
- }
348
- });
349
- t.expect(hasCheckedBox).toBe(true);
350
- let hasUncheckedBox = scene.elements.some(el => {
351
- if (el.TAG === "Checkbox") {
352
- return !el.checked;
353
- } else {
354
- return false;
355
- }
356
- });
357
- return t.expect(hasUncheckedBox).toBe(true);
358
- }
359
- console.error(ast._0);
360
- t.expect(true).toBe(false);
361
- }));
362
-
363
- Vitest.describe("SemanticParser Integration - Alignment", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => Vitest.test("SP-06: calculates element alignment based on position", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
364
- let ast = Parser.parse(`
365
- @scene: alignment
366
-
367
- +---------------------------+
368
- | [ Left ] |
369
- | |
370
- | [ Center ] |
371
- | |
372
- | [ Right ] |
373
- +---------------------------+
374
- `);
375
- if (ast.TAG === "Ok") {
376
- let scene = ast._0.scenes[0];
377
- let buttons = scene.elements.filter(el => el.TAG === "Button");
378
- t.expect(buttons.length).toBe(3);
379
- let hasLeft = buttons.some(el => {
380
- if (el.TAG !== "Button") {
381
- return false;
382
- }
383
- switch (el.align) {
384
- case "Left" :
385
- return true;
386
- case "Center" :
387
- case "Right" :
388
- return false;
389
- }
390
- });
391
- t.expect(hasLeft).toBe(true);
392
- let hasCenter = buttons.some(el => {
393
- if (el.TAG !== "Button") {
394
- return false;
395
- }
396
- switch (el.align) {
397
- case "Center" :
398
- return true;
399
- case "Left" :
400
- case "Right" :
401
- return false;
402
- }
403
- });
404
- t.expect(hasCenter).toBe(true);
405
- let hasRight = buttons.some(el => {
406
- if (el.TAG !== "Button") {
407
- return false;
408
- }
409
- switch (el.align) {
410
- case "Left" :
411
- case "Center" :
412
- return false;
413
- case "Right" :
414
- return true;
415
- }
416
- });
417
- return t.expect(hasRight).toBe(true);
418
- }
419
- console.error(ast._0);
420
- t.expect(true).toBe(false);
421
- }));
422
-
423
- Vitest.describe("SemanticParser Integration - Button Elements", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
424
- Vitest.test("SP-07: parses button with simple text", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
425
- let ast = Parser.parse(`
426
- @scene: btn
427
- +------------+
428
- | [ Submit ] |
429
- +------------+
430
- `);
431
- if (ast.TAG !== "Ok") {
432
- return t.expect(true).toBe(false);
433
- }
434
- let scene = ast._0.scenes[0];
435
- let button = scene.elements.find(el => el.TAG === "Button");
436
- if (button === undefined) {
437
- return t.expect(true).toBe(false);
438
- }
439
- if (button.TAG !== "Button") {
440
- return t.expect(true).toBe(false);
441
- }
442
- t.expect(button.text).toBe("Submit");
443
- t.expect(button.id).toBe("submit");
444
- });
445
- Vitest.test("SP-07a: parses button with multi-word text", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
446
- let ast = Parser.parse(`
447
- @scene: btn
448
- +--------------------+
449
- | [ Create Account ] |
450
- +--------------------+
451
- `);
452
- if (ast.TAG !== "Ok") {
453
- return t.expect(true).toBe(false);
454
- }
455
- let button = ast._0.scenes[0].elements.find(el => {
456
- if (el.TAG === "Button") {
457
- return el.text === "Create Account";
458
- } else {
459
- return false;
460
- }
461
- });
462
- if (button !== undefined && button.TAG === "Button") {
463
- return t.expect(button.id).toBe("create-account");
464
- } else {
465
- return t.expect(true).toBe(false);
466
- }
467
- });
468
- });
469
-
470
- Vitest.describe("SemanticParser Integration - Input Elements", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
471
- Vitest.test("SP-08: parses input field with ID", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
472
- let ast = Parser.parse(`
473
- @scene: inp
474
- +----------+
475
- | #email |
476
- +----------+
477
- `);
478
- if (ast.TAG !== "Ok") {
479
- return t.expect(true).toBe(false);
480
- }
481
- let input = ast._0.scenes[0].elements.find(el => el.TAG === "Input");
482
- if (input !== undefined && input.TAG === "Input") {
483
- return t.expect(input.id).toBe("email");
484
- } else {
485
- return t.expect(true).toBe(false);
486
- }
487
- });
488
- Vitest.test("SP-08a: parses input with label prefix", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
489
- let ast = Parser.parse(`
490
- @scene: inp
491
- +-----------------+
492
- | Email: #email |
493
- +-----------------+
494
- `);
495
- if (ast.TAG !== "Ok") {
496
- return t.expect(true).toBe(false);
497
- }
498
- let input = ast._0.scenes[0].elements.find(el => {
499
- if (el.TAG === "Input") {
500
- return el.id === "email";
501
- } else {
502
- return false;
503
- }
504
- });
505
- t.expect(input).not.toBe(undefined);
506
- });
507
- });
508
-
509
- Vitest.describe("SemanticParser Integration - Link Elements", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => Vitest.test("SP-09: parses link with quoted text", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
510
- let ast = Parser.parse(`
511
- @scene: lnk
512
- +------------------+
513
- | "Click Here" |
514
- +------------------+
515
- `);
516
- if (ast.TAG !== "Ok") {
517
- return t.expect(true).toBe(false);
518
- }
519
- let link = ast._0.scenes[0].elements.find(el => el.TAG === "Link");
520
- if (link === undefined) {
521
- return t.expect(true).toBe(false);
522
- }
523
- if (link.TAG !== "Link") {
524
- return t.expect(true).toBe(false);
525
- }
526
- t.expect(link.text).toBe("Click Here");
527
- t.expect(link.id).toBe("click-here");
528
- }));
529
-
530
- Vitest.describe("SemanticParser Integration - Checkbox Elements", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
531
- Vitest.test("SP-10: parses checked checkbox", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
532
- let ast = Parser.parse(`
533
- @scene: chk
534
- +-------------------+
535
- | [x] Accept terms |
536
- +-------------------+
537
- `);
538
- if (ast.TAG !== "Ok") {
539
- return t.expect(true).toBe(false);
540
- }
541
- let checkbox = ast._0.scenes[0].elements.find(el => {
542
- if (el.TAG === "Checkbox") {
543
- return el.checked;
544
- } else {
545
- return false;
546
- }
547
- });
548
- if (checkbox !== undefined && checkbox.TAG === "Checkbox") {
549
- return t.expect(checkbox.label).toBe("Accept terms");
550
- } else {
551
- return t.expect(true).toBe(false);
552
- }
553
- });
554
- Vitest.test("SP-10a: parses unchecked checkbox", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
555
- let ast = Parser.parse(`
556
- @scene: chk
557
- +---------------------+
558
- | [ ] Decline offer |
559
- +---------------------+
560
- `);
561
- if (ast.TAG !== "Ok") {
562
- return t.expect(true).toBe(false);
563
- }
564
- let checkbox = ast._0.scenes[0].elements.find(el => {
565
- if (el.TAG === "Checkbox") {
566
- return !el.checked;
567
- } else {
568
- return false;
569
- }
570
- });
571
- t.expect(checkbox).not.toBe(undefined);
572
- });
573
- });
574
-
575
- Vitest.describe("SemanticParser Integration - Emphasis Text", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => Vitest.test("SP-11: parses emphasis text with asterisk", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
576
- let ast = Parser.parse(`
577
- @scene: emp
578
- +-----------------+
579
- | * Important |
580
- +-----------------+
581
- `);
582
- if (ast.TAG !== "Ok") {
583
- return t.expect(true).toBe(false);
584
- }
585
- let emphasisText = ast._0.scenes[0].elements.find(el => {
586
- if (el.TAG === "Text") {
587
- return el.emphasis;
588
- } else {
589
- return false;
590
- }
591
- });
592
- if (emphasisText !== undefined && emphasisText.TAG === "Text") {
593
- return t.expect(emphasisText.content).toContain("Important");
594
- } else {
595
- return t.expect(true).toBe(false);
596
- }
597
- }));
598
-
599
- Vitest.describe("SemanticParser Integration - Mixed Content", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => Vitest.test("SP-12: parses complex scene with mixed element types", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
600
- let ast = Parser.parse(`
601
- @scene: mixed
602
-
603
- +-------------------------+
604
- | * Registration Form |
605
- | |
606
- | Name: #name |
607
- | Email: #email |
608
- | |
609
- | [x] Accept terms |
610
- | |
611
- | [ Sign Up ] |
612
- | |
613
- | "Already registered?" |
614
- +-------------------------+
615
- `);
616
- if (ast.TAG === "Ok") {
617
- let scene = ast._0.scenes[0];
618
- let emphasisCount = scene.elements.filter(el => {
619
- if (el.TAG === "Text") {
620
- return el.emphasis;
621
- } else {
622
- return false;
623
- }
624
- }).length;
625
- let inputCount = scene.elements.filter(el => el.TAG === "Input").length;
626
- let checkboxCount = scene.elements.filter(el => el.TAG === "Checkbox").length;
627
- let buttonCount = scene.elements.filter(el => el.TAG === "Button").length;
628
- let linkCount = scene.elements.filter(el => el.TAG === "Link").length;
629
- t.expect(emphasisCount).toBeGreaterThan(0);
630
- t.expect(inputCount).toBeGreaterThanOrEqual(2);
631
- t.expect(checkboxCount).toBeGreaterThan(0);
632
- t.expect(buttonCount).toBeGreaterThan(0);
633
- t.expect(linkCount).toBeGreaterThan(0);
634
- return t.expect(scene.elements.length).toBeGreaterThan(5);
635
- }
636
- console.error(ast._0);
637
- t.expect(true).toBe(false);
638
- }));
639
-
640
- Vitest.describe("SemanticParser Integration - Scene Directives", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
641
- Vitest.test("SP-14: parses scene directives correctly", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
642
- let ast = Parser.parse(`
643
- @scene: test
644
- @title: Test Scene
645
- @transition: fade
646
-
647
- +----------+
648
- | Content |
649
- +----------+
650
- `);
651
- if (ast.TAG === "Ok") {
652
- let scene = ast._0.scenes[0];
653
- t.expect(scene.id).toBe("test");
654
- t.expect(scene.title).toBe("Test Scene");
655
- return t.expect(scene.transition).toBe("fade");
656
- }
657
- console.error(ast._0);
658
- t.expect(true).toBe(false);
659
- });
660
- Vitest.test("SP-14a: handles missing optional directives", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
661
- let ast = Parser.parse(`
662
- @scene: minimal
663
-
664
- +----------+
665
- | Content |
666
- +----------+
667
- `);
668
- if (ast.TAG !== "Ok") {
669
- return t.expect(true).toBe(false);
670
- }
671
- let ast$1 = ast._0;
672
- let scene = ast$1.scenes[0];
673
- t.expect(scene.id).toBe("minimal");
674
- t.expect(ast$1.scenes.length).toBe(1);
675
- });
676
- });
677
-
678
- Vitest.describe("SemanticParser Integration - Empty Scenes", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
679
- Vitest.test("SP-15: handles empty scene gracefully", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
680
- let ast = Parser.parse(`
681
- @scene: empty
682
-
683
- +-------+
684
- | |
685
- +-------+
686
- `);
687
- if (ast.TAG !== "Ok") {
688
- return t.expect(true).toBe(false);
689
- }
690
- let ast$1 = ast._0;
691
- t.expect(ast$1.scenes.length).toBe(1);
692
- let scene = ast$1.scenes[0];
693
- t.expect(scene.id).toBe("empty");
694
- t.expect(Array.isArray(scene.elements)).toBe(true);
695
- });
696
- Vitest.test("SP-15a: handles scene with only whitespace", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
697
- let ast = Parser.parse(`
698
- @scene: whitespace
699
-
700
- +-----------+
701
- | |
702
- | |
703
- | |
704
- +-----------+
705
- `);
706
- if (ast.TAG !== "Ok") {
707
- return t.expect(true).toBe(false);
708
- }
709
- let ast$1 = ast._0;
710
- t.expect(ast$1.scenes.length).toBe(1);
711
- let scene = ast$1.scenes[0];
712
- t.expect(scene.id).toBe("whitespace");
713
- });
714
- });
715
-
716
- Vitest.describe("SemanticParser Integration - Edge Cases", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
717
- Vitest.test("handles very long element text", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
718
- let ast = Parser.parse(`
719
- @scene: long
720
-
721
- +---------------------------------------------------+
722
- | [ Very Long Button Text That Spans ] |
723
- +---------------------------------------------------+
724
- `);
725
- if (ast.TAG !== "Ok") {
726
- return t.expect(true).toBe(false);
727
- }
728
- let button = ast._0.scenes[0].elements.find(el => el.TAG === "Button");
729
- t.expect(button).not.toBe(undefined);
730
- });
731
- Vitest.test("handles special characters in text", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
732
- let ast = Parser.parse(`
733
- @scene: special
734
-
735
- +-------------------+
736
- | "Sign Up & Go!" |
737
- +-------------------+
738
- `);
739
- if (ast.TAG === "Ok") {
740
- return t.expect(ast._0.scenes.length).toBe(1);
741
- } else {
742
- return t.expect(true).toBe(false);
743
- }
744
- });
745
- Vitest.test("handles unicode characters", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
746
- let ast = Parser.parse(`
747
- @scene: unicode
748
-
749
- +-------------+
750
- | * Hello |
751
- +-------------+
752
- `);
753
- if (ast.TAG === "Ok") {
754
- return t.expect(ast._0.scenes.length).toBe(1);
755
- } else {
756
- return t.expect(true).toBe(false);
757
- }
758
- });
759
- });
760
-
761
- let pass;
762
-
763
- export {
764
- pass,
765
- collectAllElements,
766
- hasElement,
767
- }
768
- /* Not a pure module */