@reventlessdev/reventless-core 3.0.0-alpha.261 → 3.0.0-alpha.263
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/CHANGELOG.md +31 -0
- package/package.json +9 -9
- package/src/adapter/Secrets/Secrets_Node_Backend.res +60 -0
- package/src/adapter/Secrets/Secrets_Node_Backend.res.mjs +69 -0
- package/src/admin/Platform_Admin_Structure.res.mjs +1 -1
- package/src/components/Aggregate/Aggregate_Builder.res.mjs +1 -1
- package/src/components/CommandGenerator/CommandGenerator.res +4 -4
- package/src/components/CommandGenerator/CommandGenerator_Callback.res +13 -20
- package/src/components/CommandGenerator/CommandGenerator_Callback.res.mjs +3 -24
- package/src/components/Dcb/Dcb_Builder.res +45 -49
- package/src/components/Dcb/Dcb_Builder.res.mjs +31 -40
- package/src/components/StateChangeSlice/StateChangeSlice.res +2 -0
- package/src/components/StateChangeSlice/StateChangeSlice_Builder.res +6 -0
- package/src/components/StateChangeSlice/StateChangeSlice_Builder.res.mjs +4 -4
- package/src/components/StateChangeSlice/StateChangeSlice_Callback.res +51 -22
- package/src/components/StateChangeSlice/StateChangeSlice_Callback.res.mjs +47 -25
- package/src/plugin/component/Plugin_Structure.res +101 -4
- package/src/plugin/component/Plugin_Structure.res.mjs +82 -9
- package/tests/Secrets_Node_BackendTest.res +141 -0
- package/tests/Secrets_Node_BackendTest.res.mjs +152 -0
- package/tests/adapter/RuntimeExtensionHookReachTest.res.mjs +1 -1
- package/tests/admin/Platform_Admin_StructureTest.res +12 -3
- package/tests/admin/Platform_Admin_StructureTest.res.mjs +4 -3
- package/tests/commandgenerator/CommandGeneratorCallbackTest.res +1 -1
- package/tests/commandgenerator/CommandGeneratorCallbackTest.res.mjs +1 -1
- package/tests/commandgenerator/CommandGeneratorFixtures.res +2 -0
- package/tests/commandgenerator/CommandGeneratorFixtures.res.mjs +17 -3
- package/tests/commandgenerator/OwnerStampingTest.res.mjs +2 -2
- package/tests/commandtopic/CommandOutcomeHookTest.res.mjs +1 -1
- package/tests/dcb/DcbFixtures.res +18 -1
- package/tests/dcb/DcbFixtures.res.mjs +14 -0
- package/tests/dcb/DcbScopeInferenceTest.res +234 -0
- package/tests/dcb/DcbScopeInferenceTest.res.mjs +425 -13
- package/tests/dcb/DcbStateChangeSliceTest.res.mjs +22 -22
- package/tests/dcb/DcbTagTest.res +81 -68
- package/tests/dcb/DcbTagTest.res.mjs +88 -89
- package/tests/plugin/PluginStructureAccessTest.res +1 -0
- package/tests/plugin/PluginStructureAccessTest.res.mjs +1 -1
- package/tests/plugin/PluginStructureTest.res +47 -0
- package/tests/plugin/PluginStructureTest.res.mjs +50 -10
|
@@ -28,7 +28,7 @@ function ev(eventType, idFields) {
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
function slice(sliceName, commandOpt, consumedOpt, producedOpt, partitionHint) {
|
|
31
|
+
function slice(sliceName, commandOpt, consumedOpt, producedOpt, partitionHint, chapter) {
|
|
32
32
|
let command = commandOpt !== undefined ? commandOpt : [];
|
|
33
33
|
let consumed = consumedOpt !== undefined ? consumedOpt : [];
|
|
34
34
|
let produced = producedOpt !== undefined ? producedOpt : [];
|
|
@@ -37,7 +37,8 @@ function slice(sliceName, commandOpt, consumedOpt, producedOpt, partitionHint) {
|
|
|
37
37
|
command: command,
|
|
38
38
|
consumed: consumed,
|
|
39
39
|
produced: produced,
|
|
40
|
-
partitionHint: partitionHint
|
|
40
|
+
partitionHint: partitionHint,
|
|
41
|
+
chapter: chapter
|
|
41
42
|
};
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -84,7 +85,7 @@ let addProduct = slice("AddProduct", [
|
|
|
84
85
|
isList: false
|
|
85
86
|
}
|
|
86
87
|
]
|
|
87
|
-
}], undefined);
|
|
88
|
+
}], undefined, undefined);
|
|
88
89
|
|
|
89
90
|
let addCategory = slice("AddCategory", [{
|
|
90
91
|
name: "categoryId",
|
|
@@ -104,7 +105,7 @@ let addCategory = slice("AddCategory", [{
|
|
|
104
105
|
name: "categoryId",
|
|
105
106
|
isList: false
|
|
106
107
|
}]
|
|
107
|
-
}], undefined);
|
|
108
|
+
}], undefined, undefined);
|
|
108
109
|
|
|
109
110
|
let renameCategory = slice("RenameCategory", [{
|
|
110
111
|
name: "categoryId",
|
|
@@ -128,7 +129,7 @@ let renameCategory = slice("RenameCategory", [{
|
|
|
128
129
|
name: "categoryId",
|
|
129
130
|
isList: false
|
|
130
131
|
}]
|
|
131
|
-
}], undefined);
|
|
132
|
+
}], undefined, undefined);
|
|
132
133
|
|
|
133
134
|
let archiveCategory = slice("ArchiveCategory", [{
|
|
134
135
|
name: "categoryId",
|
|
@@ -148,7 +149,7 @@ let archiveCategory = slice("ArchiveCategory", [{
|
|
|
148
149
|
name: "categoryId",
|
|
149
150
|
isList: false
|
|
150
151
|
}]
|
|
151
|
-
}], undefined);
|
|
152
|
+
}], undefined, undefined);
|
|
152
153
|
|
|
153
154
|
let catalog = [
|
|
154
155
|
addProduct,
|
|
@@ -242,7 +243,7 @@ globalThis.describe("DcbScopeInference:", () => {
|
|
|
242
243
|
}
|
|
243
244
|
]
|
|
244
245
|
}
|
|
245
|
-
], "productId");
|
|
246
|
+
], "productId", undefined);
|
|
246
247
|
let d = DcbScopeInference$Reventless.infer([recordDemand]);
|
|
247
248
|
globalThis.test("the @partitionTag hint resolves the partition (no ambiguity)", () => {
|
|
248
249
|
globalThis.expect(d.partitionBySlice["RecordProductDemand"]).toEqual("productId");
|
|
@@ -295,7 +296,7 @@ globalThis.describe("DcbScopeInference:", () => {
|
|
|
295
296
|
isList: true
|
|
296
297
|
}
|
|
297
298
|
]
|
|
298
|
-
}], undefined);
|
|
299
|
+
}], undefined, undefined);
|
|
299
300
|
let productEntity = slice("SyncCatalogProduct", [{
|
|
300
301
|
name: "productId",
|
|
301
302
|
isList: false
|
|
@@ -308,7 +309,7 @@ globalThis.describe("DcbScopeInference:", () => {
|
|
|
308
309
|
name: "productId",
|
|
309
310
|
isList: false
|
|
310
311
|
}]
|
|
311
|
-
}], undefined);
|
|
312
|
+
}], undefined, undefined);
|
|
312
313
|
let d = DcbScopeInference$Reventless.infer([
|
|
313
314
|
placeOrder,
|
|
314
315
|
productEntity
|
|
@@ -342,7 +343,7 @@ globalThis.describe("DcbScopeInference:", () => {
|
|
|
342
343
|
name: "studentId",
|
|
343
344
|
isList: false
|
|
344
345
|
}]
|
|
345
|
-
}], undefined);
|
|
346
|
+
}], undefined, undefined);
|
|
346
347
|
let subscribe_command = [
|
|
347
348
|
{
|
|
348
349
|
name: "courseId",
|
|
@@ -403,6 +404,417 @@ globalThis.describe("DcbScopeInference:", () => {
|
|
|
403
404
|
globalThis.expect(issues.redundancies).toEqual([]);
|
|
404
405
|
});
|
|
405
406
|
});
|
|
407
|
+
globalThis.describe("partition: identity given back only when subtraction leaves nothing", () => {
|
|
408
|
+
globalThis.test("AddProduct without a hint stays productId, though its category arms come from a categoryId slice", () => {
|
|
409
|
+
let d = DcbScopeInference$Reventless.infer(catalog);
|
|
410
|
+
globalThis.expect(addProduct.partitionHint).toEqual(undefined);
|
|
411
|
+
globalThis.expect(d.partitionBySlice["AddProduct"]).toEqual("productId");
|
|
412
|
+
});
|
|
413
|
+
globalThis.test("a lifecycle arm naming the slice's own id resolves", () => {
|
|
414
|
+
let changeName = slice("ChangeProductName", [{
|
|
415
|
+
name: "productId",
|
|
416
|
+
isList: false
|
|
417
|
+
}], [{
|
|
418
|
+
eventType: "ProductAdded",
|
|
419
|
+
idFields: [{
|
|
420
|
+
name: "productId",
|
|
421
|
+
isList: false
|
|
422
|
+
}]
|
|
423
|
+
}], [{
|
|
424
|
+
eventType: "ProductNameChanged",
|
|
425
|
+
idFields: [{
|
|
426
|
+
name: "productId",
|
|
427
|
+
isList: false
|
|
428
|
+
}]
|
|
429
|
+
}], undefined, undefined);
|
|
430
|
+
let d = DcbScopeInference$Reventless.infer(catalog.concat([changeName]));
|
|
431
|
+
globalThis.expect(d.partitionBySlice["ChangeProductName"]).toEqual("productId");
|
|
432
|
+
globalThis.expect(d.ambiguities).toEqual([]);
|
|
433
|
+
});
|
|
434
|
+
let placeOrder = slice("PlaceOrder", [
|
|
435
|
+
{
|
|
436
|
+
name: "orderId",
|
|
437
|
+
isList: false
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
name: "customerId",
|
|
441
|
+
isList: false
|
|
442
|
+
}
|
|
443
|
+
], undefined, [{
|
|
444
|
+
eventType: "OrderPlaced",
|
|
445
|
+
idFields: [
|
|
446
|
+
{
|
|
447
|
+
name: "orderId",
|
|
448
|
+
isList: false
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
name: "customerId",
|
|
452
|
+
isList: false
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
name: "productIds",
|
|
456
|
+
isList: true
|
|
457
|
+
}
|
|
458
|
+
]
|
|
459
|
+
}], "orderId", undefined);
|
|
460
|
+
let shipOrder = slice("ShipOrder", [{
|
|
461
|
+
name: "orderId",
|
|
462
|
+
isList: false
|
|
463
|
+
}], [
|
|
464
|
+
{
|
|
465
|
+
eventType: "OrderPlaced",
|
|
466
|
+
idFields: [
|
|
467
|
+
{
|
|
468
|
+
name: "orderId",
|
|
469
|
+
isList: false
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
name: "customerId",
|
|
473
|
+
isList: false
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
name: "productIds",
|
|
477
|
+
isList: true
|
|
478
|
+
}
|
|
479
|
+
]
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
eventType: "OrderCancelled",
|
|
483
|
+
idFields: [
|
|
484
|
+
{
|
|
485
|
+
name: "orderId",
|
|
486
|
+
isList: false
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
name: "productIds",
|
|
490
|
+
isList: true
|
|
491
|
+
}
|
|
492
|
+
]
|
|
493
|
+
}
|
|
494
|
+
], [{
|
|
495
|
+
eventType: "OrderShipped",
|
|
496
|
+
idFields: [
|
|
497
|
+
{
|
|
498
|
+
name: "orderId",
|
|
499
|
+
isList: false
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
name: "customerId",
|
|
503
|
+
isList: false
|
|
504
|
+
}
|
|
505
|
+
]
|
|
506
|
+
}], undefined, undefined);
|
|
507
|
+
let cancelOrder = slice("CancelOrder", [{
|
|
508
|
+
name: "orderId",
|
|
509
|
+
isList: false
|
|
510
|
+
}], [
|
|
511
|
+
{
|
|
512
|
+
eventType: "OrderPlaced",
|
|
513
|
+
idFields: [
|
|
514
|
+
{
|
|
515
|
+
name: "orderId",
|
|
516
|
+
isList: false
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
name: "customerId",
|
|
520
|
+
isList: false
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
name: "productIds",
|
|
524
|
+
isList: true
|
|
525
|
+
}
|
|
526
|
+
]
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
eventType: "OrderShipped",
|
|
530
|
+
idFields: [
|
|
531
|
+
{
|
|
532
|
+
name: "orderId",
|
|
533
|
+
isList: false
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
name: "customerId",
|
|
537
|
+
isList: false
|
|
538
|
+
}
|
|
539
|
+
]
|
|
540
|
+
}
|
|
541
|
+
], [{
|
|
542
|
+
eventType: "OrderCancelled",
|
|
543
|
+
idFields: [
|
|
544
|
+
{
|
|
545
|
+
name: "orderId",
|
|
546
|
+
isList: false
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
name: "productIds",
|
|
550
|
+
isList: true
|
|
551
|
+
}
|
|
552
|
+
]
|
|
553
|
+
}], undefined, undefined);
|
|
554
|
+
globalThis.test("the ShipOrder ⇄ CancelOrder cycle resolves both to orderId", () => {
|
|
555
|
+
let d = DcbScopeInference$Reventless.infer([
|
|
556
|
+
placeOrder,
|
|
557
|
+
shipOrder,
|
|
558
|
+
cancelOrder
|
|
559
|
+
]);
|
|
560
|
+
globalThis.expect(d.partitionBySlice["ShipOrder"]).toEqual("orderId");
|
|
561
|
+
globalThis.expect(d.partitionBySlice["CancelOrder"]).toEqual("orderId");
|
|
562
|
+
globalThis.expect(d.ambiguities).toEqual([]);
|
|
563
|
+
});
|
|
564
|
+
globalThis.test("seen alone, the same slice names the arms to change", () => {
|
|
565
|
+
globalThis.expect(DcbScopeInference$Reventless.partitionBlockers(cancelOrder)).toEqual([
|
|
566
|
+
[
|
|
567
|
+
"orderId",
|
|
568
|
+
[
|
|
569
|
+
"OrderPlaced",
|
|
570
|
+
"OrderShipped"
|
|
571
|
+
]
|
|
572
|
+
],
|
|
573
|
+
[
|
|
574
|
+
"productId",
|
|
575
|
+
["OrderPlaced"]
|
|
576
|
+
]
|
|
577
|
+
]);
|
|
578
|
+
});
|
|
579
|
+
let recordDemand = slice("RecordProductDemand", [
|
|
580
|
+
{
|
|
581
|
+
name: "productId",
|
|
582
|
+
isList: false
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
name: "orderId",
|
|
586
|
+
isList: false
|
|
587
|
+
}
|
|
588
|
+
], [{
|
|
589
|
+
eventType: "ProductDemandRecorded",
|
|
590
|
+
idFields: [{
|
|
591
|
+
name: "orderId",
|
|
592
|
+
isList: false
|
|
593
|
+
}]
|
|
594
|
+
}], [{
|
|
595
|
+
eventType: "ProductDemandRecorded",
|
|
596
|
+
idFields: [
|
|
597
|
+
{
|
|
598
|
+
name: "productId",
|
|
599
|
+
isList: false
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
name: "orderId",
|
|
603
|
+
isList: false
|
|
604
|
+
}
|
|
605
|
+
]
|
|
606
|
+
}], undefined, undefined);
|
|
607
|
+
globalThis.test("a join without a hint stays ambiguous", () => {
|
|
608
|
+
let d = DcbScopeInference$Reventless.infer([recordDemand]);
|
|
609
|
+
globalThis.expect(d.partitionBySlice["RecordProductDemand"]).toEqual(undefined);
|
|
610
|
+
globalThis.expect(d.ambiguities.map(param => param[0])).toEqual(["RecordProductDemand"]);
|
|
611
|
+
});
|
|
612
|
+
globalThis.test("a produced id another slice is partitioned by is not dropped", () => {
|
|
613
|
+
let d = DcbScopeInference$Reventless.infer(catalog.concat([
|
|
614
|
+
placeOrder,
|
|
615
|
+
recordDemand
|
|
616
|
+
]));
|
|
617
|
+
globalThis.expect(d.partitionBySlice["RecordProductDemand"]).toEqual(undefined);
|
|
618
|
+
globalThis.expect(d.ambiguities.some(param => {
|
|
619
|
+
if (param[0] === "RecordProductDemand") {
|
|
620
|
+
return param[1].includes("orderId, productId");
|
|
621
|
+
} else {
|
|
622
|
+
return false;
|
|
623
|
+
}
|
|
624
|
+
})).toBe(true);
|
|
625
|
+
});
|
|
626
|
+
globalThis.test("a boundary that never settles is reported, not guessed", () => {
|
|
627
|
+
let a = slice("A", undefined, [
|
|
628
|
+
{
|
|
629
|
+
eventType: "BHappened",
|
|
630
|
+
idFields: [{
|
|
631
|
+
name: "xId",
|
|
632
|
+
isList: false
|
|
633
|
+
}]
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
eventType: "ZHappened",
|
|
637
|
+
idFields: [{
|
|
638
|
+
name: "yId",
|
|
639
|
+
isList: false
|
|
640
|
+
}]
|
|
641
|
+
}
|
|
642
|
+
], [{
|
|
643
|
+
eventType: "AHappened",
|
|
644
|
+
idFields: [
|
|
645
|
+
{
|
|
646
|
+
name: "xId",
|
|
647
|
+
isList: false
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
name: "yId",
|
|
651
|
+
isList: false
|
|
652
|
+
}
|
|
653
|
+
]
|
|
654
|
+
}], undefined, undefined);
|
|
655
|
+
let b = slice("B", undefined, [
|
|
656
|
+
{
|
|
657
|
+
eventType: "AHappened",
|
|
658
|
+
idFields: [{
|
|
659
|
+
name: "yId",
|
|
660
|
+
isList: false
|
|
661
|
+
}]
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
eventType: "Z2Happened",
|
|
665
|
+
idFields: [{
|
|
666
|
+
name: "xId",
|
|
667
|
+
isList: false
|
|
668
|
+
}]
|
|
669
|
+
}
|
|
670
|
+
], [{
|
|
671
|
+
eventType: "BHappened",
|
|
672
|
+
idFields: [
|
|
673
|
+
{
|
|
674
|
+
name: "xId",
|
|
675
|
+
isList: false
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
name: "yId",
|
|
679
|
+
isList: false
|
|
680
|
+
}
|
|
681
|
+
]
|
|
682
|
+
}], undefined, undefined);
|
|
683
|
+
let d = DcbScopeInference$Reventless.infer([
|
|
684
|
+
a,
|
|
685
|
+
b
|
|
686
|
+
]);
|
|
687
|
+
globalThis.expect(d.ambiguities.map(param => param[0])).toEqual([
|
|
688
|
+
"A",
|
|
689
|
+
"B"
|
|
690
|
+
]);
|
|
691
|
+
globalThis.expect(d.ambiguities.every(param => param[1].includes("did not settle"))).toBe(true);
|
|
692
|
+
});
|
|
693
|
+
});
|
|
694
|
+
globalThis.describe("partition: the chapter breaks a tie", () => {
|
|
695
|
+
let placeOrder = chapter => slice("PlaceOrder", [
|
|
696
|
+
{
|
|
697
|
+
name: "orderId",
|
|
698
|
+
isList: false
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
name: "customerId",
|
|
702
|
+
isList: false
|
|
703
|
+
}
|
|
704
|
+
], [{
|
|
705
|
+
eventType: "OrderPlaced",
|
|
706
|
+
idFields: [{
|
|
707
|
+
name: "orderId",
|
|
708
|
+
isList: false
|
|
709
|
+
}]
|
|
710
|
+
}], [{
|
|
711
|
+
eventType: "OrderPlaced",
|
|
712
|
+
idFields: [
|
|
713
|
+
{
|
|
714
|
+
name: "orderId",
|
|
715
|
+
isList: false
|
|
716
|
+
},
|
|
717
|
+
{
|
|
718
|
+
name: "customerId",
|
|
719
|
+
isList: false
|
|
720
|
+
}
|
|
721
|
+
]
|
|
722
|
+
}], undefined, chapter);
|
|
723
|
+
let cancelOrder = slice("CancelOrder", undefined, [{
|
|
724
|
+
eventType: "OrderPlaced",
|
|
725
|
+
idFields: []
|
|
726
|
+
}], [{
|
|
727
|
+
eventType: "OrderCancelled",
|
|
728
|
+
idFields: [{
|
|
729
|
+
name: "orderId",
|
|
730
|
+
isList: false
|
|
731
|
+
}]
|
|
732
|
+
}], undefined, "Order");
|
|
733
|
+
globalThis.test("an order and its customer resolve to the id every Order event carries", () => {
|
|
734
|
+
let d = DcbScopeInference$Reventless.infer([
|
|
735
|
+
placeOrder("Order"),
|
|
736
|
+
cancelOrder
|
|
737
|
+
]);
|
|
738
|
+
globalThis.expect(d.partitionBySlice["PlaceOrder"]).toEqual("orderId");
|
|
739
|
+
globalThis.expect(d.ambiguities).toEqual([]);
|
|
740
|
+
});
|
|
741
|
+
globalThis.test("without a chapter the same slice stays ambiguous", () => {
|
|
742
|
+
let d = DcbScopeInference$Reventless.infer([
|
|
743
|
+
placeOrder(undefined),
|
|
744
|
+
cancelOrder
|
|
745
|
+
]);
|
|
746
|
+
globalThis.expect(d.partitionBySlice["PlaceOrder"]).toEqual(undefined);
|
|
747
|
+
});
|
|
748
|
+
globalThis.test("a join whose chapter carries both ids stays ambiguous, and the reason says so", () => {
|
|
749
|
+
let demand = slice("RecordProductDemand", undefined, undefined, [{
|
|
750
|
+
eventType: "ProductDemandRecorded",
|
|
751
|
+
idFields: [
|
|
752
|
+
{
|
|
753
|
+
name: "productId",
|
|
754
|
+
isList: false
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
name: "orderId",
|
|
758
|
+
isList: false
|
|
759
|
+
}
|
|
760
|
+
]
|
|
761
|
+
}], undefined, "ProductDemand");
|
|
762
|
+
let d = DcbScopeInference$Reventless.infer([demand]);
|
|
763
|
+
globalThis.expect(d.partitionBySlice["RecordProductDemand"]).toEqual(undefined);
|
|
764
|
+
globalThis.expect(d.ambiguities.some(param => param[1].includes("The ProductDemand chapter does not decide"))).toBe(true);
|
|
765
|
+
});
|
|
766
|
+
globalThis.test("it never overrides a key the subtraction decided", () => {
|
|
767
|
+
let newrecord = {...addProduct};
|
|
768
|
+
newrecord.chapter = "Category";
|
|
769
|
+
let newrecord$1 = {...addCategory};
|
|
770
|
+
let d = DcbScopeInference$Reventless.infer([
|
|
771
|
+
newrecord,
|
|
772
|
+
(newrecord$1.chapter = "Category", newrecord$1)
|
|
773
|
+
]);
|
|
774
|
+
globalThis.expect(d.partitionBySlice["AddProduct"]).toEqual("productId");
|
|
775
|
+
});
|
|
776
|
+
});
|
|
777
|
+
globalThis.describe("validatePartitionHintsVsInference (@partitionTag ⇄ inference)", () => {
|
|
778
|
+
let hinted = (s, key) => {
|
|
779
|
+
let newrecord = {...s};
|
|
780
|
+
newrecord.partitionHint = key;
|
|
781
|
+
return newrecord;
|
|
782
|
+
};
|
|
783
|
+
globalThis.test("a hint naming a key the slice only references is a contradiction", () => {
|
|
784
|
+
let issues = DcbValidation$Reventless.validatePartitionHintsVsInference([
|
|
785
|
+
hinted(addProduct, "categoryId"),
|
|
786
|
+
addCategory
|
|
787
|
+
]);
|
|
788
|
+
globalThis.expect(issues.contradictions.map(e => e.sliceName)).toEqual(["AddProduct"]);
|
|
789
|
+
globalThis.expect(issues.redundancies).toEqual([]);
|
|
790
|
+
});
|
|
791
|
+
globalThis.test("a hint inference reaches unaided is redundant", () => {
|
|
792
|
+
let issues = DcbValidation$Reventless.validatePartitionHintsVsInference([
|
|
793
|
+
hinted(addProduct, "productId"),
|
|
794
|
+
addCategory
|
|
795
|
+
]);
|
|
796
|
+
globalThis.expect(issues.contradictions).toEqual([]);
|
|
797
|
+
globalThis.expect(issues.redundancies.map(e => e.sliceName)).toEqual(["AddProduct"]);
|
|
798
|
+
});
|
|
799
|
+
globalThis.test("a hint that decides a join is neither", () => {
|
|
800
|
+
let demand = slice("RecordProductDemand", undefined, undefined, [{
|
|
801
|
+
eventType: "ProductDemandRecorded",
|
|
802
|
+
idFields: [
|
|
803
|
+
{
|
|
804
|
+
name: "productId",
|
|
805
|
+
isList: false
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
name: "orderId",
|
|
809
|
+
isList: false
|
|
810
|
+
}
|
|
811
|
+
]
|
|
812
|
+
}], "productId", undefined);
|
|
813
|
+
let issues = DcbValidation$Reventless.validatePartitionHintsVsInference([demand]);
|
|
814
|
+
globalThis.expect(issues.contradictions).toEqual([]);
|
|
815
|
+
globalThis.expect(issues.redundancies).toEqual([]);
|
|
816
|
+
});
|
|
817
|
+
});
|
|
406
818
|
globalThis.describe("ambiguity surfacing", () => {
|
|
407
819
|
let aOwner = slice("A", undefined, undefined, [{
|
|
408
820
|
eventType: "AHappened",
|
|
@@ -410,14 +822,14 @@ globalThis.describe("DcbScopeInference:", () => {
|
|
|
410
822
|
name: "aId",
|
|
411
823
|
isList: false
|
|
412
824
|
}]
|
|
413
|
-
}], undefined);
|
|
825
|
+
}], undefined, undefined);
|
|
414
826
|
let bOwner = slice("B", undefined, undefined, [{
|
|
415
827
|
eventType: "BHappened",
|
|
416
828
|
idFields: [{
|
|
417
829
|
name: "bId",
|
|
418
830
|
isList: false
|
|
419
831
|
}]
|
|
420
|
-
}], undefined);
|
|
832
|
+
}], undefined, undefined);
|
|
421
833
|
let join = slice("Join", undefined, [
|
|
422
834
|
{
|
|
423
835
|
eventType: "AHappened",
|
|
@@ -445,7 +857,7 @@ globalThis.describe("DcbScopeInference:", () => {
|
|
|
445
857
|
isList: false
|
|
446
858
|
}
|
|
447
859
|
]
|
|
448
|
-
}], undefined);
|
|
860
|
+
}], undefined, undefined);
|
|
449
861
|
let d = DcbScopeInference$Reventless.infer([
|
|
450
862
|
aOwner,
|
|
451
863
|
bOwner,
|