@valbuild/core 0.12.0 → 0.13.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/jest.config.js +4 -0
- package/package.json +1 -1
- package/src/Json.ts +4 -0
- package/src/expr/README.md +193 -0
- package/src/expr/eval.test.ts +202 -0
- package/src/expr/eval.ts +248 -0
- package/src/expr/expr.ts +91 -0
- package/src/expr/index.ts +3 -0
- package/src/expr/parser.test.ts +158 -0
- package/src/expr/parser.ts +229 -0
- package/src/expr/repl.ts +93 -0
- package/src/expr/tokenizer.test.ts +539 -0
- package/src/expr/tokenizer.ts +117 -0
- package/src/fetchVal.test.ts +164 -0
- package/src/fetchVal.ts +211 -0
- package/src/fp/array.ts +30 -0
- package/src/fp/index.ts +3 -0
- package/src/fp/result.ts +214 -0
- package/src/fp/util.ts +52 -0
- package/src/index.ts +55 -0
- package/src/initSchema.ts +45 -0
- package/src/initVal.ts +96 -0
- package/src/module.test.ts +170 -0
- package/src/module.ts +333 -0
- package/src/patch/deref.test.ts +300 -0
- package/src/patch/deref.ts +128 -0
- package/src/patch/index.ts +11 -0
- package/src/patch/json.test.ts +583 -0
- package/src/patch/json.ts +304 -0
- package/src/patch/operation.ts +74 -0
- package/src/patch/ops.ts +83 -0
- package/src/patch/parse.test.ts +202 -0
- package/src/patch/parse.ts +187 -0
- package/src/patch/patch.ts +46 -0
- package/src/patch/util.ts +67 -0
- package/src/schema/array.ts +52 -0
- package/src/schema/boolean.ts +38 -0
- package/src/schema/i18n.ts +65 -0
- package/src/schema/image.ts +70 -0
- package/src/schema/index.ts +46 -0
- package/src/schema/literal.ts +42 -0
- package/src/schema/number.ts +45 -0
- package/src/schema/object.ts +67 -0
- package/src/schema/oneOf.ts +60 -0
- package/src/schema/richtext.ts +417 -0
- package/src/schema/string.ts +49 -0
- package/src/schema/union.ts +62 -0
- package/src/selector/ExprProxy.test.ts +203 -0
- package/src/selector/ExprProxy.ts +209 -0
- package/src/selector/SelectorProxy.test.ts +172 -0
- package/src/selector/SelectorProxy.ts +237 -0
- package/src/selector/array.ts +37 -0
- package/src/selector/boolean.ts +4 -0
- package/src/selector/file.ts +14 -0
- package/src/selector/i18n.ts +13 -0
- package/src/selector/index.ts +159 -0
- package/src/selector/number.ts +4 -0
- package/src/selector/object.ts +22 -0
- package/src/selector/primitive.ts +17 -0
- package/src/selector/remote.ts +9 -0
- package/src/selector/selector.test.ts +453 -0
- package/src/selector/selectorOf.ts +7 -0
- package/src/selector/string.ts +4 -0
- package/src/source/file.ts +45 -0
- package/src/source/i18n.ts +60 -0
- package/src/source/index.ts +50 -0
- package/src/source/remote.ts +54 -0
- package/src/val/array.ts +10 -0
- package/src/val/index.ts +90 -0
- package/src/val/object.ts +13 -0
- package/src/val/primitive.ts +8 -0
@@ -0,0 +1,583 @@
|
|
1
|
+
import { describe, test, expect } from "@jest/globals";
|
2
|
+
import { JSONOps } from "./json";
|
3
|
+
import * as result from "../fp/result";
|
4
|
+
import { PatchError, JSONValue } from "./ops";
|
5
|
+
import { pipe } from "../fp/util";
|
6
|
+
import { NonEmptyArray } from "../fp/array";
|
7
|
+
import { deepClone } from "./util";
|
8
|
+
|
9
|
+
describe("JSONOps", () => {
|
10
|
+
test.each<{
|
11
|
+
name: string;
|
12
|
+
input: JSONValue;
|
13
|
+
path: string[];
|
14
|
+
value: JSONValue;
|
15
|
+
expected: result.Result<JSONValue, typeof PatchError>;
|
16
|
+
}>([
|
17
|
+
{
|
18
|
+
name: "root of document",
|
19
|
+
input: { foo: "bar" },
|
20
|
+
path: [],
|
21
|
+
value: null,
|
22
|
+
expected: result.ok(null),
|
23
|
+
},
|
24
|
+
{
|
25
|
+
name: "defined property to object",
|
26
|
+
input: { foo: "bar" },
|
27
|
+
path: ["foo"],
|
28
|
+
value: null,
|
29
|
+
expected: result.ok({ foo: null }),
|
30
|
+
},
|
31
|
+
{
|
32
|
+
name: "new property to object",
|
33
|
+
input: { foo: "bar" },
|
34
|
+
path: ["bar"],
|
35
|
+
value: null,
|
36
|
+
expected: result.ok({ foo: "bar", bar: null }),
|
37
|
+
},
|
38
|
+
{
|
39
|
+
name: "property to object that is not an identifier (empty string)",
|
40
|
+
input: { foo: "bar" },
|
41
|
+
path: [""],
|
42
|
+
value: "foo",
|
43
|
+
expected: result.ok({ foo: "bar", "": "foo" }),
|
44
|
+
},
|
45
|
+
{
|
46
|
+
name: "property to object that is not an identifier (strings with whitespace)",
|
47
|
+
input: { foo: "bar" },
|
48
|
+
path: ["foo and "],
|
49
|
+
value: "foo",
|
50
|
+
expected: result.ok({ foo: "bar", "foo and ": "foo" }),
|
51
|
+
},
|
52
|
+
{
|
53
|
+
name: "item to array followed by other items",
|
54
|
+
input: ["foo", "bar"],
|
55
|
+
path: ["0"],
|
56
|
+
value: null,
|
57
|
+
expected: result.ok([null, "foo", "bar"]),
|
58
|
+
},
|
59
|
+
{
|
60
|
+
name: "item to end of array",
|
61
|
+
input: ["foo", "bar"],
|
62
|
+
path: ["2"],
|
63
|
+
value: null,
|
64
|
+
expected: result.ok(["foo", "bar", null]),
|
65
|
+
},
|
66
|
+
{
|
67
|
+
name: "item to end of array with dash",
|
68
|
+
input: ["foo", "bar"],
|
69
|
+
path: ["-"],
|
70
|
+
value: null,
|
71
|
+
expected: result.ok(["foo", "bar", null]),
|
72
|
+
},
|
73
|
+
{
|
74
|
+
name: "item to array with invalid index",
|
75
|
+
input: ["foo", "bar"],
|
76
|
+
path: ["baz"],
|
77
|
+
value: null,
|
78
|
+
expected: result.err(PatchError),
|
79
|
+
},
|
80
|
+
{
|
81
|
+
name: "item at index out of bounds of array",
|
82
|
+
input: ["foo", "bar"],
|
83
|
+
path: ["3"],
|
84
|
+
value: null,
|
85
|
+
expected: result.err(PatchError),
|
86
|
+
},
|
87
|
+
{
|
88
|
+
name: "defined property to object nested within object",
|
89
|
+
input: { foo: { bar: "baz" } },
|
90
|
+
path: ["foo", "bar"],
|
91
|
+
value: null,
|
92
|
+
expected: result.ok({ foo: { bar: null } }),
|
93
|
+
},
|
94
|
+
{
|
95
|
+
name: "defined property to object nested within array",
|
96
|
+
input: [{ foo: "bar" }],
|
97
|
+
path: ["0", "foo"],
|
98
|
+
value: null,
|
99
|
+
expected: result.ok([{ foo: null }]),
|
100
|
+
},
|
101
|
+
{
|
102
|
+
name: "to undefined object/array",
|
103
|
+
input: { foo: "bar" },
|
104
|
+
path: ["bar", "foo"],
|
105
|
+
value: null,
|
106
|
+
expected: result.err(PatchError),
|
107
|
+
},
|
108
|
+
{
|
109
|
+
name: "to non-object/array",
|
110
|
+
input: 0,
|
111
|
+
path: ["foo"],
|
112
|
+
value: null,
|
113
|
+
expected: result.err(PatchError),
|
114
|
+
},
|
115
|
+
])("add $name", ({ input, path, value, expected }) => {
|
116
|
+
const ops = new JSONOps();
|
117
|
+
expect(
|
118
|
+
pipe(
|
119
|
+
ops.add(deepClone(input), path, value),
|
120
|
+
result.mapErr(() => PatchError)
|
121
|
+
)
|
122
|
+
).toEqual(expected);
|
123
|
+
});
|
124
|
+
|
125
|
+
test.each<{
|
126
|
+
name: string;
|
127
|
+
input: JSONValue;
|
128
|
+
path: NonEmptyArray<string>;
|
129
|
+
expected: result.Result<JSONValue, typeof PatchError>;
|
130
|
+
}>([
|
131
|
+
{
|
132
|
+
name: "defined property from object",
|
133
|
+
input: { foo: "bar", bar: "baz" },
|
134
|
+
path: ["bar"],
|
135
|
+
expected: result.ok({ foo: "bar" }),
|
136
|
+
},
|
137
|
+
{
|
138
|
+
name: "undefined property to object",
|
139
|
+
input: { foo: "bar" },
|
140
|
+
path: ["bar"],
|
141
|
+
expected: result.err(PatchError),
|
142
|
+
},
|
143
|
+
{
|
144
|
+
name: "existing item from array",
|
145
|
+
input: ["foo", "bar"],
|
146
|
+
path: ["0"],
|
147
|
+
expected: result.ok(["bar"]),
|
148
|
+
},
|
149
|
+
{
|
150
|
+
name: "item from end of array with dash",
|
151
|
+
input: ["foo", "bar"],
|
152
|
+
path: ["-"],
|
153
|
+
expected: result.err(PatchError),
|
154
|
+
},
|
155
|
+
{
|
156
|
+
name: "item at index out of bounds of array",
|
157
|
+
input: ["foo", "bar"],
|
158
|
+
path: ["2"],
|
159
|
+
expected: result.err(PatchError),
|
160
|
+
},
|
161
|
+
{
|
162
|
+
name: "item from array with invalid index",
|
163
|
+
input: ["foo", "bar"],
|
164
|
+
path: ["baz"],
|
165
|
+
expected: result.err(PatchError),
|
166
|
+
},
|
167
|
+
{
|
168
|
+
name: "defined property from object nested within object",
|
169
|
+
input: { foo: { bar: "baz", baz: "bar" } },
|
170
|
+
path: ["foo", "baz"],
|
171
|
+
expected: result.ok({ foo: { bar: "baz" } }),
|
172
|
+
},
|
173
|
+
{
|
174
|
+
name: "defined property from object nested within array",
|
175
|
+
input: [{ foo: "bar", baz: "bar" }],
|
176
|
+
path: ["0", "baz"],
|
177
|
+
expected: result.ok([{ foo: "bar" }]),
|
178
|
+
},
|
179
|
+
{
|
180
|
+
name: "from undefined object/array",
|
181
|
+
input: { foo: "bar" },
|
182
|
+
path: ["bar", "foo"],
|
183
|
+
expected: result.err(PatchError),
|
184
|
+
},
|
185
|
+
{
|
186
|
+
name: "from non-object/array",
|
187
|
+
input: 0,
|
188
|
+
path: ["foo"],
|
189
|
+
expected: result.err(PatchError),
|
190
|
+
},
|
191
|
+
])("remove $name", ({ input, path, expected }) => {
|
192
|
+
const ops = new JSONOps();
|
193
|
+
expect(
|
194
|
+
pipe(
|
195
|
+
ops.remove(deepClone(input), path),
|
196
|
+
result.mapErr(() => PatchError)
|
197
|
+
)
|
198
|
+
).toEqual(expected);
|
199
|
+
});
|
200
|
+
|
201
|
+
test.each<{
|
202
|
+
name: string;
|
203
|
+
input: JSONValue;
|
204
|
+
path: string[];
|
205
|
+
value: JSONValue;
|
206
|
+
expected: result.Result<JSONValue, typeof PatchError>;
|
207
|
+
}>([
|
208
|
+
{
|
209
|
+
name: "root of document",
|
210
|
+
input: { foo: "bar" },
|
211
|
+
path: [],
|
212
|
+
value: null,
|
213
|
+
expected: result.ok(null),
|
214
|
+
},
|
215
|
+
{
|
216
|
+
name: "defined property of object",
|
217
|
+
input: { foo: "bar" },
|
218
|
+
path: ["foo"],
|
219
|
+
value: null,
|
220
|
+
expected: result.ok({ foo: null }),
|
221
|
+
},
|
222
|
+
{
|
223
|
+
name: "undefined property of object",
|
224
|
+
input: { foo: "bar" },
|
225
|
+
path: ["bar"],
|
226
|
+
value: null,
|
227
|
+
expected: result.err(PatchError),
|
228
|
+
},
|
229
|
+
{
|
230
|
+
name: "item of array",
|
231
|
+
input: ["foo", "bar"],
|
232
|
+
path: ["0"],
|
233
|
+
value: null,
|
234
|
+
expected: result.ok([null, "bar"]),
|
235
|
+
},
|
236
|
+
{
|
237
|
+
name: "item of array at invalid index",
|
238
|
+
input: ["foo", "bar"],
|
239
|
+
path: ["baz"],
|
240
|
+
value: null,
|
241
|
+
expected: result.err(PatchError),
|
242
|
+
},
|
243
|
+
{
|
244
|
+
name: "item at index out of bounds of array",
|
245
|
+
input: ["foo", "bar"],
|
246
|
+
path: ["2"],
|
247
|
+
value: null,
|
248
|
+
expected: result.err(PatchError),
|
249
|
+
},
|
250
|
+
{
|
251
|
+
name: "defined property of object nested within object",
|
252
|
+
input: { foo: { bar: "baz" } },
|
253
|
+
path: ["foo", "bar"],
|
254
|
+
value: null,
|
255
|
+
expected: result.ok({ foo: { bar: null } }),
|
256
|
+
},
|
257
|
+
{
|
258
|
+
name: "defined property of object nested within array",
|
259
|
+
input: [{ foo: "bar" }],
|
260
|
+
path: ["0", "foo"],
|
261
|
+
value: null,
|
262
|
+
expected: result.ok([{ foo: null }]),
|
263
|
+
},
|
264
|
+
{
|
265
|
+
name: "from undefined object/array",
|
266
|
+
input: { foo: "bar" },
|
267
|
+
path: ["bar", "foo"],
|
268
|
+
value: null,
|
269
|
+
expected: result.err(PatchError),
|
270
|
+
},
|
271
|
+
{
|
272
|
+
name: "from non-object/array",
|
273
|
+
input: 0,
|
274
|
+
path: ["foo"],
|
275
|
+
value: null,
|
276
|
+
expected: result.err(PatchError),
|
277
|
+
},
|
278
|
+
])("replace $name", ({ input, path, value, expected }) => {
|
279
|
+
const ops = new JSONOps();
|
280
|
+
expect(
|
281
|
+
pipe(
|
282
|
+
ops.replace(deepClone(input), path, value),
|
283
|
+
result.mapErr(() => PatchError)
|
284
|
+
)
|
285
|
+
).toEqual(expected);
|
286
|
+
});
|
287
|
+
|
288
|
+
test.each<{
|
289
|
+
name: string;
|
290
|
+
input: JSONValue;
|
291
|
+
from: NonEmptyArray<string>;
|
292
|
+
path: string[];
|
293
|
+
expected: result.Result<JSONValue, typeof PatchError>;
|
294
|
+
}>([
|
295
|
+
{
|
296
|
+
name: "value to root of document",
|
297
|
+
input: { foo: "bar" },
|
298
|
+
from: ["foo"],
|
299
|
+
path: [],
|
300
|
+
expected: result.ok("bar"),
|
301
|
+
},
|
302
|
+
{
|
303
|
+
name: "defined property to undefined property of object",
|
304
|
+
input: { foo: null, baz: 1 },
|
305
|
+
from: ["foo"],
|
306
|
+
path: ["bar"],
|
307
|
+
expected: result.ok({ baz: 1, bar: null }),
|
308
|
+
},
|
309
|
+
{
|
310
|
+
name: "defined property to defined property of object",
|
311
|
+
input: { foo: null, bar: "baz" },
|
312
|
+
from: ["foo"],
|
313
|
+
path: ["bar"],
|
314
|
+
expected: result.ok({ bar: null }),
|
315
|
+
},
|
316
|
+
{
|
317
|
+
name: "undefined property of object",
|
318
|
+
input: { foo: "bar" },
|
319
|
+
from: ["bar"],
|
320
|
+
path: ["baz"],
|
321
|
+
expected: result.err(PatchError),
|
322
|
+
},
|
323
|
+
{
|
324
|
+
name: "item within array",
|
325
|
+
input: ["foo", null],
|
326
|
+
from: ["1"],
|
327
|
+
path: ["0"],
|
328
|
+
expected: result.ok([null, "foo"]),
|
329
|
+
},
|
330
|
+
{
|
331
|
+
name: "item to end of array with dash",
|
332
|
+
input: [null, "foo"],
|
333
|
+
from: ["0"],
|
334
|
+
path: ["-"],
|
335
|
+
expected: result.ok(["foo", null]),
|
336
|
+
},
|
337
|
+
{
|
338
|
+
name: "item from invalid index of array",
|
339
|
+
input: ["foo", "bar"],
|
340
|
+
from: ["foo"],
|
341
|
+
path: ["0"],
|
342
|
+
expected: result.err(PatchError),
|
343
|
+
},
|
344
|
+
{
|
345
|
+
name: "item to invalid index of array",
|
346
|
+
input: ["foo", "bar"],
|
347
|
+
from: ["1"],
|
348
|
+
path: ["foo"],
|
349
|
+
expected: result.err(PatchError),
|
350
|
+
},
|
351
|
+
{
|
352
|
+
name: "item from index out of bounds of array",
|
353
|
+
input: ["foo", "bar"],
|
354
|
+
from: ["2"],
|
355
|
+
path: ["0"],
|
356
|
+
expected: result.err(PatchError),
|
357
|
+
},
|
358
|
+
{
|
359
|
+
name: "item to index out of bounds of array",
|
360
|
+
input: ["foo", "bar"],
|
361
|
+
from: ["0"],
|
362
|
+
path: ["2"],
|
363
|
+
expected: result.err(PatchError),
|
364
|
+
},
|
365
|
+
])("move $name", ({ input, from, path, expected }) => {
|
366
|
+
const ops = new JSONOps();
|
367
|
+
expect(
|
368
|
+
pipe(
|
369
|
+
ops.move(deepClone(input), from, path),
|
370
|
+
result.mapErr(() => PatchError)
|
371
|
+
)
|
372
|
+
).toEqual(expected);
|
373
|
+
});
|
374
|
+
|
375
|
+
test.each<{
|
376
|
+
name: string;
|
377
|
+
input: JSONValue;
|
378
|
+
from: string[];
|
379
|
+
path: string[];
|
380
|
+
expected: result.Result<JSONValue, typeof PatchError>;
|
381
|
+
}>([
|
382
|
+
{
|
383
|
+
name: "object into itself",
|
384
|
+
input: { foo: "bar" },
|
385
|
+
from: [],
|
386
|
+
path: ["foo"],
|
387
|
+
expected: result.ok({ foo: { foo: "bar" } }),
|
388
|
+
},
|
389
|
+
{
|
390
|
+
name: "value to root of document",
|
391
|
+
input: { foo: "bar" },
|
392
|
+
from: ["foo"],
|
393
|
+
path: [],
|
394
|
+
expected: result.ok("bar"),
|
395
|
+
},
|
396
|
+
{
|
397
|
+
name: "defined property to undefined property of object",
|
398
|
+
input: { foo: null, baz: 1 },
|
399
|
+
from: ["foo"],
|
400
|
+
path: ["bar"],
|
401
|
+
expected: result.ok({ foo: null, baz: 1, bar: null }),
|
402
|
+
},
|
403
|
+
{
|
404
|
+
name: "defined property to defined property of object",
|
405
|
+
input: { foo: null, bar: "baz" },
|
406
|
+
from: ["foo"],
|
407
|
+
path: ["bar"],
|
408
|
+
expected: result.ok({ foo: null, bar: null }),
|
409
|
+
},
|
410
|
+
{
|
411
|
+
name: "undefined property of object",
|
412
|
+
input: { foo: "bar" },
|
413
|
+
from: ["bar"],
|
414
|
+
path: ["baz"],
|
415
|
+
expected: result.err(PatchError),
|
416
|
+
},
|
417
|
+
{
|
418
|
+
name: "item within array",
|
419
|
+
input: ["foo", null],
|
420
|
+
from: ["1"],
|
421
|
+
path: ["0"],
|
422
|
+
expected: result.ok([null, "foo", null]),
|
423
|
+
},
|
424
|
+
{
|
425
|
+
name: "item to end of array with dash",
|
426
|
+
input: [null, "foo"],
|
427
|
+
from: ["0"],
|
428
|
+
path: ["-"],
|
429
|
+
expected: result.ok([null, "foo", null]),
|
430
|
+
},
|
431
|
+
{
|
432
|
+
name: "item from invalid index of array",
|
433
|
+
input: ["foo", "bar"],
|
434
|
+
from: ["foo"],
|
435
|
+
path: ["0"],
|
436
|
+
expected: result.err(PatchError),
|
437
|
+
},
|
438
|
+
{
|
439
|
+
name: "item to invalid index of array",
|
440
|
+
input: ["foo", "bar"],
|
441
|
+
from: ["1"],
|
442
|
+
path: ["foo"],
|
443
|
+
expected: result.err(PatchError),
|
444
|
+
},
|
445
|
+
{
|
446
|
+
name: "item from index out of bounds of array",
|
447
|
+
input: ["foo", "bar"],
|
448
|
+
from: ["2"],
|
449
|
+
path: ["0"],
|
450
|
+
expected: result.err(PatchError),
|
451
|
+
},
|
452
|
+
{
|
453
|
+
name: "item to index out of bounds of array",
|
454
|
+
input: ["foo", "bar"],
|
455
|
+
from: ["0"],
|
456
|
+
path: ["3"],
|
457
|
+
expected: result.err(PatchError),
|
458
|
+
},
|
459
|
+
])("copy $name", ({ input, from, path, expected }) => {
|
460
|
+
const ops = new JSONOps();
|
461
|
+
expect(
|
462
|
+
pipe(
|
463
|
+
ops.copy(deepClone(input), from, path),
|
464
|
+
result.mapErr(() => PatchError)
|
465
|
+
)
|
466
|
+
).toEqual(expected);
|
467
|
+
});
|
468
|
+
|
469
|
+
test.each<{
|
470
|
+
name: string;
|
471
|
+
input: JSONValue;
|
472
|
+
path: string[];
|
473
|
+
value: JSONValue;
|
474
|
+
expected: result.Result<boolean, typeof PatchError>;
|
475
|
+
}>([
|
476
|
+
{
|
477
|
+
name: "object 1",
|
478
|
+
input: { foo: "bar" },
|
479
|
+
path: [],
|
480
|
+
value: { foo: "bar" },
|
481
|
+
expected: result.ok(true),
|
482
|
+
},
|
483
|
+
{
|
484
|
+
name: "object 2",
|
485
|
+
input: { foo: "bar" },
|
486
|
+
path: [],
|
487
|
+
value: null,
|
488
|
+
expected: result.ok(false),
|
489
|
+
},
|
490
|
+
{
|
491
|
+
name: "array 1",
|
492
|
+
input: ["foo", "bar"],
|
493
|
+
path: [],
|
494
|
+
value: ["foo", "bar"],
|
495
|
+
expected: result.ok(true),
|
496
|
+
},
|
497
|
+
{
|
498
|
+
name: "array 2",
|
499
|
+
input: ["foo", "bar"],
|
500
|
+
path: [],
|
501
|
+
value: ["bar", "foo"],
|
502
|
+
expected: result.ok(false),
|
503
|
+
},
|
504
|
+
{
|
505
|
+
name: "defined property from object",
|
506
|
+
input: { foo: "bar", bar: "baz" },
|
507
|
+
path: ["bar"],
|
508
|
+
value: "baz",
|
509
|
+
expected: result.ok(true),
|
510
|
+
},
|
511
|
+
{
|
512
|
+
name: "undefined property of object",
|
513
|
+
input: { foo: "bar" },
|
514
|
+
path: ["bar"],
|
515
|
+
value: null,
|
516
|
+
expected: result.err(PatchError),
|
517
|
+
},
|
518
|
+
{
|
519
|
+
name: "item from array",
|
520
|
+
input: ["foo", "bar"],
|
521
|
+
path: ["0"],
|
522
|
+
value: "foo",
|
523
|
+
expected: result.ok(true),
|
524
|
+
},
|
525
|
+
{
|
526
|
+
name: "item from end of array with dash",
|
527
|
+
input: ["foo", "bar"],
|
528
|
+
path: ["-"],
|
529
|
+
value: null,
|
530
|
+
expected: result.err(PatchError),
|
531
|
+
},
|
532
|
+
{
|
533
|
+
name: "item at index out of bounds of array",
|
534
|
+
input: ["foo", "bar"],
|
535
|
+
path: ["2"],
|
536
|
+
value: null,
|
537
|
+
expected: result.err(PatchError),
|
538
|
+
},
|
539
|
+
{
|
540
|
+
name: "item from array with invalid index",
|
541
|
+
input: ["foo", "bar"],
|
542
|
+
path: ["baz"],
|
543
|
+
value: null,
|
544
|
+
expected: result.err(PatchError),
|
545
|
+
},
|
546
|
+
{
|
547
|
+
name: "complex nested objects",
|
548
|
+
input: { foo: { bar: "baz", baz: ["bar", { 0: 1 }] } },
|
549
|
+
path: [],
|
550
|
+
value: { foo: { bar: "baz", baz: ["bar", { 0: 1 }] } },
|
551
|
+
expected: result.ok(true),
|
552
|
+
},
|
553
|
+
{
|
554
|
+
name: "at undefined object/array",
|
555
|
+
input: { foo: "bar" },
|
556
|
+
path: ["bar", "foo"],
|
557
|
+
value: null,
|
558
|
+
expected: result.err(PatchError),
|
559
|
+
},
|
560
|
+
{
|
561
|
+
name: "escaped paths",
|
562
|
+
input: { "foo/bar~/~": "baz" },
|
563
|
+
path: ["foo/bar~/~"],
|
564
|
+
value: "baz",
|
565
|
+
expected: result.ok(true),
|
566
|
+
},
|
567
|
+
{
|
568
|
+
name: "at non-object/array",
|
569
|
+
input: 0,
|
570
|
+
path: ["foo"],
|
571
|
+
value: null,
|
572
|
+
expected: result.err(PatchError),
|
573
|
+
},
|
574
|
+
])("test $name", ({ input, path, value, expected }) => {
|
575
|
+
const ops = new JSONOps();
|
576
|
+
expect(
|
577
|
+
pipe(
|
578
|
+
ops.test(deepClone(input), path, value),
|
579
|
+
result.mapErr(() => PatchError)
|
580
|
+
)
|
581
|
+
).toEqual(expected);
|
582
|
+
});
|
583
|
+
});
|