@reventlessdev/reventless-gwt 1.0.0-alpha.100

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 (184) hide show
  1. package/CHANGELOG.md +916 -0
  2. package/LICENSE +202 -0
  3. package/bin/reventless-dev.mjs +21 -0
  4. package/package.json +54 -0
  5. package/rescript.json +36 -0
  6. package/src/.gwtignore +10 -0
  7. package/src/Automation_GWT.res +207 -0
  8. package/src/Automation_GWT.res.mjs +160 -0
  9. package/src/Behavior_GWT.res +569 -0
  10. package/src/Behavior_GWT.res.mjs +523 -0
  11. package/src/Bind.res +29 -0
  12. package/src/Bind.res.mjs +22 -0
  13. package/src/BuildClassifier.res +147 -0
  14. package/src/BuildClassifier.res.mjs +136 -0
  15. package/src/Cancellation.res +37 -0
  16. package/src/Cancellation.res.mjs +46 -0
  17. package/src/ChildProcess.res +102 -0
  18. package/src/ChildProcess.res.mjs +107 -0
  19. package/src/Cli.res +905 -0
  20. package/src/Cli.res.mjs +952 -0
  21. package/src/Collector.res +212 -0
  22. package/src/Collector.res.mjs +218 -0
  23. package/src/ComponentMeta.res +77 -0
  24. package/src/ComponentMeta.res.mjs +91 -0
  25. package/src/ComponentScan.res +103 -0
  26. package/src/ComponentScan.res.mjs +105 -0
  27. package/src/Delegate_GWT.res +303 -0
  28. package/src/Delegate_GWT.res.mjs +372 -0
  29. package/src/Diff.res +91 -0
  30. package/src/Diff.res.mjs +98 -0
  31. package/src/Discovery.res +105 -0
  32. package/src/Discovery.res.mjs +99 -0
  33. package/src/DomainDeadCode.res +98 -0
  34. package/src/DomainDeadCode.res.mjs +72 -0
  35. package/src/DomainGraph.res +0 -0
  36. package/src/DomainGraph.res.mjs +0 -0
  37. package/src/EventMapping_GWT.res +29 -0
  38. package/src/EventMapping_GWT.res.mjs +44 -0
  39. package/src/Filter.res +45 -0
  40. package/src/Filter.res.mjs +47 -0
  41. package/src/Flow_GWT.res +664 -0
  42. package/src/Flow_GWT.res.mjs +604 -0
  43. package/src/FormatterHuman.res +109 -0
  44. package/src/FormatterHuman.res.mjs +115 -0
  45. package/src/FormatterJson.res +264 -0
  46. package/src/FormatterJson.res.mjs +322 -0
  47. package/src/FormatterJunit.res +93 -0
  48. package/src/FormatterJunit.res.mjs +90 -0
  49. package/src/FormatterTap.res +100 -0
  50. package/src/FormatterTap.res.mjs +131 -0
  51. package/src/FormatterVsCode.res +352 -0
  52. package/src/FormatterVsCode.res.mjs +546 -0
  53. package/src/Hint.res +119 -0
  54. package/src/Hint.res.mjs +124 -0
  55. package/src/InboundTranslation_GWT.res +83 -0
  56. package/src/InboundTranslation_GWT.res.mjs +94 -0
  57. package/src/JestBind.res +70 -0
  58. package/src/JestBind.res.mjs +63 -0
  59. package/src/Loader.res +24 -0
  60. package/src/Loader.res.mjs +23 -0
  61. package/src/LocalHost.res +119 -0
  62. package/src/LocalHost.res.mjs +99 -0
  63. package/src/Mapping_GWT.res +474 -0
  64. package/src/Mapping_GWT.res.mjs +322 -0
  65. package/src/MismatchRender.res +72 -0
  66. package/src/MismatchRender.res.mjs +127 -0
  67. package/src/MultiSourceProjection_GWT.res +316 -0
  68. package/src/MultiSourceProjection_GWT.res.mjs +354 -0
  69. package/src/OutboundTranslation_GWT.res +238 -0
  70. package/src/OutboundTranslation_GWT.res.mjs +186 -0
  71. package/src/Outcome.res +97 -0
  72. package/src/Outcome.res.mjs +93 -0
  73. package/src/PackageScan.res +80 -0
  74. package/src/PackageScan.res.mjs +81 -0
  75. package/src/PlatformRunner.res +181 -0
  76. package/src/PlatformRunner.res.mjs +176 -0
  77. package/src/PlatformScan.res +142 -0
  78. package/src/PlatformScan.res.mjs +132 -0
  79. package/src/ProcessManager.res +135 -0
  80. package/src/ProcessManager.res.mjs +119 -0
  81. package/src/Projection_GWT.res +312 -0
  82. package/src/Projection_GWT.res.mjs +332 -0
  83. package/src/Query_GWT.res +379 -0
  84. package/src/Query_GWT.res.mjs +367 -0
  85. package/src/RenderRescript.res +125 -0
  86. package/src/RenderRescript.res.mjs +141 -0
  87. package/src/RunWorker.res +24 -0
  88. package/src/RunWorker.res.mjs +16 -0
  89. package/src/RunnerTypes.res +68 -0
  90. package/src/RunnerTypes.res.mjs +60 -0
  91. package/src/SideEffect_GWT.res +157 -0
  92. package/src/SideEffect_GWT.res.mjs +113 -0
  93. package/src/StateChange/ExternalAddCategorySlice.res +25 -0
  94. package/src/StateChange/ExternalAddCategorySlice.res.mjs +34 -0
  95. package/src/StateChange/ExternalAddCategorySlice_Behavior.res +19 -0
  96. package/src/StateChange/ExternalAddCategorySlice_Behavior.res.mjs +46 -0
  97. package/src/StateChange/WithFixtures.res +22 -0
  98. package/src/StateChange/WithFixtures.res.mjs +31 -0
  99. package/src/StateChange/WithFixtures_Behavior.res +17 -0
  100. package/src/StateChange/WithFixtures_Behavior.res.mjs +37 -0
  101. package/src/StateChange/WithManualOpen.res +23 -0
  102. package/src/StateChange/WithManualOpen.res.mjs +31 -0
  103. package/src/StateChange/WithManualOpen_Behavior.res +17 -0
  104. package/src/StateChange/WithManualOpen_Behavior.res.mjs +37 -0
  105. package/src/StubRuntime.res +54 -0
  106. package/src/StubRuntime.res.mjs +55 -0
  107. package/src/TestFixtures.res +16 -0
  108. package/src/TestFixtures.res.mjs +34 -0
  109. package/src/Watch.res +108 -0
  110. package/src/Watch.res.mjs +85 -0
  111. package/src/WatcherProbe.res +56 -0
  112. package/src/WatcherProbe.res.mjs +59 -0
  113. package/src/Worker.res +24 -0
  114. package/src/Worker.res.mjs +9 -0
  115. package/tests/AutomationGwtTest.res +71 -0
  116. package/tests/AutomationGwtTest.res.mjs +189 -0
  117. package/tests/BuildClassifierTest.res +133 -0
  118. package/tests/BuildClassifierTest.res.mjs +176 -0
  119. package/tests/CliRunEntryTest.res +57 -0
  120. package/tests/CliRunEntryTest.res.mjs +65 -0
  121. package/tests/CliWatchScopeTest.res +62 -0
  122. package/tests/CliWatchScopeTest.res.mjs +95 -0
  123. package/tests/ComponentMetaTest.res +67 -0
  124. package/tests/ComponentMetaTest.res.mjs +71 -0
  125. package/tests/DelegateGwtTest.res +487 -0
  126. package/tests/DelegateGwtTest.res.mjs +891 -0
  127. package/tests/DiscoveryTest.res +42 -0
  128. package/tests/DiscoveryTest.res.mjs +43 -0
  129. package/tests/DomainDeadCodeTest.res +119 -0
  130. package/tests/DomainDeadCodeTest.res.mjs +158 -0
  131. package/tests/DomainGraphTest.res +448 -0
  132. package/tests/DomainGraphTest.res.mjs +505 -0
  133. package/tests/FlowAggregateGwtTest.res +171 -0
  134. package/tests/FlowAggregateGwtTest.res.mjs +273 -0
  135. package/tests/FlowCrossPluginGwtTest.res +340 -0
  136. package/tests/FlowCrossPluginGwtTest.res.mjs +798 -0
  137. package/tests/FlowGwtTest.res +222 -0
  138. package/tests/FlowGwtTest.res.mjs +433 -0
  139. package/tests/FormatterGoldenTest.res +125 -0
  140. package/tests/FormatterGoldenTest.res.mjs +162 -0
  141. package/tests/FormatterVsCodeMessageTest.res +41 -0
  142. package/tests/FormatterVsCodeMessageTest.res.mjs +42 -0
  143. package/tests/InboundTranslationGwtTest.res +34 -0
  144. package/tests/InboundTranslationGwtTest.res.mjs +99 -0
  145. package/tests/LocalHostIntegration.res +70 -0
  146. package/tests/LocalHostIntegration.res.mjs +64 -0
  147. package/tests/LocalHostTest.res +71 -0
  148. package/tests/LocalHostTest.res.mjs +63 -0
  149. package/tests/MappingGwtTest.res +350 -0
  150. package/tests/MappingGwtTest.res.mjs +596 -0
  151. package/tests/OutboundTranslationGwtTest.res +59 -0
  152. package/tests/OutboundTranslationGwtTest.res.mjs +139 -0
  153. package/tests/PlatformRunnerTest.res +66 -0
  154. package/tests/PlatformRunnerTest.res.mjs +85 -0
  155. package/tests/PlatformScanTest.res +61 -0
  156. package/tests/PlatformScanTest.res.mjs +56 -0
  157. package/tests/QueryGwtTest.res +161 -0
  158. package/tests/QueryGwtTest.res.mjs +314 -0
  159. package/tests/QueryResolverGwtTest.res +71 -0
  160. package/tests/QueryResolverGwtTest.res.mjs +136 -0
  161. package/tests/RunnerUnitTest.res +219 -0
  162. package/tests/RunnerUnitTest.res.mjs +244 -0
  163. package/tests/SideEffect/FakeOrderNotification.res +23 -0
  164. package/tests/SideEffect/FakeOrderNotification.res.mjs +36 -0
  165. package/tests/SideEffect/FakeOrderNotificationGwtTest.res +35 -0
  166. package/tests/SideEffect/FakeOrderNotificationGwtTest.res.mjs +73 -0
  167. package/tests/SideEffect/MockEmail.res +18 -0
  168. package/tests/SideEffect/MockEmail.res.mjs +47 -0
  169. package/tests/StateChange/ExternalAddCategorySlice_GWT.res +27 -0
  170. package/tests/StateChange/ExternalAddCategorySlice_GWT.res.mjs +70 -0
  171. package/tests/StateChange/WithFixtures_Fixtures.res +9 -0
  172. package/tests/StateChange/WithFixtures_Fixtures.res.mjs +20 -0
  173. package/tests/StateChange/WithFixtures_GWT.res +23 -0
  174. package/tests/StateChange/WithFixtures_GWT.res.mjs +56 -0
  175. package/tests/StateChange/WithManualOpen_Fixtures.res +7 -0
  176. package/tests/StateChange/WithManualOpen_Fixtures.res.mjs +20 -0
  177. package/tests/StateChange/WithManualOpen_GWT.res +17 -0
  178. package/tests/StateChange/WithManualOpen_GWT.res.mjs +56 -0
  179. package/tests/StateChangeSliceGwtTest.res +160 -0
  180. package/tests/StateChangeSliceGwtTest.res.mjs +280 -0
  181. package/tests/StateViewSliceGwtTest.res +64 -0
  182. package/tests/StateViewSliceGwtTest.res.mjs +161 -0
  183. package/tests/WatchDebounceTest.res +106 -0
  184. package/tests/WatchDebounceTest.res.mjs +128 -0
