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,402 +0,0 @@
|
|
|
1
|
-
// LinkParser_test.res
|
|
2
|
-
// Unit tests for LinkParser module
|
|
3
|
-
//
|
|
4
|
-
// Tests cover:
|
|
5
|
-
// - Valid link patterns
|
|
6
|
-
// - Escaped quotes within link text
|
|
7
|
-
// - Empty link text
|
|
8
|
-
// - Edge cases and boundary conditions
|
|
9
|
-
|
|
10
|
-
open Vitest
|
|
11
|
-
|
|
12
|
-
describe("LinkParser", () => {
|
|
13
|
-
let testPosition = Types.Position.make(5, 10)
|
|
14
|
-
let testBounds: Types.Bounds.t = {
|
|
15
|
-
top: 0,
|
|
16
|
-
left: 0,
|
|
17
|
-
bottom: 10,
|
|
18
|
-
right: 40,
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
describe("canParse", () => {
|
|
22
|
-
test("returns true for valid quoted text", t => {
|
|
23
|
-
t->expect(LinkParser.canParse("\"Login\""))->Expect.toBe(true)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
test("returns true for quoted text with spaces", t => {
|
|
27
|
-
t->expect(LinkParser.canParse("\"Sign Up Here\""))->Expect.toBe(true)
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
test("returns true for quoted text with numbers", t => {
|
|
31
|
-
t->expect(LinkParser.canParse("\"Page 123\""))->Expect.toBe(true)
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
test("returns true for quoted text with special characters", t => {
|
|
35
|
-
t->expect(LinkParser.canParse("\"Home - Main Page\""))->Expect.toBe(true)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
test("returns false for text without quotes", t => {
|
|
39
|
-
t->expect(LinkParser.canParse("Login"))->Expect.toBe(false)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
test("returns false for text with only opening quote", t => {
|
|
43
|
-
t->expect(LinkParser.canParse("\"Login"))->Expect.toBe(false)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
test("returns false for text with only closing quote", t => {
|
|
47
|
-
t->expect(LinkParser.canParse("Login\""))->Expect.toBe(false)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
test("returns false for empty quotes", t => {
|
|
51
|
-
t->expect(LinkParser.canParse("\"\""))->Expect.toBe(false)
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
test("returns false for button syntax", t => {
|
|
55
|
-
t->expect(LinkParser.canParse("[ Submit ]"))->Expect.toBe(false)
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
test("returns false for input syntax", t => {
|
|
59
|
-
t->expect(LinkParser.canParse("#username"))->Expect.toBe(false)
|
|
60
|
-
})
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
describe("parse", () => {
|
|
64
|
-
describe("valid links", () => {
|
|
65
|
-
test("parses simple quoted text", t => {
|
|
66
|
-
let result = LinkParser.parse("\"Login\"", testPosition, testBounds)
|
|
67
|
-
|
|
68
|
-
switch result {
|
|
69
|
-
| Some(Types.Link({id, text, position, align})) => {
|
|
70
|
-
t->expect(id)->Expect.toBe("login")
|
|
71
|
-
t->expect(text)->Expect.toBe("Login")
|
|
72
|
-
t->expect(position)->Expect.toEqual(testPosition)
|
|
73
|
-
t->expect(align)->Expect.toBe(Types.Left)
|
|
74
|
-
}
|
|
75
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
76
|
-
}
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
test("parses quoted text with spaces", t => {
|
|
80
|
-
let result = LinkParser.parse("\"Sign Up Here\"", testPosition, testBounds)
|
|
81
|
-
|
|
82
|
-
switch result {
|
|
83
|
-
| Some(Types.Link({id, text})) => {
|
|
84
|
-
t->expect(id)->Expect.toBe("sign-up-here")
|
|
85
|
-
t->expect(text)->Expect.toBe("Sign Up Here")
|
|
86
|
-
}
|
|
87
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
test("parses quoted text with numbers", t => {
|
|
92
|
-
let result = LinkParser.parse("\"Page 123\"", testPosition, testBounds)
|
|
93
|
-
|
|
94
|
-
switch result {
|
|
95
|
-
| Some(Types.Link({id, text})) => {
|
|
96
|
-
t->expect(id)->Expect.toBe("page-123")
|
|
97
|
-
t->expect(text)->Expect.toBe("Page 123")
|
|
98
|
-
}
|
|
99
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
100
|
-
}
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
test("parses quoted text with hyphens", t => {
|
|
104
|
-
let result = LinkParser.parse("\"Home-Page\"", testPosition, testBounds)
|
|
105
|
-
|
|
106
|
-
switch result {
|
|
107
|
-
| Some(Types.Link({id, text})) => {
|
|
108
|
-
t->expect(id)->Expect.toBe("home-page")
|
|
109
|
-
t->expect(text)->Expect.toBe("Home-Page")
|
|
110
|
-
}
|
|
111
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
112
|
-
}
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
test("parses quoted text with special characters", t => {
|
|
116
|
-
let result = LinkParser.parse("\"Contact Us!\"", testPosition, testBounds)
|
|
117
|
-
|
|
118
|
-
switch result {
|
|
119
|
-
| Some(Types.Link({id, text})) => {
|
|
120
|
-
t->expect(id)->Expect.toBe("contact-us")
|
|
121
|
-
t->expect(text)->Expect.toBe("Contact Us!")
|
|
122
|
-
}
|
|
123
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
124
|
-
}
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
test("parses quoted text with multiple words", t => {
|
|
128
|
-
let result = LinkParser.parse("\"Learn More About Our Services\"", testPosition, testBounds)
|
|
129
|
-
|
|
130
|
-
switch result {
|
|
131
|
-
| Some(Types.Link({id, text})) => {
|
|
132
|
-
t->expect(id)->Expect.toBe("learn-more-about-our-services")
|
|
133
|
-
t->expect(text)->Expect.toBe("Learn More About Our Services")
|
|
134
|
-
}
|
|
135
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
136
|
-
}
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
test("parses link in context with surrounding text", t => {
|
|
140
|
-
let result = LinkParser.parse("Click \"Here\" to continue", testPosition, testBounds)
|
|
141
|
-
|
|
142
|
-
switch result {
|
|
143
|
-
| Some(Types.Link({id, text})) => {
|
|
144
|
-
t->expect(id)->Expect.toBe("here")
|
|
145
|
-
t->expect(text)->Expect.toBe("Here")
|
|
146
|
-
}
|
|
147
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
148
|
-
}
|
|
149
|
-
})
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
describe("escaped quotes", () => {
|
|
153
|
-
test("handles escaped quotes within link text", t => {
|
|
154
|
-
let result = LinkParser.parse("\"Say \\\"Hello\\\"\"", testPosition, testBounds)
|
|
155
|
-
|
|
156
|
-
switch result {
|
|
157
|
-
| Some(Types.Link({text})) => {
|
|
158
|
-
t->expect(text)->Expect.toBe("Say \"Hello\"")
|
|
159
|
-
}
|
|
160
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
161
|
-
}
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
test("handles multiple escaped quotes", t => {
|
|
165
|
-
let result = LinkParser.parse("\"\\\"Quote\\\" and \\\"Unquote\\\"\"", testPosition, testBounds)
|
|
166
|
-
|
|
167
|
-
switch result {
|
|
168
|
-
| Some(Types.Link({text})) => {
|
|
169
|
-
t->expect(text)->Expect.toBe("\"Quote\" and \"Unquote\"")
|
|
170
|
-
}
|
|
171
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
172
|
-
}
|
|
173
|
-
})
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
describe("empty and whitespace text", () => {
|
|
177
|
-
test("returns None for empty quotes", t => {
|
|
178
|
-
let result = LinkParser.parse("\"\"", testPosition, testBounds)
|
|
179
|
-
t->expect(result)->Expect.toBe(None)
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
test("returns None for quotes with only whitespace", t => {
|
|
183
|
-
let result = LinkParser.parse("\" \"", testPosition, testBounds)
|
|
184
|
-
t->expect(result)->Expect.toBe(None)
|
|
185
|
-
})
|
|
186
|
-
|
|
187
|
-
test("returns None for quotes with only tabs", t => {
|
|
188
|
-
let result = LinkParser.parse("\"\t\t\"", testPosition, testBounds)
|
|
189
|
-
t->expect(result)->Expect.toBe(None)
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
test("returns None for quotes with only newlines", t => {
|
|
193
|
-
let result = LinkParser.parse("\"\n\n\"", testPosition, testBounds)
|
|
194
|
-
t->expect(result)->Expect.toBe(None)
|
|
195
|
-
})
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
describe("invalid patterns", () => {
|
|
199
|
-
test("returns None for text without quotes", t => {
|
|
200
|
-
let result = LinkParser.parse("Login", testPosition, testBounds)
|
|
201
|
-
t->expect(result)->Expect.toBe(None)
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
test("returns None for text with only opening quote", t => {
|
|
205
|
-
let result = LinkParser.parse("\"Login", testPosition, testBounds)
|
|
206
|
-
t->expect(result)->Expect.toBe(None)
|
|
207
|
-
})
|
|
208
|
-
|
|
209
|
-
test("returns None for text with only closing quote", t => {
|
|
210
|
-
let result = LinkParser.parse("Login\"", testPosition, testBounds)
|
|
211
|
-
t->expect(result)->Expect.toBe(None)
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
test("returns None for button syntax", t => {
|
|
215
|
-
let result = LinkParser.parse("[ Submit ]", testPosition, testBounds)
|
|
216
|
-
t->expect(result)->Expect.toBe(None)
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
test("returns None for input syntax", t => {
|
|
220
|
-
let result = LinkParser.parse("#username", testPosition, testBounds)
|
|
221
|
-
t->expect(result)->Expect.toBe(None)
|
|
222
|
-
})
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
describe("edge cases", () => {
|
|
226
|
-
test("handles single character link", t => {
|
|
227
|
-
let result = LinkParser.parse("\"A\"", testPosition, testBounds)
|
|
228
|
-
|
|
229
|
-
switch result {
|
|
230
|
-
| Some(Types.Link({id, text})) => {
|
|
231
|
-
t->expect(id)->Expect.toBe("a")
|
|
232
|
-
t->expect(text)->Expect.toBe("A")
|
|
233
|
-
}
|
|
234
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
235
|
-
}
|
|
236
|
-
})
|
|
237
|
-
|
|
238
|
-
test("handles very long link text", t => {
|
|
239
|
-
let longText = "This is a very long link text that spans multiple words and contains various characters"
|
|
240
|
-
let result = LinkParser.parse(`"${longText}"`, testPosition, testBounds)
|
|
241
|
-
|
|
242
|
-
switch result {
|
|
243
|
-
| Some(Types.Link({text})) => {
|
|
244
|
-
t->expect(text)->Expect.toBe(longText)
|
|
245
|
-
}
|
|
246
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
247
|
-
}
|
|
248
|
-
})
|
|
249
|
-
|
|
250
|
-
test("preserves case in link text", t => {
|
|
251
|
-
let result = LinkParser.parse("\"CamelCaseLink\"", testPosition, testBounds)
|
|
252
|
-
|
|
253
|
-
switch result {
|
|
254
|
-
| Some(Types.Link({text})) => {
|
|
255
|
-
t->expect(text)->Expect.toBe("CamelCaseLink")
|
|
256
|
-
}
|
|
257
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
258
|
-
}
|
|
259
|
-
})
|
|
260
|
-
|
|
261
|
-
test("converts uppercase to lowercase in ID", t => {
|
|
262
|
-
let result = LinkParser.parse("\"UPPERCASE LINK\"", testPosition, testBounds)
|
|
263
|
-
|
|
264
|
-
switch result {
|
|
265
|
-
| Some(Types.Link({id})) => {
|
|
266
|
-
t->expect(id)->Expect.toBe("uppercase-link")
|
|
267
|
-
}
|
|
268
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
269
|
-
}
|
|
270
|
-
})
|
|
271
|
-
|
|
272
|
-
test("handles consecutive spaces in ID generation", t => {
|
|
273
|
-
let result = LinkParser.parse("\"Multiple Spaces\"", testPosition, testBounds)
|
|
274
|
-
|
|
275
|
-
switch result {
|
|
276
|
-
| Some(Types.Link({id})) => {
|
|
277
|
-
t->expect(id)->Expect.toBe("multiple-spaces")
|
|
278
|
-
}
|
|
279
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
280
|
-
}
|
|
281
|
-
})
|
|
282
|
-
})
|
|
283
|
-
})
|
|
284
|
-
|
|
285
|
-
describe("slugify", () => {
|
|
286
|
-
test("converts text to lowercase", t => {
|
|
287
|
-
t->expect(LinkParser.slugify("HELLO WORLD"))->Expect.toBe("hello-world")
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
test("replaces spaces with hyphens", t => {
|
|
291
|
-
t->expect(LinkParser.slugify("hello world"))->Expect.toBe("hello-world")
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
test("removes special characters", t => {
|
|
295
|
-
t->expect(LinkParser.slugify("hello! world?"))->Expect.toBe("hello-world")
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
test("removes consecutive hyphens", t => {
|
|
299
|
-
t->expect(LinkParser.slugify("hello---world"))->Expect.toBe("hello-world")
|
|
300
|
-
})
|
|
301
|
-
|
|
302
|
-
test("trims leading and trailing hyphens", t => {
|
|
303
|
-
t->expect(LinkParser.slugify("-hello-world-"))->Expect.toBe("hello-world")
|
|
304
|
-
})
|
|
305
|
-
|
|
306
|
-
test("handles empty string", t => {
|
|
307
|
-
t->expect(LinkParser.slugify(""))->Expect.toBe("")
|
|
308
|
-
})
|
|
309
|
-
|
|
310
|
-
test("handles only special characters", t => {
|
|
311
|
-
t->expect(LinkParser.slugify("!!!###"))->Expect.toBe("")
|
|
312
|
-
})
|
|
313
|
-
|
|
314
|
-
test("preserves numbers", t => {
|
|
315
|
-
t->expect(LinkParser.slugify("Page 123"))->Expect.toBe("page-123")
|
|
316
|
-
})
|
|
317
|
-
|
|
318
|
-
test("handles mixed alphanumeric", t => {
|
|
319
|
-
t->expect(LinkParser.slugify("Test123Page"))->Expect.toBe("test123page")
|
|
320
|
-
})
|
|
321
|
-
})
|
|
322
|
-
|
|
323
|
-
describe("unescapeQuotes", () => {
|
|
324
|
-
test("unescapes escaped quotes", t => {
|
|
325
|
-
t->expect(LinkParser.unescapeQuotes("Say \\\"Hello\\\""))->Expect.toBe("Say \"Hello\"")
|
|
326
|
-
})
|
|
327
|
-
|
|
328
|
-
test("handles multiple escaped quotes", t => {
|
|
329
|
-
t->expect(LinkParser.unescapeQuotes("\\\"A\\\" and \\\"B\\\""))->Expect.toBe("\"A\" and \"B\"")
|
|
330
|
-
})
|
|
331
|
-
|
|
332
|
-
test("returns unchanged text without escaped quotes", t => {
|
|
333
|
-
t->expect(LinkParser.unescapeQuotes("Hello World"))->Expect.toBe("Hello World")
|
|
334
|
-
})
|
|
335
|
-
|
|
336
|
-
test("handles empty string", t => {
|
|
337
|
-
t->expect(LinkParser.unescapeQuotes(""))->Expect.toBe("")
|
|
338
|
-
})
|
|
339
|
-
})
|
|
340
|
-
|
|
341
|
-
describe("make", () => {
|
|
342
|
-
test("creates parser with priority 80", t => {
|
|
343
|
-
let parser = LinkParser.make()
|
|
344
|
-
t->expect(parser.priority)->Expect.toBe(80)
|
|
345
|
-
})
|
|
346
|
-
|
|
347
|
-
test("creates parser with canParse function", t => {
|
|
348
|
-
let parser = LinkParser.make()
|
|
349
|
-
t->expect(parser.canParse("\"Link\""))->Expect.toBe(true)
|
|
350
|
-
})
|
|
351
|
-
|
|
352
|
-
test("creates parser with parse function", t => {
|
|
353
|
-
let parser = LinkParser.make()
|
|
354
|
-
let result = parser.parse("\"Link\"", testPosition, testBounds)
|
|
355
|
-
|
|
356
|
-
switch result {
|
|
357
|
-
| Some(Types.Link(_)) => ()
|
|
358
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
359
|
-
}
|
|
360
|
-
})
|
|
361
|
-
})
|
|
362
|
-
|
|
363
|
-
describe("integration", () => {
|
|
364
|
-
test("parses link within box content", t => {
|
|
365
|
-
// Simulating link within a box: "Click \"here\" for details"
|
|
366
|
-
let result = LinkParser.parse("Click \"here\" for details", testPosition, testBounds)
|
|
367
|
-
|
|
368
|
-
switch result {
|
|
369
|
-
| Some(Types.Link({id, text, position})) => {
|
|
370
|
-
t->expect(id)->Expect.toBe("here")
|
|
371
|
-
t->expect(text)->Expect.toBe("here")
|
|
372
|
-
t->expect(position.row)->Expect.toBe(5)
|
|
373
|
-
t->expect(position.col)->Expect.toBe(10)
|
|
374
|
-
}
|
|
375
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
376
|
-
}
|
|
377
|
-
})
|
|
378
|
-
|
|
379
|
-
test("distinguishes link from button syntax", t => {
|
|
380
|
-
let linkResult = LinkParser.parse("\"Submit\"", testPosition, testBounds)
|
|
381
|
-
let buttonResult = LinkParser.parse("[ Submit ]", testPosition, testBounds)
|
|
382
|
-
|
|
383
|
-
switch (linkResult, buttonResult) {
|
|
384
|
-
| (Some(Types.Link(_)), None) => ()
|
|
385
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Link parser should match quoted text but not button syntax
|
|
386
|
-
}
|
|
387
|
-
})
|
|
388
|
-
|
|
389
|
-
test("handles position information correctly", t => {
|
|
390
|
-
let customPos = Types.Position.make(20, 35)
|
|
391
|
-
let result = LinkParser.parse("\"Test\"", customPos, testBounds)
|
|
392
|
-
|
|
393
|
-
switch result {
|
|
394
|
-
| Some(Types.Link({position})) => {
|
|
395
|
-
t->expect(position.row)->Expect.toBe(20)
|
|
396
|
-
t->expect(position.col)->Expect.toBe(35)
|
|
397
|
-
}
|
|
398
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
|
|
399
|
-
}
|
|
400
|
-
})
|
|
401
|
-
})
|
|
402
|
-
})
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
|
|
3
|
-
import * as Types from "../../../Core/Types.mjs";
|
|
4
|
-
import * as Vitest from "rescript-vitest/src/Vitest.mjs";
|
|
5
|
-
import * as TextParser from "../TextParser.mjs";
|
|
6
|
-
|
|
7
|
-
let parser = TextParser.make();
|
|
8
|
-
|
|
9
|
-
function makePosition(row, col) {
|
|
10
|
-
return Types.Position.make(row, col);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function makeBounds(top, left, bottom, right) {
|
|
14
|
-
return {
|
|
15
|
-
top: top,
|
|
16
|
-
left: left,
|
|
17
|
-
bottom: bottom,
|
|
18
|
-
right: right
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
Vitest.describe("TextParser", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, () => {
|
|
23
|
-
Vitest.describe("priority", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, () => Vitest.test("should have lowest priority (1)", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => t.expect(parser.priority).toBe(1)));
|
|
24
|
-
Vitest.describe("canParse", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, () => {
|
|
25
|
-
Vitest.test("should always return true for any content", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => t.expect(parser.canParse("hello world")).toBe(true));
|
|
26
|
-
Vitest.test("should return true for empty string", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => t.expect(parser.canParse("")).toBe(true));
|
|
27
|
-
Vitest.test("should return true for special characters", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => t.expect(parser.canParse("!@#$%^&*()")).toBe(true));
|
|
28
|
-
Vitest.test("should return true for numbers", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => t.expect(parser.canParse("12345")).toBe(true));
|
|
29
|
-
Vitest.test("should return true for content that looks like other elements", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
|
|
30
|
-
t.expect(parser.canParse("[ Button ]")).toBe(true);
|
|
31
|
-
t.expect(parser.canParse("#input")).toBe(true);
|
|
32
|
-
t.expect(parser.canParse("\"Link\"")).toBe(true);
|
|
33
|
-
t.expect(parser.canParse("[x] Checkbox")).toBe(true);
|
|
34
|
-
t.expect(parser.canParse("* Emphasis")).toBe(true);
|
|
35
|
-
});
|
|
36
|
-
Vitest.test("should return true for whitespace-only content", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
|
|
37
|
-
t.expect(parser.canParse(" ")).toBe(true);
|
|
38
|
-
t.expect(parser.canParse("\t")).toBe(true);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
Vitest.describe("parse", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, () => {
|
|
42
|
-
let pos = Types.Position.make(5, 10);
|
|
43
|
-
let bounds = {
|
|
44
|
-
top: 0,
|
|
45
|
-
left: 0,
|
|
46
|
-
bottom: 10,
|
|
47
|
-
right: 20
|
|
48
|
-
};
|
|
49
|
-
Vitest.test("should parse plain text content", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
|
|
50
|
-
let result = parser.parse("Hello World", pos, bounds);
|
|
51
|
-
if (result === undefined) {
|
|
52
|
-
return t.expect(true).toBe(false);
|
|
53
|
-
}
|
|
54
|
-
if (result.TAG !== "Text") {
|
|
55
|
-
return t.expect(true).toBe(false);
|
|
56
|
-
}
|
|
57
|
-
t.expect(result.content).toBe("Hello World");
|
|
58
|
-
t.expect(result.emphasis).toBe(false);
|
|
59
|
-
t.expect(result.position).toEqual(pos);
|
|
60
|
-
t.expect(result.align).toBe("Left");
|
|
61
|
-
});
|
|
62
|
-
Vitest.test("should set emphasis to false by default", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
|
|
63
|
-
let result = parser.parse("Some text", pos, bounds);
|
|
64
|
-
if (result !== undefined && result.TAG === "Text") {
|
|
65
|
-
return t.expect(result.emphasis).toBe(false);
|
|
66
|
-
} else {
|
|
67
|
-
return t.expect(true).toBe(false);
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
Vitest.test("should preserve the exact content without modification", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
|
|
71
|
-
let testCases = [
|
|
72
|
-
"plain text",
|
|
73
|
-
" whitespace preserved ",
|
|
74
|
-
"UPPERCASE",
|
|
75
|
-
"123numbers",
|
|
76
|
-
"special!@#chars",
|
|
77
|
-
""
|
|
78
|
-
];
|
|
79
|
-
testCases.forEach(content => {
|
|
80
|
-
let result = parser.parse(content, pos, bounds);
|
|
81
|
-
if (result !== undefined && result.TAG === "Text") {
|
|
82
|
-
return t.expect(result.content).toBe(content);
|
|
83
|
-
} else {
|
|
84
|
-
return t.expect(true).toBe(false);
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
Vitest.test("should capture unrecognized patterns", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
|
|
89
|
-
let unrecognizedPatterns = [
|
|
90
|
-
"This is just text",
|
|
91
|
-
"No special syntax here",
|
|
92
|
-
"Random content 123",
|
|
93
|
-
"Unmatched [ bracket",
|
|
94
|
-
"Partial #",
|
|
95
|
-
"Quote without end\""
|
|
96
|
-
];
|
|
97
|
-
unrecognizedPatterns.forEach(content => {
|
|
98
|
-
let result = parser.parse(content, pos, bounds);
|
|
99
|
-
if (result !== undefined && result.TAG === "Text") {
|
|
100
|
-
return;
|
|
101
|
-
} else {
|
|
102
|
-
return t.expect(true).toBe(false);
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
Vitest.test("should use provided position", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
|
|
107
|
-
let customPos = Types.Position.make(42, 17);
|
|
108
|
-
let result = parser.parse("test", customPos, bounds);
|
|
109
|
-
if (result === undefined) {
|
|
110
|
-
return t.expect(true).toBe(false);
|
|
111
|
-
}
|
|
112
|
-
if (result.TAG !== "Text") {
|
|
113
|
-
return t.expect(true).toBe(false);
|
|
114
|
-
}
|
|
115
|
-
let position = result.position;
|
|
116
|
-
t.expect(position.row).toBe(42);
|
|
117
|
-
t.expect(position.col).toBe(17);
|
|
118
|
-
});
|
|
119
|
-
Vitest.test("should always use Left alignment for fallback text", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
|
|
120
|
-
let result = parser.parse("centered text", pos, bounds);
|
|
121
|
-
if (result !== undefined && result.TAG === "Text") {
|
|
122
|
-
return t.expect(result.align).toBe("Left");
|
|
123
|
-
} else {
|
|
124
|
-
return t.expect(true).toBe(false);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
Vitest.describe("integration with ParserRegistry", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, () => Vitest.test("should act as fallback when no other parser matches", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
|
|
129
|
-
let unknownContent = "This is completely unstructured text";
|
|
130
|
-
let result = parser.parse(unknownContent, Types.Position.make(0, 0), {
|
|
131
|
-
top: 0,
|
|
132
|
-
left: 0,
|
|
133
|
-
bottom: 10,
|
|
134
|
-
right: 50
|
|
135
|
-
});
|
|
136
|
-
if (result !== undefined && result.TAG === "Text") {
|
|
137
|
-
return t.expect(result.content).toBe(unknownContent);
|
|
138
|
-
} else {
|
|
139
|
-
return t.expect(true).toBe(false);
|
|
140
|
-
}
|
|
141
|
-
}));
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
export {
|
|
145
|
-
parser,
|
|
146
|
-
makePosition,
|
|
147
|
-
makeBounds,
|
|
148
|
-
}
|
|
149
|
-
/* parser Not a pure module */
|