@reventlessdev/reventless-gwt 1.0.0-alpha.115 → 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.
Files changed (91) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/package.json +5 -12
  3. package/rescript.json +0 -1
  4. package/bin/reventless-dev.mjs +0 -21
  5. package/src/Bind.res +0 -29
  6. package/src/Bind.res.mjs +0 -22
  7. package/src/BuildClassifier.res +0 -147
  8. package/src/BuildClassifier.res.mjs +0 -136
  9. package/src/Cancellation.res +0 -37
  10. package/src/Cancellation.res.mjs +0 -46
  11. package/src/ChildProcess.res +0 -102
  12. package/src/ChildProcess.res.mjs +0 -107
  13. package/src/Cli.res +0 -889
  14. package/src/Cli.res.mjs +0 -944
  15. package/src/Collector.res +0 -222
  16. package/src/Collector.res.mjs +0 -228
  17. package/src/ComponentMeta.res +0 -77
  18. package/src/ComponentMeta.res.mjs +0 -91
  19. package/src/ComponentScan.res +0 -101
  20. package/src/ComponentScan.res.mjs +0 -92
  21. package/src/Discovery.res +0 -102
  22. package/src/Discovery.res.mjs +0 -86
  23. package/src/DomainDeadCode.res +0 -98
  24. package/src/DomainDeadCode.res.mjs +0 -72
  25. package/src/DomainGraph.res +0 -0
  26. package/src/DomainGraph.res.mjs +0 -0
  27. package/src/ExnMessage.res +0 -14
  28. package/src/ExnMessage.res.mjs +0 -17
  29. package/src/ExnReflect.mjs +0 -24
  30. package/src/Filter.res +0 -45
  31. package/src/Filter.res.mjs +0 -47
  32. package/src/FormatterHuman.res +0 -109
  33. package/src/FormatterHuman.res.mjs +0 -115
  34. package/src/FormatterJson.res +0 -264
  35. package/src/FormatterJson.res.mjs +0 -322
  36. package/src/FormatterJunit.res +0 -93
  37. package/src/FormatterJunit.res.mjs +0 -90
  38. package/src/FormatterTap.res +0 -100
  39. package/src/FormatterTap.res.mjs +0 -131
  40. package/src/FormatterVsCode.res +0 -352
  41. package/src/FormatterVsCode.res.mjs +0 -546
  42. package/src/Loader.res +0 -24
  43. package/src/Loader.res.mjs +0 -23
  44. package/src/PackageScan.res +0 -80
  45. package/src/PackageScan.res.mjs +0 -81
  46. package/src/PlatformRunner.res +0 -191
  47. package/src/PlatformRunner.res.mjs +0 -178
  48. package/src/PlatformScan.res +0 -141
  49. package/src/PlatformScan.res.mjs +0 -124
  50. package/src/ProcessManager.res +0 -135
  51. package/src/ProcessManager.res.mjs +0 -119
  52. package/src/RunWorker.res +0 -24
  53. package/src/RunWorker.res.mjs +0 -16
  54. package/src/RunnerTypes.res +0 -68
  55. package/src/RunnerTypes.res.mjs +0 -60
  56. package/src/ScanIgnore.res +0 -11
  57. package/src/ScanIgnore.res.mjs +0 -23
  58. package/src/Watch.res +0 -102
  59. package/src/Watch.res.mjs +0 -80
  60. package/src/WatcherProbe.res +0 -56
  61. package/src/WatcherProbe.res.mjs +0 -59
  62. package/src/Worker.res +0 -24
  63. package/src/Worker.res.mjs +0 -9
  64. package/tests/BuildClassifierTest.res +0 -133
  65. package/tests/BuildClassifierTest.res.mjs +0 -176
  66. package/tests/CliRunEntryTest.res +0 -57
  67. package/tests/CliRunEntryTest.res.mjs +0 -65
  68. package/tests/CliWatchScopeTest.res +0 -62
  69. package/tests/CliWatchScopeTest.res.mjs +0 -95
  70. package/tests/ComponentMetaTest.res +0 -67
  71. package/tests/ComponentMetaTest.res.mjs +0 -71
  72. package/tests/DiscoveryTest.res +0 -42
  73. package/tests/DiscoveryTest.res.mjs +0 -43
  74. package/tests/DomainDeadCodeTest.res +0 -119
  75. package/tests/DomainDeadCodeTest.res.mjs +0 -158
  76. package/tests/DomainGraphTest.res +0 -448
  77. package/tests/DomainGraphTest.res.mjs +0 -505
  78. package/tests/ExnMessageTest.res +0 -42
  79. package/tests/ExnMessageTest.res.mjs +0 -64
  80. package/tests/FormatterGoldenTest.res +0 -125
  81. package/tests/FormatterGoldenTest.res.mjs +0 -162
  82. package/tests/FormatterVsCodeMessageTest.res +0 -41
  83. package/tests/FormatterVsCodeMessageTest.res.mjs +0 -42
  84. package/tests/PlatformRunnerTest.res +0 -66
  85. package/tests/PlatformRunnerTest.res.mjs +0 -85
  86. package/tests/PlatformScanTest.res +0 -61
  87. package/tests/PlatformScanTest.res.mjs +0 -56
  88. package/tests/RunnerUnitTest.res +0 -219
  89. package/tests/RunnerUnitTest.res.mjs +0 -244
  90. package/tests/WatchDebounceTest.res +0 -106
  91. package/tests/WatchDebounceTest.res.mjs +0 -128
