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,650 +0,0 @@
|
|
|
1
|
-
// Core Types Test Suite
|
|
2
|
-
// Tests for all type definitions and their behavior
|
|
3
|
-
|
|
4
|
-
open Vitest
|
|
5
|
-
open Types
|
|
6
|
-
|
|
7
|
-
describe("Types - cellChar variant", () => {
|
|
8
|
-
test("Corner variant can be created", t => {
|
|
9
|
-
let cell = Corner
|
|
10
|
-
t->expect(cell)->Expect.toBe(Corner)
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
test("HLine variant can be created", t => {
|
|
14
|
-
let cell = HLine
|
|
15
|
-
t->expect(cell)->Expect.toBe(HLine)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
test("VLine variant can be created", t => {
|
|
19
|
-
let cell = VLine
|
|
20
|
-
t->expect(cell)->Expect.toBe(VLine)
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
test("Divider variant can be created", t => {
|
|
24
|
-
let cell: cellChar = Divider
|
|
25
|
-
t->expect(cell)->Expect.toBe(Divider)
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
test("Space variant can be created", t => {
|
|
29
|
-
let cell = Space
|
|
30
|
-
t->expect(cell)->Expect.toBe(Space)
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
test("Char variant can be created with content", t => {
|
|
34
|
-
let cell = Char("a")
|
|
35
|
-
t->expect(cell)->Expect.toEqual(Char("a"))
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
test("cellChar variants are distinct", t => {
|
|
39
|
-
let divider: cellChar = Divider
|
|
40
|
-
t->expect(Corner)->Expect.not->Expect.toBe(HLine)
|
|
41
|
-
t->expect(HLine)->Expect.not->Expect.toBe(VLine)
|
|
42
|
-
t->expect(VLine)->Expect.not->Expect.toBe(divider)
|
|
43
|
-
t->expect(divider)->Expect.not->Expect.toBe(Space)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
test("Char variant with different content are distinct", t => {
|
|
47
|
-
t->expect(Char("a"))->Expect.not->Expect.toEqual(Char("b"))
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
test("pattern matching on cellChar works", t => {
|
|
51
|
-
let classify = cell =>
|
|
52
|
-
switch cell {
|
|
53
|
-
| Corner => "corner"
|
|
54
|
-
| HLine => "hline"
|
|
55
|
-
| VLine => "vline"
|
|
56
|
-
| Divider => "divider"
|
|
57
|
-
| Space => "space"
|
|
58
|
-
| Char(_) => "char"
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
t->expect(classify(Corner))->Expect.toBe("corner")
|
|
62
|
-
t->expect(classify(HLine))->Expect.toBe("hline")
|
|
63
|
-
t->expect(classify(VLine))->Expect.toBe("vline")
|
|
64
|
-
t->expect(classify(Divider))->Expect.toBe("divider")
|
|
65
|
-
t->expect(classify(Space))->Expect.toBe("space")
|
|
66
|
-
t->expect(classify(Char("x")))->Expect.toBe("char")
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
test("extracting content from Char variant", t => {
|
|
70
|
-
let cell = Char("hello")
|
|
71
|
-
switch cell {
|
|
72
|
-
| Char(content) => t->expect(content)->Expect.toBe("hello")
|
|
73
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Char variant
|
|
74
|
-
}
|
|
75
|
-
})
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
describe("Types - alignment variant", () => {
|
|
79
|
-
test("Left alignment can be created", t => {
|
|
80
|
-
let align = Left
|
|
81
|
-
t->expect(align)->Expect.toBe(Left)
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
test("Center alignment can be created", t => {
|
|
85
|
-
let align = Center
|
|
86
|
-
t->expect(align)->Expect.toBe(Center)
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
test("Right alignment can be created", t => {
|
|
90
|
-
let align = Right
|
|
91
|
-
t->expect(align)->Expect.toBe(Right)
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
test("alignment variants are distinct", t => {
|
|
95
|
-
t->expect(Left)->Expect.not->Expect.toBe(Center)
|
|
96
|
-
t->expect(Center)->Expect.not->Expect.toBe(Right)
|
|
97
|
-
t->expect(Right)->Expect.not->Expect.toBe(Left)
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
test("pattern matching on alignment works", t => {
|
|
101
|
-
let toString = align =>
|
|
102
|
-
switch align {
|
|
103
|
-
| Left => "left"
|
|
104
|
-
| Center => "center"
|
|
105
|
-
| Right => "right"
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
t->expect(toString(Left))->Expect.toBe("left")
|
|
109
|
-
t->expect(toString(Center))->Expect.toBe("center")
|
|
110
|
-
t->expect(toString(Right))->Expect.toBe("right")
|
|
111
|
-
})
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
describe("Types - position record", () => {
|
|
115
|
-
test("position can be created", t => {
|
|
116
|
-
let pos: Position.t = {row: 5, col: 10}
|
|
117
|
-
t->expect(pos.row)->Expect.toBe(5)
|
|
118
|
-
t->expect(pos.col)->Expect.toBe(10)
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
test("position equality", t => {
|
|
122
|
-
let pos1: Position.t = {row: 5, col: 10}
|
|
123
|
-
let pos2: Position.t = {row: 5, col: 10}
|
|
124
|
-
t->expect(pos1)->Expect.toEqual(pos2)
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
test("position inequality", t => {
|
|
128
|
-
let pos1: Position.t = {row: 5, col: 10}
|
|
129
|
-
let pos2: Position.t = {row: 5, col: 11}
|
|
130
|
-
t->expect(pos1)->Expect.not->Expect.toEqual(pos2)
|
|
131
|
-
})
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
describe("Types - bounds record", () => {
|
|
135
|
-
test("bounds can be created", t => {
|
|
136
|
-
let b: Bounds.t = {top: 0, left: 0, bottom: 10, right: 20}
|
|
137
|
-
t->expect(b.top)->Expect.toBe(0)
|
|
138
|
-
t->expect(b.left)->Expect.toBe(0)
|
|
139
|
-
t->expect(b.bottom)->Expect.toBe(10)
|
|
140
|
-
t->expect(b.right)->Expect.toBe(20)
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
test("bounds equality", t => {
|
|
144
|
-
let b1: Bounds.t = {top: 0, left: 0, bottom: 10, right: 20}
|
|
145
|
-
let b2: Bounds.t = {top: 0, left: 0, bottom: 10, right: 20}
|
|
146
|
-
t->expect(b1)->Expect.toEqual(b2)
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
test("bounds inequality", t => {
|
|
150
|
-
let b1: Bounds.t = {top: 0, left: 0, bottom: 10, right: 20}
|
|
151
|
-
let b2: Bounds.t = {top: 0, left: 0, bottom: 11, right: 20}
|
|
152
|
-
t->expect(b1)->Expect.not->Expect.toEqual(b2)
|
|
153
|
-
})
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
describe("Types - element variant", () => {
|
|
157
|
-
test("Box element can be created", t => {
|
|
158
|
-
let box = Box({
|
|
159
|
-
name: Some("Login"),
|
|
160
|
-
bounds: {top: 0, left: 0, bottom: 10, right: 20},
|
|
161
|
-
children: [],
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
switch box {
|
|
165
|
-
| Box({name}) =>
|
|
166
|
-
switch name {
|
|
167
|
-
| Some(n) => t->expect(n)->Expect.toBe("Login")
|
|
168
|
-
| None => t->expect(true)->Expect.toBe(false) // fail: Expected Some name
|
|
169
|
-
}
|
|
170
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Box variant
|
|
171
|
-
}
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
test("Box element with no name", t => {
|
|
175
|
-
let box = Box({
|
|
176
|
-
name: None,
|
|
177
|
-
bounds: {top: 0, left: 0, bottom: 10, right: 20},
|
|
178
|
-
children: [],
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
switch box {
|
|
182
|
-
| Box({name}) => t->expect(name)->Expect.toBe(None)
|
|
183
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Box variant
|
|
184
|
-
}
|
|
185
|
-
})
|
|
186
|
-
|
|
187
|
-
test("Button element can be created", t => {
|
|
188
|
-
let button = Button({
|
|
189
|
-
id: "submit",
|
|
190
|
-
text: "Submit",
|
|
191
|
-
position: {row: 5, col: 10},
|
|
192
|
-
align: Center,
|
|
193
|
-
actions: [],
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
switch button {
|
|
197
|
-
| Button({id, text, align}) => {
|
|
198
|
-
t->expect(id)->Expect.toBe("submit")
|
|
199
|
-
t->expect(text)->Expect.toBe("Submit")
|
|
200
|
-
t->expect(align)->Expect.toBe(Center)
|
|
201
|
-
}
|
|
202
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Button variant
|
|
203
|
-
}
|
|
204
|
-
})
|
|
205
|
-
|
|
206
|
-
test("Input element can be created", t => {
|
|
207
|
-
let input = Input({
|
|
208
|
-
id: "email",
|
|
209
|
-
placeholder: Some("Enter email"),
|
|
210
|
-
position: {row: 3, col: 5},
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
switch input {
|
|
214
|
-
| Input({id, placeholder}) => {
|
|
215
|
-
t->expect(id)->Expect.toBe("email")
|
|
216
|
-
switch placeholder {
|
|
217
|
-
| Some(p) => t->expect(p)->Expect.toBe("Enter email")
|
|
218
|
-
| None => t->expect(true)->Expect.toBe(false) // fail: Expected Some placeholder
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Input variant
|
|
222
|
-
}
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
test("Link element can be created", t => {
|
|
226
|
-
let link = Link({
|
|
227
|
-
id: "forgot-password",
|
|
228
|
-
text: "Forgot Password?",
|
|
229
|
-
position: {row: 8, col: 15},
|
|
230
|
-
align: Right,
|
|
231
|
-
actions: [],
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
switch link {
|
|
235
|
-
| Link({id, text, align}) => {
|
|
236
|
-
t->expect(id)->Expect.toBe("forgot-password")
|
|
237
|
-
t->expect(text)->Expect.toBe("Forgot Password?")
|
|
238
|
-
t->expect(align)->Expect.toBe(Right)
|
|
239
|
-
}
|
|
240
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link variant
|
|
241
|
-
}
|
|
242
|
-
})
|
|
243
|
-
|
|
244
|
-
test("Checkbox element can be created", t => {
|
|
245
|
-
let checkbox = Checkbox({
|
|
246
|
-
checked: true,
|
|
247
|
-
label: "Remember me",
|
|
248
|
-
position: {row: 6, col: 5},
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
switch checkbox {
|
|
252
|
-
| Checkbox({checked, label}) => {
|
|
253
|
-
t->expect(checked)->Expect.toBe(true)
|
|
254
|
-
t->expect(label)->Expect.toBe("Remember me")
|
|
255
|
-
}
|
|
256
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Checkbox variant
|
|
257
|
-
}
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
test("Text element can be created", t => {
|
|
261
|
-
let text = Text({
|
|
262
|
-
content: "Welcome",
|
|
263
|
-
emphasis: false,
|
|
264
|
-
position: {row: 1, col: 5},
|
|
265
|
-
align: Left,
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
switch text {
|
|
269
|
-
| Text({content, emphasis, align}) => {
|
|
270
|
-
t->expect(content)->Expect.toBe("Welcome")
|
|
271
|
-
t->expect(emphasis)->Expect.toBe(false)
|
|
272
|
-
t->expect(align)->Expect.toBe(Left)
|
|
273
|
-
}
|
|
274
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Text variant
|
|
275
|
-
}
|
|
276
|
-
})
|
|
277
|
-
|
|
278
|
-
test("Text element with emphasis", t => {
|
|
279
|
-
let text = Text({
|
|
280
|
-
content: "Important",
|
|
281
|
-
emphasis: true,
|
|
282
|
-
position: {row: 1, col: 5},
|
|
283
|
-
align: Center,
|
|
284
|
-
})
|
|
285
|
-
|
|
286
|
-
switch text {
|
|
287
|
-
| Text({emphasis}) => t->expect(emphasis)->Expect.toBe(true)
|
|
288
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Text variant
|
|
289
|
-
}
|
|
290
|
-
})
|
|
291
|
-
|
|
292
|
-
test("Divider element can be created", t => {
|
|
293
|
-
let divider = Divider({position: {row: 5, col: 0}})
|
|
294
|
-
|
|
295
|
-
switch divider {
|
|
296
|
-
| Divider({position}) => t->expect(position.row)->Expect.toBe(5)
|
|
297
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Divider variant
|
|
298
|
-
}
|
|
299
|
-
})
|
|
300
|
-
|
|
301
|
-
test("Row element can be created", t => {
|
|
302
|
-
let row = Row({
|
|
303
|
-
children: [],
|
|
304
|
-
align: Center,
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
switch row {
|
|
308
|
-
| Row({align}) => t->expect(align)->Expect.toBe(Center)
|
|
309
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Row variant
|
|
310
|
-
}
|
|
311
|
-
})
|
|
312
|
-
|
|
313
|
-
test("Section element can be created", t => {
|
|
314
|
-
let section = Section({
|
|
315
|
-
name: "Header",
|
|
316
|
-
children: [],
|
|
317
|
-
})
|
|
318
|
-
|
|
319
|
-
switch section {
|
|
320
|
-
| Section({name}) => t->expect(name)->Expect.toBe("Header")
|
|
321
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Section variant
|
|
322
|
-
}
|
|
323
|
-
})
|
|
324
|
-
|
|
325
|
-
test("Box can contain nested elements", t => {
|
|
326
|
-
let button = Button({
|
|
327
|
-
id: "submit",
|
|
328
|
-
text: "Submit",
|
|
329
|
-
position: {row: 5, col: 10},
|
|
330
|
-
align: Center,
|
|
331
|
-
actions: [],
|
|
332
|
-
})
|
|
333
|
-
|
|
334
|
-
let box = Box({
|
|
335
|
-
name: Some("Form"),
|
|
336
|
-
bounds: {top: 0, left: 0, bottom: 10, right: 20},
|
|
337
|
-
children: [button],
|
|
338
|
-
})
|
|
339
|
-
|
|
340
|
-
switch box {
|
|
341
|
-
| Box({children}) => t->expect(Array.length(children))->Expect.toBe(1)
|
|
342
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Box variant
|
|
343
|
-
}
|
|
344
|
-
})
|
|
345
|
-
|
|
346
|
-
test("pattern matching on element types", t => {
|
|
347
|
-
let getType = element =>
|
|
348
|
-
switch element {
|
|
349
|
-
| Box(_) => "box"
|
|
350
|
-
| Button(_) => "button"
|
|
351
|
-
| Input(_) => "input"
|
|
352
|
-
| Link(_) => "link"
|
|
353
|
-
| Checkbox(_) => "checkbox"
|
|
354
|
-
| Text(_) => "text"
|
|
355
|
-
| Divider(_) => "divider"
|
|
356
|
-
| Row(_) => "row"
|
|
357
|
-
| Section(_) => "section"
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
t->expect(getType(Box({name: None, bounds: {top: 0, left: 0, bottom: 1, right: 1}, children: []})))->Expect.toBe("box")
|
|
361
|
-
t->expect(getType(Button({id: "b", text: "B", position: {row: 0, col: 0}, align: Left, actions: []})))->Expect.toBe("button")
|
|
362
|
-
t->expect(getType(Input({id: "i", placeholder: None, position: {row: 0, col: 0}})))->Expect.toBe("input")
|
|
363
|
-
t->expect(getType(Link({id: "l", text: "L", position: {row: 0, col: 0}, align: Left, actions: []})))->Expect.toBe("link")
|
|
364
|
-
t->expect(getType(Checkbox({checked: false, label: "C", position: {row: 0, col: 0}})))->Expect.toBe("checkbox")
|
|
365
|
-
t->expect(getType(Text({content: "T", emphasis: false, position: {row: 0, col: 0}, align: Left})))->Expect.toBe("text")
|
|
366
|
-
t->expect(getType(Divider({position: {row: 0, col: 0}})))->Expect.toBe("divider")
|
|
367
|
-
t->expect(getType(Row({children: [], align: Left})))->Expect.toBe("row")
|
|
368
|
-
t->expect(getType(Section({name: "S", children: []})))->Expect.toBe("section")
|
|
369
|
-
})
|
|
370
|
-
})
|
|
371
|
-
|
|
372
|
-
describe("Types - scene record", () => {
|
|
373
|
-
test("scene can be created", t => {
|
|
374
|
-
let scene: scene = {
|
|
375
|
-
id: "login",
|
|
376
|
-
title: "Login Page",
|
|
377
|
-
transition: "fade",
|
|
378
|
-
device: Desktop,
|
|
379
|
-
elements: [],
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
t->expect(scene.id)->Expect.toBe("login")
|
|
383
|
-
t->expect(scene.title)->Expect.toBe("Login Page")
|
|
384
|
-
t->expect(scene.transition)->Expect.toBe("fade")
|
|
385
|
-
t->expect(Array.length(scene.elements))->Expect.toBe(0)
|
|
386
|
-
})
|
|
387
|
-
|
|
388
|
-
test("scene can contain elements", t => {
|
|
389
|
-
let button = Button({
|
|
390
|
-
id: "submit",
|
|
391
|
-
text: "Submit",
|
|
392
|
-
position: {row: 5, col: 10},
|
|
393
|
-
align: Center,
|
|
394
|
-
actions: [],
|
|
395
|
-
})
|
|
396
|
-
|
|
397
|
-
let scene: scene = {
|
|
398
|
-
id: "login",
|
|
399
|
-
title: "Login Page",
|
|
400
|
-
transition: "fade",
|
|
401
|
-
device: Desktop,
|
|
402
|
-
elements: [button],
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
t->expect(Array.length(scene.elements))->Expect.toBe(1)
|
|
406
|
-
})
|
|
407
|
-
|
|
408
|
-
test("scene equality", t => {
|
|
409
|
-
let scene1: scene = {
|
|
410
|
-
id: "login",
|
|
411
|
-
title: "Login",
|
|
412
|
-
transition: "fade",
|
|
413
|
-
device: Desktop,
|
|
414
|
-
elements: [],
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
let scene2: scene = {
|
|
418
|
-
id: "login",
|
|
419
|
-
title: "Login",
|
|
420
|
-
transition: "fade",
|
|
421
|
-
device: Desktop,
|
|
422
|
-
elements: [],
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
t->expect(scene1)->Expect.toEqual(scene2)
|
|
426
|
-
})
|
|
427
|
-
})
|
|
428
|
-
|
|
429
|
-
describe("Types - ast record", () => {
|
|
430
|
-
test("ast can be created with empty scenes", t => {
|
|
431
|
-
let ast = {scenes: []}
|
|
432
|
-
t->expect(Array.length(ast.scenes))->Expect.toBe(0)
|
|
433
|
-
})
|
|
434
|
-
|
|
435
|
-
test("ast can contain multiple scenes", t => {
|
|
436
|
-
let scene1: scene = {
|
|
437
|
-
id: "login",
|
|
438
|
-
title: "Login",
|
|
439
|
-
transition: "fade",
|
|
440
|
-
device: Desktop,
|
|
441
|
-
elements: [],
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
let scene2: scene = {
|
|
445
|
-
id: "home",
|
|
446
|
-
title: "Home",
|
|
447
|
-
transition: "slide",
|
|
448
|
-
device: Desktop,
|
|
449
|
-
elements: [],
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
let ast: ast = {scenes: [scene1, scene2]}
|
|
453
|
-
t->expect(Array.length(ast.scenes))->Expect.toBe(2)
|
|
454
|
-
})
|
|
455
|
-
|
|
456
|
-
test("ast scenes maintain order", t => {
|
|
457
|
-
let scene1: scene = {
|
|
458
|
-
id: "login",
|
|
459
|
-
title: "Login",
|
|
460
|
-
transition: "fade",
|
|
461
|
-
device: Desktop,
|
|
462
|
-
elements: [],
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
let scene2: scene = {
|
|
466
|
-
id: "home",
|
|
467
|
-
title: "Home",
|
|
468
|
-
transition: "slide",
|
|
469
|
-
device: Desktop,
|
|
470
|
-
elements: [],
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
let ast: ast = {scenes: [scene1, scene2]}
|
|
474
|
-
t->expect(Array.getUnsafe(ast.scenes, 0).id)->Expect.toBe("login")
|
|
475
|
-
t->expect(Array.getUnsafe(ast.scenes, 1).id)->Expect.toBe("home")
|
|
476
|
-
})
|
|
477
|
-
})
|
|
478
|
-
|
|
479
|
-
describe("Types - interactionVariant", () => {
|
|
480
|
-
test("Primary variant can be created", t => {
|
|
481
|
-
let variant = Primary
|
|
482
|
-
t->expect(variant)->Expect.toBe(Primary)
|
|
483
|
-
})
|
|
484
|
-
|
|
485
|
-
test("Secondary variant can be created", t => {
|
|
486
|
-
let variant = Secondary
|
|
487
|
-
t->expect(variant)->Expect.toBe(Secondary)
|
|
488
|
-
})
|
|
489
|
-
|
|
490
|
-
test("Ghost variant can be created", t => {
|
|
491
|
-
let variant = Ghost
|
|
492
|
-
t->expect(variant)->Expect.toBe(Ghost)
|
|
493
|
-
})
|
|
494
|
-
|
|
495
|
-
test("pattern matching on interactionVariant", t => {
|
|
496
|
-
let toString = variant =>
|
|
497
|
-
switch variant {
|
|
498
|
-
| Primary => "primary"
|
|
499
|
-
| Secondary => "secondary"
|
|
500
|
-
| Ghost => "ghost"
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
t->expect(toString(Primary))->Expect.toBe("primary")
|
|
504
|
-
t->expect(toString(Secondary))->Expect.toBe("secondary")
|
|
505
|
-
t->expect(toString(Ghost))->Expect.toBe("ghost")
|
|
506
|
-
})
|
|
507
|
-
})
|
|
508
|
-
|
|
509
|
-
describe("Types - interactionAction", () => {
|
|
510
|
-
test("Goto action can be created", t => {
|
|
511
|
-
let action = Goto({
|
|
512
|
-
target: "home",
|
|
513
|
-
transition: "fade",
|
|
514
|
-
condition: Some("isValid"),
|
|
515
|
-
})
|
|
516
|
-
|
|
517
|
-
switch action {
|
|
518
|
-
| Goto({target, transition, condition}) => {
|
|
519
|
-
t->expect(target)->Expect.toBe("home")
|
|
520
|
-
t->expect(transition)->Expect.toBe("fade")
|
|
521
|
-
switch condition {
|
|
522
|
-
| Some(c) => t->expect(c)->Expect.toBe("isValid")
|
|
523
|
-
| None => t->expect(true)->Expect.toBe(false) // fail: Expected Some condition
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Goto variant
|
|
527
|
-
}
|
|
528
|
-
})
|
|
529
|
-
|
|
530
|
-
test("Back action can be created", t => {
|
|
531
|
-
let action = Back
|
|
532
|
-
t->expect(action)->Expect.toBe(Back)
|
|
533
|
-
})
|
|
534
|
-
|
|
535
|
-
test("Forward action can be created", t => {
|
|
536
|
-
let action = Forward
|
|
537
|
-
t->expect(action)->Expect.toBe(Forward)
|
|
538
|
-
})
|
|
539
|
-
|
|
540
|
-
test("Validate action can be created", t => {
|
|
541
|
-
let action = Validate({fields: ["email", "password"]})
|
|
542
|
-
|
|
543
|
-
switch action {
|
|
544
|
-
| Validate({fields}) => {
|
|
545
|
-
t->expect(Array.length(fields))->Expect.toBe(2)
|
|
546
|
-
t->expect(Array.getUnsafe(fields, 0))->Expect.toBe("email")
|
|
547
|
-
t->expect(Array.getUnsafe(fields, 1))->Expect.toBe("password")
|
|
548
|
-
}
|
|
549
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Validate variant
|
|
550
|
-
}
|
|
551
|
-
})
|
|
552
|
-
|
|
553
|
-
test("Call action can be created", t => {
|
|
554
|
-
let action = Call({
|
|
555
|
-
function: "handleSubmit",
|
|
556
|
-
args: ["arg1", "arg2"],
|
|
557
|
-
condition: None,
|
|
558
|
-
})
|
|
559
|
-
|
|
560
|
-
switch action {
|
|
561
|
-
| Call({function, args, condition}) => {
|
|
562
|
-
t->expect(function)->Expect.toBe("handleSubmit")
|
|
563
|
-
t->expect(Array.length(args))->Expect.toBe(2)
|
|
564
|
-
t->expect(condition)->Expect.toBe(None)
|
|
565
|
-
}
|
|
566
|
-
| _ => t->expect(true)->Expect.toBe(false) // fail: Expected Call variant
|
|
567
|
-
}
|
|
568
|
-
})
|
|
569
|
-
|
|
570
|
-
test("pattern matching on interactionAction", t => {
|
|
571
|
-
let getType = action =>
|
|
572
|
-
switch action {
|
|
573
|
-
| Goto(_) => "goto"
|
|
574
|
-
| Back => "back"
|
|
575
|
-
| Forward => "forward"
|
|
576
|
-
| Validate(_) => "validate"
|
|
577
|
-
| Call(_) => "call"
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
t->expect(getType(Goto({target: "x", transition: "y", condition: None})))->Expect.toBe("goto")
|
|
581
|
-
t->expect(getType(Back))->Expect.toBe("back")
|
|
582
|
-
t->expect(getType(Forward))->Expect.toBe("forward")
|
|
583
|
-
t->expect(getType(Validate({fields: []})))->Expect.toBe("validate")
|
|
584
|
-
t->expect(getType(Call({function: "f", args: [], condition: None})))->Expect.toBe("call")
|
|
585
|
-
})
|
|
586
|
-
})
|
|
587
|
-
|
|
588
|
-
describe("Types - interaction record", () => {
|
|
589
|
-
test("interaction can be created", t => {
|
|
590
|
-
let props = Js.Dict.empty()
|
|
591
|
-
Js.Dict.set(props, "variant", Js.Json.string("primary"))
|
|
592
|
-
|
|
593
|
-
let interaction = {
|
|
594
|
-
elementId: "submit-button",
|
|
595
|
-
properties: props,
|
|
596
|
-
actions: [Back],
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
t->expect(interaction.elementId)->Expect.toBe("submit-button")
|
|
600
|
-
t->expect(Array.length(interaction.actions))->Expect.toBe(1)
|
|
601
|
-
})
|
|
602
|
-
|
|
603
|
-
test("interaction with multiple actions", t => {
|
|
604
|
-
let interaction = {
|
|
605
|
-
elementId: "form",
|
|
606
|
-
properties: Js.Dict.empty(),
|
|
607
|
-
actions: [
|
|
608
|
-
Validate({fields: ["email", "password"]}),
|
|
609
|
-
Goto({target: "home", transition: "fade", condition: None}),
|
|
610
|
-
],
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
t->expect(Array.length(interaction.actions))->Expect.toBe(2)
|
|
614
|
-
})
|
|
615
|
-
})
|
|
616
|
-
|
|
617
|
-
describe("Types - sceneInteractions record", () => {
|
|
618
|
-
test("sceneInteractions can be created", t => {
|
|
619
|
-
let sceneInteractions = {
|
|
620
|
-
sceneId: "login",
|
|
621
|
-
interactions: [],
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
t->expect(sceneInteractions.sceneId)->Expect.toBe("login")
|
|
625
|
-
t->expect(Array.length(sceneInteractions.interactions))->Expect.toBe(0)
|
|
626
|
-
})
|
|
627
|
-
|
|
628
|
-
test("sceneInteractions can contain multiple interactions", t => {
|
|
629
|
-
let interaction1 = {
|
|
630
|
-
elementId: "email",
|
|
631
|
-
properties: Js.Dict.empty(),
|
|
632
|
-
actions: [],
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
let interaction2 = {
|
|
636
|
-
elementId: "password",
|
|
637
|
-
properties: Js.Dict.empty(),
|
|
638
|
-
actions: [],
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
let sceneInteractions = {
|
|
642
|
-
sceneId: "login",
|
|
643
|
-
interactions: [interaction1, interaction2],
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
t->expect(Array.length(sceneInteractions.interactions))->Expect.toBe(2)
|
|
647
|
-
t->expect(Array.getUnsafe(sceneInteractions.interactions, 0).elementId)->Expect.toBe("email")
|
|
648
|
-
t->expect(Array.getUnsafe(sceneInteractions.interactions, 1).elementId)->Expect.toBe("password")
|
|
649
|
-
})
|
|
650
|
-
})
|