@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.
Files changed (88) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/package.json +5 -12
  3. package/rescript.json +0 -1
  4. package/src/JestBind.res +21 -22
  5. package/src/JestBind.res.mjs +15 -11
  6. package/src/RunnerHook.res +38 -0
  7. package/src/RunnerHook.res.mjs +26 -0
  8. package/bin/reventless-dev.mjs +0 -21
  9. package/src/Bind.res +0 -29
  10. package/src/Bind.res.mjs +0 -22
  11. package/src/BuildClassifier.res +0 -147
  12. package/src/BuildClassifier.res.mjs +0 -136
  13. package/src/Cancellation.res +0 -37
  14. package/src/Cancellation.res.mjs +0 -46
  15. package/src/ChildProcess.res +0 -102
  16. package/src/ChildProcess.res.mjs +0 -107
  17. package/src/Cli.res +0 -905
  18. package/src/Cli.res.mjs +0 -952
  19. package/src/Collector.res +0 -212
  20. package/src/Collector.res.mjs +0 -218
  21. package/src/ComponentMeta.res +0 -77
  22. package/src/ComponentMeta.res.mjs +0 -91
  23. package/src/ComponentScan.res +0 -103
  24. package/src/ComponentScan.res.mjs +0 -105
  25. package/src/Discovery.res +0 -105
  26. package/src/Discovery.res.mjs +0 -99
  27. package/src/DomainDeadCode.res +0 -98
  28. package/src/DomainDeadCode.res.mjs +0 -72
  29. package/src/DomainGraph.res +0 -0
  30. package/src/DomainGraph.res.mjs +0 -0
  31. package/src/Filter.res +0 -45
  32. package/src/Filter.res.mjs +0 -47
  33. package/src/FormatterHuman.res +0 -109
  34. package/src/FormatterHuman.res.mjs +0 -115
  35. package/src/FormatterJson.res +0 -264
  36. package/src/FormatterJson.res.mjs +0 -322
  37. package/src/FormatterJunit.res +0 -93
  38. package/src/FormatterJunit.res.mjs +0 -90
  39. package/src/FormatterTap.res +0 -100
  40. package/src/FormatterTap.res.mjs +0 -131
  41. package/src/FormatterVsCode.res +0 -352
  42. package/src/FormatterVsCode.res.mjs +0 -546
  43. package/src/Loader.res +0 -24
  44. package/src/Loader.res.mjs +0 -23
  45. package/src/PackageScan.res +0 -80
  46. package/src/PackageScan.res.mjs +0 -81
  47. package/src/PlatformRunner.res +0 -191
  48. package/src/PlatformRunner.res.mjs +0 -178
  49. package/src/PlatformScan.res +0 -142
  50. package/src/PlatformScan.res.mjs +0 -132
  51. package/src/ProcessManager.res +0 -135
  52. package/src/ProcessManager.res.mjs +0 -119
  53. package/src/RunWorker.res +0 -24
  54. package/src/RunWorker.res.mjs +0 -16
  55. package/src/RunnerTypes.res +0 -68
  56. package/src/RunnerTypes.res.mjs +0 -60
  57. package/src/Watch.res +0 -108
  58. package/src/Watch.res.mjs +0 -85
  59. package/src/WatcherProbe.res +0 -56
  60. package/src/WatcherProbe.res.mjs +0 -59
  61. package/src/Worker.res +0 -24
  62. package/src/Worker.res.mjs +0 -9
  63. package/tests/BuildClassifierTest.res +0 -133
  64. package/tests/BuildClassifierTest.res.mjs +0 -176
  65. package/tests/CliRunEntryTest.res +0 -57
  66. package/tests/CliRunEntryTest.res.mjs +0 -65
  67. package/tests/CliWatchScopeTest.res +0 -62
  68. package/tests/CliWatchScopeTest.res.mjs +0 -95
  69. package/tests/ComponentMetaTest.res +0 -67
  70. package/tests/ComponentMetaTest.res.mjs +0 -71
  71. package/tests/DiscoveryTest.res +0 -42
  72. package/tests/DiscoveryTest.res.mjs +0 -43
  73. package/tests/DomainDeadCodeTest.res +0 -119
  74. package/tests/DomainDeadCodeTest.res.mjs +0 -158
  75. package/tests/DomainGraphTest.res +0 -448
  76. package/tests/DomainGraphTest.res.mjs +0 -505
  77. package/tests/FormatterGoldenTest.res +0 -125
  78. package/tests/FormatterGoldenTest.res.mjs +0 -162
  79. package/tests/FormatterVsCodeMessageTest.res +0 -41
  80. package/tests/FormatterVsCodeMessageTest.res.mjs +0 -42
  81. package/tests/PlatformRunnerTest.res +0 -66
  82. package/tests/PlatformRunnerTest.res.mjs +0 -85
  83. package/tests/PlatformScanTest.res +0 -61
  84. package/tests/PlatformScanTest.res.mjs +0 -56
  85. package/tests/RunnerUnitTest.res +0 -219
  86. package/tests/RunnerUnitTest.res.mjs +0 -244
  87. package/tests/WatchDebounceTest.res +0 -106
  88. package/tests/WatchDebounceTest.res.mjs +0 -128
