openpuppet-language 2.0__py3-none-any.whl
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.
- openpuppet_language-2.0.data/data/share/puppet/conformance/README.md +274 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/cases/binding.json +238 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/cases/capabilities.json +155 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/cases/grammar.json +248 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/cases/interaction.json +220 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/cases/listen.json +133 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/cases/platform.json +274 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/cases/probes.json +117 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/cases/render.json +180 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/cases/tabs.json +39 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/cases/templates.json +143 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/fixtures/capabilities_bad_result.py +11 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/fixtures/capabilities_basic.py +24 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/fixtures/capabilities_deps_mismatch.py +11 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/fixtures/capabilities_no_doc.py +10 -0
- openpuppet_language-2.0.data/data/share/puppet/conformance/runner.py +721 -0
- openpuppet_language-2.0.data/data/share/puppet/spec/01-grammar.md +283 -0
- openpuppet_language-2.0.data/data/share/puppet/spec/02-ir.md +77 -0
- openpuppet_language-2.0.data/data/share/puppet/spec/03-semantics.md +167 -0
- openpuppet_language-2.0.data/data/share/puppet/spec/04-vocabulary.md +227 -0
- openpuppet_language-2.0.data/data/share/puppet/spec/05-render-contract.md +126 -0
- openpuppet_language-2.0.data/data/share/puppet/spec/06-diagnostics.md +151 -0
- openpuppet_language-2.0.data/data/share/puppet/spec/README.md +73 -0
- openpuppet_language-2.0.dist-info/METADATA +50 -0
- openpuppet_language-2.0.dist-info/RECORD +40 -0
- openpuppet_language-2.0.dist-info/WHEEL +5 -0
- openpuppet_language-2.0.dist-info/entry_points.txt +2 -0
- openpuppet_language-2.0.dist-info/top_level.txt +1 -0
- puppet/__init__.py +19 -0
- puppet/adapter.py +112 -0
- puppet/capabilities.py +172 -0
- puppet/cli.py +132 -0
- puppet/diag.py +42 -0
- puppet/engine.py +1038 -0
- puppet/eval.py +243 -0
- puppet/ir.py +538 -0
- puppet/lang.py +755 -0
- puppet/raster_adapter.py +348 -0
- puppet/tk_adapter.py +374 -0
- puppet/vocab.py +147 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "p-call-unknown",
|
|
4
|
+
"title": "调用不存在的函数是错误,不得静默返回空值",
|
|
5
|
+
"spec": "01-grammar.md 第 7.9 节;03-semantics.md 第 4.1 节",
|
|
6
|
+
"program": [
|
|
7
|
+
"add #root window #win",
|
|
8
|
+
"data #res = [] of {value: str = \"\"}"
|
|
9
|
+
],
|
|
10
|
+
"steps": [
|
|
11
|
+
{
|
|
12
|
+
"send": ["call nope with {} into #res"],
|
|
13
|
+
"expect": { "diagnostics": [{ "code": "CALL_UNKNOWN", "level": "error" }] }
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "p-call-contract",
|
|
19
|
+
"title": "缺少必需参数是错误",
|
|
20
|
+
"spec": "03-semantics.md 第 4.1 节",
|
|
21
|
+
"program": [
|
|
22
|
+
"add #root window #win",
|
|
23
|
+
"data #res = [] of {value: str = \"\"}"
|
|
24
|
+
],
|
|
25
|
+
"capabilities": [
|
|
26
|
+
{
|
|
27
|
+
"name": "compress",
|
|
28
|
+
"params": [{ "name": "input", "type": "str", "required": true }],
|
|
29
|
+
"returns": "dict",
|
|
30
|
+
"behavior": "return",
|
|
31
|
+
"value": { "path": "a", "size": 1 }
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"steps": [
|
|
35
|
+
{
|
|
36
|
+
"send": ["call compress with {} into #res"],
|
|
37
|
+
"expect": { "diagnostics": [{ "code": "CALL_CONTRACT", "level": "error" }] }
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "p-call-result",
|
|
43
|
+
"title": "返回值不可序列化是错误",
|
|
44
|
+
"spec": "03-semantics.md 第 4.1 节",
|
|
45
|
+
"program": [
|
|
46
|
+
"add #root window #win",
|
|
47
|
+
"data #res = [] of {value: str = \"\"}"
|
|
48
|
+
],
|
|
49
|
+
"capabilities": [
|
|
50
|
+
{ "name": "weird", "params": [], "returns": "dict", "behavior": "nonjson" }
|
|
51
|
+
],
|
|
52
|
+
"steps": [
|
|
53
|
+
{
|
|
54
|
+
"send": ["call weird with {} into #res"],
|
|
55
|
+
"expect": { "diagnostics": [{ "code": "CALL_RESULT", "level": "error" }] }
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"id": "p-slot-readable",
|
|
61
|
+
"title": "槽值可直接绑定读,不需要三段式处理器",
|
|
62
|
+
"spec": "03-semantics.md 第 4.4 节",
|
|
63
|
+
"program": [
|
|
64
|
+
"add #root window #win",
|
|
65
|
+
"add #win text #s text=#res.status",
|
|
66
|
+
"data #res = [] of {value: str = \"\"}"
|
|
67
|
+
],
|
|
68
|
+
"capabilities": [
|
|
69
|
+
{ "name": "echo", "params": [], "returns": "str", "behavior": "return", "value": "hi" }
|
|
70
|
+
],
|
|
71
|
+
"steps": [
|
|
72
|
+
{
|
|
73
|
+
"send": ["call echo with {} into #res"],
|
|
74
|
+
"expect": {
|
|
75
|
+
"slots": { "#res": { "status": "done" } },
|
|
76
|
+
"attrs": { "#s.text": "done" }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "p-slot-timeout",
|
|
83
|
+
"title": "挂死的调用必须超时并可见,不得永久停在“进行中”",
|
|
84
|
+
"spec": "03-semantics.md 第 4.2 节",
|
|
85
|
+
"program": [
|
|
86
|
+
"add #root window #win",
|
|
87
|
+
"data #res = [] of {value: str = \"\"}"
|
|
88
|
+
],
|
|
89
|
+
"limits": { "callTimeoutMs": 200 },
|
|
90
|
+
"capabilities": [
|
|
91
|
+
{ "name": "slow", "params": [], "returns": "dict", "behavior": "hang" }
|
|
92
|
+
],
|
|
93
|
+
"steps": [
|
|
94
|
+
{
|
|
95
|
+
"send": ["call slow with {} into #res"],
|
|
96
|
+
"expect": {
|
|
97
|
+
"diagnostics": [{ "code": "SLOT_TIMEOUT" }],
|
|
98
|
+
"slots": { "#res": { "status": "timeout" } }
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"id": "p-convergence-limit",
|
|
105
|
+
"title": "处理器级联达到上限必须报可见错误,不得静默停止传播",
|
|
106
|
+
"spec": "03-semantics.md 第 3.3 节",
|
|
107
|
+
"program": [
|
|
108
|
+
"add #root window #win",
|
|
109
|
+
"data #a = [] of {n: int = 0}",
|
|
110
|
+
"on #a change: append #a item={n: 1}"
|
|
111
|
+
],
|
|
112
|
+
"steps": [
|
|
113
|
+
{
|
|
114
|
+
"send": ["append #a item={n: 0}"],
|
|
115
|
+
"expect": { "diagnostics": [{ "code": "CONVERGENCE_LIMIT", "level": "error" }] }
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "p-persist-survives-restart",
|
|
121
|
+
"title": "persist 数据在重启后存活",
|
|
122
|
+
"spec": "03-semantics.md 第 5 节",
|
|
123
|
+
"program": [
|
|
124
|
+
"add #root window #win",
|
|
125
|
+
"data #todos persist=true = [] of {text: str = \"\"}"
|
|
126
|
+
],
|
|
127
|
+
"steps": [
|
|
128
|
+
{
|
|
129
|
+
"send": ["append #todos item={text: \"a\"}"],
|
|
130
|
+
"expect": { "data": { "#todos": [{ "text": "a" }] } }
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"restart": true,
|
|
134
|
+
"expect": { "data": { "#todos": [{ "text": "a" }] } }
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"id": "p-transient-reset-on-restart",
|
|
140
|
+
"title": "非 persist 数据在重启后回到声明初值",
|
|
141
|
+
"spec": "03-semantics.md 第 5 节",
|
|
142
|
+
"program": [
|
|
143
|
+
"add #root window #win",
|
|
144
|
+
"data #tmp = [] of {text: str = \"\"}"
|
|
145
|
+
],
|
|
146
|
+
"steps": [
|
|
147
|
+
{
|
|
148
|
+
"send": ["append #tmp item={text: \"a\"}"],
|
|
149
|
+
"expect": { "data": { "#tmp": [{ "text": "a" }] } }
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"restart": true,
|
|
153
|
+
"expect": { "data": { "#tmp": [] } }
|
|
154
|
+
}
|
|
155
|
+
]
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"id": "p-state-rebuilt",
|
|
159
|
+
"title": "没有状态文件时从声明初值重建,并产生信息级事件",
|
|
160
|
+
"spec": "03-semantics.md 第 5 节;06-diagnostics.md 第 4.6 节",
|
|
161
|
+
"program": [
|
|
162
|
+
"add #root window #win",
|
|
163
|
+
"data #todos persist=true = [] of {text: str = \"\"}"
|
|
164
|
+
],
|
|
165
|
+
"loadExpect": {
|
|
166
|
+
"diagnostics": [{ "code": "STATE_REBUILT", "level": "info" }]
|
|
167
|
+
},
|
|
168
|
+
"steps": [
|
|
169
|
+
{ "expect": { "data": { "#todos": [] } } }
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"id": "p-persist-drift",
|
|
174
|
+
"title": "持久状态出现未声明字段:报警告、不迁移、不丢数据",
|
|
175
|
+
"spec": "03-semantics.md 第 5 节;06-diagnostics.md 第 4.6 节",
|
|
176
|
+
"program": [
|
|
177
|
+
"add #root window #win",
|
|
178
|
+
"data #todos persist=true = [] of {text: str = \"\"}"
|
|
179
|
+
],
|
|
180
|
+
"seedState": {
|
|
181
|
+
"revision": 1,
|
|
182
|
+
"items": { "#todos": [{ "text": "a", "legacy": 1 }] }
|
|
183
|
+
},
|
|
184
|
+
"steps": [
|
|
185
|
+
{
|
|
186
|
+
"expect": { "data": { "#todos": [{ "text": "a", "legacy": 1 }] } }
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"restart": true,
|
|
190
|
+
"expect": {
|
|
191
|
+
"diagnostics": [{ "code": "PERSIST_SCHEMA_DRIFT", "level": "warning" }],
|
|
192
|
+
"data": { "#todos": [{ "text": "a", "legacy": 1 }] }
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"id": "p-slot-cancelled",
|
|
199
|
+
"title": "同一槽上新的调用取消进行中的旧调用,且取消可见",
|
|
200
|
+
"spec": "03-semantics.md 第 4.2 节",
|
|
201
|
+
"program": [
|
|
202
|
+
"add #root window #win",
|
|
203
|
+
"data #res = [] of {value: str = \"\"}"
|
|
204
|
+
],
|
|
205
|
+
"limits": { "callTimeoutMs": 400 },
|
|
206
|
+
"capabilities": [
|
|
207
|
+
{ "name": "slow", "params": [], "returns": "str", "behavior": "hang" },
|
|
208
|
+
{ "name": "fast", "params": [], "returns": "str", "behavior": "return", "value": "ok" }
|
|
209
|
+
],
|
|
210
|
+
"steps": [
|
|
211
|
+
{
|
|
212
|
+
"send": [
|
|
213
|
+
"call slow with {} into #res",
|
|
214
|
+
"call fast with {} into #res"
|
|
215
|
+
],
|
|
216
|
+
"expect": {
|
|
217
|
+
"diagnostics": [{ "code": "SLOT_CANCELLED", "level": "info" }],
|
|
218
|
+
"slots": { "#res": { "status": "done" } }
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
]
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"id": "p-slot-handler-dispatch",
|
|
225
|
+
"title": "槽状态变化的处理器会被派发(pending 之后 done)",
|
|
226
|
+
"spec": "03-semantics.md 第 4.2 节",
|
|
227
|
+
"program": [
|
|
228
|
+
"add #root window #win",
|
|
229
|
+
"add #win text #status text=\"\"",
|
|
230
|
+
"data #res = [] of {value: str = \"\"}",
|
|
231
|
+
"on #res done as e: set #status text=e.status",
|
|
232
|
+
"on #res error as e: set #status text=\"错误:\" + e.status"
|
|
233
|
+
],
|
|
234
|
+
"capabilities": [
|
|
235
|
+
{ "name": "echo", "params": [], "returns": "str", "behavior": "return", "value": "hi" }
|
|
236
|
+
],
|
|
237
|
+
"loadExpect": { "noDiagnostics": true },
|
|
238
|
+
"steps": [
|
|
239
|
+
{
|
|
240
|
+
"send": ["call echo with {} into #res"],
|
|
241
|
+
"expect": {
|
|
242
|
+
"attrs": { "#status.text": "done" },
|
|
243
|
+
"slots": { "#res": { "status": "done" } }
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"id": "p-observation-dropped",
|
|
250
|
+
"title": "观察流溢出必须留下可见标记,不得静默丢弃",
|
|
251
|
+
"spec": "03-semantics.md 第 6 节;06-diagnostics.md 第 4.7 节",
|
|
252
|
+
"program": [
|
|
253
|
+
"add #root window #win",
|
|
254
|
+
"data #n = [] of {v: int = 0}",
|
|
255
|
+
"listen #n change"
|
|
256
|
+
],
|
|
257
|
+
"limits": { "eventQueue": 2 },
|
|
258
|
+
"steps": [
|
|
259
|
+
{
|
|
260
|
+
"send": [
|
|
261
|
+
"append #n item={v: 1}",
|
|
262
|
+
"append #n item={v: 2}",
|
|
263
|
+
"append #n item={v: 3}",
|
|
264
|
+
"append #n item={v: 4}"
|
|
265
|
+
],
|
|
266
|
+
"expect": {
|
|
267
|
+
"diagnostics": [{ "code": "OBSERVATION_DROPPED", "level": "warning" }],
|
|
268
|
+
"events": [{ "target": "#n", "event": "change" }],
|
|
269
|
+
"data": { "#n": [{ "v": 1 }, { "v": 2 }, { "v": 3 }, { "v": 4 }] }
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
]
|
|
273
|
+
}
|
|
274
|
+
]
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "pr-tree",
|
|
4
|
+
"title": "tree 探针返回结构树",
|
|
5
|
+
"spec": "01-grammar.md 第 7.10 节",
|
|
6
|
+
"program": [
|
|
7
|
+
"add #root window #win",
|
|
8
|
+
"add #win col #main"
|
|
9
|
+
],
|
|
10
|
+
"steps": [
|
|
11
|
+
{
|
|
12
|
+
"send": ["tree"],
|
|
13
|
+
"expect": {
|
|
14
|
+
"probes": [{ "verb": "tree", "result": { "id": "#root", "type": "root" } }]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "pr-get",
|
|
21
|
+
"title": "get 探针返回单个节点的形状",
|
|
22
|
+
"spec": "01-grammar.md 第 7.10 节",
|
|
23
|
+
"program": [
|
|
24
|
+
"add #root window #win",
|
|
25
|
+
"add #win button #b text=\"x\"",
|
|
26
|
+
"on #b click: set #b text=\"hit\""
|
|
27
|
+
],
|
|
28
|
+
"steps": [
|
|
29
|
+
{
|
|
30
|
+
"send": ["get #b"],
|
|
31
|
+
"expect": {
|
|
32
|
+
"probes": [{ "verb": "get", "target": "#b",
|
|
33
|
+
"result": { "id": "#b", "type": "button" } }]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": "pr-where-degraded",
|
|
40
|
+
"title": "几何反查不可用时降级必须可见",
|
|
41
|
+
"spec": "01-grammar.md 第 7.10 节;06-diagnostics.md 第 4.7 节",
|
|
42
|
+
"program": [
|
|
43
|
+
"add #root window #win",
|
|
44
|
+
"add #win button #b text=\"x\"",
|
|
45
|
+
"on #b click: set #b text=\"hit\""
|
|
46
|
+
],
|
|
47
|
+
"rendering": { "geometry": false },
|
|
48
|
+
"steps": [
|
|
49
|
+
{
|
|
50
|
+
"send": ["where #b"],
|
|
51
|
+
"expect": {
|
|
52
|
+
"diagnostics": [{ "code": "DEGRADED_FEATURE", "level": "info" }],
|
|
53
|
+
"probes": [{ "verb": "where", "result": { "geometry": null } }]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": "pr-get-missing",
|
|
60
|
+
"title": "探针目标不存在是错误,result 为 null",
|
|
61
|
+
"spec": "01-grammar.md 第 7.10 节",
|
|
62
|
+
"program": [
|
|
63
|
+
"add #root window #win"
|
|
64
|
+
],
|
|
65
|
+
"steps": [
|
|
66
|
+
{
|
|
67
|
+
"send": ["get #ghost"],
|
|
68
|
+
"expect": {
|
|
69
|
+
"diagnostics": [{ "code": "TARGET_MISSING", "level": "error" }],
|
|
70
|
+
"probes": [{ "verb": "get", "result": null }]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"id": "pr-source-probe",
|
|
77
|
+
"title": "写在源文件里的探针在装载完成后执行",
|
|
78
|
+
"spec": "01-grammar.md 第 7.10 节",
|
|
79
|
+
"program": [
|
|
80
|
+
"add #root window #win",
|
|
81
|
+
"add #win button #b text=\"x\"",
|
|
82
|
+
"on #b click: set #b text=\"hit\"",
|
|
83
|
+
"tree"
|
|
84
|
+
],
|
|
85
|
+
"loadExpect": {
|
|
86
|
+
"probes": [{ "verb": "tree", "result": { "id": "#root", "type": "root" } }]
|
|
87
|
+
},
|
|
88
|
+
"steps": [
|
|
89
|
+
{ "expect": { "nodes": ["#b"] } }
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "pr-no-side-effects",
|
|
94
|
+
"title": "探针不改变程序或状态",
|
|
95
|
+
"spec": "01-grammar.md 第 7.10 节",
|
|
96
|
+
"program": [
|
|
97
|
+
"add #root window #win",
|
|
98
|
+
"data #n = [] of {v: int = 0}"
|
|
99
|
+
],
|
|
100
|
+
"steps": [
|
|
101
|
+
{
|
|
102
|
+
"send": ["append #n item={v: 1}", "append #n item={v: 2}", "tree"],
|
|
103
|
+
"expect": {
|
|
104
|
+
"data": { "#n": [{ "v": 1 }, { "v": 2 }] },
|
|
105
|
+
"probes": [{ "verb": "tree" }]
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"send": ["get #win"],
|
|
110
|
+
"expect": {
|
|
111
|
+
"probes": [{ "verb": "get", "result": { "id": "#win", "type": "window" } }],
|
|
112
|
+
"data": { "#n": [{ "v": 1 }, { "v": 2 }] }
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
]
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "r-relations-basic",
|
|
4
|
+
"title": "几何可用时,关系断言按矩形判定(方位/对齐/间距/包含)",
|
|
5
|
+
"spec": "05-render-contract.md 第 7.3、8 节",
|
|
6
|
+
"program": [
|
|
7
|
+
"add #root window #win",
|
|
8
|
+
"add #win row #bar gap=8",
|
|
9
|
+
"add #bar button #a text=\"A\"",
|
|
10
|
+
"add #bar button #b text=\"B\"",
|
|
11
|
+
"on #a click: set #a text=\"A\"",
|
|
12
|
+
"on #b click: set #b text=\"B\""
|
|
13
|
+
],
|
|
14
|
+
"renderGeometry": {
|
|
15
|
+
"#win": { "x": 0, "y": 0, "width": 420, "height": 640 },
|
|
16
|
+
"#bar": { "x": 16, "y": 16, "width": 388, "height": 40 },
|
|
17
|
+
"#a": { "x": 16, "y": 16, "width": 80, "height": 40 },
|
|
18
|
+
"#b": { "x": 104, "y": 16, "width": 80, "height": 40 }
|
|
19
|
+
},
|
|
20
|
+
"steps": [
|
|
21
|
+
{
|
|
22
|
+
"expect": {
|
|
23
|
+
"geometry": { "#a": { "x": 16, "y": 16, "width": 80, "height": 40 } },
|
|
24
|
+
"relations": [
|
|
25
|
+
{ "rel": "left_of", "a": "#a", "b": "#b" },
|
|
26
|
+
{ "rel": "aligned_y", "a": "#a", "b": "#b" },
|
|
27
|
+
{ "rel": "gap_h", "a": "#a", "b": "#b", "value": 8, "tol": 1 },
|
|
28
|
+
{ "rel": "same_size", "a": "#a", "b": "#b" },
|
|
29
|
+
{ "rel": "contains", "a": "#bar", "b": "#a" }
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"id": "r-tolerance",
|
|
37
|
+
"title": "对齐容差:tol 内的偏差视为对齐",
|
|
38
|
+
"spec": "05-render-contract.md 第 8 节",
|
|
39
|
+
"program": [
|
|
40
|
+
"add #root window #win",
|
|
41
|
+
"add #win row #bar gap=8",
|
|
42
|
+
"add #bar button #a text=\"A\"",
|
|
43
|
+
"add #bar button #b text=\"B\"",
|
|
44
|
+
"on #a click: set #a text=\"A\"",
|
|
45
|
+
"on #b click: set #b text=\"B\""
|
|
46
|
+
],
|
|
47
|
+
"renderGeometry": {
|
|
48
|
+
"#a": { "x": 10.0, "y": 10.0, "width": 50, "height": 20 },
|
|
49
|
+
"#b": { "x": 70.5, "y": 11.0, "width": 50, "height": 20 }
|
|
50
|
+
},
|
|
51
|
+
"steps": [
|
|
52
|
+
{
|
|
53
|
+
"expect": {
|
|
54
|
+
"relations": [
|
|
55
|
+
{ "rel": "aligned_y", "a": "#a", "b": "#b", "tol": 1.5 },
|
|
56
|
+
{ "rel": "same_width", "a": "#a", "b": "#b" }
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"id": "r-relations-extended",
|
|
64
|
+
"title": "关系词汇覆盖:包含/方位/重叠/居中/间距/比例",
|
|
65
|
+
"spec": "05-render-contract.md 第 8 节",
|
|
66
|
+
"program": [
|
|
67
|
+
"add #root window #win w=420 h=640",
|
|
68
|
+
"add #win col #nav",
|
|
69
|
+
"add #win col #content",
|
|
70
|
+
"add #content button #a text=\"A\"",
|
|
71
|
+
"add #content button #b text=\"B\"",
|
|
72
|
+
"on #a click: set #a text=\"A\"",
|
|
73
|
+
"on #b click: set #b text=\"B\""
|
|
74
|
+
],
|
|
75
|
+
"renderGeometry": {
|
|
76
|
+
"#win": { "x": 0, "y": 0, "width": 420, "height": 640 },
|
|
77
|
+
"#nav": { "x": 0, "y": 0, "width": 420, "height": 48 },
|
|
78
|
+
"#content": { "x": 0, "y": 56, "width": 420, "height": 584 },
|
|
79
|
+
"#a": { "x": 16, "y": 72, "width": 100, "height": 40 },
|
|
80
|
+
"#b": { "x": 100, "y": 72, "width": 200, "height": 40 }
|
|
81
|
+
},
|
|
82
|
+
"steps": [
|
|
83
|
+
{
|
|
84
|
+
"expect": {
|
|
85
|
+
"relations": [
|
|
86
|
+
{ "rel": "inside", "a": "#nav", "b": "#win" },
|
|
87
|
+
{ "rel": "contains", "a": "#win", "b": "#nav" },
|
|
88
|
+
{ "rel": "above", "a": "#nav", "b": "#content" },
|
|
89
|
+
{ "rel": "below", "a": "#content", "b": "#nav" },
|
|
90
|
+
{ "rel": "aligned_x", "a": "#nav", "b": "#win" },
|
|
91
|
+
{ "rel": "aligned_center_x", "a": "#nav", "b": "#win", "tol": 0.5 },
|
|
92
|
+
{ "rel": "gap_v", "a": "#nav", "b": "#content", "value": 8 },
|
|
93
|
+
{ "rel": "overlaps", "a": "#a", "b": "#b" },
|
|
94
|
+
{ "rel": "same_height", "a": "#a", "b": "#b" },
|
|
95
|
+
{ "rel": "width_ratio", "a": "#b", "b": "#a", "value": 2 }
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"id": "r-degrade-undeclared",
|
|
103
|
+
"title": "能力声明替身:未声明支持的词汇必须可见降级(control/attr/icon)",
|
|
104
|
+
"spec": "05-render-contract.md 第 1 节;06-diagnostics.md 第 4.7 节",
|
|
105
|
+
"program": [
|
|
106
|
+
"add #root window #win",
|
|
107
|
+
"add #win slider #s value=10 min=0 max=100",
|
|
108
|
+
"add #win icon #i icon=\"star\"",
|
|
109
|
+
"add #win button #b text=\"x\" shadow=4",
|
|
110
|
+
"on #b click: set #b text=\"x\""
|
|
111
|
+
],
|
|
112
|
+
"rendering": {
|
|
113
|
+
"controls": ["window", "button", "icon"],
|
|
114
|
+
"attributes": ["text", "icon", "value", "min", "max"],
|
|
115
|
+
"icons": ["add"],
|
|
116
|
+
"geometry": false,
|
|
117
|
+
"snapshot": false,
|
|
118
|
+
"headless": true
|
|
119
|
+
},
|
|
120
|
+
"loadExpect": {
|
|
121
|
+
"degraded": ["control:slider", "attr:shadow", "icon:star"]
|
|
122
|
+
},
|
|
123
|
+
"steps": [
|
|
124
|
+
{ "expect": { "nodes": ["#s", "#i", "#b"] } }
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"id": "r-geometry-face",
|
|
129
|
+
"title": "几何面:能提供则按关系判定,不能提供则必须可见降级",
|
|
130
|
+
"spec": "05-render-contract.md 第 7、8 节;06-diagnostics.md 第 4.7 节",
|
|
131
|
+
"program": [
|
|
132
|
+
"add #root window #win",
|
|
133
|
+
"add #win row #bar gap=8",
|
|
134
|
+
"add #bar button #a text=\"A\"",
|
|
135
|
+
"add #bar button #b text=\"B\"",
|
|
136
|
+
"on #a click: set #a text=\"A\"",
|
|
137
|
+
"on #b click: set #b text=\"B\""
|
|
138
|
+
],
|
|
139
|
+
"steps": [
|
|
140
|
+
{
|
|
141
|
+
"expect": {
|
|
142
|
+
"relations": [
|
|
143
|
+
{ "rel": "left_of", "a": "#a", "b": "#b" },
|
|
144
|
+
{ "rel": "aligned_y", "a": "#a", "b": "#b" }
|
|
145
|
+
],
|
|
146
|
+
"degraded": ["geometry"]
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"id": "r-snapshot-real",
|
|
153
|
+
"title": "真实截图:被请求时必须真的产出图像(只断非空,不比像素)",
|
|
154
|
+
"spec": "05-render-contract.md 第 7 节",
|
|
155
|
+
"requires": ["snapshot"],
|
|
156
|
+
"program": [
|
|
157
|
+
"add #root window #win w=200 h=120",
|
|
158
|
+
"add #win button #b text=\"x\"",
|
|
159
|
+
"on #b click: set #b text=\"y\""
|
|
160
|
+
],
|
|
161
|
+
"steps": [
|
|
162
|
+
{ "snapshot": true, "expect": { "snapshotAvailable": true } }
|
|
163
|
+
]
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"id": "r-snapshot-face",
|
|
167
|
+
"title": "视觉快照:不支持时必须在被请求时可见降级",
|
|
168
|
+
"spec": "05-render-contract.md 第 7 节;06-diagnostics.md 第 4.7 节",
|
|
169
|
+
"program": [
|
|
170
|
+
"add #root window #win",
|
|
171
|
+
"add #win text #t text=\"hi\""
|
|
172
|
+
],
|
|
173
|
+
"steps": [
|
|
174
|
+
{
|
|
175
|
+
"snapshot": true,
|
|
176
|
+
"expect": { "degraded": ["snapshot"] }
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "tb-pages-are-children",
|
|
4
|
+
"title": "tabs 的每个直接子节点是一页",
|
|
5
|
+
"spec": "04-vocabulary.md 第 2 节",
|
|
6
|
+
"program": [
|
|
7
|
+
"add #root window #win",
|
|
8
|
+
"add #win tabs #t",
|
|
9
|
+
"add #t col #p1",
|
|
10
|
+
"add #t col #p2"
|
|
11
|
+
],
|
|
12
|
+
"loadExpect": { "nodes": ["#t", "#p1", "#p2"] },
|
|
13
|
+
"steps": [
|
|
14
|
+
{ "expect": { "nodes": ["#p1", "#p2"] } }
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "tb-selected-index",
|
|
19
|
+
"title": "selected 指向页序号(从 0 起),可写",
|
|
20
|
+
"spec": "04-vocabulary.md 第 2、4 节",
|
|
21
|
+
"program": [
|
|
22
|
+
"add #root window #win",
|
|
23
|
+
"add #win tabs #t selected=0",
|
|
24
|
+
"add #t col #p1",
|
|
25
|
+
"add #t col #p2"
|
|
26
|
+
],
|
|
27
|
+
"loadExpect": { "attrs": { "#t.selected": 0 } },
|
|
28
|
+
"steps": [
|
|
29
|
+
{
|
|
30
|
+
"send": ["set #t selected=1"],
|
|
31
|
+
"expect": { "attrs": { "#t.selected": 1 } }
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"send": ["set #t selected=0"],
|
|
35
|
+
"expect": { "attrs": { "#t.selected": 0 } }
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
]
|