@@ -1,322 +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 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 */
@@ -1,93 +0,0 @@
1
- // JUnit XML emitter — one `<testsuite>` per file, one `<testcase>` per test.
2
- // Failures carry the human-readable mismatch + hint inside `<failure>` so
3
- // CI tools like Jenkins surface the ReScript-rendered expected/actual in
4
- // their test report UI.
5
-
6
- @val external processStdout: {"write": string => unit} = "process.stdout"
7
- let write = (s: string) => processStdout["write"](s)
8
- let writeLine = (s: string) => write(s ++ "\n")
9
-
10
- let escapeXml = (s: string) =>
11
- s
12
- ->String.replaceAll("&", "&amp;")
13
- ->String.replaceAll("<", "&lt;")
14
- ->String.replaceAll(">", "&gt;")
15
- ->String.replaceAll("\"", "&quot;")
16
- ->String.replaceAll("'", "&apos;")
17
-
18
- let emitFile = (f: RunnerTypes.fileResult) => {
19
- let tests = f.tests->Array.length
20
- let failures = ref(0)
21
- let skipped = ref(0)
22
- f.tests->Array.forEach(t =>
23
- switch t.status {
24
- | Fail => failures := failures.contents + 1
25
- | Skip => skipped := skipped.contents + 1
26
- | Pass => ()
27
- }
28
- )
29
- let totalTime = f.tests->Array.reduce(0.0, (a, t) => a +. t.durationMs) /. 1000.0
30
- writeLine(
31
- ` <testsuite name="${escapeXml(f.path)}" tests="${Int.toString(
32
- tests,
33
- )}" failures="${Int.toString(failures.contents)}" skipped="${Int.toString(
34
- skipped.contents,
35
- )}" time="${Float.toString(totalTime)}">`,
36
- )
37
- f.tests->Array.forEach(t => {
38
- let name = t.describePath->Array.join(" > ")
39
- let classname = name == "" ? f.path : name
40
- let time = t.durationMs /. 1000.0
41
- write(
42
- ` <testcase name="${escapeXml(t.name)}" classname="${escapeXml(
43
- classname,
44
- )}" time="${Float.toString(time)}"`,
45
- )
46
- switch t.status {
47
- | Pass => writeLine(" />")
48
- | Skip => {
49
- writeLine(">")
50
- writeLine(
51
- ` <skipped message="${escapeXml(t.skipReason->Option.getOr("skipped"))}" />`,
52
- )
53
- writeLine(` </testcase>`)
54
- }
55
- | Fail => {
56
- writeLine(">")
57
- switch t.mismatch {
58
- | Some(m) => {
59
- let hint = Hint.forMismatch(~slice=?t.slice, m)
60
- let msg =
61
- escapeXml(Outcome.kindName(m)) ++
62
- ": " ++
63
- escapeXml(Outcome.format(m)) ++
64
- "\n\n" ++
65
- escapeXml(Hint.format(hint))
66
- writeLine(
67
- ` <failure type="${escapeXml(Outcome.kindName(m))}" message="${escapeXml(
68
- Outcome.format(m),
69
- )}">${msg}</failure>`,
70
- )
71
- }
72
- | None =>
73
- writeLine(` <failure message="failed" type="unknown">failed</failure>`)
74
- }
75
- writeLine(` </testcase>`)
76
- }
77
- }
78
- })
79
- writeLine(` </testsuite>`)
80
- }
81
-
82
- let emit = (r: RunnerTypes.runResult) => {
83
- writeLine(`<?xml version="1.0" encoding="UTF-8"?>`)
84
- writeLine(
85
- `<testsuites name="reventless-gwt" tests="${Int.toString(
86
- r.summary.total,
87
- )}" failures="${Int.toString(r.summary.failed)}" skipped="${Int.toString(
88
- r.summary.skipped,
89
- )}" time="${Float.toString(r.summary.durationMs /. 1000.0)}">`,
90
- )
91
- r.files->Array.forEach(emitFile)
92
- writeLine(`</testsuites>`)
93
- }
@@ -1,90 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
4
- import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
5
- import * as Hint$ReventlessGwt from "./Hint.res.mjs";
6
- import * as Outcome$ReventlessGwt from "./Outcome.res.mjs";
7
-
8
- function write(s) {
9
- process.stdout.write(s);
10
- }
11
-
12
- function writeLine(s) {
13
- process.stdout.write(s + "\n");
14
- }
15
-
16
- function escapeXml(s) {
17
- return s.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&apos;");
18
- }
19
-
20
- function emitFile(f) {
21
- let tests = f.tests.length;
22
- let failures = {
23
- contents: 0
24
- };
25
- let skipped = {
26
- contents: 0
27
- };
28
- f.tests.forEach(t => {
29
- let match = t.status;
30
- switch (match) {
31
- case "Pass" :
32
- return;
33
- case "Fail" :
34
- failures.contents = failures.contents + 1 | 0;
35
- return;
36
- case "Skip" :
37
- skipped.contents = skipped.contents + 1 | 0;
38
- return;
39
- }
40
- });
41
- let totalTime = Stdlib_Array.reduce(f.tests, 0.0, (a, t) => a + t.durationMs) / 1000.0;
42
- let s = ` <testsuite name="` + escapeXml(f.path) + `" tests="` + tests.toString() + `" failures="` + failures.contents.toString() + `" skipped="` + skipped.contents.toString() + `" time="` + totalTime.toString() + `">`;
43
- process.stdout.write(s + "\n");
44
- f.tests.forEach(t => {
45
- let name = t.describePath.join(" > ");
46
- let classname = name === "" ? f.path : name;
47
- let time = t.durationMs / 1000.0;
48
- process.stdout.write(` <testcase name="` + escapeXml(t.name) + `" classname="` + escapeXml(classname) + `" time="` + time.toString() + `"`);
49
- let match = t.status;
50
- switch (match) {
51
- case "Pass" :
52
- return process.stdout.write(" />\n");
53
- case "Fail" :
54
- process.stdout.write(">\n");
55
- let m = t.mismatch;
56
- if (m !== undefined) {
57
- let hint = Hint$ReventlessGwt.forMismatch(t.slice, m);
58
- let msg = escapeXml(Outcome$ReventlessGwt.kindName(m)) + ": " + escapeXml(Outcome$ReventlessGwt.format(m)) + "\n\n" + escapeXml(Hint$ReventlessGwt.format(hint));
59
- let s = ` <failure type="` + escapeXml(Outcome$ReventlessGwt.kindName(m)) + `" message="` + escapeXml(Outcome$ReventlessGwt.format(m)) + `">` + msg + `</failure>`;
60
- process.stdout.write(s + "\n");
61
- } else {
62
- process.stdout.write(` <failure message="failed" type="unknown">failed</failure>` + "\n");
63
- }
64
- return process.stdout.write(` </testcase>` + "\n");
65
- case "Skip" :
66
- process.stdout.write(">\n");
67
- let s$1 = ` <skipped message="` + escapeXml(Stdlib_Option.getOr(t.skipReason, "skipped")) + `" />`;
68
- process.stdout.write(s$1 + "\n");
69
- return process.stdout.write(` </testcase>` + "\n");
70
- }
71
- });
72
- process.stdout.write(` </testsuite>` + "\n");
73
- }
74
-
75
- function emit(r) {
76
- process.stdout.write(`<?xml version="1.0" encoding="UTF-8"?>` + "\n");
77
- let s = `<testsuites name="reventless-gwt" tests="` + r.summary.total.toString() + `" failures="` + r.summary.failed.toString() + `" skipped="` + r.summary.skipped.toString() + `" time="` + (r.summary.durationMs / 1000.0).toString() + `">`;
78
- process.stdout.write(s + "\n");
79
- r.files.forEach(emitFile);
80
- process.stdout.write(`</testsuites>` + "\n");
81
- }
82
-
83
- export {
84
- write,
85
- writeLine,
86
- escapeXml,
87
- emitFile,
88
- emit,
89
- }
90
- /* No side effect */
@@ -1,100 +0,0 @@
1
- // TAP 14 emitter with YAML diagnostic blocks on failure. Streamed line-by-line
2
- // so `tap-spec` and GitHub Actions' `actions/test-reporter` can consume the
3
- // output live.
4
-
5
- @val external processStdout: {"write": string => unit} = "process.stdout"
6
- let write = (s: string) => processStdout["write"](s)
7
- let writeLine = (s: string) => write(s ++ "\n")
8
-
9
- let escapeYamlString = (s: string) =>
10
- s
11
- ->String.replaceAll("\\", "\\\\")
12
- ->String.replaceAll("\"", "\\\"")
13
- ->String.replaceAll("\n", "\\n")
14
-
15
- let yamlString = (s: string) => "\"" ++ escapeYamlString(s) ++ "\""
16
-
17
- let yamlLine = (~indent=2, key: string, value: string) =>
18
- String.repeat(" ", indent) ++ key ++ ": " ++ value
19
-
20
- let renderMismatchYaml = (m: Outcome.mismatch) => {
21
- let n = MismatchRender.normalize(m)
22
- let lines = [yamlLine("kind", yamlString(n.kind))]
23
- // `ExpectedNoEvents` is a Human-only literal (TAP simply omits `expected`);
24
- // every other field maps to one yaml `key: "escaped-value"` line.
25
- n.fields->Array.forEach(f =>
26
- switch f {
27
- | Expected(v) => lines->Array.push(yamlLine("expected", yamlString(v)))
28
- | Actual(v) => lines->Array.push(yamlLine("actual", yamlString(v)))
29
- | Key(k) => lines->Array.push(yamlLine("key", yamlString(k)))
30
- | Error(e) => lines->Array.push(yamlLine("error", yamlString(e)))
31
- | Stack(s) => lines->Array.push(yamlLine("stack", yamlString(s)))
32
- | ExpectedNoEvents => ()
33
- }
34
- )
35
- lines->Array.join("\n")
36
- }
37
-
38
- let emit = (r: RunnerTypes.runResult) => {
39
- writeLine("TAP version 14")
40
- writeLine(`1..${Int.toString(r.summary.total)}`)
41
- let index = ref(0)
42
- r.files->Array.forEach(f => {
43
- writeLine("")
44
- writeLine(`# ${f.path}`)
45
- f.tests->Array.forEach(t => {
46
- index := index.contents + 1
47
- let n = index.contents
48
- let path = t.describePath->Array.join(" > ")
49
- let title = path == "" ? t.name : `${path} > ${t.name}`
50
- let ms = ` # time=${Float.toString(t.durationMs)}ms`
51
- switch t.status {
52
- | Pass => writeLine(`ok ${Int.toString(n)} - ${title}${ms}`)
53
- | Skip => {
54
- let reason = t.skipReason->Option.getOr("skipped")
55
- writeLine(`ok ${Int.toString(n)} - ${title} # SKIP ${reason}`)
56
- }
57
- | Fail => {
58
- writeLine(`not ok ${Int.toString(n)} - ${title}${ms}`)
59
- writeLine(" ---")
60
- switch t.location {
61
- | Some(loc) =>
62
- writeLine(
63
- yamlLine(
64
- "location",
65
- `{ file: "${loc.file}", line: ${Int.toString(loc.line)} }`,
66
- ),
67
- )
68
- | None => ()
69
- }
70
- switch t.mismatch {
71
- | Some(m) => writeLine(renderMismatchYaml(m))
72
- | None => ()
73
- }
74
- switch t.mismatch {
75
- | Some(m) => {
76
- let hint = Hint.forMismatch(~slice=?t.slice, m)
77
- writeLine(yamlLine("hint", ""))
78
- writeLine(yamlLine(~indent=4, "locus", yamlString(hint.locus)))
79
- writeLine(
80
- yamlLine(
81
- ~indent=4,
82
- "branch",
83
- yamlString(hint.branch->Option.getOr("(none)")),
84
- ),
85
- )
86
- writeLine(yamlLine(~indent=4, "message", yamlString(hint.message)))
87
- }
88
- | None => ()
89
- }
90
- writeLine(" ...")
91
- }
92
- }
93
- })
94
- })
95
- writeLine("")
96
- writeLine(`# tests ${Int.toString(r.summary.total)}`)
97
- writeLine(`# pass ${Int.toString(r.summary.passed)}`)
98
- writeLine(`# fail ${Int.toString(r.summary.failed)}`)
99
- writeLine(`# skip ${Int.toString(r.summary.skipped)}`)
100
- }