@@ -0,0 +1,523 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as S from "sury/src/S.res.mjs";
4
+ import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
5
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
6
+ import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
7
+ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
8
+ import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
9
+ import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
10
+ import * as DcbDecode$Reventless from "@reventlessdev/reventless-spec/src/components/DcbDecode.res.mjs";
11
+ import * as Outcome$ReventlessGwt from "./Outcome.res.mjs";
12
+ import * as JestBind$ReventlessGwt from "./JestBind.res.mjs";
13
+ import * as Message$ReventlessCore from "@reventlessdev/reventless-core/src/Message.res.mjs";
14
+ import * as DcbScopeInference$Reventless from "@reventlessdev/reventless-spec/src/components/DcbScopeInference.res.mjs";
15
+
16
+ function encodeTag(t) {
17
+ let d = {};
18
+ d["key"] = t.key;
19
+ d["value"] = t.value;
20
+ return d;
21
+ }
22
+
23
+ function encodeQueryItem(qi) {
24
+ let d = {};
25
+ let types = qi.eventTypes;
26
+ if (types !== undefined) {
27
+ d["eventTypes"] = types.map(prim => prim);
28
+ }
29
+ let tags = qi.tags;
30
+ if (tags !== undefined) {
31
+ d["tags"] = tags.map(encodeTag);
32
+ }
33
+ return d;
34
+ }
35
+
36
+ function encodeQuery(q) {
37
+ return q.map(encodeQueryItem);
38
+ }
39
+
40
+ function encodeAppendCondition(c) {
41
+ let d = {};
42
+ d["query"] = c.query.map(encodeQueryItem);
43
+ let pos = c.after;
44
+ if (pos !== undefined) {
45
+ d["after"] = pos;
46
+ }
47
+ return d;
48
+ }
49
+
50
+ function AssertionCore(Spec) {
51
+ let errors = {
52
+ contents: []
53
+ };
54
+ let encEvent = e => Message$ReventlessCore.encode(e, Spec.eventSchema);
55
+ let encEvents = evs => evs.map(encEvent);
56
+ let encError = err => Message$ReventlessCore.encode(err, Spec.errorSchema);
57
+ let unexpectedError = events => {
58
+ let actual = Stdlib_Option.map(errors.contents[0], encError);
59
+ return Outcome$ReventlessGwt.fail({
60
+ TAG: "ErrorMismatch",
61
+ expected: null,
62
+ actual: actual,
63
+ actualEvents: events.map(encEvent)
64
+ });
65
+ };
66
+ let compareEvents = (events, expectedEvents) => {
67
+ if (errors.contents.length !== 0) {
68
+ return unexpectedError(events);
69
+ } else if (Primitive_object.equal(events, expectedEvents)) {
70
+ return Outcome$ReventlessGwt.pass;
71
+ } else {
72
+ return Outcome$ReventlessGwt.fail({
73
+ TAG: "EventsMismatch",
74
+ expected: expectedEvents.map(encEvent),
75
+ actual: events.map(encEvent)
76
+ });
77
+ }
78
+ };
79
+ let compareEventsWith = (events, expectedEvents, cmp) => {
80
+ if (errors.contents.length !== 0) {
81
+ return unexpectedError(events);
82
+ } else if (events.length === expectedEvents.length && Stdlib_Array.zip(events, expectedEvents).every(param => cmp(param[0], param[1]))) {
83
+ return Outcome$ReventlessGwt.pass;
84
+ } else {
85
+ return Outcome$ReventlessGwt.fail({
86
+ TAG: "EventsMismatch",
87
+ expected: expectedEvents.map(encEvent),
88
+ actual: events.map(encEvent)
89
+ });
90
+ }
91
+ };
92
+ let compareNoEvent = events => {
93
+ if (errors.contents.length !== 0) {
94
+ return unexpectedError(events);
95
+ } else if (events.length === 0) {
96
+ return Outcome$ReventlessGwt.pass;
97
+ } else {
98
+ return Outcome$ReventlessGwt.fail({
99
+ TAG: "NoEventExpected",
100
+ actual: events.map(encEvent)
101
+ });
102
+ }
103
+ };
104
+ let matchesError = (events, expectedEvents, expectedError) => {
105
+ let expectedErrorJson = Message$ReventlessCore.encode(expectedError, Spec.errorSchema);
106
+ let actual = errors.contents[0];
107
+ if (actual === undefined) {
108
+ return Outcome$ReventlessGwt.fail({
109
+ TAG: "ErrorMismatch",
110
+ expected: expectedErrorJson,
111
+ actual: undefined,
112
+ actualEvents: events.map(encEvent)
113
+ });
114
+ }
115
+ let actual$1 = Primitive_option.valFromOption(actual);
116
+ if (Primitive_object.notequal(actual$1, expectedError)) {
117
+ return Outcome$ReventlessGwt.fail({
118
+ TAG: "ErrorMismatch",
119
+ expected: expectedErrorJson,
120
+ actual: Message$ReventlessCore.encode(actual$1, Spec.errorSchema),
121
+ actualEvents: events.map(encEvent)
122
+ });
123
+ } else if (Primitive_object.equal(events, expectedEvents)) {
124
+ return Outcome$ReventlessGwt.pass;
125
+ } else {
126
+ return Outcome$ReventlessGwt.fail({
127
+ TAG: "EventsMismatch",
128
+ expected: expectedEvents.map(encEvent),
129
+ actual: events.map(encEvent)
130
+ });
131
+ }
132
+ };
133
+ return {
134
+ errors: errors,
135
+ encEvent: encEvent,
136
+ encEvents: encEvents,
137
+ encError: encError,
138
+ unexpectedError: unexpectedError,
139
+ compareEvents: compareEvents,
140
+ compareEventsWith: compareEventsWith,
141
+ compareNoEvent: compareNoEvent,
142
+ matchesError: matchesError
143
+ };
144
+ }
145
+
146
+ function Make(Spec) {
147
+ return Behavior => {
148
+ S.enableJson();
149
+ let test = (name, body) => JestBind$ReventlessGwt.test(Spec.name, name, body);
150
+ let errors = {
151
+ contents: []
152
+ };
153
+ let encEvent = e => Message$ReventlessCore.encode(e, Spec.eventSchema);
154
+ let encError = err => Message$ReventlessCore.encode(err, Spec.errorSchema);
155
+ let unexpectedError = events => {
156
+ let actual = Stdlib_Option.map(errors.contents[0], encError);
157
+ return Outcome$ReventlessGwt.fail({
158
+ TAG: "ErrorMismatch",
159
+ expected: null,
160
+ actual: actual,
161
+ actualEvents: events.map(encEvent)
162
+ });
163
+ };
164
+ let matchesError = (events, expectedEvents, expectedError) => {
165
+ let expectedErrorJson = Message$ReventlessCore.encode(expectedError, Spec.errorSchema);
166
+ let actual = errors.contents[0];
167
+ if (actual === undefined) {
168
+ return Outcome$ReventlessGwt.fail({
169
+ TAG: "ErrorMismatch",
170
+ expected: expectedErrorJson,
171
+ actual: undefined,
172
+ actualEvents: events.map(encEvent)
173
+ });
174
+ }
175
+ let actual$1 = Primitive_option.valFromOption(actual);
176
+ if (Primitive_object.notequal(actual$1, expectedError)) {
177
+ return Outcome$ReventlessGwt.fail({
178
+ TAG: "ErrorMismatch",
179
+ expected: expectedErrorJson,
180
+ actual: Message$ReventlessCore.encode(actual$1, Spec.errorSchema),
181
+ actualEvents: events.map(encEvent)
182
+ });
183
+ } else if (Primitive_object.equal(events, expectedEvents)) {
184
+ return Outcome$ReventlessGwt.pass;
185
+ } else {
186
+ return Outcome$ReventlessGwt.fail({
187
+ TAG: "EventsMismatch",
188
+ expected: expectedEvents.map(encEvent),
189
+ actual: events.map(encEvent)
190
+ });
191
+ }
192
+ };
193
+ let derivedCondition = {
194
+ contents: undefined
195
+ };
196
+ let appendConditionFailure = {
197
+ contents: undefined
198
+ };
199
+ let consumedEventTypes = DcbDecode$Reventless.makeDecoder(Spec.consumedEventSchema).eventTypes;
200
+ let scopeShape = DcbTag$Reventless.sliceShapeFromSchemas("", Spec.commandSchema, Spec.consumedEventSchema, Spec.eventSchema);
201
+ let set = new Set();
202
+ DcbTag$Reventless.extractCrossPartitionTagKeys(Spec.eventSchema).forEach(k => {
203
+ set.add(k);
204
+ });
205
+ DcbScopeInference$Reventless.crossPartitionForSlice(scopeShape).forEach(k => {
206
+ set.add(k);
207
+ });
208
+ let crossPartitionTagKeys = Array.from(set.values()).toSorted(Primitive_string.compare);
209
+ let tagKeysByEventType = DcbScopeInference$Reventless.infer([scopeShape]).tagKeysByEventType;
210
+ let emittedEventTypes = DcbDecode$Reventless.makeDecoder(Spec.eventSchema).eventTypes;
211
+ let consumedTagKeysByType = DcbTag$Reventless.extractTagKeysByEventType(Spec.consumedEventSchema);
212
+ let queryTagKeys = query => query.flatMap(qi => Stdlib_Option.mapOr(qi.tags, [], tags => tags.map(t => t.key)));
213
+ let selectableBy = (query, declaredKeys) => {
214
+ if (query.length === 0) {
215
+ return true;
216
+ } else {
217
+ return query.some(qi => {
218
+ let tags = qi.tags;
219
+ if (tags !== undefined && tags.length !== 0) {
220
+ return tags.every(t => declaredKeys.includes(t.key));
221
+ } else {
222
+ return true;
223
+ }
224
+ });
225
+ }
226
+ };
227
+ let unreachableForeignReads = query => {
228
+ let qKeys = queryTagKeys(query);
229
+ return Stdlib_Array.filterMap(Object.entries(consumedTagKeysByType), param => {
230
+ let keys = param[1];
231
+ let evType = param[0];
232
+ let key = keys.find(k => qKeys.includes(k));
233
+ if (key !== undefined && !emittedEventTypes.includes(evType) && !selectableBy(query, keys)) {
234
+ return [
235
+ evType,
236
+ key
237
+ ];
238
+ }
239
+ });
240
+ };
241
+ let queryTagsTotal = q => Stdlib_Array.reduce(q, 0, (acc, qi) => acc + Stdlib_Option.mapOr(qi.tags, 0, t => t.length) | 0);
242
+ let givenEvents = consumed => consumed;
243
+ let whenCmd = (history, cmd) => {
244
+ errors.contents = [];
245
+ appendConditionFailure.contents = undefined;
246
+ let query = DcbTag$Reventless.buildQueryFromCommand(consumedEventTypes, Spec.commandSchema, cmd, tagKeysByEventType, crossPartitionTagKeys);
247
+ let condition = {
248
+ query: query
249
+ };
250
+ derivedCondition.contents = condition;
251
+ if (consumedEventTypes.length !== 0 && queryTagsTotal(query) === 0) {
252
+ appendConditionFailure.contents = {
253
+ TAG: "AppendConditionMismatch",
254
+ expected: "a non-empty tag set derived from @s.matches(DcbTag.string) fields on the command",
255
+ actual: encodeAppendCondition(condition)
256
+ };
257
+ } else {
258
+ let match = unreachableForeignReads(query)[0];
259
+ if (match !== undefined) {
260
+ let key = match[1];
261
+ let evType = match[0];
262
+ appendConditionFailure.contents = {
263
+ TAG: "AppendConditionMismatch",
264
+ expected: `a decision-query clause that selects '` + evType + `' on tag '` + key + `' alone — this is a cross-entity read, so mark '` + key + `' @crossPartition (or model it as a tagged array) and it will fan into its own clause; otherwise the decision model can never see '` + evType + `'`,
265
+ actual: encodeAppendCondition(condition)
266
+ };
267
+ }
268
+ }
269
+ let state = Stdlib_Array.reduce(history, Behavior.initialState, Behavior.evolve);
270
+ let events = Behavior.decide(state, cmd);
271
+ if (events.TAG === "Ok") {
272
+ return events._0;
273
+ }
274
+ errors.contents = [events._0];
275
+ return [];
276
+ };
277
+ let checkAppendCondition = () => Stdlib_Option.map(appendConditionFailure.contents, Outcome$ReventlessGwt.fail);
278
+ let thenEvents = (events, expectedEvents) => {
279
+ let o = checkAppendCondition();
280
+ if (o !== undefined) {
281
+ return o;
282
+ } else if (errors.contents.length !== 0) {
283
+ return unexpectedError(events);
284
+ } else if (Primitive_object.equal(events, expectedEvents)) {
285
+ return Outcome$ReventlessGwt.pass;
286
+ } else {
287
+ return Outcome$ReventlessGwt.fail({
288
+ TAG: "EventsMismatch",
289
+ expected: expectedEvents.map(encEvent),
290
+ actual: events.map(encEvent)
291
+ });
292
+ }
293
+ };
294
+ let thenEvent = (events, expectedEvent) => thenEvents(events, [expectedEvent]);
295
+ let thenNoEvent = events => {
296
+ let o = checkAppendCondition();
297
+ if (o !== undefined) {
298
+ return o;
299
+ } else if (errors.contents.length !== 0) {
300
+ return unexpectedError(events);
301
+ } else if (events.length === 0) {
302
+ return Outcome$ReventlessGwt.pass;
303
+ } else {
304
+ return Outcome$ReventlessGwt.fail({
305
+ TAG: "NoEventExpected",
306
+ actual: events.map(encEvent)
307
+ });
308
+ }
309
+ };
310
+ let thenError = (events, expectedError) => {
311
+ let o = checkAppendCondition();
312
+ if (o !== undefined) {
313
+ return o;
314
+ } else {
315
+ return matchesError(events, [], expectedError);
316
+ }
317
+ };
318
+ let thenEventWithError = (events, expectedEvent, expectedError) => {
319
+ let o = checkAppendCondition();
320
+ if (o !== undefined) {
321
+ return o;
322
+ } else {
323
+ return matchesError(events, [expectedEvent], expectedError);
324
+ }
325
+ };
326
+ let thenEventsWithError = (events, expectedEvents, expectedError) => {
327
+ let o = checkAppendCondition();
328
+ if (o !== undefined) {
329
+ return o;
330
+ } else {
331
+ return matchesError(events, expectedEvents, expectedError);
332
+ }
333
+ };
334
+ let thenAppendsConditionedOn = (_events, expectedQuery) => {
335
+ let cond = derivedCondition.contents;
336
+ if (cond !== undefined) {
337
+ if (Primitive_object.equal(cond.query, expectedQuery)) {
338
+ return Outcome$ReventlessGwt.pass;
339
+ } else {
340
+ return Outcome$ReventlessGwt.fail({
341
+ TAG: "AppendConditionMismatch",
342
+ expected: encodeAppendCondition({
343
+ query: expectedQuery
344
+ }),
345
+ actual: encodeAppendCondition(cond)
346
+ });
347
+ }
348
+ } else {
349
+ return Outcome$ReventlessGwt.fail({
350
+ TAG: "Throw",
351
+ error: "thenAppendsConditionedOn: whenCmd must be called before this assertion",
352
+ stack: ""
353
+ });
354
+ }
355
+ };
356
+ let thenAppendsConditionedOnExactly = (_events, expectedCondition) => {
357
+ let cond = derivedCondition.contents;
358
+ if (cond !== undefined) {
359
+ if (Primitive_object.equal(cond, expectedCondition)) {
360
+ return Outcome$ReventlessGwt.pass;
361
+ } else {
362
+ return Outcome$ReventlessGwt.fail({
363
+ TAG: "AppendConditionMismatch",
364
+ expected: encodeAppendCondition(expectedCondition),
365
+ actual: encodeAppendCondition(cond)
366
+ });
367
+ }
368
+ } else {
369
+ return Outcome$ReventlessGwt.fail({
370
+ TAG: "Throw",
371
+ error: "thenAppendsConditionedOnExactly: whenCmd must be called before this assertion",
372
+ stack: ""
373
+ });
374
+ }
375
+ };
376
+ return {
377
+ Spec: Spec,
378
+ describe: JestBind$ReventlessGwt.describe,
379
+ todo: JestBind$ReventlessGwt.todo,
380
+ test: test,
381
+ givenEvents: givenEvents,
382
+ whenCmd: whenCmd,
383
+ thenEvent: thenEvent,
384
+ thenEvents: thenEvents,
385
+ thenNoEvent: thenNoEvent,
386
+ thenEventWithError: thenEventWithError,
387
+ thenEventsWithError: thenEventsWithError,
388
+ thenError: thenError,
389
+ thenAppendsConditionedOn: thenAppendsConditionedOn,
390
+ thenAppendsConditionedOnExactly: thenAppendsConditionedOnExactly
391
+ };
392
+ };
393
+ }
394
+
395
+ function MakeFromAggregate(Spec) {
396
+ return Behavior => {
397
+ S.enableJson();
398
+ let test = (name, body) => JestBind$ReventlessGwt.test(Spec.name, name, body);
399
+ let errors = {
400
+ contents: []
401
+ };
402
+ let encEvent = e => Message$ReventlessCore.encode(e, Spec.eventSchema);
403
+ let encError = err => Message$ReventlessCore.encode(err, Spec.errorSchema);
404
+ let unexpectedError = events => {
405
+ let actual = Stdlib_Option.map(errors.contents[0], encError);
406
+ return Outcome$ReventlessGwt.fail({
407
+ TAG: "ErrorMismatch",
408
+ expected: null,
409
+ actual: actual,
410
+ actualEvents: events.map(encEvent)
411
+ });
412
+ };
413
+ let compareEvents = (events, expectedEvents) => {
414
+ if (errors.contents.length !== 0) {
415
+ return unexpectedError(events);
416
+ } else if (Primitive_object.equal(events, expectedEvents)) {
417
+ return Outcome$ReventlessGwt.pass;
418
+ } else {
419
+ return Outcome$ReventlessGwt.fail({
420
+ TAG: "EventsMismatch",
421
+ expected: expectedEvents.map(encEvent),
422
+ actual: events.map(encEvent)
423
+ });
424
+ }
425
+ };
426
+ let compareEventsWith = (events, expectedEvents, cmp) => {
427
+ if (errors.contents.length !== 0) {
428
+ return unexpectedError(events);
429
+ } else if (events.length === expectedEvents.length && Stdlib_Array.zip(events, expectedEvents).every(param => cmp(param[0], param[1]))) {
430
+ return Outcome$ReventlessGwt.pass;
431
+ } else {
432
+ return Outcome$ReventlessGwt.fail({
433
+ TAG: "EventsMismatch",
434
+ expected: expectedEvents.map(encEvent),
435
+ actual: events.map(encEvent)
436
+ });
437
+ }
438
+ };
439
+ let compareNoEvent = events => {
440
+ if (errors.contents.length !== 0) {
441
+ return unexpectedError(events);
442
+ } else if (events.length === 0) {
443
+ return Outcome$ReventlessGwt.pass;
444
+ } else {
445
+ return Outcome$ReventlessGwt.fail({
446
+ TAG: "NoEventExpected",
447
+ actual: events.map(encEvent)
448
+ });
449
+ }
450
+ };
451
+ let matchesError = (events, expectedEvents, expectedError) => {
452
+ let expectedErrorJson = Message$ReventlessCore.encode(expectedError, Spec.errorSchema);
453
+ let actual = errors.contents[0];
454
+ if (actual === undefined) {
455
+ return Outcome$ReventlessGwt.fail({
456
+ TAG: "ErrorMismatch",
457
+ expected: expectedErrorJson,
458
+ actual: undefined,
459
+ actualEvents: events.map(encEvent)
460
+ });
461
+ }
462
+ let actual$1 = Primitive_option.valFromOption(actual);
463
+ if (Primitive_object.notequal(actual$1, expectedError)) {
464
+ return Outcome$ReventlessGwt.fail({
465
+ TAG: "ErrorMismatch",
466
+ expected: expectedErrorJson,
467
+ actual: Message$ReventlessCore.encode(actual$1, Spec.errorSchema),
468
+ actualEvents: events.map(encEvent)
469
+ });
470
+ } else if (Primitive_object.equal(events, expectedEvents)) {
471
+ return Outcome$ReventlessGwt.pass;
472
+ } else {
473
+ return Outcome$ReventlessGwt.fail({
474
+ TAG: "EventsMismatch",
475
+ expected: expectedEvents.map(encEvent),
476
+ actual: events.map(encEvent)
477
+ });
478
+ }
479
+ };
480
+ let givenEvents = events => events;
481
+ let whenCmd = (history, cmd) => {
482
+ errors.contents = [];
483
+ let state = Stdlib_Array.reduce(history, Behavior.initialState, Behavior.evolve);
484
+ let events = Behavior.decide(state, cmd);
485
+ if (events.TAG === "Ok") {
486
+ return events._0;
487
+ }
488
+ errors.contents = [events._0];
489
+ return [];
490
+ };
491
+ let thenEvent = (events, expectedEvent) => compareEvents(events, [expectedEvent]);
492
+ let thenCompareEvent = (events, expectedEvent, cmp) => compareEventsWith(events, [expectedEvent], cmp);
493
+ let thenError = (events, expectedError) => matchesError(events, [], expectedError);
494
+ let thenEventWithError = (events, expectedEvent, expectedError) => matchesError(events, [expectedEvent], expectedError);
495
+ let thenEventsWithError = matchesError;
496
+ return {
497
+ Spec: Spec,
498
+ describe: JestBind$ReventlessGwt.describe,
499
+ test: test,
500
+ givenEvents: givenEvents,
501
+ whenCmd: whenCmd,
502
+ thenEvent: thenEvent,
503
+ thenCompareEvent: thenCompareEvent,
504
+ thenNoEvent: compareNoEvent,
505
+ thenEventWithError: thenEventWithError,
506
+ thenEvents: compareEvents,
507
+ thenCompareEvents: compareEventsWith,
508
+ thenEventsWithError: thenEventsWithError,
509
+ thenError: thenError
510
+ };
511
+ };
512
+ }
513
+
514
+ export {
515
+ encodeTag,
516
+ encodeQueryItem,
517
+ encodeQuery,
518
+ encodeAppendCondition,
519
+ AssertionCore,
520
+ Make,
521
+ MakeFromAggregate,
522
+ }
523
+ /* S Not a pure module */
package/src/Bind.res ADDED
@@ -0,0 +1,29 @@
1
+ // CLI-mode binding for test files.
2
+ //
3
+ // Mirrors the shape of `JestBind` (`describe`, `test`, `testPromise`) but
4
+ // pushes directly into `Collector` instead of forwarding to Jest globals.
5
+ // Test files can either:
6
+ //
7
+ // 1. Rely on the DSL default (every `*_GWT.res` module uses `JestBind`
8
+ // internally, which routes to `Collector` when the CLI has activated it),
9
+ // or
10
+ // 2. Explicitly `open ReventlessGwt.Bind` to get these functions bound at
11
+ // compile time — useful for ad-hoc harnesses or tests that want to
12
+ // bypass the JestBind fallback entirely.
13
+ //
14
+ // Either way, the runtime contract is identical: each call pushes one entry
15
+ // into `Collector.entries`. The CLI drains the list after dynamic-import
16
+ // resolves.
17
+
18
+ let describe = (label: string, body: unit => unit) =>
19
+ Collector.pushDescribe(label, body)
20
+
21
+ let test = (~slice=?, name: string, body: unit => Outcome.outcome) => {
22
+ let location = Collector.captureLocation(1)
23
+ Collector.push(~slice?, ~location?, name, () => Promise.resolve(body()))
24
+ }
25
+
26
+ let testPromise = (~slice=?, name: string, body: unit => promise<Outcome.outcome>) => {
27
+ let location = Collector.captureLocation(1)
28
+ Collector.push(~slice?, ~location?, name, body)
29
+ }
@@ -0,0 +1,22 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Collector$ReventlessGwt from "./Collector.res.mjs";
4
+
5
+ let describe = Collector$ReventlessGwt.pushDescribe;
6
+
7
+ function test(slice, name, body) {
8
+ let location = Collector$ReventlessGwt.captureLocation(1);
9
+ Collector$ReventlessGwt.push(slice, location, undefined, name, () => Promise.resolve(body()));
10
+ }
11
+
12
+ function testPromise(slice, name, body) {
13
+ let location = Collector$ReventlessGwt.captureLocation(1);
14
+ Collector$ReventlessGwt.push(slice, location, undefined, name, body);
15
+ }
16
+
17
+ export {
18
+ describe,
19
+ test,
20
+ testPromise,
21
+ }
22
+ /* No side effect */