wyreframe 0.1.0 → 0.1.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.
- package/LICENSE +692 -0
- package/README.md +65 -5
- package/package.json +8 -7
- package/src/index.ts +425 -0
- package/src/renderer/Renderer.gen.tsx +49 -0
- package/src/renderer/Renderer.mjs +41 -1
- package/src/renderer/Renderer.res +78 -0
- package/src/test/Expect.mjs +9 -0
- package/src/parser/Core/__tests__/Bounds_test.mjs +0 -326
- package/src/parser/Core/__tests__/Bounds_test.res +0 -412
- package/src/parser/Core/__tests__/Grid_test.mjs +0 -322
- package/src/parser/Core/__tests__/Grid_test.res +0 -319
- package/src/parser/Core/__tests__/Types_test.mjs +0 -614
- package/src/parser/Core/__tests__/Types_test.res +0 -650
- package/src/parser/Detector/__tests__/BoxTracer_test.mjs +0 -70
- package/src/parser/Detector/__tests__/BoxTracer_test.res +0 -92
- package/src/parser/Detector/__tests__/HierarchyBuilder_test.mjs +0 -489
- package/src/parser/Detector/__tests__/HierarchyBuilder_test.res +0 -849
- package/src/parser/Detector/__tests__/ShapeDetector_test.mjs +0 -377
- package/src/parser/Detector/__tests__/ShapeDetector_test.res +0 -563
- package/src/parser/Interactions/__tests__/InteractionMerger_test.mjs +0 -576
- package/src/parser/Interactions/__tests__/InteractionMerger_test.res +0 -646
- package/src/parser/Scanner/__tests__/Grid_manual.mjs +0 -214
- package/src/parser/Scanner/__tests__/Grid_manual.res +0 -141
- package/src/parser/Semantic/Elements/__tests__/ButtonParser_test.mjs +0 -189
- package/src/parser/Semantic/Elements/__tests__/ButtonParser_test.res +0 -257
- package/src/parser/Semantic/Elements/__tests__/CheckboxParser_test.mjs +0 -202
- package/src/parser/Semantic/Elements/__tests__/CheckboxParser_test.res +0 -250
- package/src/parser/Semantic/Elements/__tests__/CodeTextParser_manual.mjs +0 -293
- package/src/parser/Semantic/Elements/__tests__/CodeTextParser_manual.res +0 -134
- package/src/parser/Semantic/Elements/__tests__/InputParser_test.mjs +0 -253
- package/src/parser/Semantic/Elements/__tests__/InputParser_test.res +0 -304
- package/src/parser/Semantic/Elements/__tests__/LinkParser_test.mjs +0 -289
- package/src/parser/Semantic/Elements/__tests__/LinkParser_test.res +0 -402
- package/src/parser/Semantic/Elements/__tests__/TextParser_test.mjs +0 -149
- package/src/parser/Semantic/Elements/__tests__/TextParser_test.res +0 -167
- package/src/parser/Semantic/__tests__/ASTBuilder_test.mjs +0 -187
- package/src/parser/Semantic/__tests__/ASTBuilder_test.res +0 -192
- package/src/parser/Semantic/__tests__/ParserRegistry_test.mjs +0 -154
- package/src/parser/Semantic/__tests__/ParserRegistry_test.res +0 -191
- package/src/parser/Semantic/__tests__/SemanticParser_integration_test.mjs +0 -768
- package/src/parser/Semantic/__tests__/SemanticParser_integration_test.res +0 -1069
- package/src/parser/Semantic/__tests__/SemanticParser_manual.mjs +0 -1329
- package/src/parser/Semantic/__tests__/SemanticParser_manual.res +0 -544
- package/src/parser/__tests__/GridScanner_integration.test.mjs +0 -632
- package/src/parser/__tests__/GridScanner_integration.test.res +0 -816
- package/src/parser/__tests__/Performance.test.mjs +0 -244
- package/src/parser/__tests__/Performance.test.res +0 -371
- package/src/parser/__tests__/PerformanceFixtures.mjs +0 -200
- package/src/parser/__tests__/PerformanceFixtures.res +0 -284
- package/src/parser/__tests__/WyreframeParser_integration.test.mjs +0 -770
- package/src/parser/__tests__/WyreframeParser_integration.test.res +0 -1008
- package/src/parser/__tests__/fixtures/alignment-test.txt +0 -9
- package/src/parser/__tests__/fixtures/all-elements.txt +0 -16
- package/src/parser/__tests__/fixtures/login-scene.txt +0 -17
- package/src/parser/__tests__/fixtures/multi-scene.txt +0 -25
- package/src/parser/__tests__/fixtures/nested-boxes.txt +0 -15
- package/src/parser/__tests__/fixtures/simple-box.txt +0 -5
- package/src/parser/__tests__/fixtures/with-dividers.txt +0 -14
|
@@ -1,544 +0,0 @@
|
|
|
1
|
-
// SemanticParser_test.res
|
|
2
|
-
// Unit tests for SemanticParser - Box Content Extraction
|
|
3
|
-
|
|
4
|
-
open Types
|
|
5
|
-
|
|
6
|
-
// Helper to create a simple grid for testing
|
|
7
|
-
let makeTestGrid = (lines: array<string>): Grid.t => {
|
|
8
|
-
Grid.fromLines(lines)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// Helper to create a box with bounds
|
|
12
|
-
let makeTestBox = (top: int, left: int, bottom: int, right: int): SemanticParser.box => {
|
|
13
|
-
{
|
|
14
|
-
name: None,
|
|
15
|
-
bounds: {top, left, bottom, right},
|
|
16
|
-
children: [],
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Test 1: Extract content from a simple box
|
|
21
|
-
let test_extractContentLines_simpleBox = () => {
|
|
22
|
-
let grid = makeTestGrid([
|
|
23
|
-
"+-------+",
|
|
24
|
-
"| Hello |",
|
|
25
|
-
"+-------+",
|
|
26
|
-
])
|
|
27
|
-
|
|
28
|
-
let box = makeTestBox(0, 0, 2, 8)
|
|
29
|
-
let content = SemanticParser.extractContentLines(box, grid.cells)
|
|
30
|
-
|
|
31
|
-
// Should extract: [" Hello "]
|
|
32
|
-
assert(Array.length(content) === 1)
|
|
33
|
-
assert(Array.getUnsafe(content, 0) === " Hello ")
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Test 2: Extract content from box with multiple lines
|
|
37
|
-
let test_extractContentLines_multipleLines = () => {
|
|
38
|
-
let grid = makeTestGrid([
|
|
39
|
-
"+--Login--+",
|
|
40
|
-
"| #email |",
|
|
41
|
-
"| [Submit]|",
|
|
42
|
-
"+----------+",
|
|
43
|
-
])
|
|
44
|
-
|
|
45
|
-
let box = makeTestBox(0, 0, 3, 10)
|
|
46
|
-
let content = SemanticParser.extractContentLines(box, grid.cells)
|
|
47
|
-
|
|
48
|
-
// Should extract: [" #email ", " [Submit]"]
|
|
49
|
-
assert(Array.length(content) === 2)
|
|
50
|
-
assert(Array.getUnsafe(content, 0) === " #email ")
|
|
51
|
-
assert(Array.getUnsafe(content, 1) === " [Submit]")
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Test 3: Extract content preserving internal whitespace
|
|
55
|
-
let test_extractContentLines_preserveWhitespace = () => {
|
|
56
|
-
let grid = makeTestGrid([
|
|
57
|
-
"+---------+",
|
|
58
|
-
"| a b |",
|
|
59
|
-
"+---------+",
|
|
60
|
-
])
|
|
61
|
-
|
|
62
|
-
let box = makeTestBox(0, 0, 2, 10)
|
|
63
|
-
let content = SemanticParser.extractContentLines(box, grid.cells)
|
|
64
|
-
|
|
65
|
-
// Should preserve the exact spacing: " a b "
|
|
66
|
-
assert(Array.length(content) === 1)
|
|
67
|
-
assert(Array.getUnsafe(content, 0) === " a b ")
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Test 4: Empty box (no content area)
|
|
71
|
-
let test_extractContentLines_emptyBox = () => {
|
|
72
|
-
let grid = makeTestGrid([
|
|
73
|
-
"+---+",
|
|
74
|
-
"+---+",
|
|
75
|
-
])
|
|
76
|
-
|
|
77
|
-
let box = makeTestBox(0, 0, 1, 4)
|
|
78
|
-
let content = SemanticParser.extractContentLines(box, grid.cells)
|
|
79
|
-
|
|
80
|
-
// Should return empty array for box with no content area
|
|
81
|
-
assert(Array.length(content) === 0)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Test 5: Box with divider in content
|
|
85
|
-
let test_extractContentLines_withDivider = () => {
|
|
86
|
-
let grid = makeTestGrid([
|
|
87
|
-
"+------+",
|
|
88
|
-
"| Head |",
|
|
89
|
-
"|======|",
|
|
90
|
-
"| Body |",
|
|
91
|
-
"+------+",
|
|
92
|
-
])
|
|
93
|
-
|
|
94
|
-
let box = makeTestBox(0, 0, 4, 7)
|
|
95
|
-
let content = SemanticParser.extractContentLines(box, grid.cells)
|
|
96
|
-
|
|
97
|
-
// Should extract all lines including divider
|
|
98
|
-
assert(Array.length(content) === 3)
|
|
99
|
-
assert(Array.getUnsafe(content, 0) === " Head ")
|
|
100
|
-
assert(Array.getUnsafe(content, 1) === "======")
|
|
101
|
-
assert(Array.getUnsafe(content, 2) === " Body ")
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Test 6: Box with empty lines
|
|
105
|
-
let test_extractContentLines_withEmptyLines = () => {
|
|
106
|
-
let grid = makeTestGrid([
|
|
107
|
-
"+-----+",
|
|
108
|
-
"| Top |",
|
|
109
|
-
"| |",
|
|
110
|
-
"| Bot |",
|
|
111
|
-
"+-----+",
|
|
112
|
-
])
|
|
113
|
-
|
|
114
|
-
let box = makeTestBox(0, 0, 4, 6)
|
|
115
|
-
let content = SemanticParser.extractContentLines(box, grid.cells)
|
|
116
|
-
|
|
117
|
-
// Should extract all lines, empty line as spaces
|
|
118
|
-
assert(Array.length(content) === 3)
|
|
119
|
-
assert(Array.getUnsafe(content, 0) === " Top ")
|
|
120
|
-
assert(Array.getUnsafe(content, 1) === " ")
|
|
121
|
-
assert(Array.getUnsafe(content, 2) === " Bot ")
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Test 7: Nested box scenario (inner box content)
|
|
125
|
-
let test_extractContentLines_nestedBox = () => {
|
|
126
|
-
let grid = makeTestGrid([
|
|
127
|
-
"+-----------+",
|
|
128
|
-
"| +-------+ |",
|
|
129
|
-
"| | Inner | |",
|
|
130
|
-
"| +-------+ |",
|
|
131
|
-
"+-----------+",
|
|
132
|
-
])
|
|
133
|
-
|
|
134
|
-
// Extract inner box content
|
|
135
|
-
let innerBox = makeTestBox(1, 2, 3, 9)
|
|
136
|
-
let innerContent = SemanticParser.extractContentLines(innerBox, grid.cells)
|
|
137
|
-
|
|
138
|
-
// Should extract: [" Inner "]
|
|
139
|
-
assert(Array.length(innerContent) === 1)
|
|
140
|
-
assert(Array.getUnsafe(innerContent, 0) === " Inner ")
|
|
141
|
-
|
|
142
|
-
// Extract outer box content (includes inner box structure)
|
|
143
|
-
let outerBox = makeTestBox(0, 0, 4, 12)
|
|
144
|
-
let outerContent = SemanticParser.extractContentLines(outerBox, grid.cells)
|
|
145
|
-
|
|
146
|
-
// Should extract outer content with inner box visible
|
|
147
|
-
assert(Array.length(outerContent) === 3)
|
|
148
|
-
assert(String.includes(Array.getUnsafe(outerContent, 0), "+-------+"))
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Test 8: Box with special characters in content
|
|
152
|
-
let test_extractContentLines_specialChars = () => {
|
|
153
|
-
let grid = makeTestGrid([
|
|
154
|
-
"+--------+",
|
|
155
|
-
"| a|b-c+ |",
|
|
156
|
-
"+--------+",
|
|
157
|
-
])
|
|
158
|
-
|
|
159
|
-
let box = makeTestBox(0, 0, 2, 9)
|
|
160
|
-
let content = SemanticParser.extractContentLines(box, grid.cells)
|
|
161
|
-
|
|
162
|
-
// Should preserve special chars that appear in content
|
|
163
|
-
assert(Array.length(content) === 1)
|
|
164
|
-
assert(Array.getUnsafe(content, 0) === " a|b-c+ ")
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Test utility functions
|
|
168
|
-
|
|
169
|
-
// Test: hasContent with non-empty box
|
|
170
|
-
let test_hasContent_nonEmpty = () => {
|
|
171
|
-
let grid = makeTestGrid([
|
|
172
|
-
"+-----+",
|
|
173
|
-
"| Txt |",
|
|
174
|
-
"+-----+",
|
|
175
|
-
])
|
|
176
|
-
|
|
177
|
-
let box = makeTestBox(0, 0, 2, 6)
|
|
178
|
-
assert(SemanticParser.hasContent(box, grid) === true)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Test: hasContent with empty box
|
|
182
|
-
let test_hasContent_empty = () => {
|
|
183
|
-
let grid = makeTestGrid([
|
|
184
|
-
"+-----+",
|
|
185
|
-
"| |",
|
|
186
|
-
"+-----+",
|
|
187
|
-
])
|
|
188
|
-
|
|
189
|
-
let box = makeTestBox(0, 0, 2, 6)
|
|
190
|
-
assert(SemanticParser.hasContent(box, grid) === false)
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Test: getContentLineCount
|
|
194
|
-
let test_getContentLineCount = () => {
|
|
195
|
-
let grid = makeTestGrid([
|
|
196
|
-
"+-----+",
|
|
197
|
-
"| L1 |",
|
|
198
|
-
"| L2 |",
|
|
199
|
-
"| L3 |",
|
|
200
|
-
"+-----+",
|
|
201
|
-
])
|
|
202
|
-
|
|
203
|
-
let box = makeTestBox(0, 0, 4, 6)
|
|
204
|
-
assert(SemanticParser.getContentLineCount(box, grid) === 3)
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// ============================================================================
|
|
208
|
-
// Scene Directive Parsing Tests
|
|
209
|
-
// ============================================================================
|
|
210
|
-
|
|
211
|
-
// Test: parseSceneDirectives with @scene
|
|
212
|
-
let test_parseSceneDirectives_scene = () => {
|
|
213
|
-
let lines = ["@scene: login", "+--Box--+", "| |", "+-------+"]
|
|
214
|
-
let (metadata, contentLines) = SemanticParser.parseSceneDirectives(lines)
|
|
215
|
-
|
|
216
|
-
assert(metadata.id === "login")
|
|
217
|
-
assert(metadata.title === "login")
|
|
218
|
-
assert(metadata.transition === "fade")
|
|
219
|
-
assert(Array.length(contentLines) === 3)
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// Test: parseSceneDirectives with @title
|
|
223
|
-
let test_parseSceneDirectives_title = () => {
|
|
224
|
-
let lines = ["@scene: login", "@title: Login Page", "+--Box--+"]
|
|
225
|
-
let (metadata, _) = SemanticParser.parseSceneDirectives(lines)
|
|
226
|
-
|
|
227
|
-
assert(metadata.id === "login")
|
|
228
|
-
assert(metadata.title === "Login Page")
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Test: parseSceneDirectives removes quotes from @title
|
|
232
|
-
let test_parseSceneDirectives_titleQuotes = () => {
|
|
233
|
-
let lines = ["@scene: login", "@title: \"Login Page\"", "+--Box--+"]
|
|
234
|
-
let (metadata, _) = SemanticParser.parseSceneDirectives(lines)
|
|
235
|
-
|
|
236
|
-
assert(metadata.title === "Login Page")
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// Test: parseSceneDirectives with @transition
|
|
240
|
-
let test_parseSceneDirectives_transition = () => {
|
|
241
|
-
let lines = ["@scene: login", "@transition: slide", "+--Box--+"]
|
|
242
|
-
let (metadata, _) = SemanticParser.parseSceneDirectives(lines)
|
|
243
|
-
|
|
244
|
-
assert(metadata.transition === "slide")
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// Test: parseSceneDirectives all directives together
|
|
248
|
-
let test_parseSceneDirectives_allDirectives = () => {
|
|
249
|
-
let lines = [
|
|
250
|
-
"@scene: login",
|
|
251
|
-
"@title: Login Page",
|
|
252
|
-
"@transition: slide",
|
|
253
|
-
"",
|
|
254
|
-
"+--Login--+",
|
|
255
|
-
"| #email |",
|
|
256
|
-
"+----------+",
|
|
257
|
-
]
|
|
258
|
-
let (metadata, contentLines) = SemanticParser.parseSceneDirectives(lines)
|
|
259
|
-
|
|
260
|
-
assert(metadata.id === "login")
|
|
261
|
-
assert(metadata.title === "Login Page")
|
|
262
|
-
assert(metadata.transition === "slide")
|
|
263
|
-
assert(Array.length(contentLines) === 4)
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// Test: parseSceneDirectives defaults
|
|
267
|
-
let test_parseSceneDirectives_defaults = () => {
|
|
268
|
-
let lines = ["+--Box--+", "| |", "+-------+"]
|
|
269
|
-
let (metadata, _) = SemanticParser.parseSceneDirectives(lines)
|
|
270
|
-
|
|
271
|
-
assert(metadata.id === "main")
|
|
272
|
-
assert(metadata.title === "main")
|
|
273
|
-
assert(metadata.transition === "fade")
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// Test: parseSceneDirectives ignores unknown directives
|
|
277
|
-
let test_parseSceneDirectives_unknownDirectives = () => {
|
|
278
|
-
let lines = ["@scene: login", "@unknown: something", "@custom: value", "+--Box--+"]
|
|
279
|
-
let (metadata, contentLines) = SemanticParser.parseSceneDirectives(lines)
|
|
280
|
-
|
|
281
|
-
assert(metadata.id === "login")
|
|
282
|
-
assert(Array.length(contentLines) === 1)
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// Test: splitSceneBlocks with --- separator
|
|
286
|
-
let test_splitSceneBlocks_dashedSeparator = () => {
|
|
287
|
-
let input = `@scene: login
|
|
288
|
-
+--Login--+
|
|
289
|
-
|
|
290
|
-
---
|
|
291
|
-
|
|
292
|
-
@scene: home
|
|
293
|
-
+--Home--+`
|
|
294
|
-
|
|
295
|
-
let blocks = SemanticParser.splitSceneBlocks(input)
|
|
296
|
-
|
|
297
|
-
assert(Array.length(blocks) === 2)
|
|
298
|
-
assert(String.includes(blocks[0]->Belt.Option.getExn, "@scene: login"))
|
|
299
|
-
assert(String.includes(blocks[1]->Belt.Option.getExn, "@scene: home"))
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// Test: splitSceneBlocks with @scene separator
|
|
303
|
-
let test_splitSceneBlocks_sceneDirectiveSeparator = () => {
|
|
304
|
-
let input = `@scene: login
|
|
305
|
-
+--Login--+
|
|
306
|
-
@scene: home
|
|
307
|
-
+--Home--+`
|
|
308
|
-
|
|
309
|
-
let blocks = SemanticParser.splitSceneBlocks(input)
|
|
310
|
-
|
|
311
|
-
assert(Array.length(blocks) === 2)
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// Test: splitSceneBlocks single scene
|
|
315
|
-
let test_splitSceneBlocks_singleScene = () => {
|
|
316
|
-
let input = `@scene: login
|
|
317
|
-
+--Login--+
|
|
318
|
-
| #email |
|
|
319
|
-
+----------+`
|
|
320
|
-
|
|
321
|
-
let blocks = SemanticParser.splitSceneBlocks(input)
|
|
322
|
-
|
|
323
|
-
assert(Array.length(blocks) === 1)
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// Test: splitSceneBlocks filters empty blocks
|
|
327
|
-
let test_splitSceneBlocks_filtersEmpty = () => {
|
|
328
|
-
let input = `
|
|
329
|
-
|
|
330
|
-
---
|
|
331
|
-
|
|
332
|
-
@scene: login
|
|
333
|
-
+--Box--+
|
|
334
|
-
|
|
335
|
-
---
|
|
336
|
-
|
|
337
|
-
`
|
|
338
|
-
|
|
339
|
-
let blocks = SemanticParser.splitSceneBlocks(input)
|
|
340
|
-
|
|
341
|
-
assert(Array.length(blocks) === 1)
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// Test: groupContentByScenes simple scene
|
|
345
|
-
let test_groupContentByScenes_simple = () => {
|
|
346
|
-
let input = `@scene: login
|
|
347
|
-
@title: Login Page
|
|
348
|
-
@transition: slide
|
|
349
|
-
|
|
350
|
-
+--Login--+
|
|
351
|
-
| #email |
|
|
352
|
-
+----------+`
|
|
353
|
-
|
|
354
|
-
let scenes = SemanticParser.groupContentByScenes(input)
|
|
355
|
-
|
|
356
|
-
assert(Array.length(scenes) === 1)
|
|
357
|
-
|
|
358
|
-
let (metadata, content) = scenes[0]->Belt.Option.getExn
|
|
359
|
-
assert(metadata.id === "login")
|
|
360
|
-
assert(metadata.title === "Login Page")
|
|
361
|
-
assert(metadata.transition === "slide")
|
|
362
|
-
assert(Array.length(content) > 0)
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// Test: groupContentByScenes multiple scenes
|
|
366
|
-
let test_groupContentByScenes_multiple = () => {
|
|
367
|
-
let input = `@scene: login
|
|
368
|
-
+--Login--+
|
|
369
|
-
|
|
370
|
-
---
|
|
371
|
-
|
|
372
|
-
@scene: home
|
|
373
|
-
+--Home--+
|
|
374
|
-
|
|
375
|
-
---
|
|
376
|
-
|
|
377
|
-
@scene: settings
|
|
378
|
-
+--Settings--+`
|
|
379
|
-
|
|
380
|
-
let scenes = SemanticParser.groupContentByScenes(input)
|
|
381
|
-
|
|
382
|
-
assert(Array.length(scenes) === 3)
|
|
383
|
-
|
|
384
|
-
let (meta1, _) = scenes[0]->Belt.Option.getExn
|
|
385
|
-
let (meta2, _) = scenes[1]->Belt.Option.getExn
|
|
386
|
-
let (meta3, _) = scenes[2]->Belt.Option.getExn
|
|
387
|
-
|
|
388
|
-
assert(meta1.id === "login")
|
|
389
|
-
assert(meta2.id === "home")
|
|
390
|
-
assert(meta3.id === "settings")
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// Test: groupContentByScenes default scene
|
|
394
|
-
let test_groupContentByScenes_default = () => {
|
|
395
|
-
let input = `+--Box--+
|
|
396
|
-
| Text |
|
|
397
|
-
+-------+`
|
|
398
|
-
|
|
399
|
-
let scenes = SemanticParser.groupContentByScenes(input)
|
|
400
|
-
|
|
401
|
-
assert(Array.length(scenes) === 1)
|
|
402
|
-
|
|
403
|
-
let (metadata, _) = scenes[0]->Belt.Option.getExn
|
|
404
|
-
assert(metadata.id === "main")
|
|
405
|
-
assert(metadata.title === "main")
|
|
406
|
-
assert(metadata.transition === "fade")
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
// Test: groupContentByScenes empty input
|
|
410
|
-
let test_groupContentByScenes_empty = () => {
|
|
411
|
-
let input = ""
|
|
412
|
-
let scenes = SemanticParser.groupContentByScenes(input)
|
|
413
|
-
|
|
414
|
-
assert(Array.length(scenes) === 0)
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// Test: groupContentByScenes complex example
|
|
418
|
-
let test_groupContentByScenes_complex = () => {
|
|
419
|
-
let input = `@scene: login
|
|
420
|
-
@title: "Login Page"
|
|
421
|
-
|
|
422
|
-
+--Login----------------+
|
|
423
|
-
| * WYREFRAME |
|
|
424
|
-
| |
|
|
425
|
-
| #email |
|
|
426
|
-
| #password |
|
|
427
|
-
| |
|
|
428
|
-
| [ Login ] |
|
|
429
|
-
+----------------------+
|
|
430
|
-
|
|
431
|
-
---
|
|
432
|
-
|
|
433
|
-
@scene: home
|
|
434
|
-
@transition: slide
|
|
435
|
-
|
|
436
|
-
+--Home-----------------+
|
|
437
|
-
| Welcome! |
|
|
438
|
-
+----------------------+`
|
|
439
|
-
|
|
440
|
-
let scenes = SemanticParser.groupContentByScenes(input)
|
|
441
|
-
|
|
442
|
-
assert(Array.length(scenes) === 2)
|
|
443
|
-
|
|
444
|
-
let (loginMeta, loginContent) = scenes[0]->Belt.Option.getExn
|
|
445
|
-
assert(loginMeta.id === "login")
|
|
446
|
-
assert(loginMeta.title === "Login Page")
|
|
447
|
-
assert(String.includes(Array.join(loginContent, "\n"), "#email"))
|
|
448
|
-
|
|
449
|
-
let (homeMeta, homeContent) = scenes[1]->Belt.Option.getExn
|
|
450
|
-
assert(homeMeta.id === "home")
|
|
451
|
-
assert(homeMeta.transition === "slide")
|
|
452
|
-
assert(String.includes(Array.join(homeContent, "\n"), "Welcome!"))
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
// Run all tests
|
|
456
|
-
let runTests = () => {
|
|
457
|
-
Console.log("Running SemanticParser tests...")
|
|
458
|
-
Console.log("\n=== Box Content Extraction ===")
|
|
459
|
-
|
|
460
|
-
test_extractContentLines_simpleBox()
|
|
461
|
-
Console.log("✓ Simple box content extraction")
|
|
462
|
-
|
|
463
|
-
test_extractContentLines_multipleLines()
|
|
464
|
-
Console.log("✓ Multiple lines extraction")
|
|
465
|
-
|
|
466
|
-
test_extractContentLines_preserveWhitespace()
|
|
467
|
-
Console.log("✓ Whitespace preservation")
|
|
468
|
-
|
|
469
|
-
test_extractContentLines_emptyBox()
|
|
470
|
-
Console.log("✓ Empty box handling")
|
|
471
|
-
|
|
472
|
-
test_extractContentLines_withDivider()
|
|
473
|
-
Console.log("✓ Box with divider")
|
|
474
|
-
|
|
475
|
-
test_extractContentLines_withEmptyLines()
|
|
476
|
-
Console.log("✓ Box with empty lines")
|
|
477
|
-
|
|
478
|
-
test_extractContentLines_nestedBox()
|
|
479
|
-
Console.log("✓ Nested box content")
|
|
480
|
-
|
|
481
|
-
test_extractContentLines_specialChars()
|
|
482
|
-
Console.log("✓ Special characters in content")
|
|
483
|
-
|
|
484
|
-
test_hasContent_nonEmpty()
|
|
485
|
-
Console.log("✓ hasContent (non-empty)")
|
|
486
|
-
|
|
487
|
-
test_hasContent_empty()
|
|
488
|
-
Console.log("✓ hasContent (empty)")
|
|
489
|
-
|
|
490
|
-
test_getContentLineCount()
|
|
491
|
-
Console.log("✓ getContentLineCount")
|
|
492
|
-
|
|
493
|
-
Console.log("\n=== Scene Directive Parsing ===")
|
|
494
|
-
|
|
495
|
-
test_parseSceneDirectives_scene()
|
|
496
|
-
Console.log("✓ Parse @scene directive")
|
|
497
|
-
|
|
498
|
-
test_parseSceneDirectives_title()
|
|
499
|
-
Console.log("✓ Parse @title directive")
|
|
500
|
-
|
|
501
|
-
test_parseSceneDirectives_titleQuotes()
|
|
502
|
-
Console.log("✓ Remove quotes from @title")
|
|
503
|
-
|
|
504
|
-
test_parseSceneDirectives_transition()
|
|
505
|
-
Console.log("✓ Parse @transition directive")
|
|
506
|
-
|
|
507
|
-
test_parseSceneDirectives_allDirectives()
|
|
508
|
-
Console.log("✓ Parse all directives together")
|
|
509
|
-
|
|
510
|
-
test_parseSceneDirectives_defaults()
|
|
511
|
-
Console.log("✓ Default metadata values")
|
|
512
|
-
|
|
513
|
-
test_parseSceneDirectives_unknownDirectives()
|
|
514
|
-
Console.log("✓ Ignore unknown directives")
|
|
515
|
-
|
|
516
|
-
test_splitSceneBlocks_dashedSeparator()
|
|
517
|
-
Console.log("✓ Split scenes by --- separator")
|
|
518
|
-
|
|
519
|
-
test_splitSceneBlocks_sceneDirectiveSeparator()
|
|
520
|
-
Console.log("✓ Split scenes by @scene directive")
|
|
521
|
-
|
|
522
|
-
test_splitSceneBlocks_singleScene()
|
|
523
|
-
Console.log("✓ Handle single scene")
|
|
524
|
-
|
|
525
|
-
test_splitSceneBlocks_filtersEmpty()
|
|
526
|
-
Console.log("✓ Filter empty blocks")
|
|
527
|
-
|
|
528
|
-
test_groupContentByScenes_simple()
|
|
529
|
-
Console.log("✓ Group simple scene with directives")
|
|
530
|
-
|
|
531
|
-
test_groupContentByScenes_multiple()
|
|
532
|
-
Console.log("✓ Group multiple scenes")
|
|
533
|
-
|
|
534
|
-
test_groupContentByScenes_default()
|
|
535
|
-
Console.log("✓ Create default scene")
|
|
536
|
-
|
|
537
|
-
test_groupContentByScenes_empty()
|
|
538
|
-
Console.log("✓ Handle empty input")
|
|
539
|
-
|
|
540
|
-
test_groupContentByScenes_complex()
|
|
541
|
-
Console.log("✓ Handle complex multi-scene example")
|
|
542
|
-
|
|
543
|
-
Console.log("\n✅ All SemanticParser tests passed!")
|
|
544
|
-
}
|