@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,115 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Nodepath from "node:path";
4
+ import Picocolors from "picocolors";
5
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
6
+ import * as Hint$ReventlessGwt from "./Hint.res.mjs";
7
+ import * as MismatchRender$ReventlessGwt from "./MismatchRender.res.mjs";
8
+
9
+ function write(s) {
10
+ process.stdout.write(s);
11
+ }
12
+
13
+ function writeLine(s) {
14
+ process.stdout.write(s + "\n");
15
+ }
16
+
17
+ function formatFilePath(abs) {
18
+ let base = Nodepath.basename(abs);
19
+ let name = base.endsWith(".res.mjs") ? base.slice(0, base.length - 8 | 0) : base;
20
+ let rel = Nodepath.relative(process.cwd(), abs);
21
+ return name + ` - ` + rel;
22
+ }
23
+
24
+ function formatLocation(loc) {
25
+ if (loc !== undefined) {
26
+ return loc.file + `:` + loc.line.toString();
27
+ } else {
28
+ return "";
29
+ }
30
+ }
31
+
32
+ function renderField(f) {
33
+ if (typeof f !== "object") {
34
+ return " expected no events";
35
+ }
36
+ switch (f.TAG) {
37
+ case "Expected" :
38
+ return ` expected: ` + f._0;
39
+ case "Actual" :
40
+ return ` actual: ` + f._0;
41
+ case "Key" :
42
+ return ` key: "` + f._0 + `"`;
43
+ case "Error" :
44
+ return ` error: ` + f._0;
45
+ case "Stack" :
46
+ return f._0;
47
+ }
48
+ }
49
+
50
+ function renderMismatch(m) {
51
+ return MismatchRender$ReventlessGwt.normalize(m).fields.map(renderField).join("\n");
52
+ }
53
+
54
+ function emitTest(t) {
55
+ let path = t.describePath.join(" > ");
56
+ let full = path === "" ? t.name : path + ` > ` + t.name;
57
+ let loc = formatLocation(t.location);
58
+ let locStr = loc === "" ? "" : ` ` + Picocolors.dim(loc);
59
+ let match = t.status;
60
+ switch (match) {
61
+ case "Pass" :
62
+ let s = ` ` + Picocolors.green("✓") + ` ` + full + locStr;
63
+ return process.stdout.write(s + "\n");
64
+ case "Fail" :
65
+ let s$1 = ` ` + Picocolors.red("✗") + ` ` + Picocolors.bold(full) + locStr;
66
+ process.stdout.write(s$1 + "\n");
67
+ let m = t.mismatch;
68
+ if (m === undefined) {
69
+ return;
70
+ }
71
+ process.stdout.write("\n");
72
+ let s$2 = renderMismatch(m);
73
+ process.stdout.write(s$2 + "\n");
74
+ let hint = Hint$ReventlessGwt.forMismatch(t.slice, m);
75
+ process.stdout.write("\n");
76
+ let s$3 = ` ` + Picocolors.cyan(Hint$ReventlessGwt.format(hint));
77
+ process.stdout.write(s$3 + "\n");
78
+ return process.stdout.write("\n");
79
+ case "Skip" :
80
+ let s$4 = ` ` + Picocolors.yellow("○") + ` ` + full + locStr + ` ` + Picocolors.dim(Stdlib_Option.getOr(t.skipReason, "skipped"));
81
+ return process.stdout.write(s$4 + "\n");
82
+ }
83
+ }
84
+
85
+ function emitFile(f) {
86
+ process.stdout.write("\n");
87
+ let s = Picocolors.bold(formatFilePath(f.path));
88
+ process.stdout.write(s + "\n");
89
+ f.tests.forEach(emitTest);
90
+ }
91
+
92
+ function emitSummary(s) {
93
+ process.stdout.write("\n");
94
+ let s$1 = `Tests: ` + s.total.toString() + ` ` + Picocolors.green(s.passed.toString() + " passed") + ` ` + Picocolors.red(s.failed.toString() + " failed") + ` ` + Picocolors.yellow(s.skipped.toString() + " skipped") + ` (` + s.durationMs.toString() + ` ms)`;
95
+ process.stdout.write(s$1 + "\n");
96
+ }
97
+
98
+ function emit(r) {
99
+ r.files.forEach(emitFile);
100
+ emitSummary(r.summary);
101
+ }
102
+
103
+ export {
104
+ write,
105
+ writeLine,
106
+ formatFilePath,
107
+ formatLocation,
108
+ renderField,
109
+ renderMismatch,
110
+ emitTest,
111
+ emitFile,
112
+ emitSummary,
113
+ emit,
114
+ }
115
+ /* node:path Not a pure module */
@@ -0,0 +1,264 @@
1
+ // Structured JSON formatter — the AI loop's primary input and the substrate
2
+ // for any programmatic consumer. Ships both a single-envelope mode and an
3
+ // NDJSON streaming mode (`--stream`). Shape matches §3.3 of
4
+ // `docs/analysis/given-when-then-specifications.md`.
5
+
6
+ // 1.1.0 — additive: `PublishedActionsMismatch` mismatch kind for the
7
+ // Delegate_GWT / cross-plugin Flow_GWT boundary steps.
8
+ // The default the emitted envelope carries; the `--schema-version` CLI flag
9
+ // overrides it (threaded through `emit` / `streamRunStart`) so a consumer can
10
+ // pin the schema version its AI prompt was built against.
11
+ let defaultSchemaVersion = "1.1.0"
12
+
13
+ @val external processStdout: {"write": string => unit} = "process.stdout"
14
+ let write = (s: string) => processStdout["write"](s)
15
+ let writeLine = (s: string) => write(s ++ "\n")
16
+
17
+ // Re-render a JSON value as a dual-rendered `{type, payload, rendered}` entry.
18
+ let renderValue = (j: JSON.t): JSON.t => {
19
+ let obj = Dict.make()
20
+ switch j {
21
+ | Object(dict) =>
22
+ switch dict->Dict.get("TAG") {
23
+ | Some(String(tag)) => {
24
+ obj->Dict.set("type", JSON.Encode.string(tag))
25
+ let payloadKeys =
26
+ dict
27
+ ->Dict.keysToArray
28
+ ->Array.filter(k => k != "TAG" && String.startsWith(k, "_"))
29
+ let payload = switch payloadKeys {
30
+ | [] => JSON.Encode.null
31
+ | ["_0"] =>
32
+ dict->Dict.get("_0")->Option.getOr(JSON.Encode.null)
33
+ | _ => {
34
+ let payloadDict = Dict.make()
35
+ payloadKeys->Array.forEach(k =>
36
+ payloadDict->Dict.set(
37
+ k,
38
+ dict->Dict.get(k)->Option.getOr(JSON.Encode.null),
39
+ )
40
+ )
41
+ JSON.Encode.object(payloadDict)
42
+ }
43
+ }
44
+ obj->Dict.set("payload", payload)
45
+ }
46
+ | _ => {
47
+ obj->Dict.set("type", JSON.Encode.null)
48
+ obj->Dict.set("payload", j)
49
+ }
50
+ }
51
+ | String(s) => {
52
+ obj->Dict.set("type", JSON.Encode.string(s))
53
+ obj->Dict.set("payload", JSON.Encode.null)
54
+ }
55
+ | _ => {
56
+ obj->Dict.set("type", JSON.Encode.null)
57
+ obj->Dict.set("payload", j)
58
+ }
59
+ }
60
+ obj->Dict.set("rendered", JSON.Encode.string(RenderRescript.render(j)))
61
+ JSON.Encode.object(obj)
62
+ }
63
+
64
+ let renderValues = (arr: array<JSON.t>): JSON.t =>
65
+ arr->Array.map(renderValue)->JSON.Encode.array
66
+
67
+ let mismatchJson = (m: Outcome.mismatch, slice: option<string>): JSON.t => {
68
+ let obj = Dict.make()
69
+ obj->Dict.set("kind", JSON.Encode.string(Outcome.kindName(m)))
70
+ let optVal = o =>
71
+ switch o {
72
+ | Some(v) => renderValue(v)
73
+ | None => JSON.Encode.null
74
+ }
75
+ switch m {
76
+ | EventsMismatch({expected, actual}) => {
77
+ obj->Dict.set("expected", renderValues(expected))
78
+ obj->Dict.set("actual", renderValues(actual))
79
+ obj->Dict.set("fieldDiff", Diff.toJsonArray(Diff.diffArrays(expected, actual)))
80
+ }
81
+ | ErrorMismatch({expected, actual, actualEvents}) => {
82
+ obj->Dict.set("expected", renderValue(expected))
83
+ obj->Dict.set("actual", optVal(actual))
84
+ obj->Dict.set("actualEvents", renderValues(actualEvents))
85
+ }
86
+ | StateMismatch({key, expected, actual}) => {
87
+ obj->Dict.set("key", JSON.Encode.string(key))
88
+ obj->Dict.set("expected", optVal(expected))
89
+ obj->Dict.set("actual", optVal(actual))
90
+ let eJson = expected->Option.getOr(JSON.Encode.null)
91
+ let aJson = actual->Option.getOr(JSON.Encode.null)
92
+ obj->Dict.set("fieldDiff", Diff.toJsonArray(Diff.diff(eJson, aJson)))
93
+ }
94
+ | NoEventExpected({actual}) => obj->Dict.set("actual", renderValues(actual))
95
+ | TodoMismatch({expected, actual}) => {
96
+ let pairArr = pairs =>
97
+ pairs
98
+ ->Array.map(((id, v)) => {
99
+ let d = Dict.make()
100
+ d->Dict.set("id", JSON.Encode.string(id))
101
+ d->Dict.set("value", renderValue(v))
102
+ JSON.Encode.object(d)
103
+ })
104
+ ->JSON.Encode.array
105
+ obj->Dict.set("expected", pairArr(expected))
106
+ obj->Dict.set("actual", pairArr(actual))
107
+ }
108
+ | AppendConditionMismatch({expected, actual}) => {
109
+ obj->Dict.set("expected", expected)
110
+ obj->Dict.set("actual", actual)
111
+ }
112
+ | TranslateError({expected, actual}) => {
113
+ obj->Dict.set("expected", JSON.Encode.string(expected))
114
+ obj->Dict.set(
115
+ "actual",
116
+ actual->Option.mapOr(JSON.Encode.null, JSON.Encode.string),
117
+ )
118
+ }
119
+ | QueryRowsMismatch({expected, actual}) => {
120
+ obj->Dict.set("expected", renderValues(expected))
121
+ obj->Dict.set("actual", renderValues(actual))
122
+ obj->Dict.set("fieldDiff", Diff.toJsonArray(Diff.diffArrays(expected, actual)))
123
+ }
124
+ | PublishedActionsMismatch({expected, actual}) => {
125
+ obj->Dict.set("expected", renderValues(expected))
126
+ obj->Dict.set("actual", renderValues(actual))
127
+ obj->Dict.set("fieldDiff", Diff.toJsonArray(Diff.diffArrays(expected, actual)))
128
+ }
129
+ | Throw({error, stack}) => {
130
+ obj->Dict.set("error", JSON.Encode.string(error))
131
+ obj->Dict.set("stack", JSON.Encode.string(stack))
132
+ }
133
+ }
134
+ let hint = Hint.forMismatch(~slice?, m)
135
+ obj->Dict.set("hint", Hint.toJson(hint))
136
+ JSON.Encode.object(obj)
137
+ }
138
+
139
+ let locationJson = (loc: option<Collector.location>): JSON.t =>
140
+ switch loc {
141
+ | None => JSON.Encode.null
142
+ | Some(l) => {
143
+ let d = Dict.make()
144
+ d->Dict.set("file", JSON.Encode.string(l.file))
145
+ d->Dict.set("line", JSON.Encode.int(l.line))
146
+ d->Dict.set("column", JSON.Encode.int(l.column))
147
+ JSON.Encode.object(d)
148
+ }
149
+ }
150
+
151
+ let testJson = (t: RunnerTypes.testResult): JSON.t => {
152
+ let d = Dict.make()
153
+ d->Dict.set("id", JSON.Encode.string(t.id))
154
+ d->Dict.set("name", JSON.Encode.string(t.name))
155
+ d->Dict.set(
156
+ "describePath",
157
+ t.describePath->Array.map(JSON.Encode.string)->JSON.Encode.array,
158
+ )
159
+ d->Dict.set("status", JSON.Encode.string(RunnerTypes.statusString(t.status)))
160
+ d->Dict.set("durationMs", JSON.Encode.float(t.durationMs))
161
+ d->Dict.set("location", locationJson(t.location))
162
+ switch t.mismatch {
163
+ | Some(m) => d->Dict.set("mismatch", mismatchJson(m, t.slice))
164
+ | None => ()
165
+ }
166
+ switch t.skipReason {
167
+ | Some(r) => d->Dict.set("skipReason", JSON.Encode.string(r))
168
+ | None => ()
169
+ }
170
+ JSON.Encode.object(d)
171
+ }
172
+
173
+ let fileJson = (f: RunnerTypes.fileResult): JSON.t => {
174
+ let d = Dict.make()
175
+ d->Dict.set("path", JSON.Encode.string(f.path))
176
+ d->Dict.set("tests", f.tests->Array.map(testJson)->JSON.Encode.array)
177
+ JSON.Encode.object(d)
178
+ }
179
+
180
+ let summaryJson = (s: RunnerTypes.summary): JSON.t => {
181
+ let d = Dict.make()
182
+ d->Dict.set("total", JSON.Encode.int(s.total))
183
+ d->Dict.set("passed", JSON.Encode.int(s.passed))
184
+ d->Dict.set("failed", JSON.Encode.int(s.failed))
185
+ d->Dict.set("skipped", JSON.Encode.int(s.skipped))
186
+ d->Dict.set("files", JSON.Encode.int(s.files))
187
+ JSON.Encode.object(d)
188
+ }
189
+
190
+ let envelope = (
191
+ r: RunnerTypes.runResult,
192
+ ~toolVersion: string,
193
+ ~schemaVersion: string,
194
+ ): JSON.t => {
195
+ let d = Dict.make()
196
+ d->Dict.set("schemaVersion", JSON.Encode.string(schemaVersion))
197
+ d->Dict.set("tool", JSON.Encode.string("reventless-gwt"))
198
+ d->Dict.set("toolVersion", JSON.Encode.string(toolVersion))
199
+ d->Dict.set("startedAt", JSON.Encode.string(r.summary.startedAt))
200
+ d->Dict.set("durationMs", JSON.Encode.float(r.summary.durationMs))
201
+ d->Dict.set("summary", summaryJson(r.summary))
202
+ d->Dict.set("files", r.files->Array.map(fileJson)->JSON.Encode.array)
203
+ JSON.Encode.object(d)
204
+ }
205
+
206
+ let emit = (r: RunnerTypes.runResult, ~toolVersion: string, ~schemaVersion=defaultSchemaVersion) =>
207
+ write(JSON.stringify(envelope(r, ~toolVersion, ~schemaVersion), ~space=2) ++ "\n")
208
+
209
+ // Streaming variant — NDJSON events.
210
+ let streamRunStart = (~toolVersion: string, ~startedAt: string, ~schemaVersion=defaultSchemaVersion) => {
211
+ let d = Dict.make()
212
+ d->Dict.set("type", JSON.Encode.string("runStarted"))
213
+ d->Dict.set("schemaVersion", JSON.Encode.string(schemaVersion))
214
+ d->Dict.set("toolVersion", JSON.Encode.string(toolVersion))
215
+ d->Dict.set("at", JSON.Encode.string(startedAt))
216
+ writeLine(JSON.stringify(JSON.Encode.object(d)))
217
+ }
218
+
219
+ let streamFileStart = (path: string) => {
220
+ let d = Dict.make()
221
+ d->Dict.set("type", JSON.Encode.string("fileStarted"))
222
+ d->Dict.set("path", JSON.Encode.string(path))
223
+ writeLine(JSON.stringify(JSON.Encode.object(d)))
224
+ }
225
+
226
+ let streamTest = (t: RunnerTypes.testResult) => {
227
+ let d = Dict.make()
228
+ d->Dict.set("type", JSON.Encode.string("testResult"))
229
+ let tj = testJson(t)
230
+ // Fold testJson's object keys into the envelope.
231
+ switch tj {
232
+ | Object(inner) =>
233
+ inner->Dict.keysToArray->Array.forEach(k =>
234
+ d->Dict.set(k, inner->Dict.getUnsafe(k))
235
+ )
236
+ | _ => ()
237
+ }
238
+ writeLine(JSON.stringify(JSON.Encode.object(d)))
239
+ }
240
+
241
+ let streamFileFinished = (f: RunnerTypes.fileResult) => {
242
+ let passed = ref(0)
243
+ let failed = ref(0)
244
+ f.tests->Array.forEach(t =>
245
+ switch t.status {
246
+ | Pass => passed := passed.contents + 1
247
+ | Fail => failed := failed.contents + 1
248
+ | Skip => ()
249
+ }
250
+ )
251
+ let d = Dict.make()
252
+ d->Dict.set("type", JSON.Encode.string("fileFinished"))
253
+ d->Dict.set("path", JSON.Encode.string(f.path))
254
+ d->Dict.set("passed", JSON.Encode.int(passed.contents))
255
+ d->Dict.set("failed", JSON.Encode.int(failed.contents))
256
+ writeLine(JSON.stringify(JSON.Encode.object(d)))
257
+ }
258
+
259
+ let streamRunEnd = (r: RunnerTypes.runResult) => {
260
+ let d = Dict.make()
261
+ d->Dict.set("type", JSON.Encode.string("runFinished"))
262
+ d->Dict.set("summary", summaryJson(r.summary))
263
+ writeLine(JSON.stringify(JSON.Encode.object(d)))
264
+ }
@@ -0,0 +1,322 @@
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 Diff$ReventlessGwt from "./Diff.res.mjs";
5
+ import * as Hint$ReventlessGwt from "./Hint.res.mjs";
6
+ import * as Outcome$ReventlessGwt from "./Outcome.res.mjs";
7
+ import * as RunnerTypes$ReventlessGwt from "./RunnerTypes.res.mjs";
8
+ import * as RenderRescript$ReventlessGwt from "./RenderRescript.res.mjs";
9
+
10
+ let defaultSchemaVersion = "1.1.0";
11
+
12
+ function write(s) {
13
+ process.stdout.write(s);
14
+ }
15
+
16
+ function writeLine(s) {
17
+ process.stdout.write(s + "\n");
18
+ }
19
+
20
+ function renderValue(j) {
21
+ let obj = {};
22
+ let exit = 0;
23
+ if (j === null || Array.isArray(j)) {
24
+ exit = 1;
25
+ } else {
26
+ switch (typeof j) {
27
+ case "string" :
28
+ obj["type"] = j;
29
+ obj["payload"] = null;
30
+ break;
31
+ case "object" :
32
+ let match = j["TAG"];
33
+ let exit$1 = 0;
34
+ if (typeof match === "string") {
35
+ obj["type"] = match;
36
+ let payloadKeys = Object.keys(j).filter(k => {
37
+ if (k !== "TAG") {
38
+ return k.startsWith("_");
39
+ } else {
40
+ return false;
41
+ }
42
+ });
43
+ let payload;
44
+ let exit$2 = 0;
45
+ let len = payloadKeys.length;
46
+ if (len !== 1) {
47
+ if (len !== 0) {
48
+ exit$2 = 3;
49
+ } else {
50
+ payload = null;
51
+ }
52
+ } else {
53
+ let match$1 = payloadKeys[0];
54
+ if (match$1 === "_0") {
55
+ payload = Stdlib_Option.getOr(j["_0"], null);
56
+ } else {
57
+ exit$2 = 3;
58
+ }
59
+ }
60
+ if (exit$2 === 3) {
61
+ let payloadDict = {};
62
+ payloadKeys.forEach(k => {
63
+ payloadDict[k] = Stdlib_Option.getOr(j[k], null);
64
+ });
65
+ payload = payloadDict;
66
+ }
67
+ obj["payload"] = payload;
68
+ } else {
69
+ exit$1 = 2;
70
+ }
71
+ if (exit$1 === 2) {
72
+ obj["type"] = null;
73
+ obj["payload"] = j;
74
+ }
75
+ break;
76
+ default:
77
+ exit = 1;
78
+ }
79
+ }
80
+ if (exit === 1) {
81
+ obj["type"] = null;
82
+ obj["payload"] = j;
83
+ }
84
+ obj["rendered"] = RenderRescript$ReventlessGwt.render(undefined, j);
85
+ return obj;
86
+ }
87
+
88
+ function renderValues(arr) {
89
+ return arr.map(renderValue);
90
+ }
91
+
92
+ function mismatchJson(m, slice) {
93
+ let obj = {};
94
+ obj["kind"] = Outcome$ReventlessGwt.kindName(m);
95
+ let optVal = o => {
96
+ if (o !== undefined) {
97
+ return renderValue(o);
98
+ } else {
99
+ return null;
100
+ }
101
+ };
102
+ switch (m.TAG) {
103
+ case "EventsMismatch" :
104
+ let actual = m.actual;
105
+ let expected = m.expected;
106
+ obj["expected"] = expected.map(renderValue);
107
+ obj["actual"] = actual.map(renderValue);
108
+ obj["fieldDiff"] = Diff$ReventlessGwt.toJsonArray(Diff$ReventlessGwt.diffArrays(expected, actual));
109
+ break;
110
+ case "ErrorMismatch" :
111
+ obj["expected"] = renderValue(m.expected);
112
+ obj["actual"] = optVal(m.actual);
113
+ obj["actualEvents"] = m.actualEvents.map(renderValue);
114
+ break;
115
+ case "StateMismatch" :
116
+ let actual$1 = m.actual;
117
+ let expected$1 = m.expected;
118
+ obj["key"] = m.key;
119
+ obj["expected"] = optVal(expected$1);
120
+ obj["actual"] = optVal(actual$1);
121
+ let eJson = Stdlib_Option.getOr(expected$1, null);
122
+ let aJson = Stdlib_Option.getOr(actual$1, null);
123
+ obj["fieldDiff"] = Diff$ReventlessGwt.toJsonArray(Diff$ReventlessGwt.diff(eJson, aJson));
124
+ break;
125
+ case "NoEventExpected" :
126
+ obj["actual"] = m.actual.map(renderValue);
127
+ break;
128
+ case "TodoMismatch" :
129
+ let pairArr = pairs => pairs.map(param => {
130
+ let d = {};
131
+ d["id"] = param[0];
132
+ d["value"] = renderValue(param[1]);
133
+ return d;
134
+ });
135
+ obj["expected"] = pairArr(m.expected);
136
+ obj["actual"] = pairArr(m.actual);
137
+ break;
138
+ case "AppendConditionMismatch" :
139
+ obj["expected"] = m.expected;
140
+ obj["actual"] = m.actual;
141
+ break;
142
+ case "TranslateError" :
143
+ obj["expected"] = m.expected;
144
+ obj["actual"] = Stdlib_Option.mapOr(m.actual, null, prim => prim);
145
+ break;
146
+ case "QueryRowsMismatch" :
147
+ let actual$2 = m.actual;
148
+ let expected$2 = m.expected;
149
+ obj["expected"] = expected$2.map(renderValue);
150
+ obj["actual"] = actual$2.map(renderValue);
151
+ obj["fieldDiff"] = Diff$ReventlessGwt.toJsonArray(Diff$ReventlessGwt.diffArrays(expected$2, actual$2));
152
+ break;
153
+ case "PublishedActionsMismatch" :
154
+ let actual$3 = m.actual;
155
+ let expected$3 = m.expected;
156
+ obj["expected"] = expected$3.map(renderValue);
157
+ obj["actual"] = actual$3.map(renderValue);
158
+ obj["fieldDiff"] = Diff$ReventlessGwt.toJsonArray(Diff$ReventlessGwt.diffArrays(expected$3, actual$3));
159
+ break;
160
+ case "Throw" :
161
+ obj["error"] = m.error;
162
+ obj["stack"] = m.stack;
163
+ break;
164
+ }
165
+ let hint = Hint$ReventlessGwt.forMismatch(slice, m);
166
+ obj["hint"] = Hint$ReventlessGwt.toJson(hint);
167
+ return obj;
168
+ }
169
+
170
+ function locationJson(loc) {
171
+ if (loc === undefined) {
172
+ return null;
173
+ }
174
+ let d = {};
175
+ d["file"] = loc.file;
176
+ d["line"] = loc.line;
177
+ d["column"] = loc.column;
178
+ return d;
179
+ }
180
+
181
+ function testJson(t) {
182
+ let d = {};
183
+ d["id"] = t.id;
184
+ d["name"] = t.name;
185
+ d["describePath"] = t.describePath.map(prim => prim);
186
+ d["status"] = RunnerTypes$ReventlessGwt.statusString(t.status);
187
+ d["durationMs"] = t.durationMs;
188
+ d["location"] = locationJson(t.location);
189
+ let m = t.mismatch;
190
+ if (m !== undefined) {
191
+ d["mismatch"] = mismatchJson(m, t.slice);
192
+ }
193
+ let r = t.skipReason;
194
+ if (r !== undefined) {
195
+ d["skipReason"] = r;
196
+ }
197
+ return d;
198
+ }
199
+
200
+ function fileJson(f) {
201
+ let d = {};
202
+ d["path"] = f.path;
203
+ d["tests"] = f.tests.map(testJson);
204
+ return d;
205
+ }
206
+
207
+ function summaryJson(s) {
208
+ let d = {};
209
+ d["total"] = s.total;
210
+ d["passed"] = s.passed;
211
+ d["failed"] = s.failed;
212
+ d["skipped"] = s.skipped;
213
+ d["files"] = s.files;
214
+ return d;
215
+ }
216
+
217
+ function envelope(r, toolVersion, schemaVersion) {
218
+ let d = {};
219
+ d["schemaVersion"] = schemaVersion;
220
+ d["tool"] = "reventless-gwt";
221
+ d["toolVersion"] = toolVersion;
222
+ d["startedAt"] = r.summary.startedAt;
223
+ d["durationMs"] = r.summary.durationMs;
224
+ d["summary"] = summaryJson(r.summary);
225
+ d["files"] = r.files.map(fileJson);
226
+ return d;
227
+ }
228
+
229
+ function emit(r, toolVersion, schemaVersionOpt) {
230
+ let schemaVersion = schemaVersionOpt !== undefined ? schemaVersionOpt : defaultSchemaVersion;
231
+ process.stdout.write(JSON.stringify(envelope(r, toolVersion, schemaVersion), undefined, 2) + "\n");
232
+ }
233
+
234
+ function streamRunStart(toolVersion, startedAt, schemaVersionOpt) {
235
+ let schemaVersion = schemaVersionOpt !== undefined ? schemaVersionOpt : defaultSchemaVersion;
236
+ let d = {};
237
+ d["type"] = "runStarted";
238
+ d["schemaVersion"] = schemaVersion;
239
+ d["toolVersion"] = toolVersion;
240
+ d["at"] = startedAt;
241
+ let s = JSON.stringify(d);
242
+ process.stdout.write(s + "\n");
243
+ }
244
+
245
+ function streamFileStart(path) {
246
+ let d = {};
247
+ d["type"] = "fileStarted";
248
+ d["path"] = path;
249
+ let s = JSON.stringify(d);
250
+ process.stdout.write(s + "\n");
251
+ }
252
+
253
+ function streamTest(t) {
254
+ let d = {};
255
+ d["type"] = "testResult";
256
+ let tj = testJson(t);
257
+ if (typeof tj === "object" && tj !== null && !Array.isArray(tj)) {
258
+ Object.keys(tj).forEach(k => {
259
+ d[k] = tj[k];
260
+ });
261
+ }
262
+ let s = JSON.stringify(d);
263
+ process.stdout.write(s + "\n");
264
+ }
265
+
266
+ function streamFileFinished(f) {
267
+ let passed = {
268
+ contents: 0
269
+ };
270
+ let failed = {
271
+ contents: 0
272
+ };
273
+ f.tests.forEach(t => {
274
+ let match = t.status;
275
+ switch (match) {
276
+ case "Pass" :
277
+ passed.contents = passed.contents + 1 | 0;
278
+ return;
279
+ case "Fail" :
280
+ failed.contents = failed.contents + 1 | 0;
281
+ return;
282
+ case "Skip" :
283
+ return;
284
+ }
285
+ });
286
+ let d = {};
287
+ d["type"] = "fileFinished";
288
+ d["path"] = f.path;
289
+ d["passed"] = passed.contents;
290
+ d["failed"] = failed.contents;
291
+ let s = JSON.stringify(d);
292
+ process.stdout.write(s + "\n");
293
+ }
294
+
295
+ function streamRunEnd(r) {
296
+ let d = {};
297
+ d["type"] = "runFinished";
298
+ d["summary"] = summaryJson(r.summary);
299
+ let s = JSON.stringify(d);
300
+ process.stdout.write(s + "\n");
301
+ }
302
+
303
+ export {
304
+ defaultSchemaVersion,
305
+ write,
306
+ writeLine,
307
+ renderValue,
308
+ renderValues,
309
+ mismatchJson,
310
+ locationJson,
311
+ testJson,
312
+ fileJson,
313
+ summaryJson,
314
+ envelope,
315
+ emit,
316
+ streamRunStart,
317
+ streamFileStart,
318
+ streamTest,
319
+ streamFileFinished,
320
+ streamRunEnd,
321
+ }
322
+ /* No side effect */