@@ -1,162 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Outcome$ReventlessGwt from "../src/Outcome.res.mjs";
4
- import * as FormatterTap$ReventlessGwt from "../src/FormatterTap.res.mjs";
5
- import * as FormatterHuman$ReventlessGwt from "../src/FormatterHuman.res.mjs";
6
-
7
- let evA = JSON.parse(`{"TAG":"ProductAdded","_0":{"productId":"p1","name":"Widget"}}`);
8
-
9
- let evB = JSON.parse(`{"TAG":"ProductRenamed","_0":{"productId":"p1","name":"Gadget"}}`);
10
-
11
- let stateActive = JSON.parse(`{"status":"active"}`);
12
-
13
- let stateArchived = JSON.parse(`{"status":"archived"}`);
14
-
15
- let appendExpected = JSON.parse(`{"query":[]}`);
16
-
17
- let appendActual = JSON.parse(`{"query":[{"eventTypes":["ProductAdded"]}]}`);
18
-
19
- let goldens = [
20
- {
21
- name: "EventsMismatch",
22
- mismatch: {
23
- TAG: "EventsMismatch",
24
- expected: [evA],
25
- actual: [evB]
26
- },
27
- 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}]",
28
- human: " expected: [ProductAdded({productId: \"p1\", name: \"Widget\"})]\n actual: [ProductRenamed({productId: \"p1\", name: \"Gadget\"})]",
29
- tap: " kind: \"EventsMismatch\"\n expected: \"[ProductAdded({productId: \\\"p1\\\", name: \\\"Widget\\\"})]\"\n actual: \"[ProductRenamed({productId: \\\"p1\\\", name: \\\"Gadget\\\"})]\""
30
- },
31
- {
32
- name: "ErrorMismatch",
33
- mismatch: {
34
- TAG: "ErrorMismatch",
35
- expected: "CategoryAlreadyExists",
36
- actual: undefined,
37
- actualEvents: [evA]
38
- },
39
- 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}]",
40
- human: " expected: Error(\"CategoryAlreadyExists\")\n actual: Ok([ProductAdded({productId: \"p1\", name: \"Widget\"})])",
41
- tap: " kind: \"ErrorMismatch\"\n expected: \"Error(\\\"CategoryAlreadyExists\\\")\"\n actual: \"Ok([ProductAdded({productId: \\\"p1\\\", name: \\\"Widget\\\"})])\""
42
- },
43
- {
44
- name: "StateMismatch",
45
- mismatch: {
46
- TAG: "StateMismatch",
47
- key: "p1",
48
- expected: stateActive,
49
- actual: stateArchived
50
- },
51
- format: "StateMismatch (key: p1):\n expected: {\n \"status\": \"active\"\n}\n actual: {\n \"status\": \"archived\"\n}",
52
- human: " key: \"p1\"\n expected: {status: \"active\"}\n actual: {status: \"archived\"}",
53
- tap: " kind: \"StateMismatch\"\n key: \"p1\"\n expected: \"{status: \\\"active\\\"}\"\n actual: \"{status: \\\"archived\\\"}\""
54
- },
55
- {
56
- name: "NoEventExpected",
57
- mismatch: {
58
- TAG: "NoEventExpected",
59
- actual: [evA]
60
- },
61
- format: "NoEventExpected: expected no events, got:\n [{\n \"TAG\": \"ProductAdded\",\n \"_0\": {\n \"productId\": \"p1\",\n \"name\": \"Widget\"\n }\n}]",
62
- human: " expected no events\n actual: [ProductAdded({productId: \"p1\", name: \"Widget\"})]",
63
- tap: " kind: \"NoEventExpected\"\n actual: \"[ProductAdded({productId: \\\"p1\\\", name: \\\"Widget\\\"})]\""
64
- },
65
- {
66
- name: "TranslateError",
67
- mismatch: {
68
- TAG: "TranslateError",
69
- expected: "boom",
70
- actual: "kaboom"
71
- },
72
- format: "TranslateError:\n expected: boom\n actual: kaboom",
73
- human: " expected: boom\n actual: kaboom",
74
- tap: " kind: \"TranslateError\"\n expected: \"boom\"\n actual: \"kaboom\""
75
- },
76
- {
77
- name: "Throw",
78
- mismatch: {
79
- TAG: "Throw",
80
- error: "unexpected",
81
- stack: "at foo"
82
- },
83
- format: "Throw: unexpected\nat foo",
84
- human: " error: unexpected\nat foo",
85
- tap: " kind: \"Throw\"\n error: \"unexpected\"\n stack: \"at foo\""
86
- },
87
- {
88
- name: "TodoMismatch",
89
- mismatch: {
90
- TAG: "TodoMismatch",
91
- expected: [[
92
- "case-1",
93
- evA
94
- ]],
95
- actual: [[
96
- "case-2",
97
- evB
98
- ]]
99
- },
100
- 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})]",
101
- human: " expected: [(case-1, ProductAdded({productId: \"p1\", name: \"Widget\"}))]\n actual: [(case-2, ProductRenamed({productId: \"p1\", name: \"Gadget\"}))]",
102
- tap: " kind: \"TodoMismatch\"\n expected: \"[(case-1, ProductAdded({productId: \\\"p1\\\", name: \\\"Widget\\\"}))]\"\n actual: \"[(case-2, ProductRenamed({productId: \\\"p1\\\", name: \\\"Gadget\\\"}))]\""
103
- },
104
- {
105
- name: "AppendConditionMismatch",
106
- mismatch: {
107
- TAG: "AppendConditionMismatch",
108
- expected: appendExpected,
109
- actual: appendActual
110
- },
111
- format: "AppendConditionMismatch:\n expected: {\n \"query\": []\n}\n actual: {\n \"query\": [\n {\n \"eventTypes\": [\n \"ProductAdded\"\n ]\n }\n ]\n}",
112
- human: " expected: {query: []}\n actual: {query: [{eventTypes: [\"ProductAdded\"]}]}",
113
- tap: " kind: \"AppendConditionMismatch\"\n expected: \"{query: []}\"\n actual: \"{query: [{eventTypes: [\\\"ProductAdded\\\"]}]}\""
114
- },
115
- {
116
- name: "QueryRowsMismatch",
117
- mismatch: {
118
- TAG: "QueryRowsMismatch",
119
- expected: [evA],
120
- actual: [evB]
121
- },
122
- 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}]",
123
- human: " expected: [ProductAdded({productId: \"p1\", name: \"Widget\"})]\n actual: [ProductRenamed({productId: \"p1\", name: \"Gadget\"})]",
124
- tap: " kind: \"QueryRowsMismatch\"\n expected: \"[ProductAdded({productId: \\\"p1\\\", name: \\\"Widget\\\"})]\"\n actual: \"[ProductRenamed({productId: \\\"p1\\\", name: \\\"Gadget\\\"})]\""
125
- },
126
- {
127
- name: "PublishedActionsMismatch",
128
- mismatch: {
129
- TAG: "PublishedActionsMismatch",
130
- expected: [evA],
131
- actual: [evB]
132
- },
133
- 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}]",
134
- human: " expected: [ProductAdded({productId: \"p1\", name: \"Widget\"})]\n actual: [ProductRenamed({productId: \"p1\", name: \"Gadget\"})]",
135
- tap: " kind: \"PublishedActionsMismatch\"\n expected: \"[ProductAdded({productId: \\\"p1\\\", name: \\\"Widget\\\"})]\"\n actual: \"[ProductRenamed({productId: \\\"p1\\\", name: \\\"Gadget\\\"})]\""
136
- }
137
- ];
138
-
139
- globalThis.describe("Formatter golden outputs (per-mismatch rendering)", () => {
140
- goldens.forEach(g => {
141
- globalThis.test(g.name + ` — Outcome.format`, () => {
142
- globalThis.expect(Outcome$ReventlessGwt.format(g.mismatch)).toEqual(g.format);
143
- });
144
- globalThis.test(g.name + ` — FormatterHuman.renderMismatch`, () => {
145
- globalThis.expect(FormatterHuman$ReventlessGwt.renderMismatch(g.mismatch)).toEqual(g.human);
146
- });
147
- globalThis.test(g.name + ` — FormatterTap.renderMismatchYaml`, () => {
148
- globalThis.expect(FormatterTap$ReventlessGwt.renderMismatchYaml(g.mismatch)).toEqual(g.tap);
149
- });
150
- });
151
- });
152
-
153
- export {
154
- evA,
155
- evB,
156
- stateActive,
157
- stateArchived,
158
- appendExpected,
159
- appendActual,
160
- goldens,
161
- }
162
- /* evA Not a pure module */
@@ -1,41 +0,0 @@
1
- // Unit test for FormatterVsCode.messagePayload — the failure payload the
2
- // VS Code extension renders. Asserts the `kind` discriminator (the mismatch
3
- // family) is present so a client can gate the apply-expected quick-fix.
4
-
5
- open JestGlobals
6
-
7
- let failingResult = (~mismatch): RunnerTypes.testResult => {
8
- id: "t1",
9
- name: "rejects when category already exists",
10
- describePath: [],
11
- status: RunnerTypes.Fail,
12
- durationMs: 1.0,
13
- location: None,
14
- slice: None,
15
- mismatch,
16
- skipReason: None,
17
- }
18
-
19
- describe("FormatterVsCode.messagePayload", () => {
20
- testPromise("includes the mismatch kind for an EventsMismatch", async () => {
21
- let m = FormatterVsCode.messagePayload(
22
- failingResult(~mismatch=Some(Outcome.EventsMismatch({expected: [], actual: []}))),
23
- )
24
- expect(m.kind)->toEqual(Some("EventsMismatch"))
25
- })
26
-
27
- testPromise("includes the mismatch kind for an ErrorMismatch", async () => {
28
- let m = FormatterVsCode.messagePayload(
29
- failingResult(
30
- ~mismatch=Some(
31
- Outcome.ErrorMismatch({
32
- expected: JSON.String("CategoryAlreadyExists"),
33
- actual: None,
34
- actualEvents: [],
35
- }),
36
- ),
37
- ),
38
- )
39
- expect(m.kind)->toEqual(Some("ErrorMismatch"))
40
- })
41
- })
@@ -1,42 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as FormatterVsCode$ReventlessGwt from "../src/FormatterVsCode.res.mjs";
4
-
5
- function failingResult(mismatch) {
6
- return {
7
- id: "t1",
8
- name: "rejects when category already exists",
9
- describePath: [],
10
- status: "Fail",
11
- durationMs: 1.0,
12
- location: undefined,
13
- slice: undefined,
14
- mismatch: mismatch,
15
- skipReason: undefined
16
- };
17
- }
18
-
19
- globalThis.describe("FormatterVsCode.messagePayload", () => {
20
- globalThis.test("includes the mismatch kind for an EventsMismatch", async () => {
21
- let m = FormatterVsCode$ReventlessGwt.messagePayload(failingResult({
22
- TAG: "EventsMismatch",
23
- expected: [],
24
- actual: []
25
- }));
26
- globalThis.expect(m.kind).toEqual("EventsMismatch");
27
- });
28
- globalThis.test("includes the mismatch kind for an ErrorMismatch", async () => {
29
- let m = FormatterVsCode$ReventlessGwt.messagePayload(failingResult({
30
- TAG: "ErrorMismatch",
31
- expected: "CategoryAlreadyExists",
32
- actual: undefined,
33
- actualEvents: []
34
- }));
35
- globalThis.expect(m.kind).toEqual("ErrorMismatch");
36
- });
37
- });
38
-
39
- export {
40
- failingResult,
41
- }
42
- /* Not a pure module */
@@ -1,66 +0,0 @@
1
- // Unit tests for PlatformRunner.classifyLine — the pure line classifier that turns
2
- // the spawned reventless-local platform's stdout into structured runner events
3
- // (features plan Phase 9). The tap emits sentinel-prefixed JSON; the Domain
4
- // GraphQL "listening" line marks readiness; everything else is a passthrough log.
5
-
6
- open JestGlobals
7
-
8
- describe("PlatformRunner.classifyLine", () => {
9
- testPromise("classifies a tap line as Domain with the parsed payload", async () => {
10
- let line =
11
- `@@RVLESS_EVT@@ {"event":"domainEvent","seq":1,"topic":"CatalogEventTopic","service":"CatalogDcbEventLog","payload":{"event":{"TAG":"ProductAdded"}},"ts":"2026-06-07T00:00:00.000Z"}`
12
- switch PlatformRunner.classifyLine(line) {
13
- | Domain(json) =>
14
- let topic =
15
- json
16
- ->JSON.Decode.object
17
- ->Option.flatMap(d => d->Dict.get("topic"))
18
- ->Option.flatMap(JSON.Decode.string)
19
- expect(topic)->toEqual(Some("CatalogEventTopic"))
20
- | _ => expect("not Domain")->toEqual("Domain")
21
- }
22
- })
23
-
24
- testPromise("a malformed tap line falls back to Log (never throws)", async () => {
25
- switch PlatformRunner.classifyLine("@@RVLESS_EVT@@ {not json") {
26
- | Log(_) => expect(true)->toBe(true)
27
- | _ => expect("not Log")->toEqual("Log")
28
- }
29
- })
30
-
31
- testPromise("classifies the Domain GraphQL listening line as Ready", async () => {
32
- // Real platform output carries ANSI escapes around the [GraphQL:Domain] tag;
33
- // the substring checks see through them.
34
- let line = `12:00:00 I [GraphQL:Domain] listening on http://localhost:4100/graphql (SDL: /sdl)`
35
- switch PlatformRunner.classifyLine(line) {
36
- | Ready => expect(true)->toBe(true)
37
- | _ => expect("not Ready")->toEqual("Ready")
38
- }
39
- })
40
-
41
- testPromise("the Platform (not Domain) listening line is NOT Ready", async () => {
42
- let line = `12:00:00 I [GraphQL:Platform] listening on http://localhost:4101/graphql`
43
- switch PlatformRunner.classifyLine(line) {
44
- | Log(_) => expect(true)->toBe(true)
45
- | _ => expect("expected Log")->toEqual("Log")
46
- }
47
- })
48
-
49
- testPromise("an arbitrary log line is Log", async () => {
50
- switch PlatformRunner.classifyLine("12:00:00 I [Catalog][Aggregate(Product)] handling command") {
51
- | Log(_) => expect(true)->toBe(true)
52
- | _ => expect("expected Log")->toEqual("Log")
53
- }
54
- })
55
-
56
- testPromise("a Log line preserves its ANSI colour/bold escapes (rendered in the terminal)", async () => {
57
- // The child emits coloured logs; the Log payload keeps the ANSI so the
58
- // extension's Pseudoterminal renders colour/bold. Build real ESC (0x1b) bytes.
59
- let esc = String.fromCharCode(27)
60
- let line = `12:00:00 ${esc}[36mI${esc}[0m ${esc}[1m[Catalog]${esc}[0m handling command`
61
- switch PlatformRunner.classifyLine(line) {
62
- | Log(raw) => expect(raw)->toEqual(line)
63
- | _ => expect("expected Log")->toEqual("Log")
64
- }
65
- })
66
- })
@@ -1,85 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
4
- import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
5
- import * as PlatformRunner$ReventlessGwt from "../src/PlatformRunner.res.mjs";
6
-
7
- globalThis.describe("PlatformRunner.classifyLine", () => {
8
- globalThis.test("classifies a tap line as Domain with the parsed payload", async () => {
9
- let json = PlatformRunner$ReventlessGwt.classifyLine(`@@RVLESS_EVT@@ {"event":"domainEvent","seq":1,"topic":"CatalogEventTopic","service":"CatalogDcbEventLog","payload":{"event":{"TAG":"ProductAdded"}},"ts":"2026-06-07T00:00:00.000Z"}`);
10
- if (typeof json !== "object") {
11
- globalThis.expect("not Domain").toEqual("Domain");
12
- return;
13
- }
14
- if (json.TAG === "Domain") {
15
- let topic = Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(json._0), d => d["topic"]), Stdlib_JSON.Decode.string);
16
- globalThis.expect(topic).toEqual("CatalogEventTopic");
17
- return;
18
- }
19
- globalThis.expect("not Domain").toEqual("Domain");
20
- });
21
- globalThis.test("a malformed tap line falls back to Log (never throws)", async () => {
22
- let match = PlatformRunner$ReventlessGwt.classifyLine("@@RVLESS_EVT@@ {not json");
23
- if (typeof match !== "object") {
24
- globalThis.expect("not Log").toEqual("Log");
25
- return;
26
- }
27
- if (match.TAG === "Domain") {
28
- globalThis.expect("not Log").toEqual("Log");
29
- return;
30
- }
31
- globalThis.expect(true).toBe(true);
32
- });
33
- globalThis.test("classifies the Domain GraphQL listening line as Ready", async () => {
34
- let match = PlatformRunner$ReventlessGwt.classifyLine(`12:00:00 I [GraphQL:Domain] listening on http://localhost:4100/graphql (SDL: /sdl)`);
35
- if (typeof match !== "object") {
36
- globalThis.expect(true).toBe(true);
37
- return;
38
- }
39
- if (match.TAG === "Domain") {
40
- globalThis.expect("not Ready").toEqual("Ready");
41
- return;
42
- }
43
- globalThis.expect("not Ready").toEqual("Ready");
44
- });
45
- globalThis.test("the Platform (not Domain) listening line is NOT Ready", async () => {
46
- let match = PlatformRunner$ReventlessGwt.classifyLine(`12:00:00 I [GraphQL:Platform] listening on http://localhost:4101/graphql`);
47
- if (typeof match !== "object") {
48
- globalThis.expect("expected Log").toEqual("Log");
49
- return;
50
- }
51
- if (match.TAG === "Domain") {
52
- globalThis.expect("expected Log").toEqual("Log");
53
- return;
54
- }
55
- globalThis.expect(true).toBe(true);
56
- });
57
- globalThis.test("an arbitrary log line is Log", async () => {
58
- let match = PlatformRunner$ReventlessGwt.classifyLine("12:00:00 I [Catalog][Aggregate(Product)] handling command");
59
- if (typeof match !== "object") {
60
- globalThis.expect("expected Log").toEqual("Log");
61
- return;
62
- }
63
- if (match.TAG === "Domain") {
64
- globalThis.expect("expected Log").toEqual("Log");
65
- return;
66
- }
67
- globalThis.expect(true).toBe(true);
68
- });
69
- globalThis.test("a Log line preserves its ANSI colour/bold escapes (rendered in the terminal)", async () => {
70
- let esc = String.fromCharCode(27);
71
- let line = `12:00:00 ` + esc + `[36mI` + esc + `[0m ` + esc + `[1m[Catalog]` + esc + `[0m handling command`;
72
- let raw = PlatformRunner$ReventlessGwt.classifyLine(line);
73
- if (typeof raw !== "object") {
74
- globalThis.expect("expected Log").toEqual("Log");
75
- return;
76
- }
77
- if (raw.TAG === "Domain") {
78
- globalThis.expect("expected Log").toEqual("Log");
79
- return;
80
- }
81
- globalThis.expect(raw._0).toEqual(line);
82
- });
83
- });
84
-
85
- /* Not a pure module */
@@ -1,61 +0,0 @@
1
- // Unit tests for PlatformScan.matchPlatform — the pure predicate deciding whether
2
- // a package.json + presence of src/Main.res.mjs make a launchable reventless-local
3
- // platform package, and which serve script to prefer (features plan Phase 9).
4
-
5
- open JestGlobals
6
-
7
- let pkgJson = (~deps=`{}`, ~scripts=`{}`) =>
8
- `{"name":"@app/platform-local","dependencies":${deps},"scripts":${scripts}}`
9
-
10
- describe("PlatformScan.matchPlatform", () => {
11
- testPromise("matches when it depends on reventless-local and Main.res.mjs exists", async () => {
12
- let text = pkgJson(~deps=`{"@reventlessdev/reventless-local":"workspace:*"}`)
13
- switch PlatformScan.matchPlatform(~pkgJsonText=text, ~mainExists=true) {
14
- | Some((name, _)) => expect(name)->toEqual("@app/platform-local")
15
- | None => expect("None")->toEqual("Some")
16
- }
17
- })
18
-
19
- testPromise("no match when src/Main.res.mjs is absent", async () => {
20
- let text = pkgJson(~deps=`{"@reventlessdev/reventless-local":"workspace:*"}`)
21
- expect(PlatformScan.matchPlatform(~pkgJsonText=text, ~mainExists=false)->Option.isNone)->toBe(
22
- true,
23
- )
24
- })
25
-
26
- testPromise("no match without the reventless-local dependency", async () => {
27
- let text = pkgJson(~deps=`{"sury":"^11"}`)
28
- expect(PlatformScan.matchPlatform(~pkgJsonText=text, ~mainExists=true)->Option.isNone)->toBe(
29
- true,
30
- )
31
- })
32
-
33
- testPromise("prefers the serve:memory script over serve", async () => {
34
- let text = pkgJson(
35
- ~deps=`{"@reventlessdev/reventless-local":"workspace:*"}`,
36
- ~scripts=`{"serve":"tsx Main","serve:memory":"REVENTLESS_LOCAL_BACKEND=memory tsx Main"}`,
37
- )
38
- switch PlatformScan.matchPlatform(~pkgJsonText=text, ~mainExists=true) {
39
- | Some((_, serveScript)) => expect(serveScript)->toEqual(Some("serve:memory"))
40
- | None => expect("None")->toEqual("Some")
41
- }
42
- })
43
-
44
- testPromise("falls back to serve when serve:memory is absent", async () => {
45
- let text = pkgJson(
46
- ~deps=`{"@reventlessdev/reventless-local":"workspace:*"}`,
47
- ~scripts=`{"serve":"tsx Main"}`,
48
- )
49
- switch PlatformScan.matchPlatform(~pkgJsonText=text, ~mainExists=true) {
50
- | Some((_, serveScript)) => expect(serveScript)->toEqual(Some("serve"))
51
- | None => expect("None")->toEqual("Some")
52
- }
53
- })
54
-
55
- testPromise("matches via devDependencies too", async () => {
56
- let text = `{"name":"p","devDependencies":{"@reventlessdev/reventless-local":"*"}}`
57
- expect(PlatformScan.matchPlatform(~pkgJsonText=text, ~mainExists=true)->Option.isSome)->toBe(
58
- true,
59
- )
60
- })
61
- })
@@ -1,56 +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 PlatformScan$ReventlessGwt from "../src/PlatformScan.res.mjs";
5
-
6
- function pkgJson(depsOpt, scriptsOpt) {
7
- let deps = depsOpt !== undefined ? depsOpt : `{}`;
8
- let scripts = scriptsOpt !== undefined ? scriptsOpt : `{}`;
9
- return `{"name":"@app/platform-local","dependencies":` + deps + `,"scripts":` + scripts + `}`;
10
- }
11
-
12
- globalThis.describe("PlatformScan.matchPlatform", () => {
13
- globalThis.test("matches when it depends on reventless-local and Main.res.mjs exists", async () => {
14
- let text = pkgJson(`{"@reventlessdev/reventless-local":"workspace:*"}`, undefined);
15
- let match = PlatformScan$ReventlessGwt.matchPlatform(text, true);
16
- if (match !== undefined) {
17
- globalThis.expect(match[0]).toEqual("@app/platform-local");
18
- } else {
19
- globalThis.expect("None").toEqual("Some");
20
- }
21
- });
22
- globalThis.test("no match when src/Main.res.mjs is absent", async () => {
23
- let text = pkgJson(`{"@reventlessdev/reventless-local":"workspace:*"}`, undefined);
24
- globalThis.expect(Stdlib_Option.isNone(PlatformScan$ReventlessGwt.matchPlatform(text, false))).toBe(true);
25
- });
26
- globalThis.test("no match without the reventless-local dependency", async () => {
27
- let text = pkgJson(`{"sury":"^11"}`, undefined);
28
- globalThis.expect(Stdlib_Option.isNone(PlatformScan$ReventlessGwt.matchPlatform(text, true))).toBe(true);
29
- });
30
- globalThis.test("prefers the serve:memory script over serve", async () => {
31
- let text = pkgJson(`{"@reventlessdev/reventless-local":"workspace:*"}`, `{"serve":"tsx Main","serve:memory":"REVENTLESS_LOCAL_BACKEND=memory tsx Main"}`);
32
- let match = PlatformScan$ReventlessGwt.matchPlatform(text, true);
33
- if (match !== undefined) {
34
- globalThis.expect(match[1]).toEqual("serve:memory");
35
- } else {
36
- globalThis.expect("None").toEqual("Some");
37
- }
38
- });
39
- globalThis.test("falls back to serve when serve:memory is absent", async () => {
40
- let text = pkgJson(`{"@reventlessdev/reventless-local":"workspace:*"}`, `{"serve":"tsx Main"}`);
41
- let match = PlatformScan$ReventlessGwt.matchPlatform(text, true);
42
- if (match !== undefined) {
43
- globalThis.expect(match[1]).toEqual("serve");
44
- } else {
45
- globalThis.expect("None").toEqual("Some");
46
- }
47
- });
48
- globalThis.test("matches via devDependencies too", async () => {
49
- globalThis.expect(Stdlib_Option.isSome(PlatformScan$ReventlessGwt.matchPlatform(`{"name":"p","devDependencies":{"@reventlessdev/reventless-local":"*"}}`, true))).toBe(true);
50
- });
51
- });
52
-
53
- export {
54
- pkgJson,
55
- }
56
- /* Not a pure module */