@reventlessdev/reventless-gwt 1.0.0-alpha.75 → 1.0.0-alpha.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/package.json +8 -8
- package/src/Behavior_GWT.res +125 -159
- package/src/Behavior_GWT.res.mjs +156 -59
- package/src/Bind.res.mjs +2 -2
- package/src/BuildClassifier.res +15 -5
- package/src/BuildClassifier.res.mjs +3 -3
- package/src/Cancellation.res +6 -0
- package/src/Cancellation.res.mjs +3 -2
- package/src/ChildProcess.res +19 -1
- package/src/ChildProcess.res.mjs +16 -1
- package/src/Cli.res +260 -26
- package/src/Cli.res.mjs +227 -29
- package/src/Collector.res +13 -2
- package/src/Collector.res.mjs +8 -5
- package/src/ComponentMeta.res +16 -43
- package/src/ComponentMeta.res.mjs +12 -41
- package/src/Discovery.res +19 -19
- package/src/Discovery.res.mjs +5 -9
- package/src/DomainGraph.res +0 -0
- package/src/DomainGraph.res.mjs +0 -0
- package/src/Filter.res +11 -2
- package/src/Filter.res.mjs +10 -3
- package/src/FormatterHuman.res +14 -43
- package/src/FormatterHuman.res.mjs +21 -28
- package/src/FormatterJson.res +12 -5
- package/src/FormatterJson.res.mjs +8 -6
- package/src/FormatterTap.res +13 -52
- package/src/FormatterTap.res.mjs +25 -43
- package/src/FormatterVsCode.res +4 -19
- package/src/FormatterVsCode.res.mjs +4 -23
- package/src/JestBind.res +1 -1
- package/src/JestBind.res.mjs +2 -2
- package/src/LocalHost.res +11 -27
- package/src/LocalHost.res.mjs +6 -34
- package/src/MismatchRender.res +72 -0
- package/src/MismatchRender.res.mjs +127 -0
- package/src/Outcome.res +0 -64
- package/src/Outcome.res.mjs +0 -47
- package/src/PlatformRunner.res +27 -6
- package/src/PlatformRunner.res.mjs +27 -6
- package/src/PlatformScan.res +14 -10
- package/src/PlatformScan.res.mjs +14 -13
- package/src/ProcessManager.res +51 -7
- package/src/ProcessManager.res.mjs +43 -4
- package/src/RunWorker.res +24 -0
- package/src/RunWorker.res.mjs +16 -0
- package/src/Watch.res +46 -30
- package/src/Watch.res.mjs +34 -32
- package/src/WatcherProbe.res +11 -3
- package/src/WatcherProbe.res.mjs +15 -2
- package/src/Worker.res +24 -0
- package/src/Worker.res.mjs +9 -0
- package/tests/BuildClassifierTest.res +39 -0
- package/tests/BuildClassifierTest.res.mjs +44 -0
- package/tests/CliRunEntryTest.res +57 -0
- package/tests/CliRunEntryTest.res.mjs +65 -0
- package/tests/CliWatchScopeTest.res +62 -0
- package/tests/CliWatchScopeTest.res.mjs +95 -0
- package/tests/ComponentMetaTest.res +15 -0
- package/tests/ComponentMetaTest.res.mjs +14 -0
- package/tests/DomainGraphTest.res +2 -2
- package/tests/FlowAggregateGwtTest.res +2 -0
- package/tests/FlowAggregateGwtTest.res.mjs +4 -0
- package/tests/FormatterGoldenTest.res +125 -0
- package/tests/FormatterGoldenTest.res.mjs +162 -0
- package/tests/MappingGwtTest.res +2 -0
- package/tests/MappingGwtTest.res.mjs +4 -0
- package/tests/WatchDebounceTest.res +35 -7
- package/tests/WatchDebounceTest.res.mjs +37 -6
|
@@ -0,0 +1,162 @@
|
|
|
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 */
|
package/tests/MappingGwtTest.res
CHANGED
|
@@ -33,6 +33,7 @@ module CategoryBehavior = {
|
|
|
33
33
|
module Spec = CategorySpec
|
|
34
34
|
type state = NotCreated | Created
|
|
35
35
|
let initialState = NotCreated
|
|
36
|
+
let snapshot = None
|
|
36
37
|
|
|
37
38
|
let evolve = (_state, event: CategorySpec.event) =>
|
|
38
39
|
switch event {
|
|
@@ -70,6 +71,7 @@ module ProductBehavior = {
|
|
|
70
71
|
module Spec = ProductSpec
|
|
71
72
|
type state = Pristine | Mirrored
|
|
72
73
|
let initialState = Pristine
|
|
74
|
+
let snapshot = None
|
|
73
75
|
|
|
74
76
|
let evolve = (_state, event: ProductSpec.event) =>
|
|
75
77
|
switch event {
|
|
@@ -66,6 +66,7 @@ let moduleUrl$1 = "";
|
|
|
66
66
|
let CategoryBehavior = {
|
|
67
67
|
Spec: undefined,
|
|
68
68
|
initialState: "NotCreated",
|
|
69
|
+
snapshot: undefined,
|
|
69
70
|
evolve: evolve,
|
|
70
71
|
decide: decide,
|
|
71
72
|
moduleUrl: moduleUrl$1
|
|
@@ -133,6 +134,7 @@ let moduleUrl$3 = "";
|
|
|
133
134
|
let ProductBehavior = {
|
|
134
135
|
Spec: undefined,
|
|
135
136
|
initialState: "Pristine",
|
|
137
|
+
snapshot: undefined,
|
|
136
138
|
evolve: evolve$1,
|
|
137
139
|
decide: decide$1,
|
|
138
140
|
moduleUrl: moduleUrl$3
|
|
@@ -299,6 +301,7 @@ let CategorySource = Mapping_GWT$ReventlessGwt.FromBehavior({
|
|
|
299
301
|
initialState: "NotCreated",
|
|
300
302
|
evolve: evolve,
|
|
301
303
|
decide: decide,
|
|
304
|
+
snapshot: undefined,
|
|
302
305
|
moduleUrl: moduleUrl$1
|
|
303
306
|
});
|
|
304
307
|
|
|
@@ -335,6 +338,7 @@ let ProductTarget = Mapping_GWT$ReventlessGwt.FromBehavior({
|
|
|
335
338
|
initialState: "Pristine",
|
|
336
339
|
evolve: evolve$1,
|
|
337
340
|
decide: decide$1,
|
|
341
|
+
snapshot: undefined,
|
|
338
342
|
moduleUrl: moduleUrl$3
|
|
339
343
|
});
|
|
340
344
|
|
|
@@ -49,10 +49,11 @@ describe("Watch.debounce coalescing", () => {
|
|
|
49
49
|
expect(calls.contents)->toEqual([Watch.Unlink])
|
|
50
50
|
})
|
|
51
51
|
|
|
52
|
-
testPromise("interleaved .res.mjs unlinks
|
|
52
|
+
testPromise("interleaved .res.mjs unlinks never surface; each distinct .res source does", async () => {
|
|
53
53
|
// The real directory-mv burst chokidar emits: source AND generated files
|
|
54
|
-
// unlink interleaved.
|
|
55
|
-
//
|
|
54
|
+
// unlink interleaved. Only `.res` sources are emitted (never a `.res.mjs`),
|
|
55
|
+
// and every *distinct* source is emitted — two moved modules must both drive
|
|
56
|
+
// a rebuild, not collapse to one representative.
|
|
56
57
|
let calls = ref([])
|
|
57
58
|
let fire = Watch.debounce(40, (e, p) => calls := Array.concat(calls.contents, [(e, p)]))
|
|
58
59
|
fire(Watch.Unlink, "/p/src/old/A.res")
|
|
@@ -62,10 +63,37 @@ describe("Watch.debounce coalescing", () => {
|
|
|
62
63
|
fire(Watch.Add, "/p/src/new/A.res")
|
|
63
64
|
fire(Watch.Add, "/p/src/new/A.res.mjs")
|
|
64
65
|
await delay(120)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
expect(
|
|
68
|
-
expect(
|
|
66
|
+
let paths = calls.contents->Array.map(((_, p)) => p)
|
|
67
|
+
expect(calls.contents->Array.every(((e, p)) => Watch.isStructuralSource(e, p)))->toEqual(true)
|
|
68
|
+
expect(paths->Array.includes("/p/src/old/A.res"))->toEqual(true)
|
|
69
|
+
expect(paths->Array.includes("/p/src/old/A_Behavior.res"))->toEqual(true)
|
|
70
|
+
expect(paths->Array.some(p => p->String.endsWith(".mjs")))->toEqual(false)
|
|
71
|
+
expect(calls.contents->Array.length)->toEqual(2)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
testPromise("a burst spanning two packages emits an unlink per package (A4.1)", async () => {
|
|
75
|
+
// Regression: the old single-`bestPath` debounce clean-rebuilt only one
|
|
76
|
+
// package on a multi-package burst, stranding the other with stale .res.mjs.
|
|
77
|
+
let calls = ref([])
|
|
78
|
+
let fire = Watch.debounce(40, (e, p) => calls := Array.concat(calls.contents, [(e, p)]))
|
|
79
|
+
fire(Watch.Unlink, "/pkgA/src/Foo.res")
|
|
80
|
+
fire(Watch.Unlink, "/pkgB/src/Bar.res")
|
|
81
|
+
await delay(120)
|
|
82
|
+
let paths = calls.contents->Array.map(((_, p)) => p)
|
|
83
|
+
expect(paths->Array.includes("/pkgA/src/Foo.res"))->toEqual(true)
|
|
84
|
+
expect(paths->Array.includes("/pkgB/src/Bar.res"))->toEqual(true)
|
|
85
|
+
expect(calls.contents->Array.length)->toEqual(2)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
testPromise("a structural signal suppresses a co-occurring plain change", async () => {
|
|
89
|
+
// A structural rebuild does its own re-run, so a plain edit in the same
|
|
90
|
+
// window must not also emit a separate Change (which would double-run).
|
|
91
|
+
let calls = ref([])
|
|
92
|
+
let fire = Watch.debounce(40, (e, _p) => calls := Array.concat(calls.contents, [e]))
|
|
93
|
+
fire(Watch.Change, "/p/src/Edited.res")
|
|
94
|
+
fire(Watch.Unlink, "/p/src/old/Moved.res")
|
|
95
|
+
await delay(120)
|
|
96
|
+
expect(calls.contents)->toEqual([Watch.Unlink])
|
|
69
97
|
})
|
|
70
98
|
|
|
71
99
|
testPromise("a lone change stays a change (incremental re-run)", async () => {
|
|
@@ -55,7 +55,7 @@ globalThis.describe("Watch.debounce coalescing", () => {
|
|
|
55
55
|
await delay(120);
|
|
56
56
|
globalThis.expect(calls.contents).toEqual(["Unlink"]);
|
|
57
57
|
});
|
|
58
|
-
globalThis.test("interleaved .res.mjs unlinks
|
|
58
|
+
globalThis.test("interleaved .res.mjs unlinks never surface; each distinct .res source does", async () => {
|
|
59
59
|
let calls = {
|
|
60
60
|
contents: []
|
|
61
61
|
};
|
|
@@ -72,11 +72,42 @@ globalThis.describe("Watch.debounce coalescing", () => {
|
|
|
72
72
|
fire("Add", "/p/src/new/A.res");
|
|
73
73
|
fire("Add", "/p/src/new/A.res.mjs");
|
|
74
74
|
await delay(120);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
globalThis.expect(
|
|
79
|
-
globalThis.expect(
|
|
75
|
+
let paths = calls.contents.map(param => param[1]);
|
|
76
|
+
globalThis.expect(calls.contents.every(param => Watch$ReventlessGwt.isStructuralSource(param[0], param[1]))).toEqual(true);
|
|
77
|
+
globalThis.expect(paths.includes("/p/src/old/A.res")).toEqual(true);
|
|
78
|
+
globalThis.expect(paths.includes("/p/src/old/A_Behavior.res")).toEqual(true);
|
|
79
|
+
globalThis.expect(paths.some(p => p.endsWith(".mjs"))).toEqual(false);
|
|
80
|
+
globalThis.expect(calls.contents.length).toEqual(2);
|
|
81
|
+
});
|
|
82
|
+
globalThis.test("a burst spanning two packages emits an unlink per package (A4.1)", async () => {
|
|
83
|
+
let calls = {
|
|
84
|
+
contents: []
|
|
85
|
+
};
|
|
86
|
+
let fire = Watch$ReventlessGwt.debounce(40, (e, p) => {
|
|
87
|
+
calls.contents = calls.contents.concat([[
|
|
88
|
+
e,
|
|
89
|
+
p
|
|
90
|
+
]]);
|
|
91
|
+
});
|
|
92
|
+
fire("Unlink", "/pkgA/src/Foo.res");
|
|
93
|
+
fire("Unlink", "/pkgB/src/Bar.res");
|
|
94
|
+
await delay(120);
|
|
95
|
+
let paths = calls.contents.map(param => param[1]);
|
|
96
|
+
globalThis.expect(paths.includes("/pkgA/src/Foo.res")).toEqual(true);
|
|
97
|
+
globalThis.expect(paths.includes("/pkgB/src/Bar.res")).toEqual(true);
|
|
98
|
+
globalThis.expect(calls.contents.length).toEqual(2);
|
|
99
|
+
});
|
|
100
|
+
globalThis.test("a structural signal suppresses a co-occurring plain change", async () => {
|
|
101
|
+
let calls = {
|
|
102
|
+
contents: []
|
|
103
|
+
};
|
|
104
|
+
let fire = Watch$ReventlessGwt.debounce(40, (e, _p) => {
|
|
105
|
+
calls.contents = calls.contents.concat([e]);
|
|
106
|
+
});
|
|
107
|
+
fire("Change", "/p/src/Edited.res");
|
|
108
|
+
fire("Unlink", "/p/src/old/Moved.res");
|
|
109
|
+
await delay(120);
|
|
110
|
+
globalThis.expect(calls.contents).toEqual(["Unlink"]);
|
|
80
111
|
});
|
|
81
112
|
globalThis.test("a lone change stays a change (incremental re-run)", async () => {
|
|
82
113
|
let calls = {
|