@player-ui/player 0.8.0--canary.307.9621 → 0.8.0-next.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.
Files changed (214) hide show
  1. package/dist/Player.native.js +11630 -0
  2. package/dist/Player.native.js.map +1 -0
  3. package/dist/cjs/index.cjs +5626 -0
  4. package/dist/cjs/index.cjs.map +1 -0
  5. package/dist/{index.esm.js → index.legacy-esm.js} +2044 -1667
  6. package/dist/{index.cjs.js → index.mjs} +2052 -1761
  7. package/dist/index.mjs.map +1 -0
  8. package/package.json +29 -63
  9. package/src/__tests__/data.test.ts +498 -0
  10. package/src/__tests__/flow.test.ts +312 -0
  11. package/src/__tests__/helpers/action-exp.plugin.ts +22 -0
  12. package/src/__tests__/helpers/actions.flow.ts +67 -0
  13. package/src/__tests__/helpers/binding.plugin.ts +125 -0
  14. package/src/__tests__/helpers/expression.plugin.ts +88 -0
  15. package/src/__tests__/helpers/transform-plugin.ts +19 -0
  16. package/src/__tests__/helpers/validation.flow.ts +56 -0
  17. package/src/__tests__/player.test.ts +597 -0
  18. package/src/__tests__/string-resolver.test.ts +186 -0
  19. package/src/__tests__/validation.test.ts +3555 -0
  20. package/src/__tests__/view.test.ts +715 -0
  21. package/src/binding/__tests__/binding.test.ts +113 -0
  22. package/src/binding/__tests__/index.test.ts +208 -0
  23. package/src/binding/__tests__/resolver.test.ts +83 -0
  24. package/src/binding/binding.ts +6 -6
  25. package/src/binding/index.ts +34 -34
  26. package/src/binding/resolver.ts +19 -19
  27. package/src/binding/utils.ts +7 -7
  28. package/src/binding-grammar/__tests__/parser.test.ts +64 -0
  29. package/src/binding-grammar/__tests__/test-utils/ast-cases.ts +198 -0
  30. package/src/binding-grammar/__tests__/test-utils/perf-test.ts +66 -0
  31. package/src/binding-grammar/ast.ts +11 -11
  32. package/src/binding-grammar/custom/index.ts +19 -22
  33. package/src/binding-grammar/ebnf/index.ts +20 -21
  34. package/src/binding-grammar/ebnf/types.ts +13 -13
  35. package/src/binding-grammar/index.ts +4 -4
  36. package/src/binding-grammar/parsimmon/index.ts +14 -14
  37. package/src/controllers/constants/__tests__/index.test.ts +106 -0
  38. package/src/controllers/constants/index.ts +3 -3
  39. package/src/controllers/constants/utils.ts +4 -4
  40. package/src/controllers/data/controller.ts +22 -22
  41. package/src/controllers/data/index.ts +1 -1
  42. package/src/controllers/data/utils.ts +7 -7
  43. package/src/controllers/flow/__tests__/controller.test.ts +195 -0
  44. package/src/controllers/flow/__tests__/flow.test.ts +381 -0
  45. package/src/controllers/flow/controller.ts +13 -13
  46. package/src/controllers/flow/flow.ts +23 -23
  47. package/src/controllers/flow/index.ts +2 -2
  48. package/src/controllers/index.ts +5 -5
  49. package/src/controllers/validation/binding-tracker.ts +71 -59
  50. package/src/controllers/validation/controller.ts +104 -104
  51. package/src/controllers/validation/index.ts +2 -2
  52. package/src/controllers/view/asset-transform.ts +20 -20
  53. package/src/controllers/view/controller.ts +27 -27
  54. package/src/controllers/view/index.ts +4 -4
  55. package/src/controllers/view/store.ts +3 -3
  56. package/src/controllers/view/types.ts +7 -7
  57. package/src/data/__tests__/__snapshots__/dependency-tracker.test.ts.snap +64 -0
  58. package/src/data/__tests__/dependency-tracker.test.ts +146 -0
  59. package/src/data/__tests__/local-model.test.ts +46 -0
  60. package/src/data/__tests__/model.test.ts +78 -0
  61. package/src/data/dependency-tracker.ts +16 -16
  62. package/src/data/index.ts +4 -4
  63. package/src/data/local-model.ts +6 -6
  64. package/src/data/model.ts +17 -17
  65. package/src/data/noop-model.ts +1 -1
  66. package/src/expressions/__tests__/__snapshots__/parser.test.ts.snap +854 -0
  67. package/src/expressions/__tests__/evaluator-functions.test.ts +47 -0
  68. package/src/expressions/__tests__/evaluator.test.ts +410 -0
  69. package/src/expressions/__tests__/parser.test.ts +115 -0
  70. package/src/expressions/__tests__/utils.test.ts +44 -0
  71. package/src/expressions/evaluator-functions.ts +6 -6
  72. package/src/expressions/evaluator.ts +71 -67
  73. package/src/expressions/index.ts +4 -4
  74. package/src/expressions/parser.ts +102 -105
  75. package/src/expressions/types.ts +29 -21
  76. package/src/expressions/utils.ts +32 -21
  77. package/src/index.ts +13 -13
  78. package/src/logger/__tests__/consoleLogger.test.ts +46 -0
  79. package/src/logger/__tests__/noopLogger.test.ts +13 -0
  80. package/src/logger/__tests__/proxyLogger.test.ts +31 -0
  81. package/src/logger/__tests__/tapableLogger.test.ts +41 -0
  82. package/src/logger/consoleLogger.ts +9 -9
  83. package/src/logger/index.ts +5 -5
  84. package/src/logger/noopLogger.ts +1 -1
  85. package/src/logger/proxyLogger.ts +6 -6
  86. package/src/logger/tapableLogger.ts +7 -7
  87. package/src/logger/types.ts +2 -2
  88. package/src/player.ts +60 -58
  89. package/src/plugins/default-exp-plugin.ts +10 -10
  90. package/src/plugins/default-view-plugin.ts +29 -0
  91. package/src/plugins/flow-exp-plugin.ts +6 -6
  92. package/src/schema/__tests__/schema.test.ts +243 -0
  93. package/src/schema/index.ts +2 -2
  94. package/src/schema/schema.ts +24 -24
  95. package/src/schema/types.ts +4 -4
  96. package/src/string-resolver/__tests__/index.test.ts +361 -0
  97. package/src/string-resolver/index.ts +17 -17
  98. package/src/types.ts +17 -17
  99. package/src/utils/__tests__/replaceParams.test.ts +33 -0
  100. package/src/utils/index.ts +1 -1
  101. package/src/utils/replaceParams.ts +1 -1
  102. package/src/validator/__tests__/binding-map-splice.test.ts +53 -0
  103. package/src/validator/__tests__/validation-middleware.test.ts +127 -0
  104. package/src/validator/binding-map-splice.ts +5 -5
  105. package/src/validator/index.ts +4 -4
  106. package/src/validator/registry.ts +1 -1
  107. package/src/validator/types.ts +13 -13
  108. package/src/validator/validation-middleware.ts +15 -15
  109. package/src/view/__tests__/view.immutable.test.ts +269 -0
  110. package/src/view/__tests__/view.test.ts +959 -0
  111. package/src/view/builder/index.test.ts +69 -0
  112. package/src/view/builder/index.ts +3 -3
  113. package/src/view/index.ts +5 -5
  114. package/src/view/parser/__tests__/__snapshots__/parser.test.ts.snap +394 -0
  115. package/src/view/parser/__tests__/parser.test.ts +264 -0
  116. package/src/view/parser/index.ts +43 -33
  117. package/src/view/parser/types.ts +11 -11
  118. package/src/view/parser/utils.ts +5 -5
  119. package/src/view/plugins/__tests__/__snapshots__/template.test.ts.snap +278 -0
  120. package/src/view/plugins/__tests__/applicability.test.ts +265 -0
  121. package/src/view/plugins/__tests__/string.test.ts +122 -0
  122. package/src/view/plugins/__tests__/template.test.ts +724 -0
  123. package/src/view/plugins/applicability.ts +19 -19
  124. package/src/view/plugins/index.ts +4 -5
  125. package/src/view/plugins/options.ts +1 -1
  126. package/src/view/plugins/string-resolver.ts +22 -22
  127. package/src/view/plugins/switch.ts +22 -23
  128. package/src/view/plugins/template-plugin.ts +26 -27
  129. package/src/view/resolver/__tests__/dependencies.test.ts +321 -0
  130. package/src/view/resolver/__tests__/edgecases.test.ts +626 -0
  131. package/src/view/resolver/index.ts +42 -42
  132. package/src/view/resolver/types.ts +21 -20
  133. package/src/view/resolver/utils.ts +9 -9
  134. package/src/view/view.ts +32 -22
  135. package/types/binding/binding.d.ts +50 -0
  136. package/types/binding/index.d.ts +29 -0
  137. package/types/binding/resolver.d.ts +26 -0
  138. package/types/binding/utils.d.ts +12 -0
  139. package/types/binding-grammar/ast.d.ts +67 -0
  140. package/types/binding-grammar/custom/index.d.ts +4 -0
  141. package/types/binding-grammar/ebnf/index.d.ts +4 -0
  142. package/types/binding-grammar/ebnf/types.d.ts +75 -0
  143. package/types/binding-grammar/index.d.ts +5 -0
  144. package/types/binding-grammar/parsimmon/index.d.ts +4 -0
  145. package/types/controllers/constants/index.d.ts +45 -0
  146. package/types/controllers/constants/utils.d.ts +6 -0
  147. package/types/controllers/data/controller.d.ts +45 -0
  148. package/types/controllers/data/index.d.ts +2 -0
  149. package/types/controllers/data/utils.d.ts +14 -0
  150. package/types/controllers/flow/controller.d.ts +25 -0
  151. package/types/controllers/flow/flow.d.ts +50 -0
  152. package/types/controllers/flow/index.d.ts +3 -0
  153. package/types/controllers/index.d.ts +6 -0
  154. package/types/controllers/validation/binding-tracker.d.ts +32 -0
  155. package/types/controllers/validation/controller.d.ts +151 -0
  156. package/types/controllers/validation/index.d.ts +3 -0
  157. package/types/controllers/view/asset-transform.d.ts +19 -0
  158. package/types/controllers/view/controller.d.ts +37 -0
  159. package/types/controllers/view/index.d.ts +5 -0
  160. package/types/controllers/view/store.d.ts +20 -0
  161. package/types/controllers/view/types.d.ts +16 -0
  162. package/types/data/dependency-tracker.d.ts +49 -0
  163. package/types/data/index.d.ts +5 -0
  164. package/types/data/local-model.d.ts +16 -0
  165. package/types/data/model.d.ts +86 -0
  166. package/types/data/noop-model.d.ts +13 -0
  167. package/types/expressions/evaluator-functions.d.ts +15 -0
  168. package/types/expressions/evaluator.d.ts +52 -0
  169. package/types/expressions/index.d.ts +5 -0
  170. package/types/expressions/parser.d.ts +10 -0
  171. package/types/expressions/types.d.ts +144 -0
  172. package/types/expressions/utils.d.ts +12 -0
  173. package/types/index.d.ts +14 -0
  174. package/types/logger/consoleLogger.d.ts +17 -0
  175. package/types/logger/index.d.ts +6 -0
  176. package/types/logger/noopLogger.d.ts +10 -0
  177. package/types/logger/proxyLogger.d.ts +15 -0
  178. package/types/logger/tapableLogger.d.ts +23 -0
  179. package/types/logger/types.d.ts +6 -0
  180. package/types/player.d.ts +101 -0
  181. package/types/plugins/default-exp-plugin.d.ts +9 -0
  182. package/types/plugins/default-view-plugin.d.ts +9 -0
  183. package/types/plugins/flow-exp-plugin.d.ts +11 -0
  184. package/types/schema/index.d.ts +3 -0
  185. package/types/schema/schema.d.ts +36 -0
  186. package/types/schema/types.d.ts +38 -0
  187. package/types/string-resolver/index.d.ts +30 -0
  188. package/types/types.d.ts +73 -0
  189. package/types/utils/index.d.ts +2 -0
  190. package/types/utils/replaceParams.d.ts +9 -0
  191. package/types/validator/binding-map-splice.d.ts +10 -0
  192. package/types/validator/index.d.ts +5 -0
  193. package/types/validator/registry.d.ts +11 -0
  194. package/types/validator/types.d.ts +53 -0
  195. package/types/validator/validation-middleware.d.ts +36 -0
  196. package/types/view/builder/index.d.ts +35 -0
  197. package/types/view/index.d.ts +6 -0
  198. package/types/view/parser/index.d.ts +52 -0
  199. package/types/view/parser/types.d.ts +109 -0
  200. package/types/view/parser/utils.d.ts +6 -0
  201. package/types/view/plugins/applicability.d.ts +10 -0
  202. package/types/view/plugins/index.d.ts +5 -0
  203. package/types/view/plugins/options.d.ts +4 -0
  204. package/types/view/plugins/string-resolver.d.ts +13 -0
  205. package/types/view/plugins/switch.d.ts +14 -0
  206. package/types/view/plugins/template-plugin.d.ts +33 -0
  207. package/types/view/resolver/index.d.ts +73 -0
  208. package/types/view/resolver/types.d.ts +129 -0
  209. package/types/view/resolver/utils.d.ts +11 -0
  210. package/types/view/view.d.ts +37 -0
  211. package/dist/index.d.ts +0 -1814
  212. package/dist/player.dev.js +0 -11472
  213. package/dist/player.prod.js +0 -2
  214. package/src/view/plugins/plugin.ts +0 -21
