@quenk/wml 2.13.10 → 2.14.0
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/lib/cli.d.ts +8 -8
- package/lib/cli.js +1 -3
- package/lib/cli.js.map +1 -1
- package/lib/cli.ts +48 -60
- package/lib/compile/codegen.d.ts +4 -9
- package/lib/compile/codegen.js +164 -369
- package/lib/compile/codegen.js.map +1 -1
- package/lib/compile/codegen.ts +644 -952
- package/lib/compile/index.d.ts +2 -2
- package/lib/compile/index.js +4 -4
- package/lib/compile/index.js.map +1 -1
- package/lib/compile/index.ts +14 -17
- package/lib/compile/transform.d.ts +8 -6
- package/lib/compile/transform.js +46 -18
- package/lib/compile/transform.js.map +1 -1
- package/lib/compile/transform.ts +139 -116
- package/lib/{dom.d.ts → dom/index.d.ts} +8 -2
- package/lib/{dom.js → dom/index.js} +84 -66
- package/lib/dom/index.js.map +1 -0
- package/lib/dom/index.ts +425 -0
- package/lib/dom/monitor.d.ts +33 -0
- package/lib/dom/monitor.js +60 -0
- package/lib/dom/monitor.js.map +1 -0
- package/lib/dom/monitor.ts +75 -0
- package/lib/index.d.ts +10 -95
- package/lib/index.js +10 -10
- package/lib/index.js.map +1 -1
- package/lib/index.ts +57 -182
- package/lib/main.js +17 -17
- package/lib/main.js.map +1 -1
- package/lib/main.ts +38 -44
- package/lib/parse/ast.d.ts +12 -6
- package/lib/parse/ast.js +68 -58
- package/lib/parse/ast.js.map +1 -1
- package/lib/parse/ast.ts +400 -482
- package/lib/parse/generated.d.ts +3 -5
- package/lib/parse/generated.js +9504 -9264
- package/lib/parse/index.d.ts +2 -3
- package/lib/parse/index.js.map +1 -1
- package/lib/parse/index.ts +7 -9
- package/lib/parse/test.js +194 -192
- package/lib/parse/test.js.map +1 -1
- package/lib/parse/test.ts +294 -404
- package/lib/parse/wml.y +4 -0
- package/lib/tsconfig.json +19 -20
- package/lib/util.d.ts +10 -0
- package/lib/util.js +21 -0
- package/lib/util.js.map +1 -0
- package/lib/util.ts +39 -0
- package/lib/view/frame.d.ts +103 -0
- package/lib/view/frame.js +206 -0
- package/lib/view/frame.js.map +1 -0
- package/lib/view/frame.ts +249 -0
- package/lib/view/index.d.ts +58 -0
- package/lib/view/index.js +48 -0
- package/lib/view/index.js.map +1 -0
- package/lib/view/index.ts +97 -0
- package/package.json +4 -3
- package/lib/dom.js.map +0 -1
- package/lib/dom.ts +0 -475
package/lib/parse/test.ts
CHANGED
|
@@ -1,132 +1,115 @@
|
|
|
1
1
|
export const tests: { [key: string]: any } = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
'
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
'
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
'
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
'should parse for from statements': {
|
|
78
|
-
|
|
79
|
-
input: `
|
|
2
|
+
"should parse qualified import": {
|
|
3
|
+
input: `{% import * as lib from "path/to/libs" %}`,
|
|
4
|
+
},
|
|
5
|
+
"should parse named import": {
|
|
6
|
+
input: `{% import (B) from "path/to/a/b" %}`,
|
|
7
|
+
},
|
|
8
|
+
"should detect exact duplicate imports": {
|
|
9
|
+
input: `{% import (A) from "b" %} {% import (A) from "b" %}`,
|
|
10
|
+
},
|
|
11
|
+
"should parse a self closing tag": {
|
|
12
|
+
input: "<simple/>",
|
|
13
|
+
},
|
|
14
|
+
"should parse a self closing tag with attributes 0": {
|
|
15
|
+
input: '<user name="xyaa aaz" position={{4|x(20)}} wml:val="test"/>',
|
|
16
|
+
},
|
|
17
|
+
"should parse a self closing tag with attributes 1": {
|
|
18
|
+
input: "<user app:enabled id=24 />",
|
|
19
|
+
},
|
|
20
|
+
"should parse a self closing tag with attributes 2": {
|
|
21
|
+
input: '<user name="xyaa aaz" id="24" align="left"/>',
|
|
22
|
+
},
|
|
23
|
+
"should parse a parent tag": {
|
|
24
|
+
input: "<panel> \n\n\n\n\n\n\n\n\n </panel>",
|
|
25
|
+
},
|
|
26
|
+
"should parse a parent tag with attributes": {
|
|
27
|
+
input: '<panel type="default" size="40" align="left"> </panel>',
|
|
28
|
+
},
|
|
29
|
+
"should parse parent tags with mixed children": {
|
|
30
|
+
input: "<panel> This is my offsprings.<a>Link</a>Hey now! <Input/></panel>",
|
|
31
|
+
},
|
|
32
|
+
"should parse parent tags with tag children (L1)": {
|
|
33
|
+
input: "<panel><a></a></panel>",
|
|
34
|
+
},
|
|
35
|
+
"should parse parent tags with tag children (L2)": {
|
|
36
|
+
input:
|
|
37
|
+
'<panel><a href="link" onclick={{@someting.invoke()}}>' +
|
|
38
|
+
"Click Here</a><table/></panel>",
|
|
39
|
+
},
|
|
40
|
+
"should parse parent tags with tag children (L3)": {
|
|
41
|
+
input:
|
|
42
|
+
'<panel><a href="link">Click Here</a><table/>' +
|
|
43
|
+
'<panel c="22"></panel></panel>',
|
|
44
|
+
},
|
|
45
|
+
"should do it all together now": {
|
|
46
|
+
input:
|
|
47
|
+
'<modal name="mymodal" x="1" y="2">' +
|
|
48
|
+
"<modal-header>My Modal</modal-header>" +
|
|
49
|
+
"<modal-body>" +
|
|
50
|
+
"Creativxity is inhibxited by greed and corruption." +
|
|
51
|
+
"<vote-button/>" +
|
|
52
|
+
"<vote-count source={{@}}/> Votes" +
|
|
53
|
+
'<textarea wml:id="ta" disabled size=32 onchange={{@setText}}>' +
|
|
54
|
+
" Various text" +
|
|
55
|
+
"</textarea>" +
|
|
56
|
+
"</modal-body>" +
|
|
57
|
+
"</modal>",
|
|
58
|
+
},
|
|
59
|
+
"should parse for in statements": {
|
|
60
|
+
input:
|
|
61
|
+
"<root>" +
|
|
62
|
+
"{% for value,key in [] %}" +
|
|
63
|
+
"<stem>{{value}}</stem>" +
|
|
64
|
+
"{% endfor %}" +
|
|
65
|
+
"</root>",
|
|
66
|
+
},
|
|
67
|
+
"should parse for of statements": {
|
|
68
|
+
input:
|
|
69
|
+
"<root>" +
|
|
70
|
+
"{% for value,key of {} %}" +
|
|
71
|
+
"<stem>{{key}} ~ {{value}}</stem>" +
|
|
72
|
+
"{% endfor %}" +
|
|
73
|
+
"</root>",
|
|
74
|
+
},
|
|
75
|
+
"should parse for from statements": {
|
|
76
|
+
input: `
|
|
80
77
|
<root>
|
|
81
78
|
{% for value=1 to 30 %}
|
|
82
79
|
<b>{{value}}</b>
|
|
83
80
|
{% endfor %}
|
|
84
81
|
</root>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
},
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
'should allow filter chaining': {
|
|
117
|
-
|
|
118
|
-
input: '<p>{{ @value | f1 | f2(2) | f3(@value) }}</p>'
|
|
119
|
-
|
|
120
|
-
},
|
|
121
|
-
'should parse if else statements': {
|
|
122
|
-
|
|
123
|
-
input: '<Tag>{% if value %}<text>Text</text>{% else %}<text>else</text>{% endif %}</Tag>'
|
|
124
|
-
|
|
125
|
-
},
|
|
126
|
-
|
|
127
|
-
'should parse if else if statements': {
|
|
128
|
-
|
|
129
|
-
input: `
|
|
82
|
+
`,
|
|
83
|
+
},
|
|
84
|
+
"should parse if then expressions": {
|
|
85
|
+
input: "<Html id={{@id}}>{{ if @check() then a else b }}</Html>",
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
"should parse function expressions": {
|
|
89
|
+
input: "<button onclick={{e -> call(e)}}/>",
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
"should parse function expressions (no args)": {
|
|
93
|
+
input: "<button onclick={{ -> call()}}/>",
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
"should parse calls": {
|
|
97
|
+
input: "<tr>{% for x,i in y %} {{ f(x, i) }} {% endfor %} </tr>",
|
|
98
|
+
},
|
|
99
|
+
"should parse negative numbers": {
|
|
100
|
+
input: "<tag n={{ ( -0.5 + 3) }} m={{(4 + -2)}} g={{ (10 --5) }}/>",
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
"should allow filter chaining": {
|
|
104
|
+
input: "<p>{{ @value | f1 | f2(2) | f3(@value) }}</p>",
|
|
105
|
+
},
|
|
106
|
+
"should parse if else statements": {
|
|
107
|
+
input:
|
|
108
|
+
"<Tag>{% if value %}<text>Text</text>{% else %}<text>else</text>{% endif %}</Tag>",
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
"should parse if else if statements": {
|
|
112
|
+
input: `
|
|
130
113
|
<Tag>
|
|
131
114
|
{% if value %}
|
|
132
115
|
<text>Text</text>
|
|
@@ -135,151 +118,111 @@ export const tests: { [key: string]: any } = {
|
|
|
135
118
|
{% else %}
|
|
136
119
|
no
|
|
137
120
|
{% endif %}
|
|
138
|
-
</Tag
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
'
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
},
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
'should allow for booleans in interpolations': {
|
|
204
|
-
|
|
205
|
-
input: '<bool active={{true}}>{{if fun() then false else true}}</bool>'
|
|
206
|
-
|
|
207
|
-
},
|
|
208
|
-
|
|
209
|
-
'should allow calls on expressions': {
|
|
210
|
-
|
|
211
|
-
input: '<div>{{(content() || bar)(foo)}}</div>'
|
|
212
|
-
|
|
213
|
-
},
|
|
214
|
-
'should allow boolean attribute values': {
|
|
215
|
-
|
|
216
|
-
input: '<tag on=true off=false/>'
|
|
217
|
-
|
|
218
|
-
},
|
|
219
|
-
'[view] should parse typed views': {
|
|
220
|
-
|
|
221
|
-
input: '{% view Main (Context[String]) %} <p>{{@value}}</p>'
|
|
222
|
-
|
|
223
|
-
},
|
|
224
|
-
'[view] should parse typed views with type parameters': {
|
|
225
|
-
|
|
226
|
-
input: '{% view Main [A,B] (Context[A,B]) %} <p>{{@values}}</p>'
|
|
227
|
-
|
|
228
|
-
},
|
|
229
|
-
'[view] should allow the where syntax': `
|
|
121
|
+
</Tag>`,
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
"should parse short fun statements": {
|
|
125
|
+
input: "{% fun vue () = <View/> %}",
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
"should parse short fun statements with arguments": {
|
|
129
|
+
input:
|
|
130
|
+
"{% fun vue (a:String, b:String, c:String) = " +
|
|
131
|
+
"<View a={{a}} b={{b}} c={{c}}/> %}",
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
"should parse short fun statements with type parameters": {
|
|
135
|
+
input: "{% fun vue [A,B:C,C] (a:A, b:B) = " + "{{ (a + b) + c }} %}",
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
"should parse extended fun statements": {
|
|
139
|
+
input: "{% fun vue () %} <View/> {% endfun %}",
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
"should parse extended fun statements with arguments": {
|
|
143
|
+
input:
|
|
144
|
+
"{% fun vue (a:String, b:String, c:String) %}" +
|
|
145
|
+
"<View a={{a}} b={{b}} c={{c}}/> {% endfun %}",
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
"should parse extended fun statements with type parameters": {
|
|
149
|
+
input:
|
|
150
|
+
"{% fun vue [A,B:C,C] (a:A, b:B) %} {{ ((a + b) + c) }} {% endfun %}",
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
"should parse binary expressions": {
|
|
154
|
+
input: "<p>{{(Styles.A + Styles.B)}}</p>",
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
"should parse complicated expressions": {
|
|
158
|
+
input: '<div class={{((Styles.A + " ") + Style.B)}}/>',
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
"should allow for statement as child of fun": {
|
|
162
|
+
input: "{% fun sven () %} {% for a in b %} {{b}} {% endfor %} {% endfun %}",
|
|
163
|
+
},
|
|
164
|
+
"should allow if statement as child of fun": {
|
|
165
|
+
input:
|
|
166
|
+
"{% fun ate (o:Object) %} {% if a %} {{a}} {% else %} {{a}} " +
|
|
167
|
+
"{% endif %} {% endfun %}",
|
|
168
|
+
},
|
|
169
|
+
"should allow for booleans in interpolations": {
|
|
170
|
+
input: "<bool active={{true}}>{{if fun() then false else true}}</bool>",
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
"should allow calls on expressions": {
|
|
174
|
+
input: "<div>{{(content() || bar)(foo)}}</div>",
|
|
175
|
+
},
|
|
176
|
+
"should allow boolean attribute values": {
|
|
177
|
+
input: "<tag on=true off=false/>",
|
|
178
|
+
},
|
|
179
|
+
"[view] should parse typed views": {
|
|
180
|
+
input: "{% view Main (Context[String]) %} <p>{{@value}}</p>",
|
|
181
|
+
},
|
|
182
|
+
"[view] should parse typed views with type parameters": {
|
|
183
|
+
input: "{% view Main [A,B] (Context[A,B]) %} <p>{{@values}}</p>",
|
|
184
|
+
},
|
|
185
|
+
"[view] should allow the where syntax": `
|
|
230
186
|
|
|
231
187
|
{% view HeadView where title: String %}
|
|
232
188
|
<title>{{@title}}</title>
|
|
233
189
|
`,
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
},
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
},
|
|
244
|
-
'[view] should allow multiple inline context imports': {
|
|
245
|
-
|
|
246
|
-
input: `
|
|
190
|
+
"should parse context variables": {
|
|
191
|
+
input: "<Input name={{@level.name}}/>",
|
|
192
|
+
},
|
|
193
|
+
"[view] should allow inline context import": {
|
|
194
|
+
input: '{% view MyView (Context from "./") %} <div>{{@text}}</div>',
|
|
195
|
+
},
|
|
196
|
+
"[view] should allow multiple inline context imports": {
|
|
197
|
+
input: `
|
|
247
198
|
{% view MyView (Context from "./") %} <div>{{@text}}</div>
|
|
248
199
|
{% view YourView (Context from "./") %} <div/>
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
},
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
'should allow context properties as fun application': {
|
|
276
|
-
|
|
277
|
-
input: '<div>{{ <@action()> }}</div>'
|
|
278
|
-
|
|
279
|
-
},
|
|
280
|
-
'should allow view statements after short fun': {
|
|
281
|
-
|
|
282
|
-
input: `
|
|
200
|
+
`,
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
"[view] should allow without context type": {
|
|
204
|
+
input: `{% view TestView %}<b>Test</b>`,
|
|
205
|
+
},
|
|
206
|
+
"should allow construct expression": {
|
|
207
|
+
input: "<TextView android:thing={value=1}>{{Person(@value)}}</TextView>",
|
|
208
|
+
},
|
|
209
|
+
"should allow view construction": {
|
|
210
|
+
input: "<p>{{ <Panel(@)> }}</p>",
|
|
211
|
+
},
|
|
212
|
+
"should allow fun application": {
|
|
213
|
+
input: "<p>{{ <panel(1, 2, 3)> }}</p>",
|
|
214
|
+
},
|
|
215
|
+
"should allow fun application with context": {
|
|
216
|
+
input: "<div>{{ <panel(@,12)> }}</div>",
|
|
217
|
+
},
|
|
218
|
+
"should parse list types": {
|
|
219
|
+
input: "{% fun action [A] (s: String[], a:A[]) = {{ '${s}${a}' }} %}",
|
|
220
|
+
},
|
|
221
|
+
"should allow context properties as fun application": {
|
|
222
|
+
input: "<div>{{ <@action()> }}</div>",
|
|
223
|
+
},
|
|
224
|
+
"should allow view statements after short fun": {
|
|
225
|
+
input: `
|
|
283
226
|
|
|
284
227
|
{% fun template [A] (d: Date[A], o:A, _:String, __:A[]) = {{String(o)}} %}
|
|
285
228
|
|
|
@@ -297,12 +240,10 @@ export const tests: { [key: string]: any } = {
|
|
|
297
240
|
|
|
298
241
|
{% endfor %}
|
|
299
242
|
|
|
300
|
-
</ul
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
input: `
|
|
243
|
+
</ul>`,
|
|
244
|
+
},
|
|
245
|
+
"should allow actual code": {
|
|
246
|
+
input: `
|
|
306
247
|
{% import (Table) from "@quenk/wml-widgets/lib/data/table" %}
|
|
307
248
|
{% import (TextField) from "@quenk/wml-widgets/lib/control/text-field" %}
|
|
308
249
|
{% import (Panel) from "@quenk/wml-widgets/lib/layout/panel" %}
|
|
@@ -352,37 +293,33 @@ export const tests: { [key: string]: any } = {
|
|
|
352
293
|
|
|
353
294
|
{{@children}}
|
|
354
295
|
|
|
355
|
-
</Panel
|
|
356
|
-
|
|
357
|
-
},
|
|
358
|
-
|
|
359
|
-
'should recognize type parameters': {
|
|
360
|
-
|
|
361
|
-
input: '{% fun test[A:String] (a:A) %} {{a}} {% endfun %}'
|
|
296
|
+
</Panel>`,
|
|
297
|
+
},
|
|
362
298
|
|
|
363
|
-
|
|
299
|
+
"should recognize type parameters": {
|
|
300
|
+
input: "{% fun test[A:String] (a:A) %} {{a}} {% endfun %}",
|
|
301
|
+
},
|
|
364
302
|
|
|
365
|
-
|
|
303
|
+
"should allow ifs without elses": {
|
|
304
|
+
input:
|
|
305
|
+
"{% view Test (Object) %}" +
|
|
306
|
+
"<div> {% if (value == true) %} <span/> {% endif %} </div>",
|
|
307
|
+
},
|
|
366
308
|
|
|
367
|
-
|
|
368
|
-
|
|
309
|
+
"should allow else if as final branch": {
|
|
310
|
+
input:
|
|
311
|
+
"{% view Test(Object) %} <div> " +
|
|
312
|
+
'{% if ( show == "span" ) %} <span/> {% else if (show == "div" ) %}' +
|
|
313
|
+
"<div/> {% endif %} </div>",
|
|
314
|
+
},
|
|
369
315
|
|
|
370
|
-
|
|
316
|
+
"[context] should parse constructors":
|
|
317
|
+
"{% context Test where name: String %}",
|
|
371
318
|
|
|
372
|
-
|
|
319
|
+
"[context] should parse generic constructors":
|
|
320
|
+
"{% context Test where table.name: Text[A] %}",
|
|
373
321
|
|
|
374
|
-
|
|
375
|
-
'{% if ( show == "span" ) %} <span/> {% else if (show == "div" ) %}' +
|
|
376
|
-
'<div/> {% endif %} </div>'
|
|
377
|
-
|
|
378
|
-
},
|
|
379
|
-
|
|
380
|
-
'[context] should parse constructors': '{% context Test where name: String %}',
|
|
381
|
-
|
|
382
|
-
'[context] should parse generic constructors':
|
|
383
|
-
'{% context Test where table.name: Text[A] %}',
|
|
384
|
-
|
|
385
|
-
'[context] should parse record types': `{% context Test[A] where
|
|
322
|
+
"[context] should parse record types": `{% context Test[A] where
|
|
386
323
|
|
|
387
324
|
table.data.record: {
|
|
388
325
|
|
|
@@ -392,89 +329,62 @@ export const tests: { [key: string]: any } = {
|
|
|
392
329
|
}
|
|
393
330
|
%}`,
|
|
394
331
|
|
|
395
|
-
|
|
396
|
-
`{% context Test[A] where table.data.list: A[] %}`,
|
|
332
|
+
"[context] should parse list types": `{% context Test[A] where table.data.list: A[] %}`,
|
|
397
333
|
|
|
398
|
-
|
|
399
|
-
`{% context Test[A,B] where table.data.list2: A[][] %}`,
|
|
334
|
+
"[context] should parse 2d list types": `{% context Test[A,B] where table.data.list2: A[][] %}`,
|
|
400
335
|
|
|
401
|
-
|
|
402
|
-
`{% context Test[A, B, C] where table.data.list3: A[][][] %}`,
|
|
336
|
+
"[context] should parse 3d list types": `{% context Test[A, B, C] where table.data.list3: A[][][] %}`,
|
|
403
337
|
|
|
404
|
-
|
|
405
|
-
`{% context Test where value: Test -> Number %}`,
|
|
338
|
+
"[context] should parse func with no args or parens": `{% context Test where value: Test -> Number %}`,
|
|
406
339
|
|
|
407
|
-
|
|
408
|
-
`{% context Test where value: () -> Number %}`,
|
|
340
|
+
"[context] should parse func with no args": `{% context Test where value: () -> Number %}`,
|
|
409
341
|
|
|
410
|
-
|
|
411
|
-
`{% context Test where value: String -> String %}`,
|
|
342
|
+
"[context] should parse no-parens func with constructor": `{% context Test where value: String -> String %}`,
|
|
412
343
|
|
|
413
|
-
|
|
414
|
-
`{% context Test where value: Text[A] -> Text[A] %}`,
|
|
344
|
+
"[context] should parse no-parens func with generic constructor": `{% context Test where value: Text[A] -> Text[A] %}`,
|
|
415
345
|
|
|
416
|
-
|
|
417
|
-
`{% context Test where value: {} -> { } %}`,
|
|
346
|
+
"[context] should parse no-parens func with record arg": `{% context Test where value: {} -> { } %}`,
|
|
418
347
|
|
|
419
|
-
|
|
420
|
-
`{% context Test where value: String[] -> String[] %}`,
|
|
348
|
+
"[context] should parse no-parens func with list arg": `{% context Test where value: String[] -> String[] %}`,
|
|
421
349
|
|
|
422
|
-
|
|
423
|
-
`{% context Test where value: (String) -> String %}`,
|
|
350
|
+
"[context] should parse func with cons arg": `{% context Test where value: (String) -> String %}`,
|
|
424
351
|
|
|
425
|
-
|
|
426
|
-
`{% context Test where value: (String, String) -> String %}`,
|
|
352
|
+
"[context] should parse func with 2 cons args": `{% context Test where value: (String, String) -> String %}`,
|
|
427
353
|
|
|
428
|
-
|
|
429
|
-
`{% context Test where value: (String, String, String) -> String %}`,
|
|
354
|
+
"[context] should parse func with 3 cons args": `{% context Test where value: (String, String, String) -> String %}`,
|
|
430
355
|
|
|
431
|
-
|
|
432
|
-
`{% context Test[A] where value: (Text[A]) -> Text[A] %}`,
|
|
356
|
+
"[context] should parse func with generic cons arg": `{% context Test[A] where value: (Text[A]) -> Text[A] %}`,
|
|
433
357
|
|
|
434
|
-
|
|
435
|
-
`{% context Test[A] where value: (Text[A], Text[A]) -> Text[A] %}`,
|
|
358
|
+
"[context] should parse func with 2 generic cons args": `{% context Test[A] where value: (Text[A], Text[A]) -> Text[A] %}`,
|
|
436
359
|
|
|
437
|
-
|
|
438
|
-
`{% context Test[A] where value: (Text[A], Text[A], Text[A]) -> Text[A] %}`,
|
|
360
|
+
"[context] should parse func with 3 generic cons args": `{% context Test[A] where value: (Text[A], Text[A], Text[A]) -> Text[A] %}`,
|
|
439
361
|
|
|
440
|
-
|
|
441
|
-
`{% context Test where value: ({ }) -> { } %}`,
|
|
362
|
+
"[context] should parse func with record arg": `{% context Test where value: ({ }) -> { } %}`,
|
|
442
363
|
|
|
443
|
-
|
|
444
|
-
`{% context Test where value: ({ }, { name: String }) -> { } %}`,
|
|
364
|
+
"[context] should parse func with 2 record args": `{% context Test where value: ({ }, { name: String }) -> { } %}`,
|
|
445
365
|
|
|
446
|
-
|
|
447
|
-
`{% context Test where value: ({ }, { name: String }, { value: A[]}) -> { } %}`,
|
|
366
|
+
"[context] should parse func with 3 record args": `{% context Test where value: ({ }, { name: String }, { value: A[]}) -> { } %}`,
|
|
448
367
|
|
|
449
|
-
|
|
450
|
-
`{% context Test where value: (String[]) -> String[] %}`,
|
|
368
|
+
"[context] should parse func with list arg": `{% context Test where value: (String[]) -> String[] %}`,
|
|
451
369
|
|
|
452
|
-
|
|
453
|
-
`{% context Test where value: (String[], String[]) -> String[] %}`,
|
|
370
|
+
"[context] should parse func with 2 list args": `{% context Test where value: (String[], String[]) -> String[] %}`,
|
|
454
371
|
|
|
455
|
-
|
|
456
|
-
`{% context Test where value: (String[], String[], String[]) -> String[] %}`,
|
|
372
|
+
"[context] should parse func with 3 list args": `{% context Test where value: (String[], String[], String[]) -> String[] %}`,
|
|
457
373
|
|
|
458
|
-
|
|
459
|
-
`{% context Test where value: (String -> String) -> String %}`,
|
|
374
|
+
"[context] should parse func with func arg": `{% context Test where value: (String -> String) -> String %}`,
|
|
460
375
|
|
|
461
|
-
|
|
462
|
-
`{% context Test where value: ((String -> String), (String -> String)) -> String %}`,
|
|
376
|
+
"[context] should parse func with 2 func args": `{% context Test where value: ((String -> String), (String -> String)) -> String %}`,
|
|
463
377
|
|
|
464
|
-
|
|
465
|
-
`{% context Test where
|
|
378
|
+
"[context] should parse func with 3 func args": `{% context Test where
|
|
466
379
|
value: ((String -> String), (String -> String), (String -> String)) -> String
|
|
467
380
|
%}`,
|
|
468
381
|
|
|
469
|
-
|
|
470
|
-
`{% context Test[A] where value: Number -> Text[A][] %}`,
|
|
471
|
-
|
|
472
|
-
'[context] should parse funct that return array of array':
|
|
473
|
-
`{% context Test where value: String -> Number[][] %}`,
|
|
382
|
+
"[context] should parse func that return array of generic type": `{% context Test[A] where value: Number -> Text[A][] %}`,
|
|
474
383
|
|
|
475
|
-
|
|
384
|
+
"[context] should parse funct that return array of array": `{% context Test where value: String -> Number[][] %}`,
|
|
476
385
|
|
|
477
|
-
|
|
386
|
+
"[context] should parse context definitions": {
|
|
387
|
+
input: `{% context Manager[A] where
|
|
478
388
|
|
|
479
389
|
name: String,
|
|
480
390
|
|
|
@@ -537,13 +447,11 @@ export const tests: { [key: string]: any } = {
|
|
|
537
447
|
funcRetMultiArray: String -> Number[][]
|
|
538
448
|
|
|
539
449
|
|
|
540
|
-
%}
|
|
541
|
-
|
|
542
|
-
},
|
|
450
|
+
%} `,
|
|
451
|
+
},
|
|
543
452
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
input: `{% context AContract where
|
|
453
|
+
"[context] should allow optional properties": {
|
|
454
|
+
input: `{% context AContract where
|
|
547
455
|
|
|
548
456
|
id?: Number,
|
|
549
457
|
|
|
@@ -553,13 +461,11 @@ export const tests: { [key: string]: any } = {
|
|
|
553
461
|
|
|
554
462
|
name.last?: String
|
|
555
463
|
|
|
556
|
-
%}
|
|
557
|
-
|
|
558
|
-
},
|
|
559
|
-
|
|
560
|
-
'[context] should allow extending': {
|
|
464
|
+
%}`,
|
|
465
|
+
},
|
|
561
466
|
|
|
562
|
-
|
|
467
|
+
"[context] should allow extending": {
|
|
468
|
+
input: `{% context AContract where :BContract %}
|
|
563
469
|
{% context CContract where :AContract, :BContract %}
|
|
564
470
|
{% context DContract[Type] where :CContract, member: Type %}
|
|
565
471
|
{% context EContract[A,B,C,D] where
|
|
@@ -570,25 +476,21 @@ export const tests: { [key: string]: any } = {
|
|
|
570
476
|
member1: B,
|
|
571
477
|
member2: C
|
|
572
478
|
%}
|
|
573
|
-
{% context DContract where :AContract, member: DType %}
|
|
574
|
-
|
|
479
|
+
{% context DContract where :AContract, member: DType %}`,
|
|
480
|
+
},
|
|
575
481
|
|
|
576
|
-
|
|
577
|
-
`{% context Paper where object."type"?: String %}`,
|
|
482
|
+
"[context] should mark nested properties as optional if all are": `{% context Paper where object."type"?: String %}`,
|
|
578
483
|
|
|
579
|
-
|
|
580
|
-
`{% type Type = String | Number | Boolean | Type[] | Type -> Type %}`,
|
|
484
|
+
"should parse type statements": `{% type Type = String | Number | Boolean | Type[] | Type -> Type %}`,
|
|
581
485
|
|
|
582
|
-
|
|
486
|
+
"should parse tupe types": `{% type Tuple = [Number, String, Number] %}`,
|
|
583
487
|
|
|
584
|
-
|
|
585
|
-
'<Panel onClick={{ \e -> foo(e) as User }} />',
|
|
488
|
+
"should parse type assertion": "<Panel onClick={{ \e -> foo(e) as User }} />",
|
|
586
489
|
|
|
587
|
-
|
|
588
|
-
|
|
490
|
+
"should parse partial application in expression":
|
|
491
|
+
"<Link ww:text={{truncate(50)(@text)}} />",
|
|
589
492
|
|
|
590
|
-
|
|
591
|
-
`<div>
|
|
493
|
+
"should transform special primitives": `<div>
|
|
592
494
|
{% for kind in [
|
|
593
495
|
String,
|
|
594
496
|
Boolean,
|
|
@@ -603,7 +505,7 @@ export const tests: { [key: string]: any } = {
|
|
|
603
505
|
{% endfor %}
|
|
604
506
|
</div>`,
|
|
605
507
|
|
|
606
|
-
|
|
508
|
+
"should allow casting": `
|
|
607
509
|
{% view Test (Object) %}
|
|
608
510
|
<Widget
|
|
609
511
|
val1={{String(@value)}}
|
|
@@ -611,70 +513,59 @@ export const tests: { [key: string]: any } = {
|
|
|
611
513
|
val3={{Boolean(@value)}} />
|
|
612
514
|
`,
|
|
613
515
|
|
|
614
|
-
|
|
615
|
-
`<div>{% if value ?? true %}<b>True</b>{% else %}<b>False</b>{% endif %}</div>`,
|
|
516
|
+
"should parse nullish operator": `<div>{% if value ?? true %}<b>True</b>{% else %}<b>False</b>{% endif %}</div>`,
|
|
616
517
|
|
|
617
|
-
|
|
618
|
-
`<div>{% if (value?.val) ?? 1 %}<b>True</b>{% else %}<b>False</b>{% endif %}</div>`,
|
|
518
|
+
"should parse optional chain operator": `<div>{% if (value?.val) ?? 1 %}<b>True</b>{% else %}<b>False</b>{% endif %}</div>`,
|
|
619
519
|
|
|
620
|
-
|
|
621
|
-
`{% let head:HeadCtx = {title = "Foo"} %}
|
|
520
|
+
"[let] should parse let statements": `{% let head:HeadCtx = {title = "Foo"} %}
|
|
622
521
|
{% let head2:HeadCtx = {title = "My Title"} %}
|
|
623
522
|
`,
|
|
624
523
|
|
|
625
|
-
|
|
524
|
+
"[let] should be usable in a view": `
|
|
626
525
|
{% view MyView(Object) %}
|
|
627
526
|
{% let head:HeadViewContext = {title = "My Title"} %}
|
|
628
527
|
<h1>{{<HeadView(head)>}}</h1>
|
|
629
528
|
`,
|
|
630
529
|
|
|
631
|
-
|
|
530
|
+
"[comment] should parse html comments": `<!-- This is an html comment. -->`,
|
|
632
531
|
|
|
633
|
-
|
|
532
|
+
"[comment] should parse wml comments": `{# This is a wml comment #}`,
|
|
634
533
|
|
|
635
|
-
|
|
636
|
-
`{% view Name {# This is a comment! #} (Object) %} <div/> %}`,
|
|
534
|
+
"[comment] should parse wml comments in statements": `{% view Name {# This is a comment! #} (Object) %} <div/> %}`,
|
|
637
535
|
|
|
638
|
-
|
|
536
|
+
"[fun] should parse multi dimensional array parameters": `
|
|
639
537
|
{% fun test (value:List[][]) %}<p/>{% endfun %}`,
|
|
640
538
|
|
|
641
|
-
|
|
642
|
-
`{% view Test (Object) %}
|
|
539
|
+
"should allow index access on context properties": `{% view Test (Object) %}
|
|
643
540
|
<div>
|
|
644
541
|
{% if @["type"] == 1 %}
|
|
645
542
|
<div/>
|
|
646
543
|
{% endif %}
|
|
647
544
|
</div>`,
|
|
648
545
|
|
|
649
|
-
|
|
546
|
+
"should allow paths to use brackets": `
|
|
650
547
|
{% view Test (Object) %}
|
|
651
548
|
<div>
|
|
652
549
|
{% if @values.controls["@type"] %} value {% endif %}
|
|
653
550
|
{% if @values.controls["@type"].value %} value {% endif %}
|
|
654
551
|
</div>`,
|
|
655
552
|
|
|
656
|
-
|
|
657
|
-
`<div>{% for item in our."items" %} <div/>{% endfor %}</div> `,
|
|
553
|
+
"should allow 2nd level bracket access": `<div>{% for item in our."items" %} <div/>{% endfor %}</div> `,
|
|
658
554
|
|
|
659
|
-
|
|
660
|
-
`<div>{% if item."type" == 1 %}<p/>{% endif %}</div>`,
|
|
555
|
+
"should allow type to be used in if statement expression": `<div>{% if item."type" == 1 %}<p/>{% endif %}</div>`,
|
|
661
556
|
|
|
662
|
-
|
|
663
|
-
`<Panel wml:attrs={{@panelAttrs}}><div wml:attrs={{divAttrs}}/></Panel>`,
|
|
557
|
+
"should support the special wml:attrs attribute": `<Panel wml:attrs={{@panelAttrs}}><div wml:attrs={{divAttrs}}/></Panel>`,
|
|
664
558
|
|
|
665
|
-
|
|
666
|
-
`<div>
|
|
559
|
+
"should parse widgets with type arguments": `<div>
|
|
667
560
|
<Panel[Text]>
|
|
668
561
|
<PanelHeader[Text] wml:id="header"/>
|
|
669
562
|
<PanelBody/>
|
|
670
563
|
</Panel>
|
|
671
564
|
</div>`,
|
|
672
565
|
|
|
673
|
-
|
|
674
|
-
`<div>{{<Panel[Text](@)>}}</div>`,
|
|
566
|
+
"should parse view construction with type arguments": `<div>{{<Panel[Text](@)>}}</div>`,
|
|
675
567
|
|
|
676
|
-
|
|
677
|
-
`{% view TestView (Object) %}
|
|
568
|
+
"should use createElementNS() recursively for xmlns attribute": `{% view TestView (Object) %}
|
|
678
569
|
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
|
679
570
|
<path
|
|
680
571
|
fill="none"
|
|
@@ -690,6 +581,5 @@ export const tests: { [key: string]: any } = {
|
|
|
690
581
|
m-20,10 h 10
|
|
691
582
|
m-20,10 h 10
|
|
692
583
|
m-20,10 h 10" />
|
|
693
|
-
</svg
|
|
694
|
-
|
|
695
|
-
}
|
|
584
|
+
</svg>`,
|
|
585
|
+
};
|