@reventlessdev/reventless-gwt 1.0.0-alpha.114 → 1.0.0-alpha.116
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 +19 -0
- package/package.json +5 -12
- package/rescript.json +0 -1
- package/src/JestBind.res +21 -22
- package/src/JestBind.res.mjs +15 -11
- package/src/RunnerHook.res +38 -0
- package/src/RunnerHook.res.mjs +26 -0
- package/bin/reventless-dev.mjs +0 -21
- package/src/Bind.res +0 -29
- package/src/Bind.res.mjs +0 -22
- package/src/BuildClassifier.res +0 -147
- package/src/BuildClassifier.res.mjs +0 -136
- package/src/Cancellation.res +0 -37
- package/src/Cancellation.res.mjs +0 -46
- package/src/ChildProcess.res +0 -102
- package/src/ChildProcess.res.mjs +0 -107
- package/src/Cli.res +0 -905
- package/src/Cli.res.mjs +0 -952
- package/src/Collector.res +0 -212
- package/src/Collector.res.mjs +0 -218
- package/src/ComponentMeta.res +0 -77
- package/src/ComponentMeta.res.mjs +0 -91
- package/src/ComponentScan.res +0 -103
- package/src/ComponentScan.res.mjs +0 -105
- package/src/Discovery.res +0 -105
- package/src/Discovery.res.mjs +0 -99
- package/src/DomainDeadCode.res +0 -98
- package/src/DomainDeadCode.res.mjs +0 -72
- package/src/DomainGraph.res +0 -0
- package/src/DomainGraph.res.mjs +0 -0
- package/src/Filter.res +0 -45
- package/src/Filter.res.mjs +0 -47
- package/src/FormatterHuman.res +0 -109
- package/src/FormatterHuman.res.mjs +0 -115
- package/src/FormatterJson.res +0 -264
- package/src/FormatterJson.res.mjs +0 -322
- package/src/FormatterJunit.res +0 -93
- package/src/FormatterJunit.res.mjs +0 -90
- package/src/FormatterTap.res +0 -100
- package/src/FormatterTap.res.mjs +0 -131
- package/src/FormatterVsCode.res +0 -352
- package/src/FormatterVsCode.res.mjs +0 -546
- package/src/Loader.res +0 -24
- package/src/Loader.res.mjs +0 -23
- package/src/PackageScan.res +0 -80
- package/src/PackageScan.res.mjs +0 -81
- package/src/PlatformRunner.res +0 -191
- package/src/PlatformRunner.res.mjs +0 -178
- package/src/PlatformScan.res +0 -142
- package/src/PlatformScan.res.mjs +0 -132
- package/src/ProcessManager.res +0 -135
- package/src/ProcessManager.res.mjs +0 -119
- package/src/RunWorker.res +0 -24
- package/src/RunWorker.res.mjs +0 -16
- package/src/RunnerTypes.res +0 -68
- package/src/RunnerTypes.res.mjs +0 -60
- package/src/Watch.res +0 -108
- package/src/Watch.res.mjs +0 -85
- package/src/WatcherProbe.res +0 -56
- package/src/WatcherProbe.res.mjs +0 -59
- package/src/Worker.res +0 -24
- package/src/Worker.res.mjs +0 -9
- package/tests/BuildClassifierTest.res +0 -133
- package/tests/BuildClassifierTest.res.mjs +0 -176
- package/tests/CliRunEntryTest.res +0 -57
- package/tests/CliRunEntryTest.res.mjs +0 -65
- package/tests/CliWatchScopeTest.res +0 -62
- package/tests/CliWatchScopeTest.res.mjs +0 -95
- package/tests/ComponentMetaTest.res +0 -67
- package/tests/ComponentMetaTest.res.mjs +0 -71
- package/tests/DiscoveryTest.res +0 -42
- package/tests/DiscoveryTest.res.mjs +0 -43
- package/tests/DomainDeadCodeTest.res +0 -119
- package/tests/DomainDeadCodeTest.res.mjs +0 -158
- package/tests/DomainGraphTest.res +0 -448
- package/tests/DomainGraphTest.res.mjs +0 -505
- package/tests/FormatterGoldenTest.res +0 -125
- package/tests/FormatterGoldenTest.res.mjs +0 -162
- package/tests/FormatterVsCodeMessageTest.res +0 -41
- package/tests/FormatterVsCodeMessageTest.res.mjs +0 -42
- package/tests/PlatformRunnerTest.res +0 -66
- package/tests/PlatformRunnerTest.res.mjs +0 -85
- package/tests/PlatformScanTest.res +0 -61
- package/tests/PlatformScanTest.res.mjs +0 -56
- package/tests/RunnerUnitTest.res +0 -219
- package/tests/RunnerUnitTest.res.mjs +0 -244
- package/tests/WatchDebounceTest.res +0 -106
- package/tests/WatchDebounceTest.res.mjs +0 -128
|
@@ -1,505 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
|
|
3
|
-
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
4
|
-
import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
|
|
5
|
-
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
6
|
-
import * as DomainGraph$ReventlessGwt from "../src/DomainGraph.res.mjs";
|
|
7
|
-
|
|
8
|
-
function command(name, mutationField, apiExposedOpt) {
|
|
9
|
-
let apiExposed = apiExposedOpt !== undefined ? Primitive_option.valFromOption(apiExposedOpt) : undefined;
|
|
10
|
-
return {
|
|
11
|
-
name: name,
|
|
12
|
-
schema: "",
|
|
13
|
-
level: "Instance",
|
|
14
|
-
aggregateIdField: undefined,
|
|
15
|
-
mutationField: mutationField,
|
|
16
|
-
references: [],
|
|
17
|
-
allowedStates: undefined,
|
|
18
|
-
apiExposed: apiExposed
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function evt(name) {
|
|
23
|
-
return {
|
|
24
|
-
name: name,
|
|
25
|
-
schema: "",
|
|
26
|
-
references: []
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function writable(name, commandsOpt, producesOpt, consumesOpt, linkedViewsOpt, eventsOpt, chapterOpt) {
|
|
31
|
-
let commands = commandsOpt !== undefined ? commandsOpt : [];
|
|
32
|
-
let produces = producesOpt !== undefined ? producesOpt : [];
|
|
33
|
-
let consumes = consumesOpt !== undefined ? consumesOpt : [];
|
|
34
|
-
let linkedViews = linkedViewsOpt !== undefined ? linkedViewsOpt : [];
|
|
35
|
-
let events = eventsOpt !== undefined ? eventsOpt : [];
|
|
36
|
-
let chapter = chapterOpt !== undefined ? Primitive_option.valFromOption(chapterOpt) : undefined;
|
|
37
|
-
return {
|
|
38
|
-
name: name,
|
|
39
|
-
commands: commands,
|
|
40
|
-
producedEventTypes: produces,
|
|
41
|
-
consumedEventTypes: consumes,
|
|
42
|
-
linkedViews: linkedViews,
|
|
43
|
-
consistencyRead: undefined,
|
|
44
|
-
events: events,
|
|
45
|
-
chapter: chapter
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function queryable(name, consumesOpt, visibilityOpt, chapterOpt) {
|
|
50
|
-
let consumes = consumesOpt !== undefined ? consumesOpt : [];
|
|
51
|
-
let visibility = visibilityOpt !== undefined ? Primitive_option.valFromOption(visibilityOpt) : undefined;
|
|
52
|
-
let chapter = chapterOpt !== undefined ? Primitive_option.valFromOption(chapterOpt) : undefined;
|
|
53
|
-
return {
|
|
54
|
-
name: name,
|
|
55
|
-
queryField: "",
|
|
56
|
-
schema: "",
|
|
57
|
-
consumedEventTypes: consumes,
|
|
58
|
-
linkedWriteSide: [],
|
|
59
|
-
labelField: "id",
|
|
60
|
-
searchableFields: [],
|
|
61
|
-
statusField: undefined,
|
|
62
|
-
visibility: visibility,
|
|
63
|
-
chapter: chapter
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function automation(name, consumesOpt, producesOpt, targetOpt, chapterOpt) {
|
|
68
|
-
let consumes = consumesOpt !== undefined ? consumesOpt : [];
|
|
69
|
-
let produces = producesOpt !== undefined ? producesOpt : [];
|
|
70
|
-
let target = targetOpt !== undefined ? targetOpt : "";
|
|
71
|
-
let chapter = chapterOpt !== undefined ? Primitive_option.valFromOption(chapterOpt) : undefined;
|
|
72
|
-
return {
|
|
73
|
-
name: name,
|
|
74
|
-
consumedEventTypes: consumes,
|
|
75
|
-
producedCommandTypes: produces,
|
|
76
|
-
targetName: target,
|
|
77
|
-
chapter: chapter
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function inbound(name, producesOpt, targetOpt, extOpt, chapterOpt) {
|
|
82
|
-
let produces = producesOpt !== undefined ? producesOpt : [];
|
|
83
|
-
let target = targetOpt !== undefined ? targetOpt : "";
|
|
84
|
-
let ext = extOpt !== undefined ? Primitive_option.valFromOption(extOpt) : undefined;
|
|
85
|
-
let chapter = chapterOpt !== undefined ? Primitive_option.valFromOption(chapterOpt) : undefined;
|
|
86
|
-
return {
|
|
87
|
-
name: name,
|
|
88
|
-
commandTypes: produces,
|
|
89
|
-
targetName: target,
|
|
90
|
-
externalSystem: ext,
|
|
91
|
-
chapter: chapter
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function outbound(name, consumesOpt, producesOpt, targetOpt, extOpt, chapterOpt) {
|
|
96
|
-
let consumes = consumesOpt !== undefined ? consumesOpt : [];
|
|
97
|
-
let produces = producesOpt !== undefined ? producesOpt : [];
|
|
98
|
-
let target = targetOpt !== undefined ? Primitive_option.valFromOption(targetOpt) : undefined;
|
|
99
|
-
let ext = extOpt !== undefined ? Primitive_option.valFromOption(extOpt) : undefined;
|
|
100
|
-
let chapter = chapterOpt !== undefined ? Primitive_option.valFromOption(chapterOpt) : undefined;
|
|
101
|
-
return {
|
|
102
|
-
name: name,
|
|
103
|
-
consumedEventTypes: consumes,
|
|
104
|
-
inboundCommandTypes: produces,
|
|
105
|
-
targetName: target,
|
|
106
|
-
externalSystem: ext,
|
|
107
|
-
chapter: chapter
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function structure(aggregatesOpt, readModelsOpt, stateViewSlicesOpt, stateChangeSlicesOpt, automationSlicesOpt, outboundTranslationSlicesOpt, inboundTranslationSlicesOpt, extensionPointsOpt) {
|
|
112
|
-
let aggregates = aggregatesOpt !== undefined ? aggregatesOpt : [];
|
|
113
|
-
let readModels = readModelsOpt !== undefined ? readModelsOpt : [];
|
|
114
|
-
let stateViewSlices = stateViewSlicesOpt !== undefined ? stateViewSlicesOpt : [];
|
|
115
|
-
let stateChangeSlices = stateChangeSlicesOpt !== undefined ? stateChangeSlicesOpt : [];
|
|
116
|
-
let automationSlices = automationSlicesOpt !== undefined ? automationSlicesOpt : [];
|
|
117
|
-
let outboundTranslationSlices = outboundTranslationSlicesOpt !== undefined ? outboundTranslationSlicesOpt : [];
|
|
118
|
-
let inboundTranslationSlices = inboundTranslationSlicesOpt !== undefined ? inboundTranslationSlicesOpt : [];
|
|
119
|
-
let extensionPoints = extensionPointsOpt !== undefined ? extensionPointsOpt : [];
|
|
120
|
-
return {
|
|
121
|
-
readModels: readModels,
|
|
122
|
-
stateViewSlices: stateViewSlices,
|
|
123
|
-
stateChangeSlices: stateChangeSlices,
|
|
124
|
-
aggregates: aggregates,
|
|
125
|
-
automationSlices: automationSlices,
|
|
126
|
-
outboundTranslationSlices: outboundTranslationSlices,
|
|
127
|
-
inboundTranslationSlices: inboundTranslationSlices,
|
|
128
|
-
extensions: [],
|
|
129
|
-
extensionPoints: extensionPoints
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function hasEdge(g, from, to, kind) {
|
|
134
|
-
return g.edges.some(e => {
|
|
135
|
-
if (e.from === from && e.to === to) {
|
|
136
|
-
return Primitive_object.equal(e.kind, kind);
|
|
137
|
-
} else {
|
|
138
|
-
return false;
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function edgeLabel(g, from, to, kind) {
|
|
144
|
-
return Stdlib_Option.flatMap(g.edges.find(e => {
|
|
145
|
-
if (e.from === from && e.to === to) {
|
|
146
|
-
return Primitive_object.equal(e.kind, kind);
|
|
147
|
-
} else {
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
}), e => e.label);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function nodeKind(g, id) {
|
|
154
|
-
return Stdlib_Option.map(g.nodes.find(n => n.id === id), n => n.kind);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
globalThis.describe("DomainGraph.build", () => {
|
|
158
|
-
globalThis.test("Command → Aggregate → Event → ReadModel (DCB consumedEventTypes)", async () => {
|
|
159
|
-
let shop = structure([writable("Order", [command("Place", "Shop_Order_Place", undefined)], ["Shop.Placed"], undefined, undefined, undefined, undefined)], undefined, [queryable("OrderView", ["Shop.Placed"], undefined, undefined)], undefined, undefined, undefined, undefined, undefined);
|
|
160
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
161
|
-
"Shop",
|
|
162
|
-
shop
|
|
163
|
-
]]);
|
|
164
|
-
globalThis.expect(nodeKind(g, "Shop_Order_Place")).toEqual("Command");
|
|
165
|
-
globalThis.expect(nodeKind(g, "Shop:Order")).toEqual("Aggregate");
|
|
166
|
-
globalThis.expect(nodeKind(g, "Shop.Placed")).toEqual("Event");
|
|
167
|
-
globalThis.expect(nodeKind(g, "Shop:OrderView")).toEqual("StateViewSlice");
|
|
168
|
-
globalThis.expect(hasEdge(g, "Shop_Order_Place", "Shop:Order", "Handles")).toBe(true);
|
|
169
|
-
globalThis.expect(hasEdge(g, "Shop:Order", "Shop.Placed", "Emits")).toBe(true);
|
|
170
|
-
globalThis.expect(hasEdge(g, "Shop.Placed", "Shop:OrderView", "Projects")).toBe(true);
|
|
171
|
-
});
|
|
172
|
-
globalThis.test("payload-less events (in `events`, not producedEventTypes) still get an emitted node", async () => {
|
|
173
|
-
let shop = structure([writable("Category", undefined, ["Catalog.Added"], undefined, undefined, [
|
|
174
|
-
{
|
|
175
|
-
name: "Added",
|
|
176
|
-
schema: "",
|
|
177
|
-
references: []
|
|
178
|
-
},
|
|
179
|
-
{
|
|
180
|
-
name: "Archived",
|
|
181
|
-
schema: "",
|
|
182
|
-
references: []
|
|
183
|
-
}
|
|
184
|
-
], undefined)], undefined, undefined, undefined, undefined, undefined, undefined, undefined);
|
|
185
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
186
|
-
"Catalog",
|
|
187
|
-
shop
|
|
188
|
-
]]);
|
|
189
|
-
globalThis.expect(nodeKind(g, "Catalog.Added")).toEqual("Event");
|
|
190
|
-
globalThis.expect(nodeKind(g, "Catalog.Archived")).toEqual("Event");
|
|
191
|
-
globalThis.expect(hasEdge(g, "Catalog:Category", "Catalog.Added", "Emits")).toBe(true);
|
|
192
|
-
globalThis.expect(hasEdge(g, "Catalog:Category", "Catalog.Archived", "Emits")).toBe(true);
|
|
193
|
-
});
|
|
194
|
-
globalThis.test("a payload-less event also projects into the aggregate's linked view", async () => {
|
|
195
|
-
let shop = structure([writable("Category", undefined, ["Catalog.Added"], undefined, ["Categories"], [
|
|
196
|
-
{
|
|
197
|
-
name: "Added",
|
|
198
|
-
schema: "",
|
|
199
|
-
references: []
|
|
200
|
-
},
|
|
201
|
-
{
|
|
202
|
-
name: "Archived",
|
|
203
|
-
schema: "",
|
|
204
|
-
references: []
|
|
205
|
-
}
|
|
206
|
-
], undefined)], undefined, undefined, undefined, undefined, undefined, undefined, undefined);
|
|
207
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
208
|
-
"Catalog",
|
|
209
|
-
shop
|
|
210
|
-
]]);
|
|
211
|
-
globalThis.expect(hasEdge(g, "Catalog.Added", "Catalog:Categories", "Projects")).toBe(true);
|
|
212
|
-
globalThis.expect(hasEdge(g, "Catalog.Archived", "Catalog:Categories", "Projects")).toBe(true);
|
|
213
|
-
});
|
|
214
|
-
globalThis.test("an Internal StateViewSlice still gets a node + projects edge (dev graph shows it)", async () => {
|
|
215
|
-
let shop = structure([writable("Order", undefined, ["Shop.Placed"], undefined, undefined, undefined, undefined)], undefined, [queryable("AvailableView", ["Shop.Placed"], "Internal", undefined)], undefined, undefined, undefined, undefined, undefined);
|
|
216
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
217
|
-
"Shop",
|
|
218
|
-
shop
|
|
219
|
-
]]);
|
|
220
|
-
globalThis.expect(nodeKind(g, "Shop:AvailableView")).toEqual("StateViewSlice");
|
|
221
|
-
globalThis.expect(hasEdge(g, "Shop.Placed", "Shop:AvailableView", "Projects")).toBe(true);
|
|
222
|
-
});
|
|
223
|
-
globalThis.test("classic linkedViews draws each produced event into the linked read model", async () => {
|
|
224
|
-
let shop = structure([writable("Order", undefined, [
|
|
225
|
-
"Shop.Placed",
|
|
226
|
-
"Shop.Shipped"
|
|
227
|
-
], undefined, ["Orders"], undefined, undefined)], [queryable("Orders", undefined, undefined, undefined)], undefined, undefined, undefined, undefined, undefined, undefined);
|
|
228
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
229
|
-
"Shop",
|
|
230
|
-
shop
|
|
231
|
-
]]);
|
|
232
|
-
globalThis.expect(hasEdge(g, "Shop.Placed", "Shop:Orders", "Projects")).toBe(true);
|
|
233
|
-
globalThis.expect(hasEdge(g, "Shop.Shipped", "Shop:Orders", "Projects")).toBe(true);
|
|
234
|
-
});
|
|
235
|
-
globalThis.test("automation slices are triggered by their consumed events", async () => {
|
|
236
|
-
let shop = structure([writable("Order", undefined, ["Shop.Placed"], undefined, undefined, undefined, undefined)], undefined, undefined, undefined, [automation("Notify", ["Shop.Placed"], undefined, undefined, undefined)], undefined, undefined, undefined);
|
|
237
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
238
|
-
"Shop",
|
|
239
|
-
shop
|
|
240
|
-
]]);
|
|
241
|
-
globalThis.expect(nodeKind(g, "Shop:Notify")).toEqual("AutomationSlice");
|
|
242
|
-
globalThis.expect(hasEdge(g, "Shop.Placed", "Shop:Notify", "Triggers")).toBe(true);
|
|
243
|
-
});
|
|
244
|
-
globalThis.test("an automation routes to the specific command it raises on its target", async () => {
|
|
245
|
-
let shop = structure(undefined, undefined, undefined, [writable("Ship", [
|
|
246
|
-
command("ShipOrder", "Shop_Ship_ShipOrder", undefined),
|
|
247
|
-
command("Place", "Shop_Ship_Place", undefined)
|
|
248
|
-
], ["Shop.Shipped"], undefined, undefined, undefined, undefined)], [automation("AutoShip", ["Shop.Placed"], ["AutoShip.ShipOrder"], "Ship", undefined)], undefined, undefined, undefined);
|
|
249
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
250
|
-
"Shop",
|
|
251
|
-
shop
|
|
252
|
-
]]);
|
|
253
|
-
globalThis.expect(hasEdge(g, "Shop:AutoShip", "Shop_Ship_ShipOrder", "DelegatesTo")).toBe(true);
|
|
254
|
-
globalThis.expect(hasEdge(g, "Shop:AutoShip", "Shop_Ship_Place", "DelegatesTo")).toBe(false);
|
|
255
|
-
});
|
|
256
|
-
globalThis.test("an inbound translation routes to the command it raises on its target", async () => {
|
|
257
|
-
let shop = structure(undefined, undefined, undefined, [writable("Product", [command("Add", "Shop_Product_Add", undefined)], undefined, undefined, undefined, undefined, undefined)], undefined, undefined, [inbound("ImportProduct", ["ImportProduct.Add"], "Product", undefined, undefined)], undefined);
|
|
258
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
259
|
-
"Shop",
|
|
260
|
-
shop
|
|
261
|
-
]]);
|
|
262
|
-
globalThis.expect(nodeKind(g, "Shop:ImportProduct")).toEqual("InboundTranslationSlice");
|
|
263
|
-
globalThis.expect(hasEdge(g, "Shop:ImportProduct", "Shop_Product_Add", "DelegatesTo")).toBe(true);
|
|
264
|
-
});
|
|
265
|
-
globalThis.test("an outbound translation with a target routes to the command it raises", async () => {
|
|
266
|
-
let shop = structure(undefined, undefined, undefined, [writable("Product", [command("Sync", "Shop_Product_Sync", undefined)], undefined, undefined, undefined, undefined, undefined)], undefined, [outbound("ExportProduct", ["Shop.Added"], ["ExportProduct.Sync"], "Product", undefined, undefined)], undefined, undefined);
|
|
267
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
268
|
-
"Shop",
|
|
269
|
-
shop
|
|
270
|
-
]]);
|
|
271
|
-
globalThis.expect(hasEdge(g, "Shop:ExportProduct", "Shop_Product_Sync", "DelegatesTo")).toBe(true);
|
|
272
|
-
});
|
|
273
|
-
globalThis.test("an inbound translation naming an external system draws a box feeding it", async () => {
|
|
274
|
-
let shop = structure(undefined, undefined, undefined, undefined, undefined, undefined, [inbound("ImportProduct", ["ImportProduct.Add"], "Product", "SupplierFeed", undefined)], undefined);
|
|
275
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
276
|
-
"Shop",
|
|
277
|
-
shop
|
|
278
|
-
]]);
|
|
279
|
-
globalThis.expect(nodeKind(g, "ext:SupplierFeed")).toEqual("ExternalSystem");
|
|
280
|
-
globalThis.expect(Stdlib_Option.map(g.nodes.find(n => n.id === "ext:SupplierFeed"), n => n.plugin)).toEqual("");
|
|
281
|
-
globalThis.expect(hasEdge(g, "ext:SupplierFeed", "Shop:ImportProduct", "TranslatesIn")).toBe(true);
|
|
282
|
-
globalThis.expect(edgeLabel(g, "ext:SupplierFeed", "Shop:ImportProduct", "TranslatesIn")).toEqual(undefined);
|
|
283
|
-
});
|
|
284
|
-
globalThis.test("an outbound translation naming an external system feeds the box", async () => {
|
|
285
|
-
let shop = structure(undefined, undefined, undefined, undefined, undefined, [outbound("SendEmail", ["Shop.Placed"], undefined, Primitive_option.some(undefined), "EmailService", undefined)], undefined, undefined);
|
|
286
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
287
|
-
"Shop",
|
|
288
|
-
shop
|
|
289
|
-
]]);
|
|
290
|
-
globalThis.expect(nodeKind(g, "ext:EmailService")).toEqual("ExternalSystem");
|
|
291
|
-
globalThis.expect(hasEdge(g, "Shop:SendEmail", "ext:EmailService", "TranslatesOut")).toBe(true);
|
|
292
|
-
globalThis.expect(edgeLabel(g, "Shop:SendEmail", "ext:EmailService", "TranslatesOut")).toEqual(undefined);
|
|
293
|
-
});
|
|
294
|
-
globalThis.test("translation slices with no external system draw no box (opt-in)", async () => {
|
|
295
|
-
let shop = structure(undefined, undefined, undefined, undefined, undefined, undefined, [inbound("ImportProduct", undefined, "Product", undefined, undefined)], undefined);
|
|
296
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
297
|
-
"Shop",
|
|
298
|
-
shop
|
|
299
|
-
]]);
|
|
300
|
-
globalThis.expect(g.nodes.some(n => n.kind === "ExternalSystem")).toBe(false);
|
|
301
|
-
});
|
|
302
|
-
globalThis.test("two slices naming the same external system share one deduped box", async () => {
|
|
303
|
-
let a = structure(undefined, undefined, undefined, undefined, undefined, [outbound("SendEmailA", ["A.X"], undefined, Primitive_option.some(undefined), "EmailService", undefined)], undefined, undefined);
|
|
304
|
-
let b = structure(undefined, undefined, undefined, undefined, undefined, undefined, [inbound("FromEmail", ["FromEmail.Record"], "Inbox", "EmailService", undefined)], undefined);
|
|
305
|
-
let g = DomainGraph$ReventlessGwt.build([
|
|
306
|
-
[
|
|
307
|
-
"PluginA",
|
|
308
|
-
a
|
|
309
|
-
],
|
|
310
|
-
[
|
|
311
|
-
"PluginB",
|
|
312
|
-
b
|
|
313
|
-
]
|
|
314
|
-
]);
|
|
315
|
-
globalThis.expect(g.nodes.filter(n => n.id === "ext:EmailService").length).toBe(1);
|
|
316
|
-
globalThis.expect(hasEdge(g, "PluginA:SendEmailA", "ext:EmailService", "TranslatesOut")).toBe(true);
|
|
317
|
-
globalThis.expect(hasEdge(g, "ext:EmailService", "PluginB:FromEmail", "TranslatesIn")).toBe(true);
|
|
318
|
-
});
|
|
319
|
-
globalThis.test("an event produced by two write-sides is one node with two emit edges", async () => {
|
|
320
|
-
let shop = structure([
|
|
321
|
-
writable("A", undefined, ["Shop.Touched"], undefined, undefined, undefined, undefined),
|
|
322
|
-
writable("B", undefined, ["Shop.Touched"], undefined, undefined, undefined, undefined)
|
|
323
|
-
], undefined, undefined, undefined, undefined, undefined, undefined, undefined);
|
|
324
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
325
|
-
"Shop",
|
|
326
|
-
shop
|
|
327
|
-
]]);
|
|
328
|
-
globalThis.expect(g.nodes.filter(n => n.id === "Shop.Touched").length).toBe(1);
|
|
329
|
-
globalThis.expect(hasEdge(g, "Shop:A", "Shop.Touched", "Emits")).toBe(true);
|
|
330
|
-
globalThis.expect(hasEdge(g, "Shop:B", "Shop.Touched", "Emits")).toBe(true);
|
|
331
|
-
});
|
|
332
|
-
globalThis.test("an extension renders the cross-plugin event flow EP→event→Extension→delegate", async () => {
|
|
333
|
-
let extension_delegateNames = ["ProductDemand"];
|
|
334
|
-
let extension_eventTypes = ["Ordering.Orders.ItemOrdered"];
|
|
335
|
-
let extension_commandTypes = [];
|
|
336
|
-
let extension = {
|
|
337
|
-
name: "Ordering.Orders",
|
|
338
|
-
delegateNames: extension_delegateNames,
|
|
339
|
-
eventTypes: extension_eventTypes,
|
|
340
|
-
commandTypes: extension_commandTypes
|
|
341
|
-
};
|
|
342
|
-
let init = structure([writable("ProductDemand", undefined, ["Catalog.Recorded"], undefined, undefined, undefined, undefined)], undefined, undefined, undefined, undefined, undefined, undefined, undefined);
|
|
343
|
-
let catalog_readModels = init.readModels;
|
|
344
|
-
let catalog_stateViewSlices = init.stateViewSlices;
|
|
345
|
-
let catalog_stateChangeSlices = init.stateChangeSlices;
|
|
346
|
-
let catalog_aggregates = init.aggregates;
|
|
347
|
-
let catalog_automationSlices = init.automationSlices;
|
|
348
|
-
let catalog_outboundTranslationSlices = init.outboundTranslationSlices;
|
|
349
|
-
let catalog_inboundTranslationSlices = init.inboundTranslationSlices;
|
|
350
|
-
let catalog_extensions = [extension];
|
|
351
|
-
let catalog_extensionPoints = init.extensionPoints;
|
|
352
|
-
let catalog = {
|
|
353
|
-
readModels: catalog_readModels,
|
|
354
|
-
stateViewSlices: catalog_stateViewSlices,
|
|
355
|
-
stateChangeSlices: catalog_stateChangeSlices,
|
|
356
|
-
aggregates: catalog_aggregates,
|
|
357
|
-
automationSlices: catalog_automationSlices,
|
|
358
|
-
outboundTranslationSlices: catalog_outboundTranslationSlices,
|
|
359
|
-
inboundTranslationSlices: catalog_inboundTranslationSlices,
|
|
360
|
-
extensions: catalog_extensions,
|
|
361
|
-
extensionPoints: catalog_extensionPoints
|
|
362
|
-
};
|
|
363
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
364
|
-
"Catalog",
|
|
365
|
-
catalog
|
|
366
|
-
]]);
|
|
367
|
-
globalThis.expect(nodeKind(g, "Ordering:ep:Ordering.Orders")).toEqual("ExtensionPoint");
|
|
368
|
-
globalThis.expect(hasEdge(g, "Ordering:ep:Ordering.Orders", "Ordering.Orders.ItemOrdered", "Publishes")).toBe(true);
|
|
369
|
-
globalThis.expect(hasEdge(g, "Ordering.Orders.ItemOrdered", "Catalog:ext:Ordering.Orders", "Consumes")).toBe(true);
|
|
370
|
-
globalThis.expect(hasEdge(g, "Catalog:ext:Ordering.Orders", "Catalog:ProductDemand", "DelegatesTo")).toBe(true);
|
|
371
|
-
let protoEvent = Stdlib_Option.getOrThrow(g.nodes.find(n => n.id === "Ordering.Orders.ItemOrdered"), undefined);
|
|
372
|
-
globalThis.expect(protoEvent.plugin).toBe("");
|
|
373
|
-
let ext = Stdlib_Option.getOrThrow(g.nodes.find(n => n.id === "Catalog:ext:Ordering.Orders"), undefined);
|
|
374
|
-
globalThis.expect(ext.label).toBe("Ordering.Orders.Catalog");
|
|
375
|
-
});
|
|
376
|
-
globalThis.test("an extension wires to the command(s) it creates, not straight to the delegate", async () => {
|
|
377
|
-
let extension_delegateNames = ["ProductDemand"];
|
|
378
|
-
let extension_eventTypes = ["Ordering.Orders.ItemOrdered"];
|
|
379
|
-
let extension_commandTypes = [];
|
|
380
|
-
let extension = {
|
|
381
|
-
name: "Ordering.Orders",
|
|
382
|
-
delegateNames: extension_delegateNames,
|
|
383
|
-
eventTypes: extension_eventTypes,
|
|
384
|
-
commandTypes: extension_commandTypes
|
|
385
|
-
};
|
|
386
|
-
let init = structure(undefined, undefined, undefined, [writable("ProductDemand", [command("RecordDemand", "Catalog_ProductDemand_RecordDemand", undefined)], ["Catalog.Recorded"], undefined, undefined, undefined, undefined)], undefined, undefined, undefined, undefined);
|
|
387
|
-
let catalog_readModels = init.readModels;
|
|
388
|
-
let catalog_stateViewSlices = init.stateViewSlices;
|
|
389
|
-
let catalog_stateChangeSlices = init.stateChangeSlices;
|
|
390
|
-
let catalog_aggregates = init.aggregates;
|
|
391
|
-
let catalog_automationSlices = init.automationSlices;
|
|
392
|
-
let catalog_outboundTranslationSlices = init.outboundTranslationSlices;
|
|
393
|
-
let catalog_inboundTranslationSlices = init.inboundTranslationSlices;
|
|
394
|
-
let catalog_extensions = [extension];
|
|
395
|
-
let catalog_extensionPoints = init.extensionPoints;
|
|
396
|
-
let catalog = {
|
|
397
|
-
readModels: catalog_readModels,
|
|
398
|
-
stateViewSlices: catalog_stateViewSlices,
|
|
399
|
-
stateChangeSlices: catalog_stateChangeSlices,
|
|
400
|
-
aggregates: catalog_aggregates,
|
|
401
|
-
automationSlices: catalog_automationSlices,
|
|
402
|
-
outboundTranslationSlices: catalog_outboundTranslationSlices,
|
|
403
|
-
inboundTranslationSlices: catalog_inboundTranslationSlices,
|
|
404
|
-
extensions: catalog_extensions,
|
|
405
|
-
extensionPoints: catalog_extensionPoints
|
|
406
|
-
};
|
|
407
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
408
|
-
"Catalog",
|
|
409
|
-
catalog
|
|
410
|
-
]]);
|
|
411
|
-
globalThis.expect(hasEdge(g, "Catalog:ext:Ordering.Orders", "Catalog_ProductDemand_RecordDemand", "DelegatesTo")).toBe(true);
|
|
412
|
-
globalThis.expect(hasEdge(g, "Catalog_ProductDemand_RecordDemand", "Catalog:ProductDemand", "Handles")).toBe(true);
|
|
413
|
-
globalThis.expect(hasEdge(g, "Catalog:ext:Ordering.Orders", "Catalog:ProductDemand", "DelegatesTo")).toBe(false);
|
|
414
|
-
});
|
|
415
|
-
globalThis.test("an extension with no commands falls back to delegating to the write-side", async () => {
|
|
416
|
-
let extension_delegateNames = ["ProductDemand"];
|
|
417
|
-
let extension_eventTypes = ["Ordering.Orders.ItemOrdered"];
|
|
418
|
-
let extension_commandTypes = [];
|
|
419
|
-
let extension = {
|
|
420
|
-
name: "Ordering.Orders",
|
|
421
|
-
delegateNames: extension_delegateNames,
|
|
422
|
-
eventTypes: extension_eventTypes,
|
|
423
|
-
commandTypes: extension_commandTypes
|
|
424
|
-
};
|
|
425
|
-
let init = structure([writable("ProductDemand", undefined, ["Catalog.Recorded"], undefined, undefined, undefined, undefined)], undefined, undefined, undefined, undefined, undefined, undefined, undefined);
|
|
426
|
-
let catalog_readModels = init.readModels;
|
|
427
|
-
let catalog_stateViewSlices = init.stateViewSlices;
|
|
428
|
-
let catalog_stateChangeSlices = init.stateChangeSlices;
|
|
429
|
-
let catalog_aggregates = init.aggregates;
|
|
430
|
-
let catalog_automationSlices = init.automationSlices;
|
|
431
|
-
let catalog_outboundTranslationSlices = init.outboundTranslationSlices;
|
|
432
|
-
let catalog_inboundTranslationSlices = init.inboundTranslationSlices;
|
|
433
|
-
let catalog_extensions = [extension];
|
|
434
|
-
let catalog_extensionPoints = init.extensionPoints;
|
|
435
|
-
let catalog = {
|
|
436
|
-
readModels: catalog_readModels,
|
|
437
|
-
stateViewSlices: catalog_stateViewSlices,
|
|
438
|
-
stateChangeSlices: catalog_stateChangeSlices,
|
|
439
|
-
aggregates: catalog_aggregates,
|
|
440
|
-
automationSlices: catalog_automationSlices,
|
|
441
|
-
outboundTranslationSlices: catalog_outboundTranslationSlices,
|
|
442
|
-
inboundTranslationSlices: catalog_inboundTranslationSlices,
|
|
443
|
-
extensions: catalog_extensions,
|
|
444
|
-
extensionPoints: catalog_extensionPoints
|
|
445
|
-
};
|
|
446
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
447
|
-
"Catalog",
|
|
448
|
-
catalog
|
|
449
|
-
]]);
|
|
450
|
-
globalThis.expect(hasEdge(g, "Catalog:ext:Ordering.Orders", "Catalog:ProductDemand", "DelegatesTo")).toBe(true);
|
|
451
|
-
});
|
|
452
|
-
globalThis.test("an owned extension point is fed by the producers of its source events", async () => {
|
|
453
|
-
let ep_delegateNames = ["CatalogDcbEventLog"];
|
|
454
|
-
let ep_sourceEventTypes = ["Catalog.ProductAdded"];
|
|
455
|
-
let ep_commandTypes = [];
|
|
456
|
-
let ep = {
|
|
457
|
-
name: "Catalog.Products",
|
|
458
|
-
delegateNames: ep_delegateNames,
|
|
459
|
-
sourceEventTypes: ep_sourceEventTypes,
|
|
460
|
-
commandTypes: ep_commandTypes
|
|
461
|
-
};
|
|
462
|
-
let catalog = structure(undefined, undefined, undefined, [writable("AddProduct", [command("AddProduct", "Catalog_AddProduct", undefined)], ["Catalog.ProductAdded"], undefined, undefined, undefined, undefined)], undefined, undefined, undefined, [ep]);
|
|
463
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
464
|
-
"Catalog",
|
|
465
|
-
catalog
|
|
466
|
-
]]);
|
|
467
|
-
globalThis.expect(nodeKind(g, "Catalog:ep:Catalog.Products")).toEqual("ExtensionPoint");
|
|
468
|
-
globalThis.expect(hasEdge(g, "Catalog:AddProduct", "Catalog.ProductAdded", "Emits")).toBe(true);
|
|
469
|
-
globalThis.expect(hasEdge(g, "Catalog.ProductAdded", "Catalog:ep:Catalog.Products", "Feeds")).toBe(true);
|
|
470
|
-
globalThis.expect(hasEdge(g, "Catalog:ep:Catalog.Products", "Catalog_AddProduct", "RoutesTo")).toBe(false);
|
|
471
|
-
});
|
|
472
|
-
globalThis.test("an extension point with an inbound command protocol routes to its delegate's commands", async () => {
|
|
473
|
-
let ep_delegateNames = ["AddProduct"];
|
|
474
|
-
let ep_sourceEventTypes = ["Catalog.ProductAdded"];
|
|
475
|
-
let ep_commandTypes = ["Catalog.Products.RequestAddProduct"];
|
|
476
|
-
let ep = {
|
|
477
|
-
name: "Catalog.Products",
|
|
478
|
-
delegateNames: ep_delegateNames,
|
|
479
|
-
sourceEventTypes: ep_sourceEventTypes,
|
|
480
|
-
commandTypes: ep_commandTypes
|
|
481
|
-
};
|
|
482
|
-
let catalog = structure(undefined, undefined, undefined, [writable("AddProduct", [command("AddProduct", "Catalog_AddProduct", undefined)], ["Catalog.ProductAdded"], undefined, undefined, undefined, undefined)], undefined, undefined, undefined, [ep]);
|
|
483
|
-
let g = DomainGraph$ReventlessGwt.build([[
|
|
484
|
-
"Catalog",
|
|
485
|
-
catalog
|
|
486
|
-
]]);
|
|
487
|
-
globalThis.expect(hasEdge(g, "Catalog:ep:Catalog.Products", "Catalog_AddProduct", "RoutesTo")).toBe(true);
|
|
488
|
-
globalThis.expect(hasEdge(g, "Catalog_AddProduct", "Catalog:AddProduct", "Handles")).toBe(true);
|
|
489
|
-
});
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
export {
|
|
493
|
-
command,
|
|
494
|
-
evt,
|
|
495
|
-
writable,
|
|
496
|
-
queryable,
|
|
497
|
-
automation,
|
|
498
|
-
inbound,
|
|
499
|
-
outbound,
|
|
500
|
-
structure,
|
|
501
|
-
hasEdge,
|
|
502
|
-
edgeLabel,
|
|
503
|
-
nodeKind,
|
|
504
|
-
}
|
|
505
|
-
/* Not a pure module */
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
// Golden-output tests pinning the per-mismatch rendering of the three
|
|
2
|
-
// string-emitting formatters:
|
|
3
|
-
// - `Outcome.format` (used by the JUnit `<failure>` body)
|
|
4
|
-
// - `FormatterHuman.renderMismatch` (terminal output)
|
|
5
|
-
// - `FormatterTap.renderMismatchYaml` (TAP YAML diagnostic block)
|
|
6
|
-
//
|
|
7
|
-
// These three functions are exactly what the deferred `Outcome.mismatch`
|
|
8
|
-
// normalization (plan C4) will unify. Pinning their current output byte-for-byte
|
|
9
|
-
// lets that refactor prove it preserved Human/TAP rendering — and makes the
|
|
10
|
-
// deliberate JUnit change (it currently renders via raw `Outcome.format`, unlike
|
|
11
|
-
// the RenderRescript-based Human/TAP) explicit and reviewable rather than silent.
|
|
12
|
-
//
|
|
13
|
-
// The fixtures cover all 10 mismatch kinds — the full structural variety the
|
|
14
|
-
// normalization must preserve: array expected/actual (Events/QueryRows/
|
|
15
|
-
// PublishedActions), the Error()/Ok() wrapping with a `None` actual
|
|
16
|
-
// (ErrorMismatch), the `key` extra + option rendering (StateMismatch), a
|
|
17
|
-
// single-sided actual (NoEventExpected), plain-string (non-JSON) sides
|
|
18
|
-
// (TranslateError), the `(id, value)` pair rendering (TodoMismatch), a nested
|
|
19
|
-
// JSON value (AppendConditionMismatch), and the `Throw` stack special case.
|
|
20
|
-
|
|
21
|
-
open JestGlobals
|
|
22
|
-
|
|
23
|
-
let evA = JSON.parseOrThrow(`{"TAG":"ProductAdded","_0":{"productId":"p1","name":"Widget"}}`)
|
|
24
|
-
let evB = JSON.parseOrThrow(`{"TAG":"ProductRenamed","_0":{"productId":"p1","name":"Gadget"}}`)
|
|
25
|
-
let stateActive = JSON.parseOrThrow(`{"status":"active"}`)
|
|
26
|
-
let stateArchived = JSON.parseOrThrow(`{"status":"archived"}`)
|
|
27
|
-
let appendExpected = JSON.parseOrThrow(`{"query":[]}`)
|
|
28
|
-
let appendActual = JSON.parseOrThrow(`{"query":[{"eventTypes":["ProductAdded"]}]}`)
|
|
29
|
-
|
|
30
|
-
type golden = {
|
|
31
|
-
name: string,
|
|
32
|
-
mismatch: Outcome.mismatch,
|
|
33
|
-
format: string,
|
|
34
|
-
human: string,
|
|
35
|
-
tap: string,
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
let goldens: array<golden> = [
|
|
39
|
-
{
|
|
40
|
-
name: "EventsMismatch",
|
|
41
|
-
mismatch: EventsMismatch({expected: [evA], actual: [evB]}),
|
|
42
|
-
format: "EventsMismatch:\n expected: [{\n \"TAG\": \"ProductAdded\",\n \"_0\": {\n \"productId\": \"p1\",\n \"name\": \"Widget\"\n }\n}]\n actual: [{\n \"TAG\": \"ProductRenamed\",\n \"_0\": {\n \"productId\": \"p1\",\n \"name\": \"Gadget\"\n }\n}]",
|
|
43
|
-
human: " expected: [ProductAdded({productId: \"p1\", name: \"Widget\"})]\n actual: [ProductRenamed({productId: \"p1\", name: \"Gadget\"})]",
|
|
44
|
-
tap: " kind: \"EventsMismatch\"\n expected: \"[ProductAdded({productId: \\\"p1\\\", name: \\\"Widget\\\"})]\"\n actual: \"[ProductRenamed({productId: \\\"p1\\\", name: \\\"Gadget\\\"})]\"",
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
name: "ErrorMismatch",
|
|
48
|
-
mismatch: ErrorMismatch({
|
|
49
|
-
expected: JSON.String("CategoryAlreadyExists"),
|
|
50
|
-
actual: None,
|
|
51
|
-
actualEvents: [evA],
|
|
52
|
-
}),
|
|
53
|
-
format: "ErrorMismatch:\n expected error: \"CategoryAlreadyExists\"\n actual error: (none)\n actual events: [{\n \"TAG\": \"ProductAdded\",\n \"_0\": {\n \"productId\": \"p1\",\n \"name\": \"Widget\"\n }\n}]",
|
|
54
|
-
human: " expected: Error(\"CategoryAlreadyExists\")\n actual: Ok([ProductAdded({productId: \"p1\", name: \"Widget\"})])",
|
|
55
|
-
tap: " kind: \"ErrorMismatch\"\n expected: \"Error(\\\"CategoryAlreadyExists\\\")\"\n actual: \"Ok([ProductAdded({productId: \\\"p1\\\", name: \\\"Widget\\\"})])\"",
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
name: "StateMismatch",
|
|
59
|
-
mismatch: StateMismatch({key: "p1", expected: Some(stateActive), actual: Some(stateArchived)}),
|
|
60
|
-
format: "StateMismatch (key: p1):\n expected: {\n \"status\": \"active\"\n}\n actual: {\n \"status\": \"archived\"\n}",
|
|
61
|
-
human: " key: \"p1\"\n expected: {status: \"active\"}\n actual: {status: \"archived\"}",
|
|
62
|
-
tap: " kind: \"StateMismatch\"\n key: \"p1\"\n expected: \"{status: \\\"active\\\"}\"\n actual: \"{status: \\\"archived\\\"}\"",
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
name: "NoEventExpected",
|
|
66
|
-
mismatch: NoEventExpected({actual: [evA]}),
|
|
67
|
-
format: "NoEventExpected: expected no events, got:\n [{\n \"TAG\": \"ProductAdded\",\n \"_0\": {\n \"productId\": \"p1\",\n \"name\": \"Widget\"\n }\n}]",
|
|
68
|
-
human: " expected no events\n actual: [ProductAdded({productId: \"p1\", name: \"Widget\"})]",
|
|
69
|
-
tap: " kind: \"NoEventExpected\"\n actual: \"[ProductAdded({productId: \\\"p1\\\", name: \\\"Widget\\\"})]\"",
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
name: "TranslateError",
|
|
73
|
-
mismatch: TranslateError({expected: "boom", actual: Some("kaboom")}),
|
|
74
|
-
format: "TranslateError:\n expected: boom\n actual: kaboom",
|
|
75
|
-
human: " expected: boom\n actual: kaboom",
|
|
76
|
-
tap: " kind: \"TranslateError\"\n expected: \"boom\"\n actual: \"kaboom\"",
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
name: "Throw",
|
|
80
|
-
mismatch: Throw({error: "unexpected", stack: "at foo"}),
|
|
81
|
-
format: "Throw: unexpected\nat foo",
|
|
82
|
-
human: " error: unexpected\nat foo",
|
|
83
|
-
tap: " kind: \"Throw\"\n error: \"unexpected\"\n stack: \"at foo\"",
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
name: "TodoMismatch",
|
|
87
|
-
mismatch: TodoMismatch({expected: [("case-1", evA)], actual: [("case-2", evB)]}),
|
|
88
|
-
format: "TodoMismatch:\n expected: [(case-1, {\n \"TAG\": \"ProductAdded\",\n \"_0\": {\n \"productId\": \"p1\",\n \"name\": \"Widget\"\n }\n})]\n actual: [(case-2, {\n \"TAG\": \"ProductRenamed\",\n \"_0\": {\n \"productId\": \"p1\",\n \"name\": \"Gadget\"\n }\n})]",
|
|
89
|
-
human: " expected: [(case-1, ProductAdded({productId: \"p1\", name: \"Widget\"}))]\n actual: [(case-2, ProductRenamed({productId: \"p1\", name: \"Gadget\"}))]",
|
|
90
|
-
tap: " kind: \"TodoMismatch\"\n expected: \"[(case-1, ProductAdded({productId: \\\"p1\\\", name: \\\"Widget\\\"}))]\"\n actual: \"[(case-2, ProductRenamed({productId: \\\"p1\\\", name: \\\"Gadget\\\"}))]\"",
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
name: "AppendConditionMismatch",
|
|
94
|
-
mismatch: AppendConditionMismatch({expected: appendExpected, actual: appendActual}),
|
|
95
|
-
format: "AppendConditionMismatch:\n expected: {\n \"query\": []\n}\n actual: {\n \"query\": [\n {\n \"eventTypes\": [\n \"ProductAdded\"\n ]\n }\n ]\n}",
|
|
96
|
-
human: " expected: {query: []}\n actual: {query: [{eventTypes: [\"ProductAdded\"]}]}",
|
|
97
|
-
tap: " kind: \"AppendConditionMismatch\"\n expected: \"{query: []}\"\n actual: \"{query: [{eventTypes: [\\\"ProductAdded\\\"]}]}\"",
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
name: "QueryRowsMismatch",
|
|
101
|
-
mismatch: QueryRowsMismatch({expected: [evA], actual: [evB]}),
|
|
102
|
-
format: "QueryRowsMismatch:\n expected: [{\n \"TAG\": \"ProductAdded\",\n \"_0\": {\n \"productId\": \"p1\",\n \"name\": \"Widget\"\n }\n}]\n actual: [{\n \"TAG\": \"ProductRenamed\",\n \"_0\": {\n \"productId\": \"p1\",\n \"name\": \"Gadget\"\n }\n}]",
|
|
103
|
-
human: " expected: [ProductAdded({productId: \"p1\", name: \"Widget\"})]\n actual: [ProductRenamed({productId: \"p1\", name: \"Gadget\"})]",
|
|
104
|
-
tap: " kind: \"QueryRowsMismatch\"\n expected: \"[ProductAdded({productId: \\\"p1\\\", name: \\\"Widget\\\"})]\"\n actual: \"[ProductRenamed({productId: \\\"p1\\\", name: \\\"Gadget\\\"})]\"",
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
name: "PublishedActionsMismatch",
|
|
108
|
-
mismatch: PublishedActionsMismatch({expected: [evA], actual: [evB]}),
|
|
109
|
-
format: "PublishedActionsMismatch:\n expected: [{\n \"TAG\": \"ProductAdded\",\n \"_0\": {\n \"productId\": \"p1\",\n \"name\": \"Widget\"\n }\n}]\n actual: [{\n \"TAG\": \"ProductRenamed\",\n \"_0\": {\n \"productId\": \"p1\",\n \"name\": \"Gadget\"\n }\n}]",
|
|
110
|
-
human: " expected: [ProductAdded({productId: \"p1\", name: \"Widget\"})]\n actual: [ProductRenamed({productId: \"p1\", name: \"Gadget\"})]",
|
|
111
|
-
tap: " kind: \"PublishedActionsMismatch\"\n expected: \"[ProductAdded({productId: \\\"p1\\\", name: \\\"Widget\\\"})]\"\n actual: \"[ProductRenamed({productId: \\\"p1\\\", name: \\\"Gadget\\\"})]\"",
|
|
112
|
-
},
|
|
113
|
-
]
|
|
114
|
-
|
|
115
|
-
describe("Formatter golden outputs (per-mismatch rendering)", () => {
|
|
116
|
-
goldens->Array.forEach(g => {
|
|
117
|
-
testSync(`${g.name} — Outcome.format`, () => expect(Outcome.format(g.mismatch))->toEqual(g.format))
|
|
118
|
-
testSync(`${g.name} — FormatterHuman.renderMismatch`, () =>
|
|
119
|
-
expect(FormatterHuman.renderMismatch(g.mismatch))->toEqual(g.human)
|
|
120
|
-
)
|
|
121
|
-
testSync(`${g.name} — FormatterTap.renderMismatchYaml`, () =>
|
|
122
|
-
expect(FormatterTap.renderMismatchYaml(g.mismatch))->toEqual(g.tap)
|
|
123
|
-
)
|
|
124
|
-
})
|
|
125
|
-
})
|