@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.
- package/CHANGELOG.md +916 -0
- package/LICENSE +202 -0
- package/bin/reventless-dev.mjs +21 -0
- package/package.json +54 -0
- package/rescript.json +36 -0
- package/src/.gwtignore +10 -0
- package/src/Automation_GWT.res +207 -0
- package/src/Automation_GWT.res.mjs +160 -0
- package/src/Behavior_GWT.res +569 -0
- package/src/Behavior_GWT.res.mjs +523 -0
- package/src/Bind.res +29 -0
- package/src/Bind.res.mjs +22 -0
- package/src/BuildClassifier.res +147 -0
- package/src/BuildClassifier.res.mjs +136 -0
- package/src/Cancellation.res +37 -0
- package/src/Cancellation.res.mjs +46 -0
- package/src/ChildProcess.res +102 -0
- package/src/ChildProcess.res.mjs +107 -0
- package/src/Cli.res +905 -0
- package/src/Cli.res.mjs +952 -0
- package/src/Collector.res +212 -0
- package/src/Collector.res.mjs +218 -0
- package/src/ComponentMeta.res +77 -0
- package/src/ComponentMeta.res.mjs +91 -0
- package/src/ComponentScan.res +103 -0
- package/src/ComponentScan.res.mjs +105 -0
- package/src/Delegate_GWT.res +303 -0
- package/src/Delegate_GWT.res.mjs +372 -0
- package/src/Diff.res +91 -0
- package/src/Diff.res.mjs +98 -0
- package/src/Discovery.res +105 -0
- package/src/Discovery.res.mjs +99 -0
- package/src/DomainDeadCode.res +98 -0
- package/src/DomainDeadCode.res.mjs +72 -0
- package/src/DomainGraph.res +0 -0
- package/src/DomainGraph.res.mjs +0 -0
- package/src/EventMapping_GWT.res +29 -0
- package/src/EventMapping_GWT.res.mjs +44 -0
- package/src/Filter.res +45 -0
- package/src/Filter.res.mjs +47 -0
- package/src/Flow_GWT.res +664 -0
- package/src/Flow_GWT.res.mjs +604 -0
- package/src/FormatterHuman.res +109 -0
- package/src/FormatterHuman.res.mjs +115 -0
- package/src/FormatterJson.res +264 -0
- package/src/FormatterJson.res.mjs +322 -0
- package/src/FormatterJunit.res +93 -0
- package/src/FormatterJunit.res.mjs +90 -0
- package/src/FormatterTap.res +100 -0
- package/src/FormatterTap.res.mjs +131 -0
- package/src/FormatterVsCode.res +352 -0
- package/src/FormatterVsCode.res.mjs +546 -0
- package/src/Hint.res +119 -0
- package/src/Hint.res.mjs +124 -0
- package/src/InboundTranslation_GWT.res +83 -0
- package/src/InboundTranslation_GWT.res.mjs +94 -0
- package/src/JestBind.res +70 -0
- package/src/JestBind.res.mjs +63 -0
- package/src/Loader.res +24 -0
- package/src/Loader.res.mjs +23 -0
- package/src/LocalHost.res +119 -0
- package/src/LocalHost.res.mjs +99 -0
- package/src/Mapping_GWT.res +474 -0
- package/src/Mapping_GWT.res.mjs +322 -0
- package/src/MismatchRender.res +72 -0
- package/src/MismatchRender.res.mjs +127 -0
- package/src/MultiSourceProjection_GWT.res +316 -0
- package/src/MultiSourceProjection_GWT.res.mjs +354 -0
- package/src/OutboundTranslation_GWT.res +238 -0
- package/src/OutboundTranslation_GWT.res.mjs +186 -0
- package/src/Outcome.res +97 -0
- package/src/Outcome.res.mjs +93 -0
- package/src/PackageScan.res +80 -0
- package/src/PackageScan.res.mjs +81 -0
- package/src/PlatformRunner.res +181 -0
- package/src/PlatformRunner.res.mjs +176 -0
- package/src/PlatformScan.res +142 -0
- package/src/PlatformScan.res.mjs +132 -0
- package/src/ProcessManager.res +135 -0
- package/src/ProcessManager.res.mjs +119 -0
- package/src/Projection_GWT.res +312 -0
- package/src/Projection_GWT.res.mjs +332 -0
- package/src/Query_GWT.res +379 -0
- package/src/Query_GWT.res.mjs +367 -0
- package/src/RenderRescript.res +125 -0
- package/src/RenderRescript.res.mjs +141 -0
- package/src/RunWorker.res +24 -0
- package/src/RunWorker.res.mjs +16 -0
- package/src/RunnerTypes.res +68 -0
- package/src/RunnerTypes.res.mjs +60 -0
- package/src/SideEffect_GWT.res +157 -0
- package/src/SideEffect_GWT.res.mjs +113 -0
- package/src/StateChange/ExternalAddCategorySlice.res +25 -0
- package/src/StateChange/ExternalAddCategorySlice.res.mjs +34 -0
- package/src/StateChange/ExternalAddCategorySlice_Behavior.res +19 -0
- package/src/StateChange/ExternalAddCategorySlice_Behavior.res.mjs +46 -0
- package/src/StateChange/WithFixtures.res +22 -0
- package/src/StateChange/WithFixtures.res.mjs +31 -0
- package/src/StateChange/WithFixtures_Behavior.res +17 -0
- package/src/StateChange/WithFixtures_Behavior.res.mjs +37 -0
- package/src/StateChange/WithManualOpen.res +23 -0
- package/src/StateChange/WithManualOpen.res.mjs +31 -0
- package/src/StateChange/WithManualOpen_Behavior.res +17 -0
- package/src/StateChange/WithManualOpen_Behavior.res.mjs +37 -0
- package/src/StubRuntime.res +54 -0
- package/src/StubRuntime.res.mjs +55 -0
- package/src/TestFixtures.res +16 -0
- package/src/TestFixtures.res.mjs +34 -0
- package/src/Watch.res +108 -0
- package/src/Watch.res.mjs +85 -0
- package/src/WatcherProbe.res +56 -0
- package/src/WatcherProbe.res.mjs +59 -0
- package/src/Worker.res +24 -0
- package/src/Worker.res.mjs +9 -0
- package/tests/AutomationGwtTest.res +71 -0
- package/tests/AutomationGwtTest.res.mjs +189 -0
- package/tests/BuildClassifierTest.res +133 -0
- package/tests/BuildClassifierTest.res.mjs +176 -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 +67 -0
- package/tests/ComponentMetaTest.res.mjs +71 -0
- package/tests/DelegateGwtTest.res +487 -0
- package/tests/DelegateGwtTest.res.mjs +891 -0
- package/tests/DiscoveryTest.res +42 -0
- package/tests/DiscoveryTest.res.mjs +43 -0
- package/tests/DomainDeadCodeTest.res +119 -0
- package/tests/DomainDeadCodeTest.res.mjs +158 -0
- package/tests/DomainGraphTest.res +448 -0
- package/tests/DomainGraphTest.res.mjs +505 -0
- package/tests/FlowAggregateGwtTest.res +171 -0
- package/tests/FlowAggregateGwtTest.res.mjs +273 -0
- package/tests/FlowCrossPluginGwtTest.res +340 -0
- package/tests/FlowCrossPluginGwtTest.res.mjs +798 -0
- package/tests/FlowGwtTest.res +222 -0
- package/tests/FlowGwtTest.res.mjs +433 -0
- package/tests/FormatterGoldenTest.res +125 -0
- package/tests/FormatterGoldenTest.res.mjs +162 -0
- package/tests/FormatterVsCodeMessageTest.res +41 -0
- package/tests/FormatterVsCodeMessageTest.res.mjs +42 -0
- package/tests/InboundTranslationGwtTest.res +34 -0
- package/tests/InboundTranslationGwtTest.res.mjs +99 -0
- package/tests/LocalHostIntegration.res +70 -0
- package/tests/LocalHostIntegration.res.mjs +64 -0
- package/tests/LocalHostTest.res +71 -0
- package/tests/LocalHostTest.res.mjs +63 -0
- package/tests/MappingGwtTest.res +350 -0
- package/tests/MappingGwtTest.res.mjs +596 -0
- package/tests/OutboundTranslationGwtTest.res +59 -0
- package/tests/OutboundTranslationGwtTest.res.mjs +139 -0
- package/tests/PlatformRunnerTest.res +66 -0
- package/tests/PlatformRunnerTest.res.mjs +85 -0
- package/tests/PlatformScanTest.res +61 -0
- package/tests/PlatformScanTest.res.mjs +56 -0
- package/tests/QueryGwtTest.res +161 -0
- package/tests/QueryGwtTest.res.mjs +314 -0
- package/tests/QueryResolverGwtTest.res +71 -0
- package/tests/QueryResolverGwtTest.res.mjs +136 -0
- package/tests/RunnerUnitTest.res +219 -0
- package/tests/RunnerUnitTest.res.mjs +244 -0
- package/tests/SideEffect/FakeOrderNotification.res +23 -0
- package/tests/SideEffect/FakeOrderNotification.res.mjs +36 -0
- package/tests/SideEffect/FakeOrderNotificationGwtTest.res +35 -0
- package/tests/SideEffect/FakeOrderNotificationGwtTest.res.mjs +73 -0
- package/tests/SideEffect/MockEmail.res +18 -0
- package/tests/SideEffect/MockEmail.res.mjs +47 -0
- package/tests/StateChange/ExternalAddCategorySlice_GWT.res +27 -0
- package/tests/StateChange/ExternalAddCategorySlice_GWT.res.mjs +70 -0
- package/tests/StateChange/WithFixtures_Fixtures.res +9 -0
- package/tests/StateChange/WithFixtures_Fixtures.res.mjs +20 -0
- package/tests/StateChange/WithFixtures_GWT.res +23 -0
- package/tests/StateChange/WithFixtures_GWT.res.mjs +56 -0
- package/tests/StateChange/WithManualOpen_Fixtures.res +7 -0
- package/tests/StateChange/WithManualOpen_Fixtures.res.mjs +20 -0
- package/tests/StateChange/WithManualOpen_GWT.res +17 -0
- package/tests/StateChange/WithManualOpen_GWT.res.mjs +56 -0
- package/tests/StateChangeSliceGwtTest.res +160 -0
- package/tests/StateChangeSliceGwtTest.res.mjs +280 -0
- package/tests/StateViewSliceGwtTest.res +64 -0
- package/tests/StateViewSliceGwtTest.res.mjs +161 -0
- package/tests/WatchDebounceTest.res +106 -0
- package/tests/WatchDebounceTest.res.mjs +128 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as S from "sury/src/S.res.mjs";
|
|
4
|
+
import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
|
|
5
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
6
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
7
|
+
import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
|
|
8
|
+
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
9
|
+
import * as Outcome$ReventlessGwt from "./Outcome.res.mjs";
|
|
10
|
+
import * as JestBind$ReventlessGwt from "./JestBind.res.mjs";
|
|
11
|
+
import * as Message$ReventlessCore from "@reventlessdev/reventless-core/src/Message.res.mjs";
|
|
12
|
+
import * as StubRuntime$ReventlessGwt from "./StubRuntime.res.mjs";
|
|
13
|
+
|
|
14
|
+
function encPublished(target, payload) {
|
|
15
|
+
let d = {};
|
|
16
|
+
d["target"] = target;
|
|
17
|
+
d["payload"] = payload;
|
|
18
|
+
return d;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function Make(D) {
|
|
22
|
+
S.enableJson();
|
|
23
|
+
let test = (name, timeout, body) => JestBind$ReventlessGwt.testPromise(D.name, name, timeout, body);
|
|
24
|
+
let whenInput = ev => D.run(ev);
|
|
25
|
+
let sortJson = arr => arr.toSorted((a, b) => Primitive_string.compare(JSON.stringify(a), JSON.stringify(b)));
|
|
26
|
+
let targetOf = j => Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(j), d => d["target"]), Stdlib_JSON.Decode.string), "");
|
|
27
|
+
let dropDirectives = arr => arr.filter(j => targetOf(j) !== "directive");
|
|
28
|
+
let onlyDirectives = arr => arr.filter(j => targetOf(j) === "directive");
|
|
29
|
+
let thenPublishedJson = async (actionsP, expected) => {
|
|
30
|
+
let actual = dropDirectives(await actionsP);
|
|
31
|
+
if (Primitive_object.equal(sortJson(actual), sortJson(expected))) {
|
|
32
|
+
return Outcome$ReventlessGwt.pass;
|
|
33
|
+
} else {
|
|
34
|
+
return Outcome$ReventlessGwt.fail({
|
|
35
|
+
TAG: "PublishedActionsMismatch",
|
|
36
|
+
expected: expected,
|
|
37
|
+
actual: actual
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
let thenPublishesNothing = actionsP => thenPublishedJson(actionsP, []);
|
|
42
|
+
let thenHandlesDirectivesJson = async (actionsP, expected) => {
|
|
43
|
+
let actual = onlyDirectives(await actionsP);
|
|
44
|
+
if (Primitive_object.equal(sortJson(actual), sortJson(expected))) {
|
|
45
|
+
return Outcome$ReventlessGwt.pass;
|
|
46
|
+
} else {
|
|
47
|
+
return Outcome$ReventlessGwt.fail({
|
|
48
|
+
TAG: "PublishedActionsMismatch",
|
|
49
|
+
expected: expected,
|
|
50
|
+
actual: actual
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
describe: JestBind$ReventlessGwt.describe,
|
|
56
|
+
test: test,
|
|
57
|
+
whenInput: whenInput,
|
|
58
|
+
thenPublishedJson: thenPublishedJson,
|
|
59
|
+
thenPublishesNothing: thenPublishesNothing,
|
|
60
|
+
thenHandlesDirectivesJson: thenHandlesDirectivesJson
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function FromExtensionPoint(M) {
|
|
65
|
+
let encEvent = e => Message$ReventlessCore.encode(e, M.ExtensionPoint.eventSchema);
|
|
66
|
+
let encCommand = c => Message$ReventlessCore.encode(c, M.Delegate.commandSchema);
|
|
67
|
+
let encDirective = d => encPublished("directive", Message$ReventlessCore.encode(d, M.ExtensionPoint.directiveSchema));
|
|
68
|
+
let name = M.ExtensionPoint.name;
|
|
69
|
+
let run = async event => {
|
|
70
|
+
let f = M.mapOutgoingEvent;
|
|
71
|
+
if (f !== undefined) {
|
|
72
|
+
return (await Promise.all(f("gwt-id", event, StubRuntime$ReventlessGwt.meta, StubRuntime$ReventlessGwt.queryEngine).map(async action => {
|
|
73
|
+
switch (action.TAG) {
|
|
74
|
+
case "PublishEvent" :
|
|
75
|
+
return [encPublished(action._0, Message$ReventlessCore.encode(action._1, M.ExtensionPoint.eventSchema))];
|
|
76
|
+
case "PublishEventAsync" :
|
|
77
|
+
let match = await action._0;
|
|
78
|
+
return [encPublished(match[0], Message$ReventlessCore.encode(match[1], M.ExtensionPoint.eventSchema))];
|
|
79
|
+
case "HandleDirective" :
|
|
80
|
+
return [encDirective(action._1)];
|
|
81
|
+
}
|
|
82
|
+
}))).flat();
|
|
83
|
+
} else {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
S.enableJson();
|
|
88
|
+
let test = (name$1, timeout, body) => JestBind$ReventlessGwt.testPromise(name, name$1, timeout, body);
|
|
89
|
+
let whenInput = run;
|
|
90
|
+
let sortJson = arr => arr.toSorted((a, b) => Primitive_string.compare(JSON.stringify(a), JSON.stringify(b)));
|
|
91
|
+
let targetOf = j => Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(j), d => d["target"]), Stdlib_JSON.Decode.string), "");
|
|
92
|
+
let dropDirectives = arr => arr.filter(j => targetOf(j) !== "directive");
|
|
93
|
+
let onlyDirectives = arr => arr.filter(j => targetOf(j) === "directive");
|
|
94
|
+
let thenPublishedJson = async (actionsP, expected) => {
|
|
95
|
+
let actual = dropDirectives(await actionsP);
|
|
96
|
+
if (Primitive_object.equal(sortJson(actual), sortJson(expected))) {
|
|
97
|
+
return Outcome$ReventlessGwt.pass;
|
|
98
|
+
} else {
|
|
99
|
+
return Outcome$ReventlessGwt.fail({
|
|
100
|
+
TAG: "PublishedActionsMismatch",
|
|
101
|
+
expected: expected,
|
|
102
|
+
actual: actual
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
let thenPublishesNothing = actionsP => thenPublishedJson(actionsP, []);
|
|
107
|
+
let thenHandlesDirectivesJson = async (actionsP, expected) => {
|
|
108
|
+
let actual = onlyDirectives(await actionsP);
|
|
109
|
+
if (Primitive_object.equal(sortJson(actual), sortJson(expected))) {
|
|
110
|
+
return Outcome$ReventlessGwt.pass;
|
|
111
|
+
} else {
|
|
112
|
+
return Outcome$ReventlessGwt.fail({
|
|
113
|
+
TAG: "PublishedActionsMismatch",
|
|
114
|
+
expected: expected,
|
|
115
|
+
actual: actual
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
let EvCore = {
|
|
120
|
+
describe: JestBind$ReventlessGwt.describe,
|
|
121
|
+
test: test,
|
|
122
|
+
whenInput: whenInput,
|
|
123
|
+
thenPublishedJson: thenPublishedJson,
|
|
124
|
+
thenPublishesNothing: thenPublishesNothing,
|
|
125
|
+
thenHandlesDirectivesJson: thenHandlesDirectivesJson
|
|
126
|
+
};
|
|
127
|
+
let name$1 = M.ExtensionPoint.name;
|
|
128
|
+
let run$1 = async command => Stdlib_Array.filterMap(M.mapIncomingCommand("gwt-id", command, StubRuntime$ReventlessGwt.meta), action => {
|
|
129
|
+
if (action.TAG === "PublishCommand") {
|
|
130
|
+
return encPublished(action._0, Message$ReventlessCore.encode(action._1, M.Delegate.commandSchema));
|
|
131
|
+
} else {
|
|
132
|
+
return encDirective(action._1);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
S.enableJson();
|
|
136
|
+
let test$1 = (name$2, timeout, body) => JestBind$ReventlessGwt.testPromise(name$1, name$2, timeout, body);
|
|
137
|
+
let whenInput$1 = run$1;
|
|
138
|
+
let sortJson$1 = arr => arr.toSorted((a, b) => Primitive_string.compare(JSON.stringify(a), JSON.stringify(b)));
|
|
139
|
+
let targetOf$1 = j => Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(j), d => d["target"]), Stdlib_JSON.Decode.string), "");
|
|
140
|
+
let dropDirectives$1 = arr => arr.filter(j => targetOf$1(j) !== "directive");
|
|
141
|
+
let onlyDirectives$1 = arr => arr.filter(j => targetOf$1(j) === "directive");
|
|
142
|
+
let thenPublishedJson$1 = async (actionsP, expected) => {
|
|
143
|
+
let actual = dropDirectives$1(await actionsP);
|
|
144
|
+
if (Primitive_object.equal(sortJson$1(actual), sortJson$1(expected))) {
|
|
145
|
+
return Outcome$ReventlessGwt.pass;
|
|
146
|
+
} else {
|
|
147
|
+
return Outcome$ReventlessGwt.fail({
|
|
148
|
+
TAG: "PublishedActionsMismatch",
|
|
149
|
+
expected: expected,
|
|
150
|
+
actual: actual
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
let thenPublishesNothing$1 = actionsP => thenPublishedJson$1(actionsP, []);
|
|
155
|
+
let thenHandlesDirectivesJson$1 = async (actionsP, expected) => {
|
|
156
|
+
let actual = onlyDirectives$1(await actionsP);
|
|
157
|
+
if (Primitive_object.equal(sortJson$1(actual), sortJson$1(expected))) {
|
|
158
|
+
return Outcome$ReventlessGwt.pass;
|
|
159
|
+
} else {
|
|
160
|
+
return Outcome$ReventlessGwt.fail({
|
|
161
|
+
TAG: "PublishedActionsMismatch",
|
|
162
|
+
expected: expected,
|
|
163
|
+
actual: actual
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
let CmdCore = {
|
|
168
|
+
describe: JestBind$ReventlessGwt.describe,
|
|
169
|
+
test: test$1,
|
|
170
|
+
whenInput: whenInput$1,
|
|
171
|
+
thenPublishedJson: thenPublishedJson$1,
|
|
172
|
+
thenPublishesNothing: thenPublishesNothing$1,
|
|
173
|
+
thenHandlesDirectivesJson: thenHandlesDirectivesJson$1
|
|
174
|
+
};
|
|
175
|
+
let thenPublishesEvent = (actionsP, id, event) => thenPublishedJson(actionsP, [encPublished(id, Message$ReventlessCore.encode(event, M.ExtensionPoint.eventSchema))]);
|
|
176
|
+
let thenPublishesEvents = (actionsP, pairs) => thenPublishedJson(actionsP, pairs.map(param => encPublished(param[0], Message$ReventlessCore.encode(param[1], M.ExtensionPoint.eventSchema))));
|
|
177
|
+
let thenPublishesCommand = (actionsP, id, cmd) => thenPublishedJson$1(actionsP, [encPublished(id, Message$ReventlessCore.encode(cmd, M.Delegate.commandSchema))]);
|
|
178
|
+
let thenPublishesCommands = (actionsP, pairs) => thenPublishedJson$1(actionsP, pairs.map(param => encPublished(param[0], Message$ReventlessCore.encode(param[1], M.Delegate.commandSchema))));
|
|
179
|
+
let thenHandlesDirective = (actionsP, directive) => thenHandlesDirectivesJson(actionsP, [encDirective(directive)]);
|
|
180
|
+
let thenHandlesDirectives = (actionsP, directives) => thenHandlesDirectivesJson(actionsP, directives.map(encDirective));
|
|
181
|
+
let thenHandlesNoDirective = actionsP => thenHandlesDirectivesJson(actionsP, []);
|
|
182
|
+
return {
|
|
183
|
+
encEvent: encEvent,
|
|
184
|
+
encCommand: encCommand,
|
|
185
|
+
encDirective: encDirective,
|
|
186
|
+
EvCore: EvCore,
|
|
187
|
+
CmdCore: CmdCore,
|
|
188
|
+
describe: JestBind$ReventlessGwt.describe,
|
|
189
|
+
test: test,
|
|
190
|
+
thenPublishesNothing: thenPublishesNothing,
|
|
191
|
+
whenDelegateEvent: whenInput,
|
|
192
|
+
thenPublishesEvent: thenPublishesEvent,
|
|
193
|
+
thenPublishesEvents: thenPublishesEvents,
|
|
194
|
+
whenIncomingCommand: whenInput$1,
|
|
195
|
+
thenPublishesCommand: thenPublishesCommand,
|
|
196
|
+
thenPublishesCommands: thenPublishesCommands,
|
|
197
|
+
thenHandlesDirective: thenHandlesDirective,
|
|
198
|
+
thenHandlesDirectives: thenHandlesDirectives,
|
|
199
|
+
thenHandlesNoDirective: thenHandlesNoDirective
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function FromExtension(M) {
|
|
204
|
+
let encCmd = c => Message$ReventlessCore.encode(c, M.Delegate.commandSchema);
|
|
205
|
+
let encEpCmd = c => Message$ReventlessCore.encode(c, M.ExtensionPoint.commandSchema);
|
|
206
|
+
let encDirective = d => encPublished("directive", Message$ReventlessCore.encode(d, M.ExtensionPoint.directiveSchema));
|
|
207
|
+
let name = M.Delegate.name;
|
|
208
|
+
let run = async event => (await Promise.all(M.mapIncomingEvent("gwt-id", event, StubRuntime$ReventlessGwt.meta, StubRuntime$ReventlessGwt.pluginDefinition, StubRuntime$ReventlessGwt.queryEngine).map(async action => {
|
|
209
|
+
switch (action.TAG) {
|
|
210
|
+
case "PublishAggregateCommand" :
|
|
211
|
+
return [encPublished(action._0, Message$ReventlessCore.encode(action._1, M.Delegate.commandSchema))];
|
|
212
|
+
case "PublishAggregateCommandAsync" :
|
|
213
|
+
let match = await action._0;
|
|
214
|
+
return [encPublished(match[0], Message$ReventlessCore.encode(match[1], M.Delegate.commandSchema))];
|
|
215
|
+
case "PublishAggregateCommandsAsync" :
|
|
216
|
+
return (await action._0).map(param => encPublished(param[0], Message$ReventlessCore.encode(param[1], M.Delegate.commandSchema)));
|
|
217
|
+
case "PublishStateChangeSliceCommand" :
|
|
218
|
+
return [encPublished(M.Delegate.name, Message$ReventlessCore.encode(action._0, M.Delegate.commandSchema))];
|
|
219
|
+
case "PublishStateChangeSliceCommandAsync" :
|
|
220
|
+
let cmd = await action._0;
|
|
221
|
+
return [encPublished(M.Delegate.name, Message$ReventlessCore.encode(cmd, M.Delegate.commandSchema))];
|
|
222
|
+
case "PublishStateChangeSliceCommandsAsync" :
|
|
223
|
+
return (await action._0).map(cmd => encPublished(M.Delegate.name, Message$ReventlessCore.encode(cmd, M.Delegate.commandSchema)));
|
|
224
|
+
case "PublishExtensionPointCommand" :
|
|
225
|
+
return [encPublished(action._0, Message$ReventlessCore.encode(action._1, M.ExtensionPoint.commandSchema))];
|
|
226
|
+
case "ForwardCommand" :
|
|
227
|
+
let match$1 = action._0;
|
|
228
|
+
return [encPublished(match$1.extensionPointName + `:` + match$1.id, match$1.commandJson)];
|
|
229
|
+
case "HandleDirective" :
|
|
230
|
+
return [encDirective(action._1)];
|
|
231
|
+
}
|
|
232
|
+
}))).flat();
|
|
233
|
+
S.enableJson();
|
|
234
|
+
let test = (name$1, timeout, body) => JestBind$ReventlessGwt.testPromise(name, name$1, timeout, body);
|
|
235
|
+
let whenInput = run;
|
|
236
|
+
let sortJson = arr => arr.toSorted((a, b) => Primitive_string.compare(JSON.stringify(a), JSON.stringify(b)));
|
|
237
|
+
let targetOf = j => Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(j), d => d["target"]), Stdlib_JSON.Decode.string), "");
|
|
238
|
+
let dropDirectives = arr => arr.filter(j => targetOf(j) !== "directive");
|
|
239
|
+
let onlyDirectives = arr => arr.filter(j => targetOf(j) === "directive");
|
|
240
|
+
let thenPublishedJson = async (actionsP, expected) => {
|
|
241
|
+
let actual = dropDirectives(await actionsP);
|
|
242
|
+
if (Primitive_object.equal(sortJson(actual), sortJson(expected))) {
|
|
243
|
+
return Outcome$ReventlessGwt.pass;
|
|
244
|
+
} else {
|
|
245
|
+
return Outcome$ReventlessGwt.fail({
|
|
246
|
+
TAG: "PublishedActionsMismatch",
|
|
247
|
+
expected: expected,
|
|
248
|
+
actual: actual
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
let thenPublishesNothing = actionsP => thenPublishedJson(actionsP, []);
|
|
253
|
+
let thenHandlesDirectivesJson = async (actionsP, expected) => {
|
|
254
|
+
let actual = onlyDirectives(await actionsP);
|
|
255
|
+
if (Primitive_object.equal(sortJson(actual), sortJson(expected))) {
|
|
256
|
+
return Outcome$ReventlessGwt.pass;
|
|
257
|
+
} else {
|
|
258
|
+
return Outcome$ReventlessGwt.fail({
|
|
259
|
+
TAG: "PublishedActionsMismatch",
|
|
260
|
+
expected: expected,
|
|
261
|
+
actual: actual
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
let EvCore = {
|
|
266
|
+
describe: JestBind$ReventlessGwt.describe,
|
|
267
|
+
test: test,
|
|
268
|
+
whenInput: whenInput,
|
|
269
|
+
thenPublishedJson: thenPublishedJson,
|
|
270
|
+
thenPublishesNothing: thenPublishesNothing,
|
|
271
|
+
thenHandlesDirectivesJson: thenHandlesDirectivesJson
|
|
272
|
+
};
|
|
273
|
+
let name$1 = M.Delegate.name;
|
|
274
|
+
let run$1 = async event => {
|
|
275
|
+
let f = M.mapOutgoingEvent;
|
|
276
|
+
if (f !== undefined) {
|
|
277
|
+
return Stdlib_Array.filterMap(f("gwt-id", event, StubRuntime$ReventlessGwt.meta, StubRuntime$ReventlessGwt.pluginDefinition), action => {
|
|
278
|
+
switch (action.TAG) {
|
|
279
|
+
case "PublishExtensionPointCommand" :
|
|
280
|
+
return encPublished(action._0, Message$ReventlessCore.encode(action._1, M.ExtensionPoint.commandSchema));
|
|
281
|
+
case "ForwardCommand" :
|
|
282
|
+
let match = action._0;
|
|
283
|
+
return encPublished(match.extensionPointName + `:` + match.id, match.commandJson);
|
|
284
|
+
case "HandleDirective" :
|
|
285
|
+
return encDirective(action._1);
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
} else {
|
|
289
|
+
return [];
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
S.enableJson();
|
|
293
|
+
let test$1 = (name$2, timeout, body) => JestBind$ReventlessGwt.testPromise(name$1, name$2, timeout, body);
|
|
294
|
+
let whenInput$1 = run$1;
|
|
295
|
+
let sortJson$1 = arr => arr.toSorted((a, b) => Primitive_string.compare(JSON.stringify(a), JSON.stringify(b)));
|
|
296
|
+
let targetOf$1 = j => Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(j), d => d["target"]), Stdlib_JSON.Decode.string), "");
|
|
297
|
+
let dropDirectives$1 = arr => arr.filter(j => targetOf$1(j) !== "directive");
|
|
298
|
+
let onlyDirectives$1 = arr => arr.filter(j => targetOf$1(j) === "directive");
|
|
299
|
+
let thenPublishedJson$1 = async (actionsP, expected) => {
|
|
300
|
+
let actual = dropDirectives$1(await actionsP);
|
|
301
|
+
if (Primitive_object.equal(sortJson$1(actual), sortJson$1(expected))) {
|
|
302
|
+
return Outcome$ReventlessGwt.pass;
|
|
303
|
+
} else {
|
|
304
|
+
return Outcome$ReventlessGwt.fail({
|
|
305
|
+
TAG: "PublishedActionsMismatch",
|
|
306
|
+
expected: expected,
|
|
307
|
+
actual: actual
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
let thenPublishesNothing$1 = actionsP => thenPublishedJson$1(actionsP, []);
|
|
312
|
+
let thenHandlesDirectivesJson$1 = async (actionsP, expected) => {
|
|
313
|
+
let actual = onlyDirectives$1(await actionsP);
|
|
314
|
+
if (Primitive_object.equal(sortJson$1(actual), sortJson$1(expected))) {
|
|
315
|
+
return Outcome$ReventlessGwt.pass;
|
|
316
|
+
} else {
|
|
317
|
+
return Outcome$ReventlessGwt.fail({
|
|
318
|
+
TAG: "PublishedActionsMismatch",
|
|
319
|
+
expected: expected,
|
|
320
|
+
actual: actual
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
let OutCore = {
|
|
325
|
+
describe: JestBind$ReventlessGwt.describe,
|
|
326
|
+
test: test$1,
|
|
327
|
+
whenInput: whenInput$1,
|
|
328
|
+
thenPublishedJson: thenPublishedJson$1,
|
|
329
|
+
thenPublishesNothing: thenPublishesNothing$1,
|
|
330
|
+
thenHandlesDirectivesJson: thenHandlesDirectivesJson$1
|
|
331
|
+
};
|
|
332
|
+
let thenPublishesCommand = (actionsP, cmd) => thenPublishedJson(actionsP, [encPublished(M.Delegate.name, Message$ReventlessCore.encode(cmd, M.Delegate.commandSchema))]);
|
|
333
|
+
let thenPublishesCommands = (actionsP, cmds) => thenPublishedJson(actionsP, cmds.map(cmd => encPublished(M.Delegate.name, Message$ReventlessCore.encode(cmd, M.Delegate.commandSchema))));
|
|
334
|
+
let thenPublishesAggregateCommand = (actionsP, id, cmd) => thenPublishedJson(actionsP, [encPublished(id, Message$ReventlessCore.encode(cmd, M.Delegate.commandSchema))]);
|
|
335
|
+
let thenPublishesExtensionPointCommand = (actionsP, id, cmd) => thenPublishedJson$1(actionsP, [encPublished(id, Message$ReventlessCore.encode(cmd, M.ExtensionPoint.commandSchema))]);
|
|
336
|
+
let thenHandlesDirective = (actionsP, directive) => thenHandlesDirectivesJson(actionsP, [encDirective(directive)]);
|
|
337
|
+
let thenHandlesDirectives = (actionsP, directives) => thenHandlesDirectivesJson(actionsP, directives.map(encDirective));
|
|
338
|
+
let thenHandlesNoDirective = actionsP => thenHandlesDirectivesJson(actionsP, []);
|
|
339
|
+
return {
|
|
340
|
+
encCmd: encCmd,
|
|
341
|
+
encEpCmd: encEpCmd,
|
|
342
|
+
encDirective: encDirective,
|
|
343
|
+
EvCore: EvCore,
|
|
344
|
+
OutCore: OutCore,
|
|
345
|
+
describe: JestBind$ReventlessGwt.describe,
|
|
346
|
+
test: test,
|
|
347
|
+
thenPublishesNothing: thenPublishesNothing,
|
|
348
|
+
whenIncomingEvent: whenInput,
|
|
349
|
+
thenPublishesCommand: thenPublishesCommand,
|
|
350
|
+
thenPublishesCommands: thenPublishesCommands,
|
|
351
|
+
thenPublishesAggregateCommand: thenPublishesAggregateCommand,
|
|
352
|
+
whenDelegateEvent: whenInput$1,
|
|
353
|
+
thenPublishesExtensionPointCommand: thenPublishesExtensionPointCommand,
|
|
354
|
+
thenHandlesDirective: thenHandlesDirective,
|
|
355
|
+
thenHandlesDirectives: thenHandlesDirectives,
|
|
356
|
+
thenHandlesNoDirective: thenHandlesNoDirective
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
let EPMapping;
|
|
361
|
+
|
|
362
|
+
let ExtMapping;
|
|
363
|
+
|
|
364
|
+
export {
|
|
365
|
+
EPMapping,
|
|
366
|
+
ExtMapping,
|
|
367
|
+
encPublished,
|
|
368
|
+
Make,
|
|
369
|
+
FromExtensionPoint,
|
|
370
|
+
FromExtension,
|
|
371
|
+
}
|
|
372
|
+
/* S Not a pure module */
|
package/src/Diff.res
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Produces a structural `fieldDiff` for the JSON format (§3.3) and TAP
|
|
2
|
+
// emitters. Walks two JSON values and returns a list of differing leaves
|
|
3
|
+
// as `{path, expected, actual}` entries. Rendered values use
|
|
4
|
+
// `RenderRescript.render` so diff rows read as ReScript, not JSON.
|
|
5
|
+
|
|
6
|
+
type entry = {
|
|
7
|
+
path: string,
|
|
8
|
+
expected: string,
|
|
9
|
+
actual: string,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let joinPath = (prefix, segment) =>
|
|
13
|
+
if prefix == "" {
|
|
14
|
+
segment
|
|
15
|
+
} else {
|
|
16
|
+
prefix ++ "." ++ segment
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let rec walk = (~path="", expected: JSON.t, actual: JSON.t, acc: array<entry>) =>
|
|
20
|
+
switch (expected, actual) {
|
|
21
|
+
| (Object(e), Object(a)) =>
|
|
22
|
+
let keys =
|
|
23
|
+
Array.concat(e->Dict.keysToArray, a->Dict.keysToArray)
|
|
24
|
+
->Array.reduce([], (uniq, k) =>
|
|
25
|
+
if Array.includes(uniq, k) {
|
|
26
|
+
uniq
|
|
27
|
+
} else {
|
|
28
|
+
Array.concat(uniq, [k])
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
keys->Array.reduce(acc, (acc, k) => {
|
|
32
|
+
let childExpected =
|
|
33
|
+
e->Dict.get(k)->Option.getOr(JSON.Encode.null)
|
|
34
|
+
let childActual =
|
|
35
|
+
a->Dict.get(k)->Option.getOr(JSON.Encode.null)
|
|
36
|
+
walk(~path=joinPath(path, k), childExpected, childActual, acc)
|
|
37
|
+
})
|
|
38
|
+
| (Array(e), Array(a)) =>
|
|
39
|
+
let lenE = e->Array.length
|
|
40
|
+
let lenA = a->Array.length
|
|
41
|
+
let len = lenE > lenA ? lenE : lenA
|
|
42
|
+
let rec loop = (i, acc) =>
|
|
43
|
+
if i >= len {
|
|
44
|
+
acc
|
|
45
|
+
} else {
|
|
46
|
+
let childExpected =
|
|
47
|
+
e->Array.get(i)->Option.getOr(JSON.Encode.null)
|
|
48
|
+
let childActual =
|
|
49
|
+
a->Array.get(i)->Option.getOr(JSON.Encode.null)
|
|
50
|
+
let acc = walk(
|
|
51
|
+
~path=joinPath(path, Int.toString(i)),
|
|
52
|
+
childExpected,
|
|
53
|
+
childActual,
|
|
54
|
+
acc,
|
|
55
|
+
)
|
|
56
|
+
loop(i + 1, acc)
|
|
57
|
+
}
|
|
58
|
+
loop(0, acc)
|
|
59
|
+
| _ =>
|
|
60
|
+
if expected == actual {
|
|
61
|
+
acc
|
|
62
|
+
} else {
|
|
63
|
+
Array.concat(
|
|
64
|
+
acc,
|
|
65
|
+
[
|
|
66
|
+
{
|
|
67
|
+
path,
|
|
68
|
+
expected: RenderRescript.render(expected),
|
|
69
|
+
actual: RenderRescript.render(actual),
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let diff = (expected: JSON.t, actual: JSON.t): array<entry> =>
|
|
77
|
+
walk(expected, actual, [])
|
|
78
|
+
|
|
79
|
+
let diffArrays = (expected: array<JSON.t>, actual: array<JSON.t>): array<entry> =>
|
|
80
|
+
walk(JSON.Encode.array(expected), JSON.Encode.array(actual), [])
|
|
81
|
+
|
|
82
|
+
let toJson = (e: entry): JSON.t => {
|
|
83
|
+
let obj = Dict.make()
|
|
84
|
+
obj->Dict.set("path", JSON.Encode.string(e.path))
|
|
85
|
+
obj->Dict.set("expected", JSON.Encode.string(e.expected))
|
|
86
|
+
obj->Dict.set("actual", JSON.Encode.string(e.actual))
|
|
87
|
+
JSON.Encode.object(obj)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let toJsonArray = (entries: array<entry>): JSON.t =>
|
|
91
|
+
entries->Array.map(toJson)->JSON.Encode.array
|
package/src/Diff.res.mjs
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
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 Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
|
|
6
|
+
import * as RenderRescript$ReventlessGwt from "./RenderRescript.res.mjs";
|
|
7
|
+
|
|
8
|
+
function joinPath(prefix, segment) {
|
|
9
|
+
if (prefix === "") {
|
|
10
|
+
return segment;
|
|
11
|
+
} else {
|
|
12
|
+
return prefix + "." + segment;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function walk(pathOpt, expected, actual, acc) {
|
|
17
|
+
let path = pathOpt !== undefined ? pathOpt : "";
|
|
18
|
+
if (Array.isArray(expected)) {
|
|
19
|
+
if (Array.isArray(actual)) {
|
|
20
|
+
let lenE = expected.length;
|
|
21
|
+
let lenA = actual.length;
|
|
22
|
+
let len = lenE > lenA ? lenE : lenA;
|
|
23
|
+
let _i = 0;
|
|
24
|
+
let _acc = acc;
|
|
25
|
+
while (true) {
|
|
26
|
+
let acc$1 = _acc;
|
|
27
|
+
let i = _i;
|
|
28
|
+
if (i >= len) {
|
|
29
|
+
return acc$1;
|
|
30
|
+
}
|
|
31
|
+
let childExpected = Stdlib_Option.getOr(expected[i], null);
|
|
32
|
+
let childActual = Stdlib_Option.getOr(actual[i], null);
|
|
33
|
+
let acc$2 = walk(joinPath(path, i.toString()), childExpected, childActual, acc$1);
|
|
34
|
+
_acc = acc$2;
|
|
35
|
+
_i = i + 1 | 0;
|
|
36
|
+
continue;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
} else if (expected !== null) {
|
|
40
|
+
switch (typeof expected) {
|
|
41
|
+
case "object" :
|
|
42
|
+
if (typeof actual === "object" && actual !== null && !Array.isArray(actual)) {
|
|
43
|
+
let keys = Stdlib_Array.reduce(Object.keys(expected).concat(Object.keys(actual)), [], (uniq, k) => {
|
|
44
|
+
if (uniq.includes(k)) {
|
|
45
|
+
return uniq;
|
|
46
|
+
} else {
|
|
47
|
+
return uniq.concat([k]);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return Stdlib_Array.reduce(keys, acc, (acc, k) => {
|
|
51
|
+
let childExpected = Stdlib_Option.getOr(expected[k], null);
|
|
52
|
+
let childActual = Stdlib_Option.getOr(actual[k], null);
|
|
53
|
+
return walk(joinPath(path, k), childExpected, childActual, acc);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (Primitive_object.equal(expected, actual)) {
|
|
60
|
+
return acc;
|
|
61
|
+
} else {
|
|
62
|
+
return acc.concat([{
|
|
63
|
+
path: path,
|
|
64
|
+
expected: RenderRescript$ReventlessGwt.render(undefined, expected),
|
|
65
|
+
actual: RenderRescript$ReventlessGwt.render(undefined, actual)
|
|
66
|
+
}]);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function diff(expected, actual) {
|
|
71
|
+
return walk(undefined, expected, actual, []);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function diffArrays(expected, actual) {
|
|
75
|
+
return walk(undefined, expected, actual, []);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function toJson(e) {
|
|
79
|
+
let obj = {};
|
|
80
|
+
obj["path"] = e.path;
|
|
81
|
+
obj["expected"] = e.expected;
|
|
82
|
+
obj["actual"] = e.actual;
|
|
83
|
+
return obj;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function toJsonArray(entries) {
|
|
87
|
+
return entries.map(toJson);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export {
|
|
91
|
+
joinPath,
|
|
92
|
+
walk,
|
|
93
|
+
diff,
|
|
94
|
+
diffArrays,
|
|
95
|
+
toJson,
|
|
96
|
+
toJsonArray,
|
|
97
|
+
}
|
|
98
|
+
/* No side effect */
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// Walks a directory tree and returns absolute paths of compiled GWT test
|
|
2
|
+
// files (`*_GWT.res.mjs` plus `*GwtTest.res.mjs` — the two shapes used in
|
|
3
|
+
// the monorepo today). Respects a minimal ignore set (`node_modules`,
|
|
4
|
+
// `lib`, `.git`, `dist`, `.history`). Pruning `lib` covers compiled
|
|
5
|
+
// `lib/bs` / `lib/ocaml` outputs. Full `.gitignore` parsing is out of scope;
|
|
6
|
+
// the ignore set is enough to make a bare cwd scan (the auto-discovery
|
|
7
|
+
// default) cheap and correct across a multi-package workspace.
|
|
8
|
+
|
|
9
|
+
type dirent = {
|
|
10
|
+
name: string,
|
|
11
|
+
@as("isDirectory") _isDirectory: unit => bool,
|
|
12
|
+
@as("isFile") _isFile: unit => bool,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type readdirOpts = {withFileTypes: bool}
|
|
16
|
+
|
|
17
|
+
@module("node:fs/promises")
|
|
18
|
+
external _readdir: (string, readdirOpts) => promise<array<dirent>> = "readdir"
|
|
19
|
+
|
|
20
|
+
type stats = {
|
|
21
|
+
@as("isDirectory") _isDirectory: unit => bool,
|
|
22
|
+
@as("isFile") _isFile: unit => bool,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@module("node:fs/promises") external _stat: string => promise<stats> = "stat"
|
|
26
|
+
|
|
27
|
+
@module("node:path") external join: (string, string) => string = "join"
|
|
28
|
+
@module("node:path") external isAbsolute: string => bool = "isAbsolute"
|
|
29
|
+
@module("node:path") external resolve: string => string = "resolve"
|
|
30
|
+
|
|
31
|
+
let ignoreNames = ["node_modules", ".git", "dist", "lib", ".history"]
|
|
32
|
+
let shouldIgnore = (name: string) => Array.includes(ignoreNames, name)
|
|
33
|
+
|
|
34
|
+
// A directory carrying this sentinel file — and its whole subtree — is pruned
|
|
35
|
+
// from discovery. Unlike the `ignoreNames` dir-name list, this is filesystem
|
|
36
|
+
// state, so it excludes generated/vendored trees (e.g. codegen golden fixtures)
|
|
37
|
+
// even when compiled `*_GWT.res.mjs` are present on disk.
|
|
38
|
+
let gwtIgnoreFile = ".gwtignore"
|
|
39
|
+
let isPruned = (entries: array<dirent>) => entries->Array.some(e => e.name == gwtIgnoreFile)
|
|
40
|
+
|
|
41
|
+
let isGwtTestFile = (name: string) =>
|
|
42
|
+
String.endsWith(name, "_GWT.res.mjs") ||
|
|
43
|
+
String.endsWith(name, "GwtTest.res.mjs") ||
|
|
44
|
+
String.endsWith(name, "Gwt.res.mjs")
|
|
45
|
+
|
|
46
|
+
// Depth-first, pushing into a shared accumulator instead of rebuilding it with
|
|
47
|
+
// `Array.concat` per entry (which was O(n²) over a large tree). The traversal
|
|
48
|
+
// order is unchanged: files and nested subtree results still land in on-disk
|
|
49
|
+
// entry order.
|
|
50
|
+
let rec walk = async (dir: string, acc: array<string>): unit => {
|
|
51
|
+
let entries = try {
|
|
52
|
+
await _readdir(dir, {withFileTypes: true})
|
|
53
|
+
} catch {
|
|
54
|
+
| _ => []
|
|
55
|
+
}
|
|
56
|
+
if isPruned(entries) {
|
|
57
|
+
()
|
|
58
|
+
} else {
|
|
59
|
+
for i in 0 to entries->Array.length - 1 {
|
|
60
|
+
let entry = entries->Array.getUnsafe(i)
|
|
61
|
+
if !shouldIgnore(entry.name) {
|
|
62
|
+
let full = join(dir, entry.name)
|
|
63
|
+
if entry._isDirectory() {
|
|
64
|
+
await walk(full, acc)
|
|
65
|
+
} else if entry._isFile() && isGwtTestFile(entry.name) {
|
|
66
|
+
acc->Array.push(full)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Returns absolute paths of `*GWT*.res.mjs` test files reachable from the
|
|
74
|
+
// supplied roots. A root may be a directory or a single file.
|
|
75
|
+
let discover = async (roots: array<string>): array<string> => {
|
|
76
|
+
let found = []
|
|
77
|
+
for i in 0 to roots->Array.length - 1 {
|
|
78
|
+
let root = roots->Array.getUnsafe(i)
|
|
79
|
+
let absolute = isAbsolute(root) ? root : resolve(root)
|
|
80
|
+
let isDir = try {
|
|
81
|
+
let s = await _stat(absolute)
|
|
82
|
+
s._isDirectory()
|
|
83
|
+
} catch {
|
|
84
|
+
| _ => false
|
|
85
|
+
}
|
|
86
|
+
if isDir {
|
|
87
|
+
await walk(absolute, found)
|
|
88
|
+
} else if isGwtTestFile(absolute) {
|
|
89
|
+
found->Array.push(absolute)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Deduplicate (if roots overlap).
|
|
93
|
+
let seen = Dict.make()
|
|
94
|
+
let unique = []
|
|
95
|
+
found->Array.forEach(path =>
|
|
96
|
+
switch seen->Dict.get(path) {
|
|
97
|
+
| Some(_) => ()
|
|
98
|
+
| None => {
|
|
99
|
+
seen->Dict.set(path, true)
|
|
100
|
+
unique->Array.push(path)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
unique
|
|
105
|
+
}
|