@@ -0,0 +1,724 @@
1
+ import { describe, it, expect, beforeEach } from "vitest";
2
+ import { BindingParser } from "../../../binding";
3
+ import type { DataModelWithParser } from "../../../data";
4
+ import { LocalModel, withParser } from "../../../data";
5
+ import { ExpressionEvaluator } from "../../../expressions";
6
+ import { SchemaController } from "../../../schema";
7
+ import { NodeType } from "../../parser";
8
+ import { Parser } from "../../parser";
9
+ import { ViewInstance } from "../../view";
10
+ import type { Options } from "../options";
11
+ import TemplatePlugin from "../template-plugin";
12
+ import { StringResolverPlugin, toNodeResolveOptions } from "../..";
13
+
14
+ const templateJoinValues = {
15
+ id: "snippet-of-json",
16
+ topic: "Snippet",
17
+ schema: {},
18
+ data: {
19
+ forms: {
20
+ "1099-A": [
21
+ {
22
+ description: "Desciption of concept 1099 1",
23
+ amount: "Help",
24
+ },
25
+ ],
26
+ "1099-B": [
27
+ {
28
+ description: "Desciption of concept 1099 2",
29
+ amount: "Help",
30
+ },
31
+ ],
32
+ },
33
+ },
34
+ views: [
35
+ {
36
+ id: "overviewGroup",
37
+ type: "overviewGroup",
38
+ metaData: {
39
+ role: "stateful",
40
+ },
41
+ modifiers: [
42
+ {
43
+ type: "tag",
44
+ value: "fancy-header",
45
+ },
46
+ ],
47
+ headers: {
48
+ label: {
49
+ asset: {
50
+ id: "line-of-work-summary-gh-header-label",
51
+ type: "text",
52
+ value: "Header",
53
+ },
54
+ },
55
+ values: [
56
+ {
57
+ asset: {
58
+ id: "line-of-work-summary-gh-expenses-simple-header-previous-year",
59
+ type: "text",
60
+ value: "Type",
61
+ },
62
+ },
63
+ {
64
+ asset: {
65
+ id: "line-of-work-summary-gh-expenses-simple-header-cy",
66
+ type: "text",
67
+ value: "2022",
68
+ },
69
+ },
70
+ ],
71
+ },
72
+ template: [
73
+ {
74
+ data: "forms.1099-A",
75
+ output: "values",
76
+ value: {
77
+ asset: {
78
+ id: "overviewItem3",
79
+ type: "overviewItem",
80
+ label: {
81
+ asset: {
82
+ id: "overviewItem3-label",
83
+ type: "text",
84
+ value: "1099-A",
85
+ },
86
+ },
87
+ values: [
88
+ {
89
+ asset: {
90
+ id: "overviewItem3-year",
91
+ type: "text",
92
+ value: "Desciption of concept 1099 1",
93
+ },
94
+ },
95
+ {
96
+ asset: {
97
+ id: "loverviewItem3-cy",
98
+ type: "text",
99
+ value: "4000",
100
+ },
101
+ },
102
+ ],
103
+ },
104
+ },
105
+ },
106
+ {
107
+ data: "forms.1099-B",
108
+ output: "values",
109
+ value: {
110
+ asset: {
111
+ id: "overviewItem4",
112
+ type: "overviewItem",
113
+ label: {
114
+ asset: {
115
+ id: "overviewItem4-label",
116
+ type: "text",
117
+ value: "1099-B",
118
+ },
119
+ },
120
+ values: [
121
+ {
122
+ asset: {
123
+ id: "overviewItem4-year",
124
+ type: "text",
125
+ value: "Desciption of concept 1099 2",
126
+ },
127
+ },
128
+ {
129
+ asset: {
130
+ id: "loverviewItem3-cy",
131
+ type: "text",
132
+ value: "6000",
133
+ },
134
+ },
135
+ ],
136
+ },
137
+ },
138
+ },
139
+ ],
140
+ values: [
141
+ {
142
+ asset: {
143
+ id: "overviewItem1",
144
+ type: "overviewItem",
145
+ label: {
146
+ asset: {
147
+ id: "overviewItem1-label",
148
+ type: "text",
149
+ value: "First Summary",
150
+ },
151
+ },
152
+ values: [
153
+ {
154
+ asset: {
155
+ id: "overviewItem1-year",
156
+ type: "text",
157
+ value: "Desciption of year summary 1",
158
+ },
159
+ },
160
+ {
161
+ asset: {
162
+ id: "loverviewItem1-cy",
163
+ type: "text",
164
+ value: "14000",
165
+ },
166
+ },
167
+ ],
168
+ },
169
+ },
170
+ {
171
+ asset: {
172
+ id: "overviewItem2",
173
+ type: "overviewItem",
174
+ label: {
175
+ asset: {
176
+ id: "overviewItem2-label",
177
+ type: "text",
178
+ value: "Second year Summary",
179
+ },
180
+ },
181
+ values: [
182
+ {
183
+ asset: {
184
+ id: "overviewItem2-year",
185
+ type: "text",
186
+ value: "Desciption of year summary item 2",
187
+ },
188
+ },
189
+ {
190
+ asset: {
191
+ id: "loverviewItem1-cy",
192
+ type: "text",
193
+ value: "19000",
194
+ },
195
+ },
196
+ ],
197
+ },
198
+ },
199
+ ],
200
+ },
201
+ {
202
+ id: "overviewGroup",
203
+ type: "overviewGroup",
204
+ metaData: {
205
+ role: "stateful",
206
+ },
207
+ modifiers: [
208
+ {
209
+ type: "tag",
210
+ value: "fancy-header",
211
+ },
212
+ ],
213
+ headers: {
214
+ label: {
215
+ asset: {
216
+ id: "line-of-work-summary-gh-header-label",
217
+ type: "text",
218
+ value: "Header",
219
+ },
220
+ },
221
+ values: [
222
+ {
223
+ asset: {
224
+ id: "line-of-work-summary-gh-expenses-simple-header-previous-year",
225
+ type: "text",
226
+ value: "Type",
227
+ },
228
+ },
229
+ {
230
+ asset: {
231
+ id: "line-of-work-summary-gh-expenses-simple-header-cy",
232
+ type: "text",
233
+ value: "2022",
234
+ },
235
+ },
236
+ ],
237
+ },
238
+ values: [
239
+ {
240
+ asset: {
241
+ id: "overviewItem1",
242
+ type: "overviewItem",
243
+ label: {
244
+ asset: {
245
+ id: "overviewItem1-label",
246
+ type: "text",
247
+ value: "First Summary",
248
+ },
249
+ },
250
+ values: [
251
+ {
252
+ asset: {
253
+ id: "overviewItem1-year",
254
+ type: "text",
255
+ value: "Desciption of year summary 1",
256
+ },
257
+ },
258
+ {
259
+ asset: {
260
+ id: "loverviewItem1-cy",
261
+ type: "text",
262
+ value: "14000",
263
+ },
264
+ },
265
+ ],
266
+ },
267
+ },
268
+ {
269
+ asset: {
270
+ id: "overviewItem2",
271
+ type: "overviewItem",
272
+ label: {
273
+ asset: {
274
+ id: "overviewItem2-label",
275
+ type: "text",
276
+ value: "Second year Summary",
277
+ },
278
+ },
279
+ values: [
280
+ {
281
+ asset: {
282
+ id: "overviewItem2-year",
283
+ type: "text",
284
+ value: "Desciption of year summary item 2",
285
+ },
286
+ },
287
+ {
288
+ asset: {
289
+ id: "loverviewItem1-cy",
290
+ type: "text",
291
+ value: "19000",
292
+ },
293
+ },
294
+ ],
295
+ },
296
+ },
297
+ ],
298
+ template: [
299
+ {
300
+ data: "forms.1099-A",
301
+ output: "values",
302
+ value: {
303
+ asset: {
304
+ id: "overviewItem3",
305
+ type: "overviewItem",
306
+ label: {
307
+ asset: {
308
+ id: "overviewItem3-label",
309
+ type: "text",
310
+ value: "1099-A",
311
+ },
312
+ },
313
+ values: [
314
+ {
315
+ asset: {
316
+ id: "overviewItem3-year",
317
+ type: "text",
318
+ value: "Desciption of concept 1099 1",
319
+ },
320
+ },
321
+ {
322
+ asset: {
323
+ id: "loverviewItem3-cy",
324
+ type: "text",
325
+ value: "4000",
326
+ },
327
+ },
328
+ ],
329
+ },
330
+ },
331
+ },
332
+ {
333
+ data: "forms.1099-B",
334
+ output: "values",
335
+ value: {
336
+ asset: {
337
+ id: "overviewItem4",
338
+ type: "overviewItem",
339
+ label: {
340
+ asset: {
341
+ id: "overviewItem4-label",
342
+ type: "text",
343
+ value: "1099-B",
344
+ },
345
+ },
346
+ values: [
347
+ {
348
+ asset: {
349
+ id: "overviewItem4-year",
350
+ type: "text",
351
+ value: "Desciption of concept 1099 2",
352
+ },
353
+ },
354
+ {
355
+ asset: {
356
+ id: "loverviewItem3-cy",
357
+ type: "text",
358
+ value: "6000",
359
+ },
360
+ },
361
+ ],
362
+ },
363
+ },
364
+ },
365
+ ],
366
+ },
367
+ ],
368
+ navigation: {
369
+ BEGIN: "SnippetFlow",
370
+ SnippetFlow: {
371
+ startState: "VIEW_Snippet-View1",
372
+ "VIEW_Snippet-View1": {
373
+ ref: "overviewGroup",
374
+ state_type: "VIEW",
375
+ },
376
+ },
377
+ },
378
+ };
379
+
380
+ const parseBinding = new BindingParser().parse;
381
+
382
+ describe("templates", () => {
383
+ let model: DataModelWithParser;
384
+ let expressionEvaluator: ExpressionEvaluator;
385
+ let options: Options;
386
+ let parser: Parser;
387
+
388
+ beforeEach(() => {
389
+ model = withParser(new LocalModel(), parseBinding);
390
+ expressionEvaluator = new ExpressionEvaluator({
391
+ model,
392
+ });
393
+ parser = new Parser();
394
+ options = {
395
+ evaluate: expressionEvaluator.evaluate,
396
+ schema: new SchemaController(),
397
+ data: {
398
+ format: (binding, val) => val,
399
+ formatValue: (val) => val,
400
+ model,
401
+ },
402
+ };
403
+ new TemplatePlugin(options).applyParser(parser);
404
+ });
405
+
406
+ it("works with simple ones", () => {
407
+ const petNames = ["Ginger", "Daisy", "Afra"];
408
+ model.set([["foo.bar", petNames]]);
409
+
410
+ expect(
411
+ parser.parseObject({
412
+ id: "foo",
413
+ type: "collection",
414
+ template: [
415
+ {
416
+ data: "foo.bar",
417
+ output: "values",
418
+ value: {
419
+ value: "{{foo.bar._index_}}",
420
+ },
421
+ },
422
+ ],
423
+ }),
424
+ ).toMatchSnapshot();
425
+ });
426
+
427
+ it("works with nested templates", () => {
428
+ const petNames = ["Ginger", "Daisy", "Afra"];
429
+ model.set([["foo.pets", petNames]]);
430
+
431
+ const peopleNames = ["Adam", "Jenny"];
432
+ model.set([["foo.people", peopleNames]]);
433
+
434
+ expect(
435
+ parser.parseObject({
436
+ id: "foo",
437
+ type: "collection",
438
+ template: [
439
+ {
440
+ data: "foo.pets",
441
+ output: "values",
442
+ value: {
443
+ asset: {
444
+ type: "collection",
445
+ id: "outer-collection-_index_",
446
+ template: [
447
+ {
448
+ data: "foo.people",
449
+ output: "values",
450
+ value: {
451
+ text: "{{foo.pets._index_}} + {{foo.people._index1_}}",
452
+ },
453
+ },
454
+ ],
455
+ },
456
+ },
457
+ },
458
+ ],
459
+ }),
460
+ ).toMatchSnapshot();
461
+ });
462
+
463
+ it("determines if nodeType is template", () => {
464
+ const nodeTest = "template";
465
+ const nodeType = parser.hooks.determineNodeType.call(nodeTest);
466
+ expect(nodeType).toStrictEqual("template");
467
+ });
468
+
469
+ it("Does not return a nodeType", () => {
470
+ const nodeTest = {
471
+ value: "foo",
472
+ };
473
+ const nodeType = parser.hooks.determineNodeType.call(nodeTest);
474
+ expect(nodeType).toBe(undefined);
475
+ });
476
+
477
+ it("returns templateNode if template exists", () => {
478
+ const obj = {
479
+ dynamic: true,
480
+ data: "foo.bar",
481
+ output: "values",
482
+ value: {
483
+ value: "{{foo.bar._index_}}",
484
+ },
485
+ };
486
+ const nodeOptions = {
487
+ templateDepth: 1,
488
+ };
489
+ const parsedNode = parser.hooks.parseNode.call(
490
+ obj,
491
+ NodeType.Value,
492
+ nodeOptions,
493
+ NodeType.Template,
494
+ );
495
+ expect(parsedNode).toStrictEqual({
496
+ data: "foo.bar",
497
+ depth: 1,
498
+ dynamic: true,
499
+ template: {
500
+ value: "{{foo.bar._index_}}",
501
+ },
502
+ type: "template",
503
+ });
504
+ });
505
+
506
+ it("returns templateNode if template exists, and templateDepth is not set", () => {
507
+ const obj = {
508
+ data: "foo.bar2",
509
+ output: "values",
510
+ dynamic: true,
511
+ value: {
512
+ value: "{{foo.bar2._index_}}",
513
+ },
514
+ };
515
+ const nodeOptions = {};
516
+ const parsedNode = parser.hooks.parseNode.call(
517
+ obj,
518
+ NodeType.Value,
519
+ nodeOptions,
520
+ NodeType.Template,
521
+ );
522
+ expect(parsedNode).toStrictEqual({
523
+ data: "foo.bar2",
524
+ depth: 0,
525
+ dynamic: true,
526
+ template: {
527
+ value: "{{foo.bar2._index_}}",
528
+ },
529
+ type: "template",
530
+ });
531
+ });
532
+ });
533
+
534
+ describe("dynamic templates", () => {
535
+ it("static - nodes are not updated", () => {
536
+ const petNames = ["Ginger", "Vokey"];
537
+ const model = withParser(new LocalModel({}), parseBinding);
538
+ const evaluator = new ExpressionEvaluator({ model });
539
+ const schema = new SchemaController();
540
+
541
+ const view = new ViewInstance(
542
+ {
543
+ id: "my-view",
544
+ asset: {
545
+ id: "foo",
546
+ type: "collection",
547
+ template: [
548
+ {
549
+ dynamic: false,
550
+ data: "foo.bar",
551
+ output: "values",
552
+ value: {
553
+ value: "{{foo.bar._index_}}",
554
+ },
555
+ },
556
+ ],
557
+ },
558
+ } as any,
559
+ {
560
+ model,
561
+ parseBinding,
562
+ evaluator,
563
+ schema,
564
+ },
565
+ );
566
+
567
+ const pluginOptions = toNodeResolveOptions(view.resolverOptions);
568
+ new TemplatePlugin(pluginOptions).apply(view);
569
+ new StringResolverPlugin().apply(view);
570
+
571
+ model.set([["foo.bar", petNames]]);
572
+
573
+ const resolved = view.update();
574
+
575
+ expect(resolved).toStrictEqual({
576
+ id: "my-view",
577
+ asset: {
578
+ id: "foo",
579
+ type: "collection",
580
+ values: ["Ginger", "Vokey"].map((value) => ({ value })),
581
+ },
582
+ });
583
+
584
+ model.set([["foo.bar", ["Ginger", "Vokey", "Harry"]]]);
585
+
586
+ let updated = view.update();
587
+ expect(updated).toStrictEqual({
588
+ id: "my-view",
589
+ asset: {
590
+ id: "foo",
591
+ type: "collection",
592
+ values: ["Ginger", "Vokey"].map((value) => ({ value })),
593
+ },
594
+ });
595
+
596
+ model.set([["foo.bar", ["Ginger"]]]);
597
+ updated = view.update();
598
+ expect(updated).toStrictEqual({
599
+ id: "my-view",
600
+ asset: {
601
+ id: "foo",
602
+ type: "collection",
603
+ values: ["Ginger", undefined].map((value) => ({ value })),
604
+ },
605
+ });
606
+ });
607
+
608
+ it("dynamic - nodes are updated", () => {
609
+ const petNames = ["Ginger", "Vokey"];
610
+ const model = withParser(new LocalModel({}), parseBinding);
611
+ const evaluator = new ExpressionEvaluator({ model });
612
+ const schema = new SchemaController();
613
+
614
+ const view = new ViewInstance(
615
+ {
616
+ id: "my-view",
617
+ asset: {
618
+ id: "foo",
619
+ type: "collection",
620
+ template: [
621
+ {
622
+ dynamic: true,
623
+ data: "foo.bar",
624
+ output: "values",
625
+ value: {
626
+ value: "{{foo.bar._index_}}",
627
+ },
628
+ },
629
+ ],
630
+ },
631
+ } as any,
632
+ {
633
+ model,
634
+ parseBinding,
635
+ evaluator,
636
+ schema,
637
+ },
638
+ );
639
+
640
+ const pluginOptions = toNodeResolveOptions(view.resolverOptions);
641
+ new TemplatePlugin(pluginOptions).apply(view);
642
+ new StringResolverPlugin().apply(view);
643
+
644
+ model.set([["foo.bar", petNames]]);
645
+
646
+ const resolved = view.update();
647
+
648
+ expect(resolved).toStrictEqual({
649
+ id: "my-view",
650
+ asset: {
651
+ id: "foo",
652
+ type: "collection",
653
+ values: ["Ginger", "Vokey"].map((value) => ({ value })),
654
+ },
655
+ });
656
+
657
+ const barBinding = parseBinding("foo.bar");
658
+ model.set([[barBinding, ["Vokey", "Louis", "Bob"]]]);
659
+
660
+ let updated = view.update();
661
+ expect(updated).toStrictEqual({
662
+ id: "my-view",
663
+ asset: {
664
+ id: "foo",
665
+ type: "collection",
666
+ values: ["Vokey", "Louis", "Bob"].map((value) => ({ value })),
667
+ },
668
+ });
669
+
670
+ model.set([[barBinding, ["Nuri"]]]);
671
+ updated = view.update();
672
+ expect(updated).toStrictEqual({
673
+ id: "my-view",
674
+ asset: {
675
+ id: "foo",
676
+ type: "collection",
677
+ values: ["Nuri"].map((value) => ({ value })),
678
+ },
679
+ });
680
+ });
681
+
682
+ describe("Works with template items plus value items", () => {
683
+ const model = withParser(
684
+ new LocalModel(templateJoinValues.data),
685
+ parseBinding,
686
+ );
687
+ const evaluator = new ExpressionEvaluator({ model });
688
+
689
+ it("Should show template item first when coming before values on lexical order", () => {
690
+ const view = new ViewInstance(templateJoinValues.views[0], {
691
+ model,
692
+ parseBinding,
693
+ evaluator,
694
+ schema: new SchemaController(),
695
+ });
696
+
697
+ const pluginOptions = toNodeResolveOptions(view.resolverOptions);
698
+ new TemplatePlugin(pluginOptions).apply(view);
699
+ new StringResolverPlugin().apply(view);
700
+
701
+ const resolved = view.update();
702
+
703
+ expect(resolved.values).toHaveLength(4);
704
+ expect(resolved.values[0]).toMatchSnapshot();
705
+ });
706
+ it("Should show template item last when coming after values on lexical order", () => {
707
+ const view = new ViewInstance(templateJoinValues.views[1], {
708
+ model,
709
+ parseBinding,
710
+ evaluator,
711
+ schema: new SchemaController(),
712
+ });
713
+
714
+ const pluginOptions = toNodeResolveOptions(view.resolverOptions);
715
+ new TemplatePlugin(pluginOptions).apply(view);
716
+ new StringResolverPlugin().apply(view);
717
+
718
+ const resolved = view.update();
719
+
720
+ expect(resolved.values).toHaveLength(4);
721
+ expect(resolved.values[0]).toMatchSnapshot();
722
+ });
723
+ });
724
+ });