@sdeverywhere/check-core 0.1.0 → 0.1.2
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/README.md +28 -2
- package/dist/index.cjs +2071 -710
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1272 -0
- package/dist/index.d.ts +672 -307
- package/dist/index.js +2059 -696
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
- package/schema/comparison.schema.json +456 -0
package/dist/index.js
CHANGED
|
@@ -17,84 +17,38 @@ var __spreadValues = (a, b) => {
|
|
|
17
17
|
return a;
|
|
18
18
|
};
|
|
19
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
key,
|
|
41
|
-
groupKey,
|
|
42
|
-
settings
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
function inputAtPositionScenario(inputVarId, groupKey, position) {
|
|
46
|
-
const key = keyForInputAtPosition(`input${inputVarId}`, position);
|
|
47
|
-
return settingsScenario(key, groupKey, [positionSetting(inputVarId, position)]);
|
|
48
|
-
}
|
|
49
|
-
function inputAtValueScenario(inputVarId, groupKey, value) {
|
|
50
|
-
const key = keyForInputAtValue(`input${inputVarId}`, value);
|
|
51
|
-
return settingsScenario(key, groupKey, [valueSetting(inputVarId, value)]);
|
|
52
|
-
}
|
|
53
|
-
function allInputsAtPositionScenario(position) {
|
|
54
|
-
return {
|
|
55
|
-
kind: "all-inputs",
|
|
56
|
-
key: keyForInputAtPosition("all_inputs", position),
|
|
57
|
-
groupKey: "all_inputs",
|
|
58
|
-
position
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
function matrixScenarios(inputVarIds) {
|
|
62
|
-
const scenarios = [];
|
|
63
|
-
scenarios.push(allInputsAtPositionScenario("at-default"));
|
|
64
|
-
scenarios.push(allInputsAtPositionScenario("at-minimum"));
|
|
65
|
-
scenarios.push(allInputsAtPositionScenario("at-maximum"));
|
|
66
|
-
for (const inputVarId of inputVarIds) {
|
|
67
|
-
scenarios.push(inputAtPositionScenario(inputVarId, inputVarId, "at-minimum"));
|
|
68
|
-
scenarios.push(inputAtPositionScenario(inputVarId, inputVarId, "at-maximum"));
|
|
69
|
-
}
|
|
70
|
-
return scenarios;
|
|
71
|
-
}
|
|
72
|
-
function keyForInputPosition(position) {
|
|
73
|
-
switch (position) {
|
|
74
|
-
case "at-default":
|
|
75
|
-
return "default";
|
|
76
|
-
case "at-minimum":
|
|
77
|
-
return "min";
|
|
78
|
-
case "at-maximum":
|
|
79
|
-
return "max";
|
|
80
|
-
default:
|
|
81
|
-
assertNever(position);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
function keyForInputAtPosition(inputKey, position) {
|
|
85
|
-
return `${inputKey}_at_${keyForInputPosition(position)}`;
|
|
86
|
-
}
|
|
87
|
-
function keyForInputAtValue(inputKey, value) {
|
|
88
|
-
return `${inputKey}_at_${value}`;
|
|
89
|
-
}
|
|
20
|
+
var __async = (__this, __arguments, generator) => {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
var fulfilled = (value) => {
|
|
23
|
+
try {
|
|
24
|
+
step(generator.next(value));
|
|
25
|
+
} catch (e) {
|
|
26
|
+
reject(e);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var rejected = (value) => {
|
|
30
|
+
try {
|
|
31
|
+
step(generator.throw(value));
|
|
32
|
+
} catch (e) {
|
|
33
|
+
reject(e);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
37
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
38
|
+
});
|
|
39
|
+
};
|
|
90
40
|
|
|
91
41
|
// src/_shared/task-queue.ts
|
|
92
42
|
var TaskQueue = class {
|
|
93
43
|
constructor(processor) {
|
|
94
44
|
this.processor = processor;
|
|
45
|
+
/** The queue of task keys, most recent at front. */
|
|
95
46
|
this.taskKeyQueue = [];
|
|
47
|
+
/** The map of tasks. */
|
|
96
48
|
this.taskMap = /* @__PURE__ */ new Map();
|
|
49
|
+
/** Whether tasks are being processed. */
|
|
97
50
|
this.processing = false;
|
|
51
|
+
/** Whether `shutdown` has been called. */
|
|
98
52
|
this.stopped = false;
|
|
99
53
|
}
|
|
100
54
|
addTask(key, input, onComplete) {
|
|
@@ -132,39 +86,41 @@ var TaskQueue = class {
|
|
|
132
86
|
});
|
|
133
87
|
}
|
|
134
88
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const task = this.taskMap.get(taskKey);
|
|
142
|
-
if (task) {
|
|
143
|
-
this.taskMap.delete(taskKey);
|
|
144
|
-
} else {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
let output;
|
|
148
|
-
try {
|
|
149
|
-
output = await this.processor.process(task.input);
|
|
150
|
-
} catch (e) {
|
|
151
|
-
if (!this.stopped) {
|
|
152
|
-
this.shutdown();
|
|
153
|
-
(_a = this.onIdle) == null ? void 0 : _a.call(this, e);
|
|
89
|
+
processNextTask() {
|
|
90
|
+
return __async(this, null, function* () {
|
|
91
|
+
var _a, _b;
|
|
92
|
+
const taskKey = this.taskKeyQueue.shift();
|
|
93
|
+
if (!taskKey) {
|
|
94
|
+
return;
|
|
154
95
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
this.processNextTask();
|
|
161
|
-
});
|
|
162
|
-
} else {
|
|
163
|
-
this.processing = false;
|
|
164
|
-
if (!this.stopped) {
|
|
165
|
-
(_b = this.onIdle) == null ? void 0 : _b.call(this);
|
|
96
|
+
const task = this.taskMap.get(taskKey);
|
|
97
|
+
if (task) {
|
|
98
|
+
this.taskMap.delete(taskKey);
|
|
99
|
+
} else {
|
|
100
|
+
return;
|
|
166
101
|
}
|
|
167
|
-
|
|
102
|
+
let output;
|
|
103
|
+
try {
|
|
104
|
+
output = yield this.processor.process(task.input);
|
|
105
|
+
} catch (e) {
|
|
106
|
+
if (!this.stopped) {
|
|
107
|
+
this.shutdown();
|
|
108
|
+
(_a = this.onIdle) == null ? void 0 : _a.call(this, e);
|
|
109
|
+
}
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
task.onComplete(output);
|
|
113
|
+
if (this.taskKeyQueue.length > 0) {
|
|
114
|
+
setTimeout(() => {
|
|
115
|
+
this.processNextTask();
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
this.processing = false;
|
|
119
|
+
if (!this.stopped) {
|
|
120
|
+
(_b = this.onIdle) == null ? void 0 : _b.call(this);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
168
124
|
}
|
|
169
125
|
};
|
|
170
126
|
|
|
@@ -173,18 +129,18 @@ var CheckDataCoordinator = class {
|
|
|
173
129
|
constructor(bundleModel) {
|
|
174
130
|
this.bundleModel = bundleModel;
|
|
175
131
|
this.taskQueue = new TaskQueue({
|
|
176
|
-
process:
|
|
177
|
-
const result =
|
|
132
|
+
process: (request) => __async(this, null, function* () {
|
|
133
|
+
const result = yield this.bundleModel.getDatasetsForScenario(request.scenarioSpec, [request.datasetKey]);
|
|
178
134
|
const dataset = result.datasetMap.get(request.datasetKey);
|
|
179
135
|
return {
|
|
180
136
|
dataset
|
|
181
137
|
};
|
|
182
|
-
}
|
|
138
|
+
})
|
|
183
139
|
});
|
|
184
140
|
}
|
|
185
|
-
requestDataset(requestKey,
|
|
141
|
+
requestDataset(requestKey, scenarioSpec, datasetKey, onResponse) {
|
|
186
142
|
const request = {
|
|
187
|
-
|
|
143
|
+
scenarioSpec,
|
|
188
144
|
datasetKey
|
|
189
145
|
};
|
|
190
146
|
this.taskQueue.addTask(requestKey, request, (response) => {
|
|
@@ -197,10 +153,10 @@ var CheckDataCoordinator = class {
|
|
|
197
153
|
};
|
|
198
154
|
|
|
199
155
|
// src/check/check-report.ts
|
|
200
|
-
import
|
|
156
|
+
import assertNever2 from "assert-never";
|
|
201
157
|
|
|
202
158
|
// src/check/check-predicate.ts
|
|
203
|
-
import
|
|
159
|
+
import assertNever from "assert-never";
|
|
204
160
|
function symbolForPredicateOp(op) {
|
|
205
161
|
switch (op) {
|
|
206
162
|
case "gt":
|
|
@@ -216,7 +172,7 @@ function symbolForPredicateOp(op) {
|
|
|
216
172
|
case "approx":
|
|
217
173
|
return "\u2248";
|
|
218
174
|
default:
|
|
219
|
-
|
|
175
|
+
assertNever(op);
|
|
220
176
|
}
|
|
221
177
|
}
|
|
222
178
|
|
|
@@ -230,7 +186,7 @@ function buildCheckReport(checkPlan, checkResults) {
|
|
|
230
186
|
const scenarioReports = [];
|
|
231
187
|
for (const scenarioPlan of testPlan.scenarios) {
|
|
232
188
|
let scenarioStatus = "passed";
|
|
233
|
-
if (scenarioPlan.checkScenario.
|
|
189
|
+
if (scenarioPlan.checkScenario.spec === void 0) {
|
|
234
190
|
testStatus = "error";
|
|
235
191
|
scenarioStatus = "error";
|
|
236
192
|
}
|
|
@@ -327,14 +283,14 @@ function predicateReport(predicatePlan, checkKey, result) {
|
|
|
327
283
|
};
|
|
328
284
|
opRef = opDataRef;
|
|
329
285
|
opValue = `${sym} '${dataRef.dataset.name}'`;
|
|
330
|
-
const
|
|
331
|
-
if (!
|
|
286
|
+
const refScenarioSpec = (_b = dataRef.scenario) == null ? void 0 : _b.spec;
|
|
287
|
+
if (!refScenarioSpec) {
|
|
332
288
|
return;
|
|
333
289
|
}
|
|
334
290
|
if (predOp.scenario === "inherit") {
|
|
335
291
|
opValue += ` (w/ same scenario)`;
|
|
336
292
|
} else {
|
|
337
|
-
if (
|
|
293
|
+
if (refScenarioSpec.kind === "all-inputs" && refScenarioSpec.position === "at-default") {
|
|
338
294
|
opValue += ` (w/ default scenario)`;
|
|
339
295
|
} else {
|
|
340
296
|
opValue += ` (w/ configured scenario)`;
|
|
@@ -369,7 +325,7 @@ function predicateReport(predicatePlan, checkKey, result) {
|
|
|
369
325
|
}
|
|
370
326
|
function scenarioMessage(scenario, bold) {
|
|
371
327
|
const checkScenario = scenario.checkScenario;
|
|
372
|
-
if (checkScenario.
|
|
328
|
+
if (checkScenario.spec === void 0) {
|
|
373
329
|
if (checkScenario.error) {
|
|
374
330
|
switch (checkScenario.error.kind) {
|
|
375
331
|
case "unknown-input-group":
|
|
@@ -377,7 +333,7 @@ function scenarioMessage(scenario, bold) {
|
|
|
377
333
|
case "empty-input-group":
|
|
378
334
|
return `error: input group ${bold(checkScenario.error.name)} is empty`;
|
|
379
335
|
default:
|
|
380
|
-
|
|
336
|
+
assertNever2(checkScenario.error.kind);
|
|
381
337
|
}
|
|
382
338
|
} else {
|
|
383
339
|
const badInputNames = checkScenario.inputDescs.filter((d) => d.inputVar === void 0).map((d) => bold(d.name));
|
|
@@ -394,7 +350,7 @@ function scenarioMessage(scenario, bold) {
|
|
|
394
350
|
case "at-maximum":
|
|
395
351
|
return "maximum";
|
|
396
352
|
default:
|
|
397
|
-
|
|
353
|
+
assertNever2(position);
|
|
398
354
|
}
|
|
399
355
|
}
|
|
400
356
|
function inputMessage(inputDesc) {
|
|
@@ -409,13 +365,13 @@ function scenarioMessage(scenario, bold) {
|
|
|
409
365
|
}
|
|
410
366
|
return msg;
|
|
411
367
|
}
|
|
412
|
-
if (checkScenario.
|
|
413
|
-
const position = checkScenario.
|
|
368
|
+
if (checkScenario.spec.kind === "all-inputs") {
|
|
369
|
+
const position = checkScenario.spec.position;
|
|
414
370
|
return `when ${bold("all inputs")} are at ${bold(positionName(position))}...`;
|
|
415
371
|
} else if (checkScenario.inputGroupName) {
|
|
416
372
|
let position = "at-default";
|
|
417
|
-
if (checkScenario.
|
|
418
|
-
position = checkScenario.
|
|
373
|
+
if (checkScenario.spec.settings[0].kind === "position") {
|
|
374
|
+
position = checkScenario.spec.settings[0].position;
|
|
419
375
|
}
|
|
420
376
|
const groupName = checkScenario.inputGroupName;
|
|
421
377
|
return `when all inputs in ${bold(groupName)} are at ${bold(positionName(position))}...`;
|
|
@@ -448,7 +404,7 @@ function predicateMessage(predicate, bold) {
|
|
|
448
404
|
case "empty-input-group":
|
|
449
405
|
return `error: referenced input group ${bold(result.errorInfo.name)} is empty`;
|
|
450
406
|
default:
|
|
451
|
-
|
|
407
|
+
assertNever2(result.errorInfo.kind);
|
|
452
408
|
}
|
|
453
409
|
} else {
|
|
454
410
|
return `unknown error`;
|
|
@@ -1019,7 +975,7 @@ function parseTestYaml(yamlStrings) {
|
|
|
1019
975
|
groups.push(group);
|
|
1020
976
|
}
|
|
1021
977
|
} else {
|
|
1022
|
-
let msg = "Failed to parse YAML
|
|
978
|
+
let msg = "Failed to parse YAML check definitions";
|
|
1023
979
|
for (const error of validate.errors || []) {
|
|
1024
980
|
if (error.message) {
|
|
1025
981
|
msg += `
|
|
@@ -1193,9 +1149,12 @@ function actionForPredicate(predicateSpec) {
|
|
|
1193
1149
|
|
|
1194
1150
|
// src/_shared/combo.ts
|
|
1195
1151
|
function cartesianProductOf(arr) {
|
|
1196
|
-
return arr.reduce(
|
|
1197
|
-
|
|
1198
|
-
|
|
1152
|
+
return arr.reduce(
|
|
1153
|
+
(a, b) => {
|
|
1154
|
+
return a.map((x) => b.map((y) => x.concat([y]))).reduce((v, w) => v.concat(w), []);
|
|
1155
|
+
},
|
|
1156
|
+
[[]]
|
|
1157
|
+
);
|
|
1199
1158
|
}
|
|
1200
1159
|
|
|
1201
1160
|
// src/check/check-dataset.ts
|
|
@@ -1286,14 +1245,16 @@ function matchByName(modelSpec, datasetName, datasetSource) {
|
|
|
1286
1245
|
};
|
|
1287
1246
|
}
|
|
1288
1247
|
function matchByGroup(modelSpec, groupName) {
|
|
1289
|
-
const groupToMatch = groupName.toLowerCase();
|
|
1290
1248
|
let matchedGroupName;
|
|
1291
1249
|
let matchedGroupDatasetKeys;
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1250
|
+
if (modelSpec.datasetGroups) {
|
|
1251
|
+
const groupToMatch = groupName.toLowerCase();
|
|
1252
|
+
for (const [group, datasetKeys] of modelSpec.datasetGroups) {
|
|
1253
|
+
if (group.toLowerCase() === groupToMatch) {
|
|
1254
|
+
matchedGroupName = group;
|
|
1255
|
+
matchedGroupDatasetKeys = datasetKeys;
|
|
1256
|
+
break;
|
|
1257
|
+
}
|
|
1297
1258
|
}
|
|
1298
1259
|
}
|
|
1299
1260
|
if (matchedGroupName === void 0) {
|
|
@@ -1370,6 +1331,65 @@ function matchByType(modelSpec, varTypeToMatch) {
|
|
|
1370
1331
|
|
|
1371
1332
|
// src/check/check-scenario.ts
|
|
1372
1333
|
import assertNever4 from "assert-never";
|
|
1334
|
+
|
|
1335
|
+
// src/_shared/scenario-specs.ts
|
|
1336
|
+
import { assertNever as assertNever3 } from "assert-never";
|
|
1337
|
+
function positionSetting(inputVarId, position) {
|
|
1338
|
+
return {
|
|
1339
|
+
kind: "position",
|
|
1340
|
+
inputVarId,
|
|
1341
|
+
position
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
function valueSetting(inputVarId, value) {
|
|
1345
|
+
return {
|
|
1346
|
+
kind: "value",
|
|
1347
|
+
inputVarId,
|
|
1348
|
+
value
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
function inputSettingsSpec(settings) {
|
|
1352
|
+
const uidParts = settings.map((setting) => {
|
|
1353
|
+
switch (setting.kind) {
|
|
1354
|
+
case "position":
|
|
1355
|
+
return `${setting.inputVarId}_at_${keyForInputPosition(setting.position)}`;
|
|
1356
|
+
case "value":
|
|
1357
|
+
return `${setting.inputVarId}_at_${setting.value}`;
|
|
1358
|
+
default:
|
|
1359
|
+
assertNever3(setting);
|
|
1360
|
+
}
|
|
1361
|
+
});
|
|
1362
|
+
const uid = `inputs_${uidParts.sort().join("_")}`;
|
|
1363
|
+
return {
|
|
1364
|
+
kind: "input-settings",
|
|
1365
|
+
uid,
|
|
1366
|
+
settings
|
|
1367
|
+
};
|
|
1368
|
+
}
|
|
1369
|
+
function inputAtPositionSpec(inputVarId, position) {
|
|
1370
|
+
return inputSettingsSpec([positionSetting(inputVarId, position)]);
|
|
1371
|
+
}
|
|
1372
|
+
function allInputsAtPositionSpec(position) {
|
|
1373
|
+
return {
|
|
1374
|
+
kind: "all-inputs",
|
|
1375
|
+
uid: `all_inputs_at_${keyForInputPosition(position)}`,
|
|
1376
|
+
position
|
|
1377
|
+
};
|
|
1378
|
+
}
|
|
1379
|
+
function keyForInputPosition(position) {
|
|
1380
|
+
switch (position) {
|
|
1381
|
+
case "at-default":
|
|
1382
|
+
return "default";
|
|
1383
|
+
case "at-minimum":
|
|
1384
|
+
return "min";
|
|
1385
|
+
case "at-maximum":
|
|
1386
|
+
return "max";
|
|
1387
|
+
default:
|
|
1388
|
+
assertNever3(position);
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
// src/check/check-scenario.ts
|
|
1373
1393
|
function expandScenarios(modelSpec, scenarioSpecs, simplify) {
|
|
1374
1394
|
if (scenarioSpecs.length === 0) {
|
|
1375
1395
|
const scenarioSpec = {
|
|
@@ -1446,10 +1466,12 @@ function inputDescForName(modelSpec, inputName, at) {
|
|
|
1446
1466
|
}
|
|
1447
1467
|
}
|
|
1448
1468
|
function groupForName(modelSpec, groupName) {
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1469
|
+
if (modelSpec.inputGroups) {
|
|
1470
|
+
const groupToMatch = groupName.toLowerCase();
|
|
1471
|
+
for (const [group, inputVars] of modelSpec.inputGroups) {
|
|
1472
|
+
if (group.toLowerCase() === groupToMatch) {
|
|
1473
|
+
return [group, inputVars];
|
|
1474
|
+
}
|
|
1453
1475
|
}
|
|
1454
1476
|
}
|
|
1455
1477
|
return void 0;
|
|
@@ -1464,56 +1486,35 @@ function errorScenarioForInputGroup(kind, groupName) {
|
|
|
1464
1486
|
};
|
|
1465
1487
|
}
|
|
1466
1488
|
function checkScenarioWithAllInputsAtPosition(position) {
|
|
1467
|
-
const scenario = allInputsAtPositionScenario(position);
|
|
1468
1489
|
return {
|
|
1469
|
-
|
|
1490
|
+
spec: allInputsAtPositionSpec(position),
|
|
1470
1491
|
inputDescs: []
|
|
1471
1492
|
};
|
|
1472
1493
|
}
|
|
1473
1494
|
function checkScenarioWithInputAtPosition(inputVar, position) {
|
|
1474
1495
|
const varId = inputVar.varId;
|
|
1475
|
-
const scenario = inputAtPositionScenario(varId, varId, position);
|
|
1476
1496
|
return {
|
|
1477
|
-
|
|
1497
|
+
spec: inputAtPositionSpec(varId, position),
|
|
1478
1498
|
inputDescs: [inputDescAtPosition(inputVar, position)]
|
|
1479
1499
|
};
|
|
1480
1500
|
}
|
|
1481
1501
|
function checkScenarioForInputDescs(groupName, inputDescs) {
|
|
1482
|
-
let
|
|
1502
|
+
let spec;
|
|
1483
1503
|
if (inputDescs.every((desc) => desc.inputVar !== void 0)) {
|
|
1484
|
-
const settings =
|
|
1485
|
-
const keyParts = [];
|
|
1486
|
-
for (const inputDesc of inputDescs) {
|
|
1504
|
+
const settings = inputDescs.map((inputDesc) => {
|
|
1487
1505
|
const varId = inputDesc.inputVar.varId;
|
|
1488
1506
|
if (inputDesc.position) {
|
|
1489
|
-
|
|
1490
|
-
keyParts.push(keyForInputAtPosition(varId, inputDesc.position));
|
|
1491
|
-
} else {
|
|
1492
|
-
settings.push(valueSetting(varId, inputDesc.value));
|
|
1493
|
-
keyParts.push(keyForInputAtValue(varId, inputDesc.value));
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
1496
|
-
if (settings.length === 1) {
|
|
1497
|
-
const scenarioKey = `input${keyParts[0]}`;
|
|
1498
|
-
const groupKey = settings[0].inputVarId;
|
|
1499
|
-
scenario = settingsScenario(scenarioKey, groupKey, settings);
|
|
1500
|
-
} else if (settings.length > 1) {
|
|
1501
|
-
let scenarioKey;
|
|
1502
|
-
let groupKey;
|
|
1503
|
-
if (groupName) {
|
|
1504
|
-
scenarioKey = `group_${groupName.toLowerCase().replace(/ /g, "_")}`;
|
|
1505
|
-
groupKey = scenarioKey;
|
|
1507
|
+
return positionSetting(varId, inputDesc.position);
|
|
1506
1508
|
} else {
|
|
1507
|
-
|
|
1508
|
-
groupKey = scenarioKey;
|
|
1509
|
+
return valueSetting(varId, inputDesc.value);
|
|
1509
1510
|
}
|
|
1510
|
-
|
|
1511
|
-
|
|
1511
|
+
});
|
|
1512
|
+
spec = inputSettingsSpec(settings);
|
|
1512
1513
|
} else {
|
|
1513
|
-
|
|
1514
|
+
spec = void 0;
|
|
1514
1515
|
}
|
|
1515
1516
|
return {
|
|
1516
|
-
|
|
1517
|
+
spec,
|
|
1517
1518
|
inputGroupName: groupName,
|
|
1518
1519
|
inputDescs
|
|
1519
1520
|
};
|
|
@@ -1627,7 +1628,7 @@ var CheckPlanner = class {
|
|
|
1627
1628
|
}
|
|
1628
1629
|
const planScenarios = [];
|
|
1629
1630
|
for (const checkScenario of checkScenarios) {
|
|
1630
|
-
if (checkScenario.
|
|
1631
|
+
if (checkScenario.spec === void 0) {
|
|
1631
1632
|
planScenarios.push({
|
|
1632
1633
|
checkScenario,
|
|
1633
1634
|
datasets: []
|
|
@@ -1687,6 +1688,24 @@ var CheckPlanner = class {
|
|
|
1687
1688
|
dataRefs: this.dataRefs
|
|
1688
1689
|
};
|
|
1689
1690
|
}
|
|
1691
|
+
/**
|
|
1692
|
+
* Record any references to additional datasets contained in the given predicate.
|
|
1693
|
+
* For example, if the predicate is:
|
|
1694
|
+
* ```
|
|
1695
|
+
* gt:
|
|
1696
|
+
* dataset:
|
|
1697
|
+
* name: 'XYZ'
|
|
1698
|
+
* scenario:
|
|
1699
|
+
* inputs: all
|
|
1700
|
+
* at: default
|
|
1701
|
+
* ```
|
|
1702
|
+
* this will add a reference to the scenario/dataset pair so that the data can
|
|
1703
|
+
* be fetched in a later stage.
|
|
1704
|
+
*
|
|
1705
|
+
* @param predicateSpec The predicate spec.
|
|
1706
|
+
* @param checkScenario The scenario in which the dataset is being checked.
|
|
1707
|
+
* @param checkDataset The dataset that is being checked.
|
|
1708
|
+
*/
|
|
1690
1709
|
addDataRefs(predicateSpec, checkScenario, checkDataset) {
|
|
1691
1710
|
let dataRefs;
|
|
1692
1711
|
const addDataRef = (op) => {
|
|
@@ -1736,8 +1755,8 @@ var CheckPlanner = class {
|
|
|
1736
1755
|
}
|
|
1737
1756
|
}
|
|
1738
1757
|
let dataRefKey;
|
|
1739
|
-
if (refScenario.
|
|
1740
|
-
dataRefKey = `${refScenario.
|
|
1758
|
+
if (refScenario.spec && refDataset.datasetKey) {
|
|
1759
|
+
dataRefKey = `${refScenario.spec.uid}::${refDataset.datasetKey}`;
|
|
1741
1760
|
}
|
|
1742
1761
|
const dataRef = {
|
|
1743
1762
|
key: dataRefKey,
|
|
@@ -1792,14 +1811,14 @@ function checkSummaryFromReport(checkReport) {
|
|
|
1792
1811
|
predicateSummaries
|
|
1793
1812
|
};
|
|
1794
1813
|
}
|
|
1795
|
-
function checkReportFromSummary(checkConfig, checkSummary
|
|
1814
|
+
function checkReportFromSummary(checkConfig, checkSummary) {
|
|
1796
1815
|
const checkSpecResult = parseTestYaml(checkConfig.tests);
|
|
1797
1816
|
if (checkSpecResult.isErr()) {
|
|
1798
1817
|
return void 0;
|
|
1799
1818
|
}
|
|
1800
1819
|
const checkSpec = checkSpecResult.value;
|
|
1801
1820
|
const checkPlanner = new CheckPlanner(checkConfig.bundle.model.modelSpec);
|
|
1802
|
-
checkPlanner.addAllChecks(checkSpec,
|
|
1821
|
+
checkPlanner.addAllChecks(checkSpec, false);
|
|
1803
1822
|
const checkPlan = checkPlanner.buildPlan();
|
|
1804
1823
|
const checkResults = /* @__PURE__ */ new Map();
|
|
1805
1824
|
for (const predicateSummary of checkSummary.predicateSummaries) {
|
|
@@ -1808,44 +1827,74 @@ function checkReportFromSummary(checkConfig, checkSummary, simplifyScenarios) {
|
|
|
1808
1827
|
return buildCheckReport(checkPlan, checkResults);
|
|
1809
1828
|
}
|
|
1810
1829
|
|
|
1811
|
-
// src/
|
|
1830
|
+
// src/comparison/run/comparison-data-coordinator.ts
|
|
1812
1831
|
import { assertNever as assertNever7 } from "assert-never";
|
|
1813
|
-
var
|
|
1832
|
+
var ComparisonDataCoordinator = class {
|
|
1814
1833
|
constructor(bundleModelL, bundleModelR) {
|
|
1815
1834
|
this.bundleModelL = bundleModelL;
|
|
1816
1835
|
this.bundleModelR = bundleModelR;
|
|
1817
1836
|
this.taskQueue = new TaskQueue({
|
|
1818
|
-
process:
|
|
1837
|
+
process: (request) => __async(this, null, function* () {
|
|
1819
1838
|
switch (request.kind) {
|
|
1820
|
-
case "dataset":
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
]);
|
|
1825
|
-
return {
|
|
1826
|
-
kind: "dataset",
|
|
1827
|
-
datasetMapL: resultL.datasetMap,
|
|
1828
|
-
datasetMapR: resultR.datasetMap
|
|
1829
|
-
};
|
|
1830
|
-
}
|
|
1831
|
-
case "graph-data": {
|
|
1832
|
-
const bundleModel = request.bundle === "right" ? this.bundleModelR : this.bundleModelL;
|
|
1833
|
-
const graphData = await bundleModel.getGraphDataForScenario(request.scenario, request.graphId);
|
|
1834
|
-
return {
|
|
1835
|
-
kind: "graph-data",
|
|
1836
|
-
graphData
|
|
1837
|
-
};
|
|
1838
|
-
}
|
|
1839
|
+
case "dataset":
|
|
1840
|
+
return this.processDatasetRequest(request);
|
|
1841
|
+
case "graph-data":
|
|
1842
|
+
return this.processGraphDataRequest(request);
|
|
1839
1843
|
default:
|
|
1840
1844
|
assertNever7(request);
|
|
1841
1845
|
}
|
|
1846
|
+
})
|
|
1847
|
+
});
|
|
1848
|
+
}
|
|
1849
|
+
processDatasetRequest(request) {
|
|
1850
|
+
return __async(this, null, function* () {
|
|
1851
|
+
function fetchDatasets(bundleModel, scenarioSpec) {
|
|
1852
|
+
return __async(this, null, function* () {
|
|
1853
|
+
if (scenarioSpec) {
|
|
1854
|
+
return bundleModel.getDatasetsForScenario(scenarioSpec, request.datasetKeys);
|
|
1855
|
+
} else {
|
|
1856
|
+
return void 0;
|
|
1857
|
+
}
|
|
1858
|
+
});
|
|
1859
|
+
}
|
|
1860
|
+
const [resultL, resultR] = yield Promise.all([
|
|
1861
|
+
fetchDatasets(this.bundleModelL, request.scenarioSpecL),
|
|
1862
|
+
fetchDatasets(this.bundleModelR, request.scenarioSpecR)
|
|
1863
|
+
]);
|
|
1864
|
+
return {
|
|
1865
|
+
kind: "dataset",
|
|
1866
|
+
datasetMapL: resultL == null ? void 0 : resultL.datasetMap,
|
|
1867
|
+
datasetMapR: resultR == null ? void 0 : resultR.datasetMap
|
|
1868
|
+
};
|
|
1869
|
+
});
|
|
1870
|
+
}
|
|
1871
|
+
processGraphDataRequest(request) {
|
|
1872
|
+
return __async(this, null, function* () {
|
|
1873
|
+
function fetchGraphData(bundleModel, scenarioSpec) {
|
|
1874
|
+
return __async(this, null, function* () {
|
|
1875
|
+
if (scenarioSpec) {
|
|
1876
|
+
return bundleModel.getGraphDataForScenario(scenarioSpec, request.graphId);
|
|
1877
|
+
} else {
|
|
1878
|
+
return void 0;
|
|
1879
|
+
}
|
|
1880
|
+
});
|
|
1842
1881
|
}
|
|
1882
|
+
const [graphDataL, graphDataR] = yield Promise.all([
|
|
1883
|
+
fetchGraphData(this.bundleModelL, request.scenarioSpecL),
|
|
1884
|
+
fetchGraphData(this.bundleModelR, request.scenarioSpecR)
|
|
1885
|
+
]);
|
|
1886
|
+
return {
|
|
1887
|
+
kind: "graph-data",
|
|
1888
|
+
graphDataL,
|
|
1889
|
+
graphDataR
|
|
1890
|
+
};
|
|
1843
1891
|
});
|
|
1844
1892
|
}
|
|
1845
|
-
requestDatasetMaps(requestKey,
|
|
1893
|
+
requestDatasetMaps(requestKey, scenarioSpecL, scenarioSpecR, datasetKeys, onResponse) {
|
|
1846
1894
|
const request = {
|
|
1847
1895
|
kind: "dataset",
|
|
1848
|
-
|
|
1896
|
+
scenarioSpecL,
|
|
1897
|
+
scenarioSpecR,
|
|
1849
1898
|
datasetKeys
|
|
1850
1899
|
};
|
|
1851
1900
|
this.taskQueue.addTask(requestKey, request, (response) => {
|
|
@@ -1854,16 +1903,16 @@ var CompareDataCoordinator = class {
|
|
|
1854
1903
|
}
|
|
1855
1904
|
});
|
|
1856
1905
|
}
|
|
1857
|
-
requestGraphData(requestKey,
|
|
1906
|
+
requestGraphData(requestKey, scenarioSpecL, scenarioSpecR, graphId, onResponse) {
|
|
1858
1907
|
const request = {
|
|
1859
1908
|
kind: "graph-data",
|
|
1860
|
-
|
|
1861
|
-
|
|
1909
|
+
scenarioSpecL,
|
|
1910
|
+
scenarioSpecR,
|
|
1862
1911
|
graphId
|
|
1863
1912
|
};
|
|
1864
1913
|
this.taskQueue.addTask(requestKey, request, (response) => {
|
|
1865
1914
|
if (response.kind === "graph-data") {
|
|
1866
|
-
onResponse(response.
|
|
1915
|
+
onResponse(response.graphDataL, response.graphDataR);
|
|
1867
1916
|
}
|
|
1868
1917
|
});
|
|
1869
1918
|
}
|
|
@@ -1872,7 +1921,7 @@ var CompareDataCoordinator = class {
|
|
|
1872
1921
|
}
|
|
1873
1922
|
};
|
|
1874
1923
|
|
|
1875
|
-
// src/
|
|
1924
|
+
// src/comparison/diff-datasets/diff-datasets.ts
|
|
1876
1925
|
function diffDatasets(datasetL, datasetR) {
|
|
1877
1926
|
let minValueL = Number.MAX_VALUE;
|
|
1878
1927
|
let maxValueL = Number.MIN_VALUE;
|
|
@@ -1967,19 +2016,9 @@ function diffDatasets(datasetL, datasetR) {
|
|
|
1967
2016
|
maxDiffPoint
|
|
1968
2017
|
};
|
|
1969
2018
|
}
|
|
1970
|
-
function compareDatasets(scenarioKey, datasetKey, datasetMapL, datasetMapR) {
|
|
1971
|
-
const datasetL = datasetMapL.get(datasetKey);
|
|
1972
|
-
const datasetR = datasetMapR.get(datasetKey);
|
|
1973
|
-
const diffReport = diffDatasets(datasetL, datasetR);
|
|
1974
|
-
return {
|
|
1975
|
-
scenarioKey,
|
|
1976
|
-
datasetKey,
|
|
1977
|
-
diffReport
|
|
1978
|
-
};
|
|
1979
|
-
}
|
|
1980
2019
|
|
|
1981
|
-
// src/
|
|
1982
|
-
function diffGraphs(graphL, graphR, scenarioKey,
|
|
2020
|
+
// src/comparison/diff-graphs/diff-graphs.ts
|
|
2021
|
+
function diffGraphs(graphL, graphR, scenarioKey, testSummaries) {
|
|
1983
2022
|
let inclusion;
|
|
1984
2023
|
if (graphL && graphR) {
|
|
1985
2024
|
inclusion = "both";
|
|
@@ -2021,8 +2060,8 @@ function diffGraphs(graphL, graphR, scenarioKey, datasetSummaries) {
|
|
|
2021
2060
|
datasetKeys.add(dataset.datasetKey);
|
|
2022
2061
|
}
|
|
2023
2062
|
for (const datasetKey of datasetKeys) {
|
|
2024
|
-
const
|
|
2025
|
-
const maxDiff =
|
|
2063
|
+
const testSummary = testSummaries.find((summary) => summary.d === datasetKey && summary.s === scenarioKey);
|
|
2064
|
+
const maxDiff = testSummary == null ? void 0 : testSummary.md;
|
|
2026
2065
|
datasetReports.push({
|
|
2027
2066
|
datasetKey,
|
|
2028
2067
|
maxDiff
|
|
@@ -2036,12 +2075,12 @@ function diffGraphs(graphL, graphR, scenarioKey, datasetSummaries) {
|
|
|
2036
2075
|
};
|
|
2037
2076
|
}
|
|
2038
2077
|
|
|
2039
|
-
// src/
|
|
2040
|
-
function
|
|
2041
|
-
const
|
|
2042
|
-
for (const r of
|
|
2078
|
+
// src/comparison/report/comparison-reporting.ts
|
|
2079
|
+
function comparisonSummaryFromReport(comparisonReport) {
|
|
2080
|
+
const terseSummaries = [];
|
|
2081
|
+
for (const r of comparisonReport.testReports) {
|
|
2043
2082
|
if (r.diffReport.validity === "both" && r.diffReport.maxDiff > 0) {
|
|
2044
|
-
|
|
2083
|
+
terseSummaries.push({
|
|
2045
2084
|
s: r.scenarioKey,
|
|
2046
2085
|
d: r.datasetKey,
|
|
2047
2086
|
md: r.diffReport.maxDiff
|
|
@@ -2049,394 +2088,1633 @@ function compareSummaryFromReport(compareReport) {
|
|
|
2049
2088
|
}
|
|
2050
2089
|
}
|
|
2051
2090
|
return {
|
|
2052
|
-
|
|
2053
|
-
perfReportL:
|
|
2054
|
-
perfReportR:
|
|
2091
|
+
testSummaries: terseSummaries,
|
|
2092
|
+
perfReportL: comparisonReport.perfReportL,
|
|
2093
|
+
perfReportR: comparisonReport.perfReportR
|
|
2055
2094
|
};
|
|
2056
2095
|
}
|
|
2096
|
+
function restoreFromTerseSummaries(comparisonConfig, terseSummaries) {
|
|
2097
|
+
const existingSummaries = /* @__PURE__ */ new Map();
|
|
2098
|
+
for (const summary of terseSummaries) {
|
|
2099
|
+
const key = `${summary.s}::${summary.d}`;
|
|
2100
|
+
existingSummaries.set(key, summary);
|
|
2101
|
+
}
|
|
2102
|
+
const allTestSummaries = [];
|
|
2103
|
+
for (const scenario of comparisonConfig.scenarios.getAllScenarios()) {
|
|
2104
|
+
const datasetKeys = comparisonConfig.datasets.getDatasetKeysForScenario(scenario);
|
|
2105
|
+
for (const datasetKey of datasetKeys) {
|
|
2106
|
+
const key = `${scenario.key}::${datasetKey}`;
|
|
2107
|
+
const existingSummary = existingSummaries.get(key);
|
|
2108
|
+
const maxDiff = (existingSummary == null ? void 0 : existingSummary.md) || 0;
|
|
2109
|
+
allTestSummaries.push({
|
|
2110
|
+
s: scenario.key,
|
|
2111
|
+
d: datasetKey,
|
|
2112
|
+
md: maxDiff
|
|
2113
|
+
});
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
return allTestSummaries;
|
|
2117
|
+
}
|
|
2057
2118
|
|
|
2058
|
-
// src/
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2119
|
+
// src/comparison/report/comparison-grouping.ts
|
|
2120
|
+
import { assertNever as assertNever8 } from "assert-never";
|
|
2121
|
+
|
|
2122
|
+
// src/comparison/report/buckets.ts
|
|
2123
|
+
function getBucketIndex(diffPct, thresholds) {
|
|
2124
|
+
if (diffPct === 0) {
|
|
2125
|
+
return 0;
|
|
2126
|
+
}
|
|
2127
|
+
for (let i = 0; i < thresholds.length; i++) {
|
|
2128
|
+
if (diffPct < thresholds[i]) {
|
|
2129
|
+
return i + 1;
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
return thresholds.length + 1;
|
|
2133
|
+
}
|
|
2134
|
+
|
|
2135
|
+
// src/comparison/report/comparison-grouping.ts
|
|
2136
|
+
function categorizeComparisonTestSummaries(comparisonConfig, terseSummaries) {
|
|
2137
|
+
const allTestSummaries = restoreFromTerseSummaries(comparisonConfig, terseSummaries);
|
|
2138
|
+
const groupsByScenario = groupComparisonTestSummaries(allTestSummaries, "by-scenario");
|
|
2139
|
+
const byScenario = categorizeComparisonGroups(comparisonConfig, [...groupsByScenario.values()]);
|
|
2140
|
+
const groupsByDataset = groupComparisonTestSummaries(allTestSummaries, "by-dataset");
|
|
2141
|
+
const byDataset = categorizeComparisonGroups(comparisonConfig, [...groupsByDataset.values()]);
|
|
2062
2142
|
return {
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
return promiseQueue.add(() => sourceModel.getDatasetsForScenario(scenario, datasetKeys));
|
|
2066
|
-
},
|
|
2067
|
-
getGraphsForDataset: (_a = sourceModel.getGraphsForDataset) == null ? void 0 : _a.bind(sourceModel),
|
|
2068
|
-
getGraphDataForScenario: (scenario, graphId) => {
|
|
2069
|
-
return promiseQueue.add(() => sourceModel.getGraphDataForScenario(scenario, graphId));
|
|
2070
|
-
},
|
|
2071
|
-
getGraphLinksForScenario: sourceModel.getGraphLinksForScenario.bind(sourceModel)
|
|
2143
|
+
byScenario,
|
|
2144
|
+
byDataset
|
|
2072
2145
|
};
|
|
2073
2146
|
}
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2147
|
+
function groupComparisonTestSummaries(testSummaries, groupKind) {
|
|
2148
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2149
|
+
for (const testSummary of testSummaries) {
|
|
2150
|
+
let groupKey;
|
|
2151
|
+
switch (groupKind) {
|
|
2152
|
+
case "by-dataset":
|
|
2153
|
+
groupKey = testSummary.d;
|
|
2154
|
+
break;
|
|
2155
|
+
case "by-scenario":
|
|
2156
|
+
groupKey = testSummary.s;
|
|
2157
|
+
break;
|
|
2158
|
+
default:
|
|
2159
|
+
assertNever8(groupKind);
|
|
2160
|
+
}
|
|
2161
|
+
const group = groups.get(groupKey);
|
|
2162
|
+
if (group) {
|
|
2163
|
+
group.testSummaries.push(testSummary);
|
|
2164
|
+
} else {
|
|
2165
|
+
groups.set(groupKey, {
|
|
2166
|
+
kind: groupKind,
|
|
2167
|
+
key: groupKey,
|
|
2168
|
+
testSummaries: [testSummary]
|
|
2169
|
+
});
|
|
2170
|
+
}
|
|
2078
2171
|
}
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2172
|
+
return groups;
|
|
2173
|
+
}
|
|
2174
|
+
function categorizeComparisonGroups(comparisonConfig, allGroups) {
|
|
2175
|
+
const allGroupSummaries = /* @__PURE__ */ new Map();
|
|
2176
|
+
const withErrors = [];
|
|
2177
|
+
const onlyInLeft = [];
|
|
2178
|
+
const onlyInRight = [];
|
|
2179
|
+
let withDiffs = [];
|
|
2180
|
+
const withoutDiffs = [];
|
|
2181
|
+
function addSummaryForGroup(group, root, validInL, validInR) {
|
|
2182
|
+
let scores;
|
|
2183
|
+
if (validInL && validInR) {
|
|
2184
|
+
scores = getScoresForGroup(group, comparisonConfig.thresholds);
|
|
2185
|
+
}
|
|
2186
|
+
const groupSummary = {
|
|
2187
|
+
root,
|
|
2188
|
+
group,
|
|
2189
|
+
scores
|
|
2190
|
+
};
|
|
2191
|
+
allGroupSummaries.set(group.key, groupSummary);
|
|
2192
|
+
if (validInL && validInR) {
|
|
2193
|
+
if (scores.totalDiffCount !== scores.diffCountByBucket[0]) {
|
|
2194
|
+
withDiffs.push(groupSummary);
|
|
2096
2195
|
} else {
|
|
2097
|
-
|
|
2196
|
+
withoutDiffs.push(groupSummary);
|
|
2098
2197
|
}
|
|
2099
|
-
})
|
|
2198
|
+
} else if (validInL) {
|
|
2199
|
+
onlyInLeft.push(groupSummary);
|
|
2200
|
+
} else if (validInR) {
|
|
2201
|
+
onlyInRight.push(groupSummary);
|
|
2202
|
+
} else {
|
|
2203
|
+
withErrors.push(groupSummary);
|
|
2204
|
+
}
|
|
2100
2205
|
}
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2206
|
+
for (const group of allGroups.values()) {
|
|
2207
|
+
switch (group.kind) {
|
|
2208
|
+
case "by-dataset": {
|
|
2209
|
+
const dataset = comparisonConfig.datasets.getDataset(group.key);
|
|
2210
|
+
const validInL = (dataset == null ? void 0 : dataset.outputVarL) !== void 0;
|
|
2211
|
+
const validInR = (dataset == null ? void 0 : dataset.outputVarR) !== void 0;
|
|
2212
|
+
addSummaryForGroup(group, dataset, validInL, validInR);
|
|
2213
|
+
break;
|
|
2106
2214
|
}
|
|
2215
|
+
case "by-scenario": {
|
|
2216
|
+
const scenario = comparisonConfig.scenarios.getScenario(group.key);
|
|
2217
|
+
const validInL = (scenario == null ? void 0 : scenario.specL) !== void 0;
|
|
2218
|
+
const validInR = (scenario == null ? void 0 : scenario.specR) !== void 0;
|
|
2219
|
+
addSummaryForGroup(group, scenario, validInL, validInR);
|
|
2220
|
+
break;
|
|
2221
|
+
}
|
|
2222
|
+
default:
|
|
2223
|
+
assertNever8(group.kind);
|
|
2107
2224
|
}
|
|
2108
2225
|
}
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
let currentBundle;
|
|
2116
|
-
let compareConfig;
|
|
2117
|
-
if (options.compare === void 0) {
|
|
2118
|
-
currentBundle = origCurrentBundle;
|
|
2119
|
-
} else {
|
|
2120
|
-
const baselineBundle = await loadSynchronized(options.compare.baseline);
|
|
2121
|
-
const renamedDatasetKeys = options.compare.datasets.renamedDatasetKeys;
|
|
2122
|
-
const invertedRenamedKeys = /* @__PURE__ */ new Map();
|
|
2123
|
-
renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.forEach((newKey, oldKey) => {
|
|
2124
|
-
invertedRenamedKeys.set(newKey, oldKey);
|
|
2125
|
-
});
|
|
2126
|
-
const rightKeyForLeftKey = (leftKey) => {
|
|
2127
|
-
return (renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.get(leftKey)) || leftKey;
|
|
2128
|
-
};
|
|
2129
|
-
const leftKeyForRightKey = (rightKey) => {
|
|
2130
|
-
return invertedRenamedKeys.get(rightKey) || rightKey;
|
|
2131
|
-
};
|
|
2132
|
-
const origBundleModelR = origCurrentBundle.model;
|
|
2133
|
-
const adjBundleModelR = {
|
|
2134
|
-
modelSpec: origBundleModelR.modelSpec,
|
|
2135
|
-
getDatasetsForScenario: async (scenario, datasetKeys) => {
|
|
2136
|
-
const rightKeys = datasetKeys.map(rightKeyForLeftKey);
|
|
2137
|
-
const result = await origBundleModelR.getDatasetsForScenario(scenario, rightKeys);
|
|
2138
|
-
const mapWithRightKeys = result.datasetMap;
|
|
2139
|
-
const mapWithLeftKeys = /* @__PURE__ */ new Map();
|
|
2140
|
-
for (const [rightKey, dataset] of mapWithRightKeys.entries()) {
|
|
2141
|
-
const leftKey = leftKeyForRightKey(rightKey);
|
|
2142
|
-
mapWithLeftKeys.set(leftKey, dataset);
|
|
2143
|
-
}
|
|
2144
|
-
return {
|
|
2145
|
-
datasetMap: mapWithLeftKeys,
|
|
2146
|
-
modelRunTime: result.modelRunTime
|
|
2147
|
-
};
|
|
2148
|
-
},
|
|
2149
|
-
getGraphsForDataset: (_a = origBundleModelR.getGraphsForDataset) == null ? void 0 : _a.bind(origBundleModelR),
|
|
2150
|
-
getGraphDataForScenario: origBundleModelR.getGraphDataForScenario.bind(origBundleModelR),
|
|
2151
|
-
getGraphLinksForScenario: origBundleModelR.getGraphLinksForScenario.bind(origBundleModelR)
|
|
2152
|
-
};
|
|
2153
|
-
currentBundle = __spreadProps(__spreadValues({}, origCurrentBundle), {
|
|
2154
|
-
model: adjBundleModelR
|
|
2155
|
-
});
|
|
2156
|
-
compareConfig = {
|
|
2157
|
-
bundleL: baselineBundle,
|
|
2158
|
-
bundleR: currentBundle,
|
|
2159
|
-
thresholds: options.compare.thresholds,
|
|
2160
|
-
scenarios: options.compare.scenarios,
|
|
2161
|
-
datasets: options.compare.datasets
|
|
2162
|
-
};
|
|
2226
|
+
if (withDiffs.length > 1) {
|
|
2227
|
+
if (withDiffs[0].group.kind === "by-dataset") {
|
|
2228
|
+
withDiffs = sortDatasetGroupSummaries(withDiffs);
|
|
2229
|
+
} else if (withDiffs[0].group.kind === "by-scenario") {
|
|
2230
|
+
withDiffs = sortScenarioGroupSummaries(withDiffs);
|
|
2231
|
+
}
|
|
2163
2232
|
}
|
|
2164
|
-
const checkConfig = {
|
|
2165
|
-
bundle: currentBundle,
|
|
2166
|
-
tests: options.check.tests
|
|
2167
|
-
};
|
|
2168
2233
|
return {
|
|
2169
|
-
|
|
2170
|
-
|
|
2234
|
+
allGroupSummaries,
|
|
2235
|
+
withErrors,
|
|
2236
|
+
onlyInLeft,
|
|
2237
|
+
onlyInRight,
|
|
2238
|
+
withDiffs,
|
|
2239
|
+
withoutDiffs
|
|
2171
2240
|
};
|
|
2172
2241
|
}
|
|
2173
|
-
|
|
2174
|
-
const
|
|
2175
|
-
const
|
|
2242
|
+
function getScoresForGroup(group, thresholds) {
|
|
2243
|
+
const diffCountByBucket = Array(thresholds.length + 2).fill(0);
|
|
2244
|
+
const totalMaxDiffByBucket = Array(thresholds.length + 2).fill(0);
|
|
2245
|
+
let totalDiffCount = 0;
|
|
2246
|
+
for (const testSummary of group.testSummaries) {
|
|
2247
|
+
const bucketIndex = getBucketIndex(testSummary.md, thresholds);
|
|
2248
|
+
diffCountByBucket[bucketIndex]++;
|
|
2249
|
+
totalMaxDiffByBucket[bucketIndex] += testSummary.md;
|
|
2250
|
+
totalDiffCount++;
|
|
2251
|
+
}
|
|
2252
|
+
let diffPercentByBucket;
|
|
2253
|
+
if (totalDiffCount > 0) {
|
|
2254
|
+
diffPercentByBucket = diffCountByBucket.map((count) => count / totalDiffCount * 100);
|
|
2255
|
+
} else {
|
|
2256
|
+
diffPercentByBucket = [];
|
|
2257
|
+
}
|
|
2176
2258
|
return {
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2259
|
+
totalDiffCount,
|
|
2260
|
+
totalMaxDiffByBucket,
|
|
2261
|
+
diffCountByBucket,
|
|
2262
|
+
diffPercentByBucket
|
|
2180
2263
|
};
|
|
2181
2264
|
}
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
var
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2265
|
+
function sortDatasetGroupSummaries(summaries) {
|
|
2266
|
+
return summaries.sort((a, b) => {
|
|
2267
|
+
var _a, _b;
|
|
2268
|
+
const scoreResult = compareScores(a.scores, b.scores);
|
|
2269
|
+
if (scoreResult !== 0) {
|
|
2270
|
+
return -scoreResult;
|
|
2271
|
+
} else {
|
|
2272
|
+
const aVar = a.root.outputVarL;
|
|
2273
|
+
const bVar = b.root.outputVarR;
|
|
2274
|
+
const aSource = ((_a = aVar.sourceName) == null ? void 0 : _a.toLowerCase()) || "";
|
|
2275
|
+
const bSource = ((_b = bVar.sourceName) == null ? void 0 : _b.toLowerCase()) || "";
|
|
2276
|
+
if (aSource !== bSource) {
|
|
2277
|
+
return aSource.localeCompare(bSource);
|
|
2278
|
+
} else {
|
|
2279
|
+
const aName = aVar.varName.toLowerCase();
|
|
2280
|
+
const bName = bVar.varName.toLowerCase();
|
|
2281
|
+
return aName.localeCompare(bName);
|
|
2282
|
+
}
|
|
2195
2283
|
}
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2284
|
+
});
|
|
2285
|
+
}
|
|
2286
|
+
function sortScenarioGroupSummaries(summaries) {
|
|
2287
|
+
return summaries.sort((a, b) => {
|
|
2288
|
+
var _a, _b;
|
|
2289
|
+
const scoreResult = compareScores(a.scores, b.scores);
|
|
2290
|
+
if (scoreResult !== 0) {
|
|
2291
|
+
return -scoreResult;
|
|
2292
|
+
} else {
|
|
2293
|
+
const aScenario = a.root;
|
|
2294
|
+
const bScenario = b.root;
|
|
2295
|
+
const aTitle = aScenario.title.toLowerCase();
|
|
2296
|
+
const bTitle = bScenario.title.toLowerCase();
|
|
2297
|
+
if (aTitle !== bTitle) {
|
|
2298
|
+
return aTitle.localeCompare(bTitle);
|
|
2299
|
+
} else {
|
|
2300
|
+
const aSubtitle = ((_a = aScenario.subtitle) == null ? void 0 : _a.toLowerCase()) || "";
|
|
2301
|
+
const bSubtitle = ((_b = bScenario.subtitle) == null ? void 0 : _b.toLowerCase()) || "";
|
|
2302
|
+
return aSubtitle.localeCompare(bSubtitle);
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
});
|
|
2306
|
+
}
|
|
2307
|
+
function compareScores(a, b) {
|
|
2308
|
+
if (a.totalMaxDiffByBucket.length !== b.totalMaxDiffByBucket.length) {
|
|
2309
|
+
return 0;
|
|
2310
|
+
}
|
|
2311
|
+
const len = a.totalMaxDiffByBucket.length;
|
|
2312
|
+
for (let i = len - 1; i >= 0; i--) {
|
|
2313
|
+
const aTotal = a.totalMaxDiffByBucket[i];
|
|
2314
|
+
const bTotal = b.totalMaxDiffByBucket[i];
|
|
2315
|
+
if (aTotal > bTotal) {
|
|
2316
|
+
return 1;
|
|
2317
|
+
} else if (aTotal < bTotal) {
|
|
2318
|
+
return -1;
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
return 0;
|
|
2322
|
+
}
|
|
2323
|
+
|
|
2324
|
+
// src/bundle/model-inputs.ts
|
|
2325
|
+
var ModelInputs = class {
|
|
2326
|
+
constructor(modelSpec) {
|
|
2327
|
+
/** All inputs keyed by lookup name (lowercase variable name or alias). */
|
|
2328
|
+
this.inputsByLookupName = /* @__PURE__ */ new Map();
|
|
2329
|
+
/** All input ID aliases. */
|
|
2330
|
+
this.inputIdAliases = /* @__PURE__ */ new Set();
|
|
2331
|
+
for (const inputVar of modelSpec.inputVars.values()) {
|
|
2332
|
+
const varNameKey = inputVar.varName.toLowerCase();
|
|
2333
|
+
this.inputsByLookupName.set(varNameKey, inputVar);
|
|
2334
|
+
if (inputVar.inputId) {
|
|
2335
|
+
const idAlias = `id ${inputVar.inputId}`;
|
|
2336
|
+
this.inputIdAliases.add(idAlias);
|
|
2337
|
+
const idKey = idAlias.toLowerCase();
|
|
2338
|
+
this.inputsByLookupName.set(idKey, inputVar);
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
if (modelSpec.inputAliases) {
|
|
2342
|
+
for (const [alias, varId] of modelSpec.inputAliases.entries()) {
|
|
2343
|
+
const aliasKey = alias.toLowerCase();
|
|
2344
|
+
if (this.inputsByLookupName.has(aliasKey)) {
|
|
2345
|
+
console.warn(
|
|
2346
|
+
`WARNING: Input variable already defined with a name that collides with alias '${alias}', skipping`
|
|
2347
|
+
);
|
|
2348
|
+
continue;
|
|
2349
|
+
}
|
|
2350
|
+
const inputVar = modelSpec.inputVars.get(varId);
|
|
2351
|
+
if (inputVar === void 0) {
|
|
2352
|
+
console.warn(`WARNING: No input variable found for '${varId}' associated with alias '${alias}', skipping`);
|
|
2353
|
+
continue;
|
|
2354
|
+
}
|
|
2355
|
+
this.inputsByLookupName.set(aliasKey, inputVar);
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
/**
|
|
2360
|
+
* Return the set of `id XYZ` aliases for all input variables.
|
|
2361
|
+
*/
|
|
2362
|
+
getAllInputIdAliases() {
|
|
2363
|
+
return [...this.inputIdAliases];
|
|
2364
|
+
}
|
|
2365
|
+
/**
|
|
2366
|
+
* Return the `InputVar` that matches the requested name (either by variable name or alias).
|
|
2367
|
+
*
|
|
2368
|
+
* @param name The variable name or alias to match.
|
|
2369
|
+
*/
|
|
2370
|
+
getInputVarForName(name) {
|
|
2371
|
+
return this.inputsByLookupName.get(name.toLowerCase());
|
|
2372
|
+
}
|
|
2373
|
+
};
|
|
2374
|
+
|
|
2375
|
+
// src/comparison/config/parse/comparison-parser.ts
|
|
2376
|
+
import Ajv2 from "ajv";
|
|
2377
|
+
import assertNever9 from "assert-never";
|
|
2378
|
+
import { err as err2, ok as ok2 } from "neverthrow";
|
|
2379
|
+
import yaml2 from "yaml";
|
|
2380
|
+
|
|
2381
|
+
// src/comparison/config/parse/comparison.schema.js
|
|
2382
|
+
var comparison_schema_default = {
|
|
2383
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
2384
|
+
title: "Model Comparison Test",
|
|
2385
|
+
type: "array",
|
|
2386
|
+
description: "A group of model comparison scenarios and views.",
|
|
2387
|
+
items: {
|
|
2388
|
+
$ref: "#/$defs/top_level_array_item"
|
|
2389
|
+
},
|
|
2390
|
+
$defs: {
|
|
2391
|
+
//
|
|
2392
|
+
// TOP-LEVEL
|
|
2393
|
+
//
|
|
2394
|
+
top_level_array_item: {
|
|
2395
|
+
oneOf: [
|
|
2396
|
+
{ $ref: "#/$defs/scenario_array_item" },
|
|
2397
|
+
{ $ref: "#/$defs/scenario_group_array_item" },
|
|
2398
|
+
{ $ref: "#/$defs/view_group_array_item" }
|
|
2399
|
+
]
|
|
2400
|
+
},
|
|
2401
|
+
//
|
|
2402
|
+
// SCENARIOS
|
|
2403
|
+
//
|
|
2404
|
+
scenario_array_item: {
|
|
2405
|
+
type: "object",
|
|
2406
|
+
additionalProperties: false,
|
|
2407
|
+
properties: {
|
|
2408
|
+
scenario: {
|
|
2409
|
+
$ref: "#/$defs/scenario"
|
|
2410
|
+
}
|
|
2411
|
+
},
|
|
2412
|
+
required: ["scenario"]
|
|
2413
|
+
},
|
|
2414
|
+
scenario: {
|
|
2415
|
+
oneOf: [
|
|
2416
|
+
{ $ref: "#/$defs/scenario_with_input_at_position" },
|
|
2417
|
+
{ $ref: "#/$defs/scenario_with_input_at_value" },
|
|
2418
|
+
{ $ref: "#/$defs/scenario_with_multiple_input_settings" },
|
|
2419
|
+
{ $ref: "#/$defs/scenario_with_inputs_in_preset_at_position" },
|
|
2420
|
+
// { $ref: '#/$defs/scenario_with_inputs_in_group_at_position' }
|
|
2421
|
+
{ $ref: "#/$defs/scenario_preset" }
|
|
2422
|
+
// { $ref: '#/$defs/scenario_expand_for_each_input_in_group' }
|
|
2423
|
+
]
|
|
2424
|
+
},
|
|
2425
|
+
scenario_position: {
|
|
2426
|
+
type: "string",
|
|
2427
|
+
enum: ["min", "max", "default"]
|
|
2428
|
+
},
|
|
2429
|
+
scenario_with_input_at_position: {
|
|
2430
|
+
type: "object",
|
|
2431
|
+
additionalProperties: false,
|
|
2432
|
+
properties: {
|
|
2433
|
+
id: {
|
|
2434
|
+
type: "string"
|
|
2435
|
+
},
|
|
2436
|
+
title: {
|
|
2437
|
+
type: "string"
|
|
2438
|
+
},
|
|
2439
|
+
subtitle: {
|
|
2440
|
+
type: "string"
|
|
2441
|
+
},
|
|
2442
|
+
with: {
|
|
2443
|
+
type: "string"
|
|
2444
|
+
},
|
|
2445
|
+
at: {
|
|
2446
|
+
$ref: "#/$defs/scenario_position"
|
|
2447
|
+
}
|
|
2448
|
+
},
|
|
2449
|
+
required: ["with", "at"]
|
|
2450
|
+
},
|
|
2451
|
+
scenario_with_input_at_value: {
|
|
2452
|
+
type: "object",
|
|
2453
|
+
additionalProperties: false,
|
|
2454
|
+
properties: {
|
|
2455
|
+
id: {
|
|
2456
|
+
type: "string"
|
|
2457
|
+
},
|
|
2458
|
+
title: {
|
|
2459
|
+
type: "string"
|
|
2460
|
+
},
|
|
2461
|
+
subtitle: {
|
|
2462
|
+
type: "string"
|
|
2463
|
+
},
|
|
2464
|
+
with: {
|
|
2465
|
+
type: "string"
|
|
2466
|
+
},
|
|
2467
|
+
at: {
|
|
2468
|
+
type: "number"
|
|
2469
|
+
}
|
|
2470
|
+
},
|
|
2471
|
+
required: ["with", "at"]
|
|
2472
|
+
},
|
|
2473
|
+
scenario_input_at_position: {
|
|
2474
|
+
type: "object",
|
|
2475
|
+
additionalProperties: false,
|
|
2476
|
+
properties: {
|
|
2477
|
+
input: {
|
|
2478
|
+
type: "string"
|
|
2479
|
+
},
|
|
2480
|
+
at: {
|
|
2481
|
+
$ref: "#/$defs/scenario_position"
|
|
2482
|
+
}
|
|
2483
|
+
},
|
|
2484
|
+
required: ["input", "at"]
|
|
2485
|
+
},
|
|
2486
|
+
scenario_input_at_value: {
|
|
2487
|
+
type: "object",
|
|
2488
|
+
additionalProperties: false,
|
|
2489
|
+
properties: {
|
|
2490
|
+
input: {
|
|
2491
|
+
type: "string"
|
|
2492
|
+
},
|
|
2493
|
+
at: {
|
|
2494
|
+
type: "number"
|
|
2495
|
+
}
|
|
2496
|
+
},
|
|
2497
|
+
required: ["input", "at"]
|
|
2498
|
+
},
|
|
2499
|
+
scenario_input_setting: {
|
|
2500
|
+
oneOf: [{ $ref: "#/$defs/scenario_input_at_position" }, { $ref: "#/$defs/scenario_input_at_value" }]
|
|
2501
|
+
},
|
|
2502
|
+
scenario_input_setting_array: {
|
|
2503
|
+
type: "array",
|
|
2504
|
+
items: {
|
|
2505
|
+
$ref: "#/$defs/scenario_input_setting"
|
|
2506
|
+
},
|
|
2507
|
+
minItems: 1
|
|
2508
|
+
},
|
|
2509
|
+
scenario_with_multiple_input_settings: {
|
|
2510
|
+
type: "object",
|
|
2511
|
+
additionalProperties: false,
|
|
2512
|
+
properties: {
|
|
2513
|
+
id: {
|
|
2514
|
+
type: "string"
|
|
2515
|
+
},
|
|
2516
|
+
title: {
|
|
2517
|
+
type: "string"
|
|
2518
|
+
},
|
|
2519
|
+
subtitle: {
|
|
2520
|
+
type: "string"
|
|
2521
|
+
},
|
|
2522
|
+
with: {
|
|
2523
|
+
$ref: "#/$defs/scenario_input_setting_array"
|
|
2524
|
+
}
|
|
2525
|
+
},
|
|
2526
|
+
required: ["with"]
|
|
2527
|
+
},
|
|
2528
|
+
scenario_with_inputs_in_preset_at_position: {
|
|
2529
|
+
type: "object",
|
|
2530
|
+
additionalProperties: false,
|
|
2531
|
+
properties: {
|
|
2532
|
+
id: {
|
|
2533
|
+
type: "string"
|
|
2534
|
+
},
|
|
2535
|
+
title: {
|
|
2536
|
+
type: "string"
|
|
2537
|
+
},
|
|
2538
|
+
subtitle: {
|
|
2539
|
+
type: "string"
|
|
2540
|
+
},
|
|
2541
|
+
with_inputs: {
|
|
2542
|
+
type: "string",
|
|
2543
|
+
enum: ["all"]
|
|
2544
|
+
},
|
|
2545
|
+
at: {
|
|
2546
|
+
$ref: "#/$defs/scenario_position"
|
|
2547
|
+
}
|
|
2548
|
+
},
|
|
2549
|
+
required: ["with_inputs", "at"]
|
|
2550
|
+
},
|
|
2551
|
+
scenario_preset: {
|
|
2552
|
+
type: "object",
|
|
2553
|
+
additionalProperties: false,
|
|
2554
|
+
properties: {
|
|
2555
|
+
preset: {
|
|
2556
|
+
type: "string",
|
|
2557
|
+
enum: ["matrix"]
|
|
2558
|
+
}
|
|
2559
|
+
},
|
|
2560
|
+
required: ["preset"]
|
|
2561
|
+
},
|
|
2562
|
+
//
|
|
2563
|
+
// SCENARIO GROUPS
|
|
2564
|
+
//
|
|
2565
|
+
scenario_group_array_item: {
|
|
2566
|
+
type: "object",
|
|
2567
|
+
additionalProperties: false,
|
|
2568
|
+
properties: {
|
|
2569
|
+
scenario_group: {
|
|
2570
|
+
$ref: "#/$defs/scenario_group"
|
|
2571
|
+
}
|
|
2572
|
+
},
|
|
2573
|
+
required: ["scenario_group"]
|
|
2574
|
+
},
|
|
2575
|
+
scenario_group: {
|
|
2576
|
+
type: "object",
|
|
2577
|
+
additionalProperties: false,
|
|
2578
|
+
properties: {
|
|
2579
|
+
id: {
|
|
2580
|
+
type: "string"
|
|
2581
|
+
},
|
|
2582
|
+
title: {
|
|
2583
|
+
type: "string"
|
|
2584
|
+
},
|
|
2585
|
+
scenarios: {
|
|
2586
|
+
type: "array",
|
|
2587
|
+
items: {
|
|
2588
|
+
$ref: "#/$defs/scenario_group_scenarios_array_item"
|
|
2589
|
+
},
|
|
2590
|
+
minItems: 1
|
|
2591
|
+
}
|
|
2592
|
+
},
|
|
2593
|
+
required: ["title", "scenarios"]
|
|
2594
|
+
},
|
|
2595
|
+
scenario_group_scenarios_array_item: {
|
|
2596
|
+
oneOf: [{ $ref: "#/$defs/scenario_array_item" }, { $ref: "#/$defs/scenario_ref_array_item" }]
|
|
2597
|
+
},
|
|
2598
|
+
scenario_ref_id: {
|
|
2599
|
+
type: "string"
|
|
2600
|
+
},
|
|
2601
|
+
scenario_ref_object: {
|
|
2602
|
+
type: "object",
|
|
2603
|
+
additionalProperties: false,
|
|
2604
|
+
properties: {
|
|
2605
|
+
id: {
|
|
2606
|
+
type: "string"
|
|
2607
|
+
},
|
|
2608
|
+
title: {
|
|
2609
|
+
type: "string"
|
|
2610
|
+
},
|
|
2611
|
+
subtitle: {
|
|
2612
|
+
type: "string"
|
|
2613
|
+
}
|
|
2614
|
+
},
|
|
2615
|
+
required: ["id"]
|
|
2616
|
+
},
|
|
2617
|
+
scenario_ref: {
|
|
2618
|
+
oneOf: [{ $ref: "#/$defs/scenario_ref_id" }, { $ref: "#/$defs/scenario_ref_object" }]
|
|
2619
|
+
},
|
|
2620
|
+
scenario_ref_array_item: {
|
|
2621
|
+
type: "object",
|
|
2622
|
+
additionalProperties: false,
|
|
2623
|
+
properties: {
|
|
2624
|
+
scenario_ref: {
|
|
2625
|
+
$ref: "#/$defs/scenario_ref"
|
|
2626
|
+
}
|
|
2627
|
+
},
|
|
2628
|
+
required: ["scenario_ref"]
|
|
2629
|
+
},
|
|
2630
|
+
scenario_group_ref: {
|
|
2631
|
+
type: "object",
|
|
2632
|
+
additionalProperties: false,
|
|
2633
|
+
properties: {
|
|
2634
|
+
scenario_group_ref: {
|
|
2635
|
+
type: "string"
|
|
2636
|
+
}
|
|
2637
|
+
},
|
|
2638
|
+
required: ["scenario_group_ref"]
|
|
2639
|
+
},
|
|
2640
|
+
//
|
|
2641
|
+
// VIEWS
|
|
2642
|
+
//
|
|
2643
|
+
view: {
|
|
2644
|
+
type: "object",
|
|
2645
|
+
additionalProperties: false,
|
|
2646
|
+
properties: {
|
|
2647
|
+
title: {
|
|
2648
|
+
type: "string"
|
|
2649
|
+
},
|
|
2650
|
+
subtitle: {
|
|
2651
|
+
type: "string"
|
|
2652
|
+
},
|
|
2653
|
+
scenario_ref: {
|
|
2654
|
+
type: "string"
|
|
2655
|
+
},
|
|
2656
|
+
graphs: {
|
|
2657
|
+
$ref: "#/$defs/view_graphs"
|
|
2658
|
+
}
|
|
2659
|
+
},
|
|
2660
|
+
required: ["scenario_ref", "graphs"]
|
|
2661
|
+
},
|
|
2662
|
+
view_graphs: {
|
|
2663
|
+
oneOf: [{ $ref: "#/$defs/view_graphs_preset" }, { $ref: "#/$defs/view_graphs_array" }]
|
|
2664
|
+
},
|
|
2665
|
+
view_graphs_preset: {
|
|
2666
|
+
type: "string",
|
|
2667
|
+
enum: ["all"]
|
|
2668
|
+
},
|
|
2669
|
+
view_graphs_array: {
|
|
2670
|
+
type: "array",
|
|
2671
|
+
items: {
|
|
2672
|
+
type: "string"
|
|
2673
|
+
},
|
|
2674
|
+
minItems: 1
|
|
2675
|
+
},
|
|
2676
|
+
//
|
|
2677
|
+
// VIEW GROUPS
|
|
2678
|
+
//
|
|
2679
|
+
view_group_array_item: {
|
|
2680
|
+
type: "object",
|
|
2681
|
+
additionalProperties: false,
|
|
2682
|
+
properties: {
|
|
2683
|
+
view_group: {
|
|
2684
|
+
$ref: "#/$defs/view_group"
|
|
2685
|
+
}
|
|
2686
|
+
},
|
|
2687
|
+
required: ["view_group"]
|
|
2688
|
+
},
|
|
2689
|
+
view_group: {
|
|
2690
|
+
oneOf: [
|
|
2691
|
+
{ $ref: "#/$defs/view_group_with_views_array" },
|
|
2692
|
+
{ $ref: "#/$defs/view_group_shorthand_with_scenarios_array" }
|
|
2693
|
+
]
|
|
2694
|
+
},
|
|
2695
|
+
view_group_with_views_array: {
|
|
2696
|
+
type: "object",
|
|
2697
|
+
additionalProperties: false,
|
|
2698
|
+
properties: {
|
|
2699
|
+
title: {
|
|
2700
|
+
type: "string"
|
|
2701
|
+
},
|
|
2702
|
+
views: {
|
|
2703
|
+
type: "array",
|
|
2704
|
+
items: {
|
|
2705
|
+
$ref: "#/$defs/view_group_views_array_item"
|
|
2706
|
+
},
|
|
2707
|
+
minItems: 1
|
|
2708
|
+
}
|
|
2709
|
+
},
|
|
2710
|
+
required: ["title", "views"]
|
|
2711
|
+
},
|
|
2712
|
+
view_group_views_array_item: {
|
|
2713
|
+
type: "object",
|
|
2714
|
+
additionalProperties: false,
|
|
2715
|
+
properties: {
|
|
2716
|
+
view: {
|
|
2717
|
+
$ref: "#/$defs/view"
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
},
|
|
2721
|
+
view_group_shorthand_with_scenarios_array: {
|
|
2722
|
+
type: "object",
|
|
2723
|
+
additionalProperties: false,
|
|
2724
|
+
properties: {
|
|
2725
|
+
title: {
|
|
2726
|
+
type: "string"
|
|
2727
|
+
},
|
|
2728
|
+
scenarios: {
|
|
2729
|
+
type: "array",
|
|
2730
|
+
items: {
|
|
2731
|
+
$ref: "#/$defs/view_group_scenarios_array_item"
|
|
2732
|
+
},
|
|
2733
|
+
minItems: 1
|
|
2734
|
+
},
|
|
2735
|
+
graphs: {
|
|
2736
|
+
$ref: "#/$defs/view_graphs"
|
|
2737
|
+
}
|
|
2738
|
+
},
|
|
2739
|
+
required: ["title", "scenarios", "graphs"]
|
|
2740
|
+
},
|
|
2741
|
+
view_group_scenarios_array_item: {
|
|
2742
|
+
oneOf: [{ $ref: "#/$defs/scenario_ref_array_item" }, { $ref: "#/$defs/scenario_group_ref" }]
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
};
|
|
2746
|
+
|
|
2747
|
+
// src/comparison/config/parse/comparison-parser.ts
|
|
2748
|
+
function parseComparisonSpecs(specSource) {
|
|
2749
|
+
const scenarios = [];
|
|
2750
|
+
const scenarioGroups = [];
|
|
2751
|
+
const viewGroups = [];
|
|
2752
|
+
const ajv = new Ajv2();
|
|
2753
|
+
const validate = ajv.compile(comparison_schema_default);
|
|
2754
|
+
let parsed;
|
|
2755
|
+
switch (specSource.kind) {
|
|
2756
|
+
case "json":
|
|
2757
|
+
parsed = JSON.parse(specSource.content);
|
|
2758
|
+
break;
|
|
2759
|
+
case "yaml":
|
|
2760
|
+
parsed = yaml2.parse(specSource.content);
|
|
2761
|
+
break;
|
|
2762
|
+
default:
|
|
2763
|
+
assertNever9(specSource.kind);
|
|
2764
|
+
}
|
|
2765
|
+
if (validate(parsed)) {
|
|
2766
|
+
for (const specItem of parsed) {
|
|
2767
|
+
if ("scenario" in specItem) {
|
|
2768
|
+
scenarios.push(scenarioSpecFromParsed(specItem.scenario));
|
|
2769
|
+
} else if ("scenario_group" in specItem) {
|
|
2770
|
+
scenarioGroups.push(scenarioGroupSpecFromParsed(specItem.scenario_group));
|
|
2771
|
+
} else if ("view_group" in specItem) {
|
|
2772
|
+
viewGroups.push(viewGroupSpecFromParsed(specItem.view_group));
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
} else {
|
|
2776
|
+
let msg = "Failed to parse YAML comparison definitions";
|
|
2777
|
+
for (const error of validate.errors || []) {
|
|
2778
|
+
if (error.message) {
|
|
2779
|
+
msg += `
|
|
2780
|
+
${error.message}`;
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
return err2(new Error(msg));
|
|
2784
|
+
}
|
|
2785
|
+
return ok2({
|
|
2786
|
+
scenarios,
|
|
2787
|
+
scenarioGroups,
|
|
2788
|
+
viewGroups
|
|
2789
|
+
});
|
|
2790
|
+
}
|
|
2791
|
+
function scenarioSpecFromParsed(parsedScenario) {
|
|
2792
|
+
if (parsedScenario.preset === "matrix") {
|
|
2793
|
+
return {
|
|
2794
|
+
kind: "scenario-matrix"
|
|
2795
|
+
};
|
|
2796
|
+
}
|
|
2797
|
+
if (parsedScenario.with !== void 0) {
|
|
2798
|
+
let inputSpecs;
|
|
2799
|
+
if (Array.isArray(parsedScenario.with)) {
|
|
2800
|
+
const parsedInputs = parsedScenario.with;
|
|
2801
|
+
inputSpecs = parsedInputs.map(inputSpecFromParsed);
|
|
2802
|
+
} else {
|
|
2803
|
+
inputSpecs = [
|
|
2804
|
+
inputSpecFromParsed({
|
|
2805
|
+
input: parsedScenario.with,
|
|
2806
|
+
at: parsedScenario.at
|
|
2807
|
+
})
|
|
2808
|
+
];
|
|
2809
|
+
}
|
|
2810
|
+
return {
|
|
2811
|
+
kind: "scenario-with-inputs",
|
|
2812
|
+
id: parsedScenario.id,
|
|
2813
|
+
title: parsedScenario.title,
|
|
2814
|
+
subtitle: parsedScenario.subtitle,
|
|
2815
|
+
inputs: inputSpecs
|
|
2816
|
+
};
|
|
2817
|
+
}
|
|
2818
|
+
if (parsedScenario.with_inputs === "all") {
|
|
2819
|
+
return {
|
|
2820
|
+
kind: "scenario-with-all-inputs",
|
|
2821
|
+
id: parsedScenario.id,
|
|
2822
|
+
title: parsedScenario.title,
|
|
2823
|
+
subtitle: parsedScenario.subtitle,
|
|
2824
|
+
position: parsedScenario.at
|
|
2825
|
+
};
|
|
2826
|
+
}
|
|
2827
|
+
throw new Error(`Unable to convert parsed scenario: ${JSON.stringify(parsedScenario)}`);
|
|
2828
|
+
}
|
|
2829
|
+
function inputSpecFromParsed(parsedInput) {
|
|
2830
|
+
if (typeof parsedInput.at === "number") {
|
|
2831
|
+
const value = parsedInput.at;
|
|
2832
|
+
return {
|
|
2833
|
+
kind: "input-at-value",
|
|
2834
|
+
inputName: parsedInput.input,
|
|
2835
|
+
value
|
|
2836
|
+
};
|
|
2837
|
+
} else {
|
|
2838
|
+
return {
|
|
2839
|
+
kind: "input-at-position",
|
|
2840
|
+
inputName: parsedInput.input,
|
|
2841
|
+
position: parsedInput.at
|
|
2842
|
+
};
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
function scenarioGroupSpecFromParsed(parsedScenarioGroup) {
|
|
2846
|
+
const scenarioSpecs = parsedScenarioGroup.scenarios.map(
|
|
2847
|
+
(parsedScenarioOrRef) => {
|
|
2848
|
+
if ("scenario_ref" in parsedScenarioOrRef) {
|
|
2849
|
+
return scenarioRefSpecFromParsed(parsedScenarioOrRef);
|
|
2850
|
+
} else {
|
|
2851
|
+
return scenarioSpecFromParsed(parsedScenarioOrRef.scenario);
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
);
|
|
2855
|
+
return {
|
|
2856
|
+
kind: "scenario-group",
|
|
2857
|
+
id: parsedScenarioGroup.id,
|
|
2858
|
+
title: parsedScenarioGroup.title,
|
|
2859
|
+
scenarios: scenarioSpecs
|
|
2860
|
+
};
|
|
2861
|
+
}
|
|
2862
|
+
function scenarioRefSpecFromParsed(parsedScenarioRef) {
|
|
2863
|
+
if (typeof parsedScenarioRef.scenario_ref === "string") {
|
|
2864
|
+
return {
|
|
2865
|
+
kind: "scenario-ref",
|
|
2866
|
+
scenarioId: parsedScenarioRef.scenario_ref
|
|
2867
|
+
};
|
|
2868
|
+
} else {
|
|
2869
|
+
return {
|
|
2870
|
+
kind: "scenario-ref",
|
|
2871
|
+
scenarioId: parsedScenarioRef.scenario_ref.id,
|
|
2872
|
+
title: parsedScenarioRef.scenario_ref.title,
|
|
2873
|
+
subtitle: parsedScenarioRef.scenario_ref.subtitle
|
|
2874
|
+
};
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
function scenarioGroupRefSpecFromParsed(parsedGroupRef) {
|
|
2878
|
+
return {
|
|
2879
|
+
kind: "scenario-group-ref",
|
|
2880
|
+
groupId: parsedGroupRef.scenario_group_ref
|
|
2881
|
+
};
|
|
2882
|
+
}
|
|
2883
|
+
function viewSpecFromParsed(parsedView) {
|
|
2884
|
+
return {
|
|
2885
|
+
kind: "view",
|
|
2886
|
+
title: parsedView.title,
|
|
2887
|
+
subtitle: parsedView.subtitle,
|
|
2888
|
+
scenarioId: parsedView.scenario_ref,
|
|
2889
|
+
graphs: viewGraphsSpecFromParsed(parsedView.graphs)
|
|
2890
|
+
};
|
|
2891
|
+
}
|
|
2892
|
+
function viewGraphsSpecFromParsed(parsedGraphs) {
|
|
2893
|
+
if (parsedGraphs === "all") {
|
|
2894
|
+
return {
|
|
2895
|
+
kind: "graphs-preset",
|
|
2896
|
+
preset: "all"
|
|
2897
|
+
};
|
|
2898
|
+
} else {
|
|
2899
|
+
return {
|
|
2900
|
+
kind: "graphs-array",
|
|
2901
|
+
graphIds: parsedGraphs
|
|
2902
|
+
};
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
function viewGroupSpecFromParsed(parsedViewGroup) {
|
|
2906
|
+
if (parsedViewGroup.views !== void 0) {
|
|
2907
|
+
return {
|
|
2908
|
+
kind: "view-group-with-views",
|
|
2909
|
+
title: parsedViewGroup.title,
|
|
2910
|
+
views: parsedViewGroup.views.map((item) => viewSpecFromParsed(item.view))
|
|
2911
|
+
};
|
|
2912
|
+
} else if (parsedViewGroup.scenarios !== void 0) {
|
|
2913
|
+
const scenarios = parsedViewGroup.scenarios.map(
|
|
2914
|
+
(parsedScenarioOrGroupRef) => {
|
|
2915
|
+
if ("scenario_ref" in parsedScenarioOrGroupRef) {
|
|
2916
|
+
return scenarioRefSpecFromParsed(parsedScenarioOrGroupRef);
|
|
2917
|
+
} else if ("scenario_group_ref" in parsedScenarioOrGroupRef) {
|
|
2918
|
+
return scenarioGroupRefSpecFromParsed(parsedScenarioOrGroupRef);
|
|
2919
|
+
} else {
|
|
2920
|
+
throw new Error("Invalid view group");
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
);
|
|
2924
|
+
return {
|
|
2925
|
+
kind: "view-group-with-scenarios",
|
|
2926
|
+
title: parsedViewGroup.title,
|
|
2927
|
+
scenarios,
|
|
2928
|
+
graphs: viewGraphsSpecFromParsed(parsedViewGroup.graphs)
|
|
2929
|
+
};
|
|
2930
|
+
} else {
|
|
2931
|
+
throw new Error("Invalid view group");
|
|
2932
|
+
}
|
|
2933
|
+
}
|
|
2934
|
+
|
|
2935
|
+
// src/comparison/config/resolve/comparison-resolver.ts
|
|
2936
|
+
import { assertNever as assertNever11 } from "assert-never";
|
|
2937
|
+
|
|
2938
|
+
// src/comparison/config/resolve/comparison-scenario-specs.ts
|
|
2939
|
+
import { assertNever as assertNever10 } from "assert-never";
|
|
2940
|
+
function scenarioSpecsFromSettings(settings) {
|
|
2941
|
+
switch (settings.kind) {
|
|
2942
|
+
case "all-inputs-settings": {
|
|
2943
|
+
const scenario = allInputsAtPositionSpec(settings.position);
|
|
2944
|
+
return [scenario, scenario];
|
|
2945
|
+
}
|
|
2946
|
+
case "input-settings": {
|
|
2947
|
+
const specL = scenarioSpecFromInputs(settings.inputs, "left");
|
|
2948
|
+
const specR = scenarioSpecFromInputs(settings.inputs, "right");
|
|
2949
|
+
return [specL, specR];
|
|
2950
|
+
}
|
|
2951
|
+
default:
|
|
2952
|
+
assertNever10(settings);
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
function scenarioSpecFromInputs(inputs, side) {
|
|
2956
|
+
const settings = [];
|
|
2957
|
+
for (const input of inputs) {
|
|
2958
|
+
const state = side === "left" ? input.stateL : input.stateR;
|
|
2959
|
+
if (state.inputVar === void 0) {
|
|
2960
|
+
return void 0;
|
|
2961
|
+
}
|
|
2962
|
+
settings.push(inputSettingFromResolvedInputState(state));
|
|
2963
|
+
}
|
|
2964
|
+
return inputSettingsSpec(settings);
|
|
2965
|
+
}
|
|
2966
|
+
function inputSettingFromResolvedInputState(state) {
|
|
2967
|
+
const varId = state.inputVar.varId;
|
|
2968
|
+
if (state.position) {
|
|
2969
|
+
return positionSetting(varId, state.position);
|
|
2970
|
+
} else {
|
|
2971
|
+
return valueSetting(varId, state.value);
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
|
|
2975
|
+
// src/comparison/config/resolve/comparison-resolver.ts
|
|
2976
|
+
function resolveComparisonSpecs(modelInputsL, modelInputsR, specs) {
|
|
2977
|
+
let key = 1;
|
|
2978
|
+
const genKey = () => {
|
|
2979
|
+
return `${key++}`;
|
|
2980
|
+
};
|
|
2981
|
+
const resolvedScenarios = new ResolvedScenarios();
|
|
2982
|
+
for (const scenarioSpec of specs.scenarios) {
|
|
2983
|
+
resolvedScenarios.add(resolveScenariosFromSpec(modelInputsL, modelInputsR, scenarioSpec, genKey));
|
|
2984
|
+
}
|
|
2985
|
+
const partiallyResolvedScenarioGroups = [];
|
|
2986
|
+
for (const scenarioGroupSpec of specs.scenarioGroups) {
|
|
2987
|
+
const scenariosForGroup = [];
|
|
2988
|
+
for (const scenarioItem of scenarioGroupSpec.scenarios) {
|
|
2989
|
+
if (scenarioItem.kind === "scenario-ref") {
|
|
2990
|
+
scenariosForGroup.push(scenarioItem);
|
|
2991
|
+
} else {
|
|
2992
|
+
const scenarios = resolveScenariosFromSpec(modelInputsL, modelInputsR, scenarioItem, genKey);
|
|
2993
|
+
resolvedScenarios.add(scenarios);
|
|
2994
|
+
scenariosForGroup.push(...scenarios);
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
partiallyResolvedScenarioGroups.push({
|
|
2998
|
+
spec: scenarioGroupSpec,
|
|
2999
|
+
scenarios: scenariosForGroup
|
|
3000
|
+
});
|
|
3001
|
+
}
|
|
3002
|
+
const resolvedScenarioGroups = new ResolvedScenarioGroups();
|
|
3003
|
+
for (const partiallyResolvedGroup of partiallyResolvedScenarioGroups) {
|
|
3004
|
+
const scenariosForGroup = [];
|
|
3005
|
+
for (const scenarioItem of partiallyResolvedGroup.scenarios) {
|
|
3006
|
+
if (scenarioItem.kind === "scenario-ref") {
|
|
3007
|
+
const referencedScenario = resolvedScenarios.getScenarioForId(scenarioItem.scenarioId);
|
|
3008
|
+
if (referencedScenario) {
|
|
3009
|
+
const resolvedScenario = __spreadValues({}, referencedScenario);
|
|
3010
|
+
if (scenarioItem.title) {
|
|
3011
|
+
resolvedScenario.title = scenarioItem.title;
|
|
3012
|
+
}
|
|
3013
|
+
if (scenarioItem.subtitle) {
|
|
3014
|
+
resolvedScenario.subtitle = scenarioItem.subtitle;
|
|
3015
|
+
}
|
|
3016
|
+
scenariosForGroup.push(resolvedScenario);
|
|
3017
|
+
} else {
|
|
3018
|
+
scenariosForGroup.push({
|
|
3019
|
+
kind: "unresolved-scenario-ref",
|
|
3020
|
+
scenarioId: scenarioItem.scenarioId
|
|
3021
|
+
});
|
|
3022
|
+
}
|
|
3023
|
+
} else {
|
|
3024
|
+
scenariosForGroup.push(scenarioItem);
|
|
3025
|
+
}
|
|
3026
|
+
}
|
|
3027
|
+
resolvedScenarioGroups.add({
|
|
3028
|
+
kind: "scenario-group",
|
|
3029
|
+
id: partiallyResolvedGroup.spec.id,
|
|
3030
|
+
title: partiallyResolvedGroup.spec.title,
|
|
3031
|
+
scenarios: scenariosForGroup
|
|
3032
|
+
});
|
|
3033
|
+
}
|
|
3034
|
+
const resolvedViewGroups = [];
|
|
3035
|
+
for (const viewGroupSpec of specs.viewGroups) {
|
|
3036
|
+
const resolvedViewGroup = resolveViewGroupFromSpec(resolvedScenarios, resolvedScenarioGroups, viewGroupSpec);
|
|
3037
|
+
resolvedViewGroups.push(resolvedViewGroup);
|
|
3038
|
+
}
|
|
3039
|
+
return {
|
|
3040
|
+
scenarios: resolvedScenarios.getAll(),
|
|
3041
|
+
scenarioGroups: resolvedScenarioGroups.getAll(),
|
|
3042
|
+
viewGroups: resolvedViewGroups
|
|
3043
|
+
};
|
|
3044
|
+
}
|
|
3045
|
+
var ResolvedScenarios = class {
|
|
3046
|
+
constructor() {
|
|
3047
|
+
/** The array of all resolved scenarios. */
|
|
3048
|
+
this.resolvedScenarios = [];
|
|
3049
|
+
/** The set of resolved scenarios that include an ID, keyed by ID. */
|
|
3050
|
+
this.resolvedScenariosById = /* @__PURE__ */ new Map();
|
|
3051
|
+
}
|
|
3052
|
+
add(scenarios) {
|
|
3053
|
+
for (const resolvedScenario of scenarios) {
|
|
3054
|
+
this.resolvedScenarios.push(resolvedScenario);
|
|
3055
|
+
if (resolvedScenario.id !== void 0) {
|
|
3056
|
+
if (this.resolvedScenariosById.has(resolvedScenario.id)) {
|
|
3057
|
+
throw new Error(`Multiple scenarios defined with the same id (${resolvedScenario.id})`);
|
|
3058
|
+
}
|
|
3059
|
+
this.resolvedScenariosById.set(resolvedScenario.id, resolvedScenario);
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
3063
|
+
getAll() {
|
|
3064
|
+
return this.resolvedScenarios;
|
|
3065
|
+
}
|
|
3066
|
+
getScenarioForId(id) {
|
|
3067
|
+
return this.resolvedScenariosById.get(id);
|
|
3068
|
+
}
|
|
3069
|
+
};
|
|
3070
|
+
function resolveScenariosFromSpec(modelInputsL, modelInputsR, scenarioSpec, genKey) {
|
|
3071
|
+
switch (scenarioSpec.kind) {
|
|
3072
|
+
case "scenario-matrix":
|
|
3073
|
+
return resolveScenarioMatrix(modelInputsL, modelInputsR, genKey);
|
|
3074
|
+
case "scenario-with-all-inputs": {
|
|
3075
|
+
const position = inputPosition2(scenarioSpec.position);
|
|
3076
|
+
return [
|
|
3077
|
+
resolveScenarioWithAllInputsAtPosition(
|
|
3078
|
+
genKey(),
|
|
3079
|
+
scenarioSpec.id,
|
|
3080
|
+
scenarioSpec.title,
|
|
3081
|
+
scenarioSpec.subtitle,
|
|
3082
|
+
position
|
|
3083
|
+
)
|
|
3084
|
+
];
|
|
3085
|
+
}
|
|
3086
|
+
case "scenario-with-inputs": {
|
|
3087
|
+
return [
|
|
3088
|
+
resolveScenarioForInputSpecs(
|
|
3089
|
+
modelInputsL,
|
|
3090
|
+
modelInputsR,
|
|
3091
|
+
genKey(),
|
|
3092
|
+
scenarioSpec.id,
|
|
3093
|
+
scenarioSpec.title,
|
|
3094
|
+
scenarioSpec.subtitle,
|
|
3095
|
+
scenarioSpec.inputs
|
|
3096
|
+
)
|
|
3097
|
+
];
|
|
3098
|
+
}
|
|
3099
|
+
case "scenario-with-distinct-inputs": {
|
|
3100
|
+
return [
|
|
3101
|
+
resolveScenarioForDistinctInputSpecs(
|
|
3102
|
+
modelInputsL,
|
|
3103
|
+
modelInputsR,
|
|
3104
|
+
genKey(),
|
|
3105
|
+
scenarioSpec.id,
|
|
3106
|
+
scenarioSpec.title,
|
|
3107
|
+
scenarioSpec.subtitle,
|
|
3108
|
+
scenarioSpec.inputsL,
|
|
3109
|
+
scenarioSpec.inputsR
|
|
3110
|
+
)
|
|
3111
|
+
];
|
|
3112
|
+
}
|
|
3113
|
+
default:
|
|
3114
|
+
assertNever11(scenarioSpec);
|
|
3115
|
+
}
|
|
3116
|
+
}
|
|
3117
|
+
function resolveScenarioMatrix(modelInputsL, modelInputsR, genKey) {
|
|
3118
|
+
const resolvedScenarios = [];
|
|
3119
|
+
resolvedScenarios.push(
|
|
3120
|
+
resolveScenarioWithAllInputsAtPosition(genKey(), void 0, void 0, void 0, "at-default")
|
|
3121
|
+
);
|
|
3122
|
+
const inputIdAliases = /* @__PURE__ */ new Set();
|
|
3123
|
+
modelInputsL.getAllInputIdAliases().forEach((alias) => inputIdAliases.add(alias));
|
|
3124
|
+
modelInputsR.getAllInputIdAliases().forEach((alias) => inputIdAliases.add(alias));
|
|
3125
|
+
for (const inputIdAlias of inputIdAliases) {
|
|
3126
|
+
const inputAtMin = {
|
|
3127
|
+
kind: "input-at-position",
|
|
3128
|
+
inputName: inputIdAlias,
|
|
3129
|
+
position: "min"
|
|
3130
|
+
};
|
|
3131
|
+
const inputAtMax = {
|
|
3132
|
+
kind: "input-at-position",
|
|
3133
|
+
inputName: inputIdAlias,
|
|
3134
|
+
position: "max"
|
|
3135
|
+
};
|
|
3136
|
+
resolvedScenarios.push(
|
|
3137
|
+
resolveScenarioForInputSpecs(modelInputsL, modelInputsR, genKey(), void 0, void 0, void 0, [inputAtMin])
|
|
3138
|
+
);
|
|
3139
|
+
resolvedScenarios.push(
|
|
3140
|
+
resolveScenarioForInputSpecs(modelInputsL, modelInputsR, genKey(), void 0, void 0, void 0, [inputAtMax])
|
|
3141
|
+
);
|
|
3142
|
+
}
|
|
3143
|
+
return resolvedScenarios;
|
|
3144
|
+
}
|
|
3145
|
+
function resolveScenarioWithAllInputsAtPosition(key, id, title, subtitle, position) {
|
|
3146
|
+
const settings = {
|
|
3147
|
+
kind: "all-inputs-settings",
|
|
3148
|
+
position
|
|
3149
|
+
};
|
|
3150
|
+
const [specL, specR] = scenarioSpecsFromSettings(settings);
|
|
3151
|
+
return {
|
|
3152
|
+
kind: "scenario",
|
|
3153
|
+
key,
|
|
3154
|
+
id,
|
|
3155
|
+
title,
|
|
3156
|
+
subtitle,
|
|
3157
|
+
settings,
|
|
3158
|
+
specL,
|
|
3159
|
+
specR
|
|
3160
|
+
};
|
|
3161
|
+
}
|
|
3162
|
+
function resolveScenarioForInputSpecs(modelInputsL, modelInputsR, key, id, title, subtitle, inputSpecs) {
|
|
3163
|
+
const resolvedInputs = inputSpecs.map((inputSpec) => {
|
|
3164
|
+
switch (inputSpec.kind) {
|
|
3165
|
+
case "input-at-position":
|
|
3166
|
+
return resolveInputForName(modelInputsL, modelInputsR, inputSpec.inputName, inputSpec.position);
|
|
3167
|
+
case "input-at-value":
|
|
3168
|
+
return resolveInputForName(modelInputsL, modelInputsR, inputSpec.inputName, inputSpec.value);
|
|
3169
|
+
default:
|
|
3170
|
+
assertNever11(inputSpec);
|
|
3171
|
+
}
|
|
3172
|
+
});
|
|
3173
|
+
const settings = {
|
|
3174
|
+
kind: "input-settings",
|
|
3175
|
+
inputs: resolvedInputs
|
|
3176
|
+
};
|
|
3177
|
+
const [specL, specR] = scenarioSpecsFromSettings(settings);
|
|
3178
|
+
return {
|
|
3179
|
+
kind: "scenario",
|
|
3180
|
+
key,
|
|
3181
|
+
id,
|
|
3182
|
+
title,
|
|
3183
|
+
subtitle,
|
|
3184
|
+
settings,
|
|
3185
|
+
specL,
|
|
3186
|
+
specR
|
|
3187
|
+
};
|
|
3188
|
+
}
|
|
3189
|
+
function resolveScenarioForDistinctInputSpecs(modelInputsL, modelInputsR, key, id, title, subtitle, inputSpecsL, inputSpecsR) {
|
|
3190
|
+
const inputsWithErrors = [];
|
|
3191
|
+
const settingsL = [];
|
|
3192
|
+
const settingsR = [];
|
|
3193
|
+
function resolveInputSpec(side, modelInputs, inputSpec) {
|
|
3194
|
+
let inputState;
|
|
3195
|
+
switch (inputSpec.kind) {
|
|
3196
|
+
case "input-at-position":
|
|
3197
|
+
inputState = resolveInputForNameInModel(modelInputs, inputSpec.inputName, inputSpec.position);
|
|
3198
|
+
break;
|
|
3199
|
+
case "input-at-value":
|
|
3200
|
+
inputState = resolveInputForNameInModel(modelInputs, inputSpec.inputName, inputSpec.value);
|
|
3201
|
+
break;
|
|
3202
|
+
default:
|
|
3203
|
+
assertNever11(inputSpec);
|
|
3204
|
+
}
|
|
3205
|
+
if (inputState.error !== void 0) {
|
|
3206
|
+
inputsWithErrors.push({
|
|
3207
|
+
requestedName: inputSpec.inputName,
|
|
3208
|
+
stateL: side === "left" ? inputState : {},
|
|
3209
|
+
stateR: side === "right" ? inputState : {}
|
|
3210
|
+
});
|
|
3211
|
+
} else {
|
|
3212
|
+
const inputSetting = inputSettingFromResolvedInputState(inputState);
|
|
3213
|
+
if (side === "left") {
|
|
3214
|
+
settingsL.push(inputSetting);
|
|
3215
|
+
} else {
|
|
3216
|
+
settingsR.push(inputSetting);
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
}
|
|
3220
|
+
inputSpecsL.forEach((inputSpec) => resolveInputSpec("left", modelInputsL, inputSpec));
|
|
3221
|
+
inputSpecsR.forEach((inputSpec) => resolveInputSpec("right", modelInputsR, inputSpec));
|
|
3222
|
+
let specL;
|
|
3223
|
+
let specR;
|
|
3224
|
+
if (inputsWithErrors.length === 0) {
|
|
3225
|
+
specL = inputSettingsSpec(settingsL);
|
|
3226
|
+
specR = inputSettingsSpec(settingsR);
|
|
3227
|
+
}
|
|
3228
|
+
return {
|
|
3229
|
+
kind: "scenario",
|
|
3230
|
+
key,
|
|
3231
|
+
id,
|
|
3232
|
+
title,
|
|
3233
|
+
subtitle,
|
|
3234
|
+
settings: {
|
|
3235
|
+
kind: "input-settings",
|
|
3236
|
+
inputs: inputsWithErrors
|
|
3237
|
+
},
|
|
3238
|
+
specL,
|
|
3239
|
+
specR
|
|
3240
|
+
};
|
|
3241
|
+
}
|
|
3242
|
+
function resolveInputForName(modelInputsL, modelInputsR, inputName, at) {
|
|
3243
|
+
return {
|
|
3244
|
+
requestedName: inputName,
|
|
3245
|
+
stateL: resolveInputForNameInModel(modelInputsL, inputName, at),
|
|
3246
|
+
stateR: resolveInputForNameInModel(modelInputsR, inputName, at)
|
|
3247
|
+
};
|
|
3248
|
+
}
|
|
3249
|
+
function resolveInputForNameInModel(modelInputs, inputName, at) {
|
|
3250
|
+
const inputVar = modelInputs.getInputVarForName(inputName);
|
|
3251
|
+
if (inputVar) {
|
|
3252
|
+
return resolveInputVar(inputVar, at);
|
|
3253
|
+
} else {
|
|
3254
|
+
return {
|
|
3255
|
+
error: {
|
|
3256
|
+
kind: "unknown-input"
|
|
3257
|
+
}
|
|
3258
|
+
};
|
|
3259
|
+
}
|
|
3260
|
+
}
|
|
3261
|
+
function resolveInputVar(inputVar, at) {
|
|
3262
|
+
if (typeof at === "number") {
|
|
3263
|
+
const value = at;
|
|
3264
|
+
return resolveInputVarAtValue(inputVar, value);
|
|
3265
|
+
} else {
|
|
3266
|
+
const position = inputPosition2(at);
|
|
3267
|
+
return resolveInputVarAtPosition(inputVar, position);
|
|
3268
|
+
}
|
|
3269
|
+
}
|
|
3270
|
+
function resolveInputVarAtPosition(inputVar, position) {
|
|
3271
|
+
return {
|
|
3272
|
+
inputVar,
|
|
3273
|
+
position,
|
|
3274
|
+
value: inputValueAtPosition2(inputVar, position)
|
|
3275
|
+
};
|
|
3276
|
+
}
|
|
3277
|
+
function resolveInputVarAtValue(inputVar, value) {
|
|
3278
|
+
if (value >= inputVar.minValue && value <= inputVar.maxValue) {
|
|
3279
|
+
return {
|
|
3280
|
+
inputVar,
|
|
3281
|
+
value
|
|
3282
|
+
};
|
|
3283
|
+
} else {
|
|
3284
|
+
return {
|
|
3285
|
+
error: {
|
|
3286
|
+
kind: "invalid-value"
|
|
3287
|
+
}
|
|
3288
|
+
};
|
|
3289
|
+
}
|
|
3290
|
+
}
|
|
3291
|
+
function inputPosition2(position) {
|
|
3292
|
+
switch (position) {
|
|
3293
|
+
case "default":
|
|
3294
|
+
return "at-default";
|
|
3295
|
+
case "min":
|
|
3296
|
+
return "at-minimum";
|
|
3297
|
+
case "max":
|
|
3298
|
+
return "at-maximum";
|
|
3299
|
+
default:
|
|
3300
|
+
return void 0;
|
|
3301
|
+
}
|
|
3302
|
+
}
|
|
3303
|
+
function inputValueAtPosition2(inputVar, position) {
|
|
3304
|
+
switch (position) {
|
|
3305
|
+
case "at-default":
|
|
3306
|
+
return inputVar.defaultValue;
|
|
3307
|
+
case "at-minimum":
|
|
3308
|
+
return inputVar.minValue;
|
|
3309
|
+
case "at-maximum":
|
|
3310
|
+
return inputVar.maxValue;
|
|
3311
|
+
default:
|
|
3312
|
+
assertNever11(position);
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
var ResolvedScenarioGroups = class {
|
|
3316
|
+
constructor() {
|
|
3317
|
+
/** The array of all resolved scenario groups. */
|
|
3318
|
+
this.resolvedGroups = [];
|
|
3319
|
+
/** The set of resolved scenario groups that include an ID, keyed by ID. */
|
|
3320
|
+
this.resolvedGroupsById = /* @__PURE__ */ new Map();
|
|
3321
|
+
}
|
|
3322
|
+
add(group) {
|
|
3323
|
+
this.resolvedGroups.push(group);
|
|
3324
|
+
if (group.id !== void 0) {
|
|
3325
|
+
if (this.resolvedGroupsById.has(group.id)) {
|
|
3326
|
+
throw new Error(`Multiple scenario groups defined with the same id (${group.id})`);
|
|
3327
|
+
}
|
|
3328
|
+
this.resolvedGroupsById.set(group.id, group);
|
|
3329
|
+
}
|
|
3330
|
+
}
|
|
3331
|
+
getAll() {
|
|
3332
|
+
return this.resolvedGroups;
|
|
3333
|
+
}
|
|
3334
|
+
getGroupForId(id) {
|
|
3335
|
+
return this.resolvedGroupsById.get(id);
|
|
3336
|
+
}
|
|
3337
|
+
};
|
|
3338
|
+
function resolveGraphsFromSpec(graphsSpec) {
|
|
3339
|
+
switch (graphsSpec.kind) {
|
|
3340
|
+
case "graphs-preset":
|
|
3341
|
+
return "all";
|
|
3342
|
+
case "graphs-array":
|
|
3343
|
+
return graphsSpec.graphIds;
|
|
3344
|
+
default:
|
|
3345
|
+
assertNever11(graphsSpec);
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
function resolveViewForScenarioId(resolvedScenarios, viewTitle, viewSubtitle, scenarioId, graphs) {
|
|
3349
|
+
const resolvedScenario = resolvedScenarios.getScenarioForId(scenarioId);
|
|
3350
|
+
if (resolvedScenario) {
|
|
3351
|
+
return resolveViewForScenario(viewTitle, viewSubtitle, resolvedScenario, graphs);
|
|
3352
|
+
} else {
|
|
3353
|
+
return unresolvedViewForScenarioId(viewTitle, viewSubtitle, scenarioId);
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
function resolveViewForScenarioRefSpec(resolvedScenarios, refSpec, graphs) {
|
|
3357
|
+
const resolvedScenario = resolvedScenarios.getScenarioForId(refSpec.scenarioId);
|
|
3358
|
+
if (resolvedScenario) {
|
|
3359
|
+
return resolveViewForScenario(refSpec.title, refSpec.subtitle, resolvedScenario, graphs);
|
|
3360
|
+
} else {
|
|
3361
|
+
return unresolvedViewForScenarioId(void 0, void 0, refSpec.scenarioId);
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
3364
|
+
function resolveViewForScenario(viewTitle, viewSubtitle, resolvedScenario, graphs) {
|
|
3365
|
+
if (viewTitle === void 0) {
|
|
3366
|
+
viewTitle = resolvedScenario.title;
|
|
3367
|
+
if (viewTitle === void 0) {
|
|
3368
|
+
viewTitle = "Untitled view";
|
|
3369
|
+
}
|
|
3370
|
+
if (viewSubtitle === void 0) {
|
|
3371
|
+
viewSubtitle = resolvedScenario.subtitle;
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
return {
|
|
3375
|
+
kind: "view",
|
|
3376
|
+
title: viewTitle,
|
|
3377
|
+
subtitle: viewSubtitle,
|
|
3378
|
+
scenario: resolvedScenario,
|
|
3379
|
+
graphs
|
|
3380
|
+
};
|
|
3381
|
+
}
|
|
3382
|
+
function unresolvedViewForScenarioId(viewTitle, viewSubtitle, scenarioId) {
|
|
3383
|
+
return {
|
|
3384
|
+
kind: "unresolved-view",
|
|
3385
|
+
title: viewTitle,
|
|
3386
|
+
subtitle: viewSubtitle,
|
|
3387
|
+
scenarioId
|
|
3388
|
+
};
|
|
3389
|
+
}
|
|
3390
|
+
function unresolvedViewForScenarioGroupId(viewTitle, viewSubtitle, scenarioGroupId) {
|
|
3391
|
+
return {
|
|
3392
|
+
kind: "unresolved-view",
|
|
3393
|
+
title: viewTitle,
|
|
3394
|
+
subtitle: viewSubtitle,
|
|
3395
|
+
scenarioGroupId
|
|
3396
|
+
};
|
|
3397
|
+
}
|
|
3398
|
+
function resolveViewGroupFromSpec(resolvedScenarios, resolvedScenarioGroups, viewGroupSpec) {
|
|
3399
|
+
let views;
|
|
3400
|
+
switch (viewGroupSpec.kind) {
|
|
3401
|
+
case "view-group-with-views": {
|
|
3402
|
+
views = viewGroupSpec.views.map((viewSpec) => {
|
|
3403
|
+
const graphs = resolveGraphsFromSpec(viewSpec.graphs);
|
|
3404
|
+
return resolveViewForScenarioId(
|
|
3405
|
+
resolvedScenarios,
|
|
3406
|
+
viewSpec.title,
|
|
3407
|
+
viewSpec.subtitle,
|
|
3408
|
+
viewSpec.scenarioId,
|
|
3409
|
+
graphs
|
|
3410
|
+
);
|
|
3411
|
+
});
|
|
3412
|
+
break;
|
|
3413
|
+
}
|
|
3414
|
+
case "view-group-with-scenarios": {
|
|
3415
|
+
const graphs = resolveGraphsFromSpec(viewGroupSpec.graphs);
|
|
3416
|
+
views = [];
|
|
3417
|
+
for (const refSpec of viewGroupSpec.scenarios) {
|
|
3418
|
+
switch (refSpec.kind) {
|
|
3419
|
+
case "scenario-ref":
|
|
3420
|
+
views.push(resolveViewForScenarioRefSpec(resolvedScenarios, refSpec, graphs));
|
|
3421
|
+
break;
|
|
3422
|
+
case "scenario-group-ref": {
|
|
3423
|
+
const resolvedGroup = resolvedScenarioGroups.getGroupForId(refSpec.groupId);
|
|
3424
|
+
if (resolvedGroup) {
|
|
3425
|
+
for (const scenario of resolvedGroup.scenarios) {
|
|
3426
|
+
switch (scenario.kind) {
|
|
3427
|
+
case "unresolved-scenario-ref":
|
|
3428
|
+
views.push(unresolvedViewForScenarioId(void 0, void 0, scenario.scenarioId));
|
|
3429
|
+
break;
|
|
3430
|
+
case "scenario":
|
|
3431
|
+
views.push(resolveViewForScenario(void 0, void 0, scenario, graphs));
|
|
3432
|
+
break;
|
|
3433
|
+
default:
|
|
3434
|
+
assertNever11(scenario);
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3437
|
+
} else {
|
|
3438
|
+
views.push(unresolvedViewForScenarioGroupId(void 0, void 0, refSpec.groupId));
|
|
3439
|
+
}
|
|
3440
|
+
break;
|
|
3441
|
+
}
|
|
3442
|
+
default:
|
|
3443
|
+
assertNever11(refSpec);
|
|
3444
|
+
}
|
|
3445
|
+
}
|
|
3446
|
+
break;
|
|
3447
|
+
}
|
|
3448
|
+
default:
|
|
3449
|
+
assertNever11(viewGroupSpec);
|
|
3450
|
+
}
|
|
3451
|
+
return {
|
|
3452
|
+
kind: "view-group",
|
|
3453
|
+
title: viewGroupSpec.title,
|
|
3454
|
+
views
|
|
3455
|
+
};
|
|
3456
|
+
}
|
|
3457
|
+
|
|
3458
|
+
// src/comparison/config/comparison-config.ts
|
|
3459
|
+
function resolveComparisonSpecsFromSources(modelInputsL, modelInputsR, specSources) {
|
|
3460
|
+
const combinedSpecs = {
|
|
3461
|
+
scenarios: [],
|
|
3462
|
+
scenarioGroups: [],
|
|
3463
|
+
viewGroups: []
|
|
3464
|
+
};
|
|
3465
|
+
for (const specSource of specSources) {
|
|
3466
|
+
let specs;
|
|
3467
|
+
if ("kind" in specSource) {
|
|
3468
|
+
const parseResult = parseComparisonSpecs(specSource);
|
|
3469
|
+
if (parseResult.isOk()) {
|
|
3470
|
+
specs = parseResult.value;
|
|
3471
|
+
} else {
|
|
3472
|
+
const filenamePart = specSource.filename ? ` in ${specSource.filename}` : "";
|
|
3473
|
+
console.error(`ERROR: Failed to parse comparison spec${filenamePart}, skipping`);
|
|
3474
|
+
continue;
|
|
3475
|
+
}
|
|
3476
|
+
} else {
|
|
3477
|
+
specs = specSource;
|
|
3478
|
+
}
|
|
3479
|
+
combinedSpecs.scenarios.push(...specs.scenarios);
|
|
3480
|
+
combinedSpecs.scenarioGroups.push(...specs.scenarioGroups);
|
|
3481
|
+
combinedSpecs.viewGroups.push(...specs.viewGroups);
|
|
3482
|
+
}
|
|
3483
|
+
return resolveComparisonSpecs(modelInputsL, modelInputsR, combinedSpecs);
|
|
3484
|
+
}
|
|
3485
|
+
|
|
3486
|
+
// src/comparison/config/comparison-datasets.ts
|
|
3487
|
+
function getComparisonDatasets(modelSpecL, modelSpecR, datasetOptions) {
|
|
3488
|
+
return new ComparisonDatasetsImpl(modelSpecL, modelSpecR, datasetOptions);
|
|
3489
|
+
}
|
|
3490
|
+
var ComparisonDatasetsImpl = class {
|
|
3491
|
+
/**
|
|
3492
|
+
* @param modelSpecL The model spec for the "left" bundle being compared.
|
|
3493
|
+
* @param modelSpecR The model spec for the "right" bundle being compared.
|
|
3494
|
+
* @param datasetOptions The custom configuration for the datasets to be compared.
|
|
3495
|
+
*/
|
|
3496
|
+
constructor(modelSpecL, modelSpecR, datasetOptions) {
|
|
3497
|
+
this.datasetOptions = datasetOptions;
|
|
3498
|
+
const renamedDatasetKeys = datasetOptions == null ? void 0 : datasetOptions.renamedDatasetKeys;
|
|
3499
|
+
const invertedRenamedKeys = /* @__PURE__ */ new Map();
|
|
3500
|
+
renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.forEach((newKey, oldKey) => {
|
|
3501
|
+
invertedRenamedKeys.set(newKey, oldKey);
|
|
3502
|
+
});
|
|
3503
|
+
function leftKeyForRightKey(rightKey) {
|
|
3504
|
+
return invertedRenamedKeys.get(rightKey) || rightKey;
|
|
3505
|
+
}
|
|
3506
|
+
const allOutputVarKeysSet = /* @__PURE__ */ new Set();
|
|
3507
|
+
const modelOutputVarKeysSet = /* @__PURE__ */ new Set();
|
|
3508
|
+
function addOutputVars(outputVars, handleRenames) {
|
|
3509
|
+
outputVars.forEach((outputVar, key) => {
|
|
3510
|
+
const remappedKey = handleRenames ? leftKeyForRightKey(key) : key;
|
|
3511
|
+
allOutputVarKeysSet.add(remappedKey);
|
|
2202
3512
|
if (outputVar.sourceName === void 0) {
|
|
2203
3513
|
modelOutputVarKeysSet.add(remappedKey);
|
|
2204
3514
|
}
|
|
2205
3515
|
});
|
|
2206
3516
|
}
|
|
2207
|
-
addOutputVars(
|
|
2208
|
-
addOutputVars(
|
|
3517
|
+
addOutputVars(modelSpecL.outputVars, false);
|
|
3518
|
+
addOutputVars(modelSpecR.outputVars, true);
|
|
2209
3519
|
this.allOutputVarKeys = Array.from(allOutputVarKeysSet);
|
|
2210
3520
|
this.modelOutputVarKeys = Array.from(modelOutputVarKeysSet);
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
3521
|
+
this.allDatasets = /* @__PURE__ */ new Map();
|
|
3522
|
+
for (const datasetKeyL of this.allOutputVarKeys) {
|
|
3523
|
+
const datasetKeyR = (renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.get(datasetKeyL)) || datasetKeyL;
|
|
3524
|
+
const outputVarL = modelSpecL.outputVars.get(datasetKeyL);
|
|
3525
|
+
const outputVarR = modelSpecR.outputVars.get(datasetKeyR);
|
|
3526
|
+
this.allDatasets.set(datasetKeyL, {
|
|
3527
|
+
kind: "dataset",
|
|
3528
|
+
key: datasetKeyL,
|
|
3529
|
+
outputVarL,
|
|
3530
|
+
outputVarR
|
|
3531
|
+
});
|
|
2217
3532
|
}
|
|
2218
3533
|
}
|
|
2219
|
-
|
|
3534
|
+
// from ComparisonDatasets interface
|
|
3535
|
+
getAllDatasets() {
|
|
3536
|
+
return this.allDatasets.values();
|
|
3537
|
+
}
|
|
3538
|
+
// from ComparisonDatasets interface
|
|
3539
|
+
getDataset(datasetKey) {
|
|
3540
|
+
return this.allDatasets.get(datasetKey);
|
|
3541
|
+
}
|
|
3542
|
+
// from ComparisonDatasets interface
|
|
3543
|
+
getDatasetKeysForScenario(scenario) {
|
|
2220
3544
|
var _a;
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
const datasetKeyL = datasetKey;
|
|
2224
|
-
const datasetKeyR = ((_a = this.renamedDatasetKeys) == null ? void 0 : _a.get(datasetKeyL)) || datasetKeyL;
|
|
2225
|
-
const outputVarL = modelSpecL.outputVars.get(datasetKeyL);
|
|
2226
|
-
const outputVarR = modelSpecR.outputVars.get(datasetKeyR);
|
|
2227
|
-
let varName;
|
|
2228
|
-
let newVarName;
|
|
2229
|
-
let sourceName;
|
|
2230
|
-
let newSourceName;
|
|
2231
|
-
if (outputVarL && outputVarR && outputVarL.varName != outputVarR.varName) {
|
|
2232
|
-
varName = outputVarL.varName;
|
|
2233
|
-
newVarName = outputVarR.varName;
|
|
2234
|
-
} else {
|
|
2235
|
-
const outputVar = outputVarR || outputVarL;
|
|
2236
|
-
varName = (outputVar == null ? void 0 : outputVar.varName) || "Unknown";
|
|
2237
|
-
}
|
|
2238
|
-
if (outputVarL && outputVarR && outputVarL.sourceName != outputVarR.sourceName) {
|
|
2239
|
-
sourceName = outputVarL.sourceName;
|
|
2240
|
-
newSourceName = outputVarR.sourceName;
|
|
3545
|
+
if (((_a = this.datasetOptions) == null ? void 0 : _a.datasetKeysForScenario) !== void 0) {
|
|
3546
|
+
return this.datasetOptions.datasetKeysForScenario(this.allOutputVarKeys, scenario);
|
|
2241
3547
|
} else {
|
|
2242
|
-
|
|
2243
|
-
|
|
3548
|
+
if (scenario.settings.kind === "all-inputs-settings" && scenario.settings.position === "at-default") {
|
|
3549
|
+
return this.allOutputVarKeys;
|
|
3550
|
+
} else {
|
|
3551
|
+
return this.modelOutputVarKeys;
|
|
3552
|
+
}
|
|
2244
3553
|
}
|
|
2245
|
-
return {
|
|
2246
|
-
varName,
|
|
2247
|
-
newVarName,
|
|
2248
|
-
sourceName,
|
|
2249
|
-
newSourceName,
|
|
2250
|
-
relatedItems: (outputVarR == null ? void 0 : outputVarR.relatedItems) || []
|
|
2251
|
-
};
|
|
2252
3554
|
}
|
|
2253
3555
|
};
|
|
2254
3556
|
|
|
2255
|
-
// src/config/
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
this.
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
this.groupInfo = /* @__PURE__ */ new Map();
|
|
2265
|
-
}
|
|
2266
|
-
getScenarios() {
|
|
2267
|
-
return [...this.scenarios.values()];
|
|
2268
|
-
}
|
|
2269
|
-
getScenario(scenarioKey) {
|
|
2270
|
-
return this.scenarios.get(scenarioKey);
|
|
2271
|
-
}
|
|
2272
|
-
getScenarioGroupInfo(groupKey) {
|
|
2273
|
-
return this.groupInfo.get(groupKey);
|
|
2274
|
-
}
|
|
2275
|
-
getScenarioInfo(scenario, groupKey) {
|
|
2276
|
-
if (scenario.key === "all_inputs_at_default") {
|
|
2277
|
-
const defaultInfo = this.defaultInfoForGroup.get(groupKey);
|
|
2278
|
-
if (defaultInfo) {
|
|
2279
|
-
return defaultInfo;
|
|
2280
|
-
}
|
|
2281
|
-
}
|
|
2282
|
-
return this.scenarioInfo.get(scenario.key);
|
|
2283
|
-
}
|
|
2284
|
-
setDefaultScenarioInfoForGroup(groupKey, scenarioInfo) {
|
|
2285
|
-
this.defaultInfoForGroup.set(groupKey, scenarioInfo);
|
|
2286
|
-
}
|
|
2287
|
-
addScenario(scenario, scenarioInfo, groupInfo) {
|
|
2288
|
-
this.scenarios.set(scenario.key, scenario);
|
|
2289
|
-
if (!scenarioInfo) {
|
|
2290
|
-
scenarioInfo = this.getInfoForScenario(scenario);
|
|
2291
|
-
}
|
|
2292
|
-
this.scenarioInfo.set(scenario.key, scenarioInfo);
|
|
2293
|
-
if (!groupInfo) {
|
|
2294
|
-
groupInfo = this.getGroupInfoForScenario(scenario);
|
|
2295
|
-
}
|
|
2296
|
-
this.groupInfo.set(scenario.groupKey, groupInfo);
|
|
2297
|
-
}
|
|
2298
|
-
addScenarioMatrix() {
|
|
2299
|
-
const inputVarIdsL = Array.from(this.bundleL.modelSpec.inputVars.keys());
|
|
2300
|
-
const inputVarIdsR = Array.from(this.bundleR.modelSpec.inputVars.keys());
|
|
2301
|
-
const inputVarIds = /* @__PURE__ */ new Set([...inputVarIdsL, ...inputVarIdsR]);
|
|
2302
|
-
this.addScenario(allInputsAtPositionScenario("at-default"));
|
|
2303
|
-
this.addScenario(allInputsAtPositionScenario("at-minimum"));
|
|
2304
|
-
this.addScenario(allInputsAtPositionScenario("at-maximum"));
|
|
2305
|
-
for (const inputVarId of inputVarIds) {
|
|
2306
|
-
this.addScenario(inputAtPositionScenario(inputVarId, inputVarId, "at-minimum"));
|
|
2307
|
-
this.addScenario(inputAtPositionScenario(inputVarId, inputVarId, "at-maximum"));
|
|
2308
|
-
}
|
|
2309
|
-
}
|
|
2310
|
-
getGroupInfoForScenario(scenario) {
|
|
2311
|
-
switch (scenario.kind) {
|
|
2312
|
-
case "all-inputs":
|
|
2313
|
-
return {
|
|
2314
|
-
title: "All Inputs",
|
|
2315
|
-
relatedItems: []
|
|
2316
|
-
};
|
|
2317
|
-
case "settings":
|
|
2318
|
-
if (scenario.settings.length === 1) {
|
|
2319
|
-
const inputVar = this.getInputVarForSetting(scenario.settings[0]);
|
|
2320
|
-
let relatedItems;
|
|
2321
|
-
let subtitle;
|
|
2322
|
-
if (inputVar == null ? void 0 : inputVar.relatedItem) {
|
|
2323
|
-
relatedItems = [inputVar.relatedItem];
|
|
2324
|
-
subtitle = inputVar.relatedItem.locationPath.join(' <span class="related-sep">></span> ');
|
|
2325
|
-
} else {
|
|
2326
|
-
relatedItems = [];
|
|
2327
|
-
subtitle = void 0;
|
|
2328
|
-
}
|
|
2329
|
-
return {
|
|
2330
|
-
title: (inputVar == null ? void 0 : inputVar.varName) || "Unknown Input",
|
|
2331
|
-
subtitle,
|
|
2332
|
-
relatedItems
|
|
2333
|
-
};
|
|
2334
|
-
} else {
|
|
2335
|
-
return {
|
|
2336
|
-
title: "Multiple Inputs",
|
|
2337
|
-
relatedItems: this.getRelatedItemsForSettings(scenario.settings)
|
|
2338
|
-
};
|
|
2339
|
-
}
|
|
2340
|
-
default:
|
|
2341
|
-
assertNever8(scenario);
|
|
3557
|
+
// src/comparison/config/comparison-scenarios.ts
|
|
3558
|
+
function getComparisonScenarios(scenarios) {
|
|
3559
|
+
return new ComparisonScenariosImpl(scenarios);
|
|
3560
|
+
}
|
|
3561
|
+
var ComparisonScenariosImpl = class {
|
|
3562
|
+
constructor(scenarios) {
|
|
3563
|
+
this.scenarioDefs = /* @__PURE__ */ new Map();
|
|
3564
|
+
for (const scenario of scenarios) {
|
|
3565
|
+
this.scenarioDefs.set(scenario.key, scenario);
|
|
2342
3566
|
}
|
|
2343
3567
|
}
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
if (scenario.settings.length === 1 && scenario.settings[0].kind === "position") {
|
|
2350
|
-
const setting = scenario.settings[0];
|
|
2351
|
-
return this.getInfoForPositionSetting(setting.inputVarId, setting.position);
|
|
2352
|
-
} else {
|
|
2353
|
-
return {
|
|
2354
|
-
title: `PLACEHOLDER (scenario info not provided)`,
|
|
2355
|
-
position: 1
|
|
2356
|
-
};
|
|
2357
|
-
}
|
|
2358
|
-
default:
|
|
2359
|
-
assertNever8(scenario);
|
|
2360
|
-
}
|
|
3568
|
+
/**
|
|
3569
|
+
* Return all `ComparisonScenario` instances that are available for comparisons.
|
|
3570
|
+
*/
|
|
3571
|
+
getAllScenarios() {
|
|
3572
|
+
return this.scenarioDefs.values();
|
|
2361
3573
|
}
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
3574
|
+
/**
|
|
3575
|
+
* Return the scenario definition for the given key.
|
|
3576
|
+
*
|
|
3577
|
+
* @param key The key for the scenario.
|
|
3578
|
+
*/
|
|
3579
|
+
getScenario(key) {
|
|
3580
|
+
return this.scenarioDefs.get(key);
|
|
3581
|
+
}
|
|
3582
|
+
};
|
|
3583
|
+
|
|
3584
|
+
// src/config/synchronized-model.ts
|
|
3585
|
+
function synchronizedBundleModel(sourceModel) {
|
|
3586
|
+
const promiseQueue = new PromiseQueue();
|
|
3587
|
+
return {
|
|
3588
|
+
modelSpec: sourceModel.modelSpec,
|
|
3589
|
+
getDatasetsForScenario: (scenarioSpec, datasetKeys) => {
|
|
3590
|
+
return promiseQueue.add(() => sourceModel.getDatasetsForScenario(scenarioSpec, datasetKeys));
|
|
3591
|
+
},
|
|
3592
|
+
getGraphDataForScenario: (scenarioSpec, graphId) => {
|
|
3593
|
+
return promiseQueue.add(() => sourceModel.getGraphDataForScenario(scenarioSpec, graphId));
|
|
3594
|
+
},
|
|
3595
|
+
getGraphLinksForScenario: sourceModel.getGraphLinksForScenario.bind(sourceModel)
|
|
3596
|
+
};
|
|
3597
|
+
}
|
|
3598
|
+
var PromiseQueue = class {
|
|
3599
|
+
constructor() {
|
|
3600
|
+
this.tasks = [];
|
|
3601
|
+
this.runningCount = 0;
|
|
3602
|
+
}
|
|
3603
|
+
add(f) {
|
|
3604
|
+
return new Promise((resolve, reject) => {
|
|
3605
|
+
const run = () => __async(this, null, function* () {
|
|
3606
|
+
this.runningCount++;
|
|
3607
|
+
const promise = f();
|
|
3608
|
+
try {
|
|
3609
|
+
const result = yield promise;
|
|
3610
|
+
resolve(result);
|
|
3611
|
+
} catch (e) {
|
|
3612
|
+
reject(e);
|
|
3613
|
+
} finally {
|
|
3614
|
+
this.runningCount--;
|
|
3615
|
+
this.runNext();
|
|
3616
|
+
}
|
|
3617
|
+
});
|
|
3618
|
+
if (this.runningCount < 1) {
|
|
3619
|
+
run();
|
|
2378
3620
|
} else {
|
|
2379
|
-
|
|
3621
|
+
this.tasks.push(run);
|
|
2380
3622
|
}
|
|
2381
|
-
}
|
|
2382
|
-
subtitle = void 0;
|
|
2383
|
-
}
|
|
2384
|
-
let position;
|
|
2385
|
-
switch (inputPosition2) {
|
|
2386
|
-
case "at-default":
|
|
2387
|
-
position = 0;
|
|
2388
|
-
break;
|
|
2389
|
-
case "at-minimum":
|
|
2390
|
-
position = 1;
|
|
2391
|
-
break;
|
|
2392
|
-
case "at-maximum":
|
|
2393
|
-
position = 2;
|
|
2394
|
-
break;
|
|
2395
|
-
default:
|
|
2396
|
-
assertNever8(inputPosition2);
|
|
2397
|
-
}
|
|
2398
|
-
return {
|
|
2399
|
-
title,
|
|
2400
|
-
subtitle,
|
|
2401
|
-
position
|
|
2402
|
-
};
|
|
3623
|
+
});
|
|
2403
3624
|
}
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
relatedItems.push(inputVar.relatedItem);
|
|
3625
|
+
runNext() {
|
|
3626
|
+
if (this.tasks.length > 0) {
|
|
3627
|
+
const task = this.tasks.shift();
|
|
3628
|
+
if (task) {
|
|
3629
|
+
task();
|
|
2410
3630
|
}
|
|
2411
3631
|
}
|
|
2412
|
-
return relatedItems;
|
|
2413
|
-
}
|
|
2414
|
-
getInputVarForSetting(setting) {
|
|
2415
|
-
const inputVarId = setting.inputVarId;
|
|
2416
|
-
const inputVarL = this.bundleL.modelSpec.inputVars.get(inputVarId);
|
|
2417
|
-
const inputVarR = this.bundleR.modelSpec.inputVars.get(inputVarId);
|
|
2418
|
-
return inputVarR || inputVarL;
|
|
2419
3632
|
}
|
|
2420
3633
|
};
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
3634
|
+
|
|
3635
|
+
// src/config/config.ts
|
|
3636
|
+
function createConfig(options) {
|
|
3637
|
+
return __async(this, null, function* () {
|
|
3638
|
+
var _a;
|
|
3639
|
+
const origCurrentBundle = yield loadSynchronized(options.current);
|
|
3640
|
+
let currentBundle;
|
|
3641
|
+
let comparisonConfig;
|
|
3642
|
+
if (options.comparison === void 0) {
|
|
3643
|
+
currentBundle = origCurrentBundle;
|
|
3644
|
+
} else {
|
|
3645
|
+
const baselineBundle = yield loadSynchronized(options.comparison.baseline);
|
|
3646
|
+
const renamedDatasetKeys = (_a = options.comparison.datasets) == null ? void 0 : _a.renamedDatasetKeys;
|
|
3647
|
+
const invertedRenamedKeys = /* @__PURE__ */ new Map();
|
|
3648
|
+
renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.forEach((newKey, oldKey) => {
|
|
3649
|
+
invertedRenamedKeys.set(newKey, oldKey);
|
|
3650
|
+
});
|
|
3651
|
+
const rightKeyForLeftKey = (leftKey) => {
|
|
3652
|
+
return (renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.get(leftKey)) || leftKey;
|
|
3653
|
+
};
|
|
3654
|
+
const leftKeyForRightKey = (rightKey) => {
|
|
3655
|
+
return invertedRenamedKeys.get(rightKey) || rightKey;
|
|
3656
|
+
};
|
|
3657
|
+
const origBundleModelR = origCurrentBundle.model;
|
|
3658
|
+
const adjBundleModelR = {
|
|
3659
|
+
modelSpec: origBundleModelR.modelSpec,
|
|
3660
|
+
getDatasetsForScenario: (scenarioSpec, datasetKeys) => __async(this, null, function* () {
|
|
3661
|
+
const rightKeys = datasetKeys.map(rightKeyForLeftKey);
|
|
3662
|
+
const result = yield origBundleModelR.getDatasetsForScenario(scenarioSpec, rightKeys);
|
|
3663
|
+
const mapWithRightKeys = result.datasetMap;
|
|
3664
|
+
const mapWithLeftKeys = /* @__PURE__ */ new Map();
|
|
3665
|
+
for (const [rightKey, dataset] of mapWithRightKeys.entries()) {
|
|
3666
|
+
const leftKey = leftKeyForRightKey(rightKey);
|
|
3667
|
+
mapWithLeftKeys.set(leftKey, dataset);
|
|
3668
|
+
}
|
|
3669
|
+
return {
|
|
3670
|
+
datasetMap: mapWithLeftKeys,
|
|
3671
|
+
modelRunTime: result.modelRunTime
|
|
3672
|
+
};
|
|
3673
|
+
}),
|
|
3674
|
+
getGraphDataForScenario: origBundleModelR.getGraphDataForScenario.bind(origBundleModelR),
|
|
3675
|
+
getGraphLinksForScenario: origBundleModelR.getGraphLinksForScenario.bind(origBundleModelR)
|
|
3676
|
+
};
|
|
3677
|
+
currentBundle = __spreadProps(__spreadValues({}, origCurrentBundle), {
|
|
3678
|
+
model: adjBundleModelR
|
|
3679
|
+
});
|
|
3680
|
+
const modelSpecL = baselineBundle.model.modelSpec;
|
|
3681
|
+
const modelSpecR = currentBundle.model.modelSpec;
|
|
3682
|
+
const modelInputsL = new ModelInputs(modelSpecL);
|
|
3683
|
+
const modelInputsR = new ModelInputs(modelSpecR);
|
|
3684
|
+
const comparisonDefs = resolveComparisonSpecsFromSources(modelInputsL, modelInputsR, options.comparison.specs);
|
|
3685
|
+
comparisonConfig = {
|
|
3686
|
+
bundleL: baselineBundle,
|
|
3687
|
+
bundleR: currentBundle,
|
|
3688
|
+
thresholds: options.comparison.thresholds,
|
|
3689
|
+
scenarios: getComparisonScenarios(comparisonDefs.scenarios),
|
|
3690
|
+
datasets: getComparisonDatasets(modelSpecL, modelSpecR, options.comparison.datasets),
|
|
3691
|
+
viewGroups: comparisonDefs.viewGroups
|
|
3692
|
+
};
|
|
2432
3693
|
}
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
3694
|
+
const checkConfig = {
|
|
3695
|
+
bundle: currentBundle,
|
|
3696
|
+
tests: options.check.tests
|
|
3697
|
+
};
|
|
3698
|
+
return {
|
|
3699
|
+
check: checkConfig,
|
|
3700
|
+
comparison: comparisonConfig
|
|
3701
|
+
};
|
|
3702
|
+
});
|
|
3703
|
+
}
|
|
3704
|
+
function loadSynchronized(sourceBundle) {
|
|
3705
|
+
return __async(this, null, function* () {
|
|
3706
|
+
const sourceModel = yield sourceBundle.bundle.initModel();
|
|
3707
|
+
const synchronizedModel = synchronizedBundleModel(sourceModel);
|
|
3708
|
+
return {
|
|
3709
|
+
name: sourceBundle.name,
|
|
3710
|
+
version: sourceBundle.bundle.version,
|
|
3711
|
+
model: synchronizedModel
|
|
3712
|
+
};
|
|
3713
|
+
});
|
|
2436
3714
|
}
|
|
2437
3715
|
|
|
2438
3716
|
// src/perf/perf-runner.ts
|
|
2439
|
-
import { assertNever as
|
|
3717
|
+
import { assertNever as assertNever12 } from "assert-never";
|
|
2440
3718
|
|
|
2441
3719
|
// src/perf/perf-stats.ts
|
|
2442
3720
|
var PerfStats = class {
|
|
@@ -2480,26 +3758,26 @@ var PerfRunner = class {
|
|
|
2480
3758
|
this.bundleModelL = bundleModelL;
|
|
2481
3759
|
this.bundleModelR = bundleModelR;
|
|
2482
3760
|
this.mode = mode;
|
|
2483
|
-
const
|
|
3761
|
+
const scenarioSpec = allInputsAtPositionSpec("at-default");
|
|
2484
3762
|
this.taskQueue = new TaskQueue({
|
|
2485
|
-
process:
|
|
3763
|
+
process: (request) => __async(this, null, function* () {
|
|
2486
3764
|
switch (request.kind) {
|
|
2487
3765
|
case "left": {
|
|
2488
|
-
const result =
|
|
3766
|
+
const result = yield bundleModelL.getDatasetsForScenario(scenarioSpec, []);
|
|
2489
3767
|
return {
|
|
2490
3768
|
runTimeL: result.modelRunTime
|
|
2491
3769
|
};
|
|
2492
3770
|
}
|
|
2493
3771
|
case "right": {
|
|
2494
|
-
const result =
|
|
3772
|
+
const result = yield bundleModelR.getDatasetsForScenario(scenarioSpec, []);
|
|
2495
3773
|
return {
|
|
2496
3774
|
runTimeR: result.modelRunTime
|
|
2497
3775
|
};
|
|
2498
3776
|
}
|
|
2499
3777
|
case "both": {
|
|
2500
|
-
const [resultL, resultR] =
|
|
2501
|
-
bundleModelL.getDatasetsForScenario(
|
|
2502
|
-
bundleModelR.getDatasetsForScenario(
|
|
3778
|
+
const [resultL, resultR] = yield Promise.all([
|
|
3779
|
+
bundleModelL.getDatasetsForScenario(scenarioSpec, []),
|
|
3780
|
+
bundleModelR.getDatasetsForScenario(scenarioSpec, [])
|
|
2503
3781
|
]);
|
|
2504
3782
|
return {
|
|
2505
3783
|
runTimeL: resultL.modelRunTime,
|
|
@@ -2507,9 +3785,9 @@ var PerfRunner = class {
|
|
|
2507
3785
|
};
|
|
2508
3786
|
}
|
|
2509
3787
|
default:
|
|
2510
|
-
|
|
3788
|
+
assertNever12(request.kind);
|
|
2511
3789
|
}
|
|
2512
|
-
}
|
|
3790
|
+
})
|
|
2513
3791
|
});
|
|
2514
3792
|
}
|
|
2515
3793
|
start() {
|
|
@@ -2555,46 +3833,164 @@ var PerfRunner = class {
|
|
|
2555
3833
|
}
|
|
2556
3834
|
};
|
|
2557
3835
|
|
|
2558
|
-
// src/suite/suite-runner.ts
|
|
2559
|
-
import assertNever10 from "assert-never";
|
|
2560
|
-
|
|
2561
3836
|
// src/data/data-planner.ts
|
|
2562
|
-
var
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
3837
|
+
var DataPlanner = class {
|
|
3838
|
+
/**
|
|
3839
|
+
* @param batchSize The maximum number of impl vars that can be fetched
|
|
3840
|
+
* with a single request; this is usually the same as the number of
|
|
3841
|
+
* normal model outputs.
|
|
3842
|
+
*/
|
|
3843
|
+
constructor(batchSize) {
|
|
3844
|
+
this.batchSize = batchSize;
|
|
3845
|
+
/** Tasks that need to access both "left" and "right" models in parallel. */
|
|
3846
|
+
this.taskSetsLR = /* @__PURE__ */ new Map();
|
|
3847
|
+
/** Tasks that only need to access the "left" model. */
|
|
3848
|
+
this.taskSetsL = /* @__PURE__ */ new Map();
|
|
3849
|
+
/** Tasks that only need to access the "right" model. */
|
|
3850
|
+
this.taskSetsR = /* @__PURE__ */ new Map();
|
|
3851
|
+
this.complete = false;
|
|
2568
3852
|
}
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
3853
|
+
/**
|
|
3854
|
+
* Add a request to the plan for the given scenario(s) and data task.
|
|
3855
|
+
*
|
|
3856
|
+
* @param scenarioSpecL The input scenario used to configure the "left" model, or undefined if no data
|
|
3857
|
+
* is needed from the left model.
|
|
3858
|
+
* @param scenarioSpecR The input scenario used to configure the "right" model, or undefined if no data
|
|
3859
|
+
* is needed from the right model.
|
|
3860
|
+
* @param datasetKey The key for the dataset to be fetched from each model for the given scenario.
|
|
3861
|
+
* @param dataAction The action to be performed with the fetched datasets.
|
|
3862
|
+
*/
|
|
3863
|
+
addRequest(scenarioSpecL, scenarioSpecR, datasetKey, dataAction) {
|
|
3864
|
+
if (scenarioSpecL === void 0 && scenarioSpecR === void 0) {
|
|
3865
|
+
console.warn("WARNING: Both scenario specs are undefined for DataPlanner request, skipping");
|
|
3866
|
+
return;
|
|
3867
|
+
}
|
|
3868
|
+
let taskSetsMap;
|
|
3869
|
+
let uid;
|
|
3870
|
+
if (scenarioSpecL && scenarioSpecR) {
|
|
3871
|
+
taskSetsMap = this.taskSetsLR;
|
|
3872
|
+
uid = scenarioPairUid(scenarioSpecL, scenarioSpecR);
|
|
3873
|
+
} else if (scenarioSpecR) {
|
|
3874
|
+
taskSetsMap = this.taskSetsR;
|
|
3875
|
+
uid = scenarioSpecR.uid;
|
|
3876
|
+
} else {
|
|
3877
|
+
taskSetsMap = this.taskSetsL;
|
|
3878
|
+
uid = scenarioSpecL.uid;
|
|
2572
3879
|
}
|
|
2573
|
-
|
|
3880
|
+
let taskSet = taskSetsMap.get(uid);
|
|
3881
|
+
if (!taskSet) {
|
|
3882
|
+
taskSet = new DataTaskSet(scenarioSpecL, scenarioSpecR);
|
|
3883
|
+
taskSetsMap.set(uid, taskSet);
|
|
3884
|
+
}
|
|
3885
|
+
taskSet.addTask({
|
|
2574
3886
|
datasetKey,
|
|
2575
|
-
|
|
3887
|
+
dataAction
|
|
3888
|
+
});
|
|
3889
|
+
}
|
|
3890
|
+
/**
|
|
3891
|
+
* Build a plan that minimizes the number of data fetches needed.
|
|
3892
|
+
*/
|
|
3893
|
+
buildPlan() {
|
|
3894
|
+
if (this.complete) {
|
|
3895
|
+
throw new Error("DataPlanner.buildPlan() can only be called once");
|
|
3896
|
+
}
|
|
3897
|
+
this.complete = true;
|
|
3898
|
+
const lKeyMappings = /* @__PURE__ */ new Map();
|
|
3899
|
+
const rKeyMappings = /* @__PURE__ */ new Map();
|
|
3900
|
+
for (const lrUid of this.taskSetsLR.keys()) {
|
|
3901
|
+
const [lUid, rUid] = lrUid.split("::");
|
|
3902
|
+
if (!lKeyMappings.has(lUid)) {
|
|
3903
|
+
lKeyMappings.set(lUid, lrUid);
|
|
3904
|
+
}
|
|
3905
|
+
if (!rKeyMappings.has(rUid)) {
|
|
3906
|
+
rKeyMappings.set(rUid, lrUid);
|
|
3907
|
+
}
|
|
3908
|
+
}
|
|
3909
|
+
function merge(taskSetsLR, taskSetsForSide, keyMappingsForSide) {
|
|
3910
|
+
for (const [keyForSide, taskSetForSide] of taskSetsForSide.entries()) {
|
|
3911
|
+
const lrKey = keyMappingsForSide.get(keyForSide);
|
|
3912
|
+
if (lrKey) {
|
|
3913
|
+
const taskSetLR = taskSetsLR.get(lrKey);
|
|
3914
|
+
taskSetLR.merge(taskSetForSide);
|
|
3915
|
+
taskSetsForSide.delete(keyForSide);
|
|
3916
|
+
}
|
|
3917
|
+
}
|
|
3918
|
+
}
|
|
3919
|
+
merge(this.taskSetsLR, this.taskSetsL, lKeyMappings);
|
|
3920
|
+
merge(this.taskSetsLR, this.taskSetsR, rKeyMappings);
|
|
3921
|
+
const requests = [];
|
|
3922
|
+
const batchSize = this.batchSize;
|
|
3923
|
+
function addRequests(taskSets) {
|
|
3924
|
+
for (const taskSet of taskSets) {
|
|
3925
|
+
requests.push(...taskSet.buildRequests(batchSize));
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
addRequests(this.taskSetsLR.values());
|
|
3929
|
+
addRequests(this.taskSetsL.values());
|
|
3930
|
+
addRequests(this.taskSetsR.values());
|
|
3931
|
+
return {
|
|
3932
|
+
requests
|
|
2576
3933
|
};
|
|
3934
|
+
}
|
|
3935
|
+
};
|
|
3936
|
+
var DataTaskSet = class {
|
|
3937
|
+
constructor(scenarioSpecL, scenarioSpecR) {
|
|
3938
|
+
this.scenarioSpecL = scenarioSpecL;
|
|
3939
|
+
this.scenarioSpecR = scenarioSpecR;
|
|
3940
|
+
this.modelTasks = /* @__PURE__ */ new Map();
|
|
3941
|
+
this.modelImplTasks = /* @__PURE__ */ new Map();
|
|
3942
|
+
}
|
|
3943
|
+
/**
|
|
3944
|
+
* Add a task that will be performed when the data is fetched for the scenario(s)
|
|
3945
|
+
* associated with this task set.
|
|
3946
|
+
*
|
|
3947
|
+
* @param dataTask A task that performs an action using the fetched dataset(s).
|
|
3948
|
+
*/
|
|
3949
|
+
addTask(dataTask) {
|
|
2577
3950
|
let taskMap;
|
|
2578
|
-
if (datasetKey.startsWith("ModelImpl")) {
|
|
3951
|
+
if (dataTask.datasetKey.startsWith("ModelImpl")) {
|
|
2579
3952
|
taskMap = this.modelImplTasks;
|
|
2580
3953
|
} else {
|
|
2581
3954
|
taskMap = this.modelTasks;
|
|
2582
3955
|
}
|
|
2583
|
-
let tasks = taskMap.get(datasetKey);
|
|
3956
|
+
let tasks = taskMap.get(dataTask.datasetKey);
|
|
2584
3957
|
if (!tasks) {
|
|
2585
3958
|
tasks = [];
|
|
2586
|
-
taskMap.set(datasetKey, tasks);
|
|
3959
|
+
taskMap.set(dataTask.datasetKey, tasks);
|
|
2587
3960
|
}
|
|
2588
3961
|
tasks.push(dataTask);
|
|
2589
3962
|
}
|
|
3963
|
+
/**
|
|
3964
|
+
* Add all tasks from the given set into this set.
|
|
3965
|
+
*
|
|
3966
|
+
* @param otherTaskSet The other task set that will be merged into this one.
|
|
3967
|
+
*/
|
|
3968
|
+
merge(otherTaskSet) {
|
|
3969
|
+
for (const tasks of otherTaskSet.modelTasks.values()) {
|
|
3970
|
+
for (const task of tasks) {
|
|
3971
|
+
this.addTask(task);
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3974
|
+
for (const tasks of otherTaskSet.modelImplTasks.values()) {
|
|
3975
|
+
for (const task of tasks) {
|
|
3976
|
+
this.addTask(task);
|
|
3977
|
+
}
|
|
3978
|
+
}
|
|
3979
|
+
}
|
|
3980
|
+
/**
|
|
3981
|
+
* Create one or more data requests that can be used to fetch data for the configured scenario(s).
|
|
3982
|
+
*
|
|
3983
|
+
* @param batchSize The maximum number of impl vars that can be fetched with a single request.
|
|
3984
|
+
* This is usually the same as the number of normal model outputs.
|
|
3985
|
+
*/
|
|
2590
3986
|
buildRequests(batchSize) {
|
|
2591
3987
|
const dataRequests = [];
|
|
2592
3988
|
if (this.modelTasks.size > 0) {
|
|
2593
3989
|
const dataTasks = [];
|
|
2594
3990
|
this.modelTasks.forEach((tasks) => dataTasks.push(...tasks));
|
|
2595
3991
|
dataRequests.push({
|
|
2596
|
-
|
|
2597
|
-
|
|
3992
|
+
scenarioSpecL: this.scenarioSpecL,
|
|
3993
|
+
scenarioSpecR: this.scenarioSpecR,
|
|
2598
3994
|
dataTasks
|
|
2599
3995
|
});
|
|
2600
3996
|
}
|
|
@@ -2607,8 +4003,8 @@ var ScenarioTaskSet = class {
|
|
|
2607
4003
|
dataTasks.push(...this.modelImplTasks.get(datasetKey));
|
|
2608
4004
|
}
|
|
2609
4005
|
dataRequests.push({
|
|
2610
|
-
|
|
2611
|
-
|
|
4006
|
+
scenarioSpecL: this.scenarioSpecL,
|
|
4007
|
+
scenarioSpecR: this.scenarioSpecR,
|
|
2612
4008
|
dataTasks
|
|
2613
4009
|
});
|
|
2614
4010
|
}
|
|
@@ -2616,29 +4012,11 @@ var ScenarioTaskSet = class {
|
|
|
2616
4012
|
return dataRequests;
|
|
2617
4013
|
}
|
|
2618
4014
|
};
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
addRequest(kind, scenario, datasetKey, dataFunc) {
|
|
2625
|
-
let scenarioTaskSet = this.scenarioTaskSets.get(scenario.key);
|
|
2626
|
-
if (!scenarioTaskSet) {
|
|
2627
|
-
scenarioTaskSet = new ScenarioTaskSet(scenario);
|
|
2628
|
-
this.scenarioTaskSets.set(scenario.key, scenarioTaskSet);
|
|
2629
|
-
}
|
|
2630
|
-
scenarioTaskSet.addTask(kind, datasetKey, dataFunc);
|
|
2631
|
-
}
|
|
2632
|
-
buildPlan() {
|
|
2633
|
-
const requests = [];
|
|
2634
|
-
for (const taskSet of this.scenarioTaskSets.values()) {
|
|
2635
|
-
requests.push(...taskSet.buildRequests(this.batchSize));
|
|
2636
|
-
}
|
|
2637
|
-
return {
|
|
2638
|
-
requests
|
|
2639
|
-
};
|
|
2640
|
-
}
|
|
2641
|
-
};
|
|
4015
|
+
function scenarioPairUid(scenarioSpecL, scenarioSpecR) {
|
|
4016
|
+
const uidL = (scenarioSpecL == null ? void 0 : scenarioSpecL.uid) || "";
|
|
4017
|
+
const uidR = (scenarioSpecR == null ? void 0 : scenarioSpecR.uid) || "";
|
|
4018
|
+
return `${uidL}::${uidR}`;
|
|
4019
|
+
}
|
|
2642
4020
|
|
|
2643
4021
|
// src/check/check-runner.ts
|
|
2644
4022
|
function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner, simplifyScenarios) {
|
|
@@ -2648,7 +4026,7 @@ function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner, simplify
|
|
|
2648
4026
|
const checkPlan = checkPlanner.buildPlan();
|
|
2649
4027
|
const refDatasets = /* @__PURE__ */ new Map();
|
|
2650
4028
|
for (const [dataRefKey, dataRef] of checkPlan.dataRefs.entries()) {
|
|
2651
|
-
refDataPlanner.addRequest(
|
|
4029
|
+
refDataPlanner.addRequest(void 0, dataRef.scenario.spec, dataRef.dataset.datasetKey, (datasets) => {
|
|
2652
4030
|
const dataset = datasets.datasetR;
|
|
2653
4031
|
if (dataset) {
|
|
2654
4032
|
refDatasets.set(dataRefKey, dataset);
|
|
@@ -2657,7 +4035,7 @@ function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner, simplify
|
|
|
2657
4035
|
}
|
|
2658
4036
|
const checkResults = /* @__PURE__ */ new Map();
|
|
2659
4037
|
for (const [checkKey, checkTask] of checkPlan.tasks.entries()) {
|
|
2660
|
-
dataPlanner.addRequest(
|
|
4038
|
+
dataPlanner.addRequest(void 0, checkTask.scenario.spec, checkTask.dataset.datasetKey, (datasets) => {
|
|
2661
4039
|
const dataset = datasets.datasetR;
|
|
2662
4040
|
const checkResult = runCheck(checkTask, dataset, refDatasets);
|
|
2663
4041
|
checkResults.set(checkKey, checkResult);
|
|
@@ -2688,7 +4066,7 @@ function runCheck(checkTask, dataset, refDatasets) {
|
|
|
2688
4066
|
name: dataRef.dataset.name
|
|
2689
4067
|
}
|
|
2690
4068
|
};
|
|
2691
|
-
} else if (dataRef.scenario.
|
|
4069
|
+
} else if (dataRef.scenario.spec === void 0) {
|
|
2692
4070
|
if (dataRef.scenario.error) {
|
|
2693
4071
|
return {
|
|
2694
4072
|
status: "error",
|
|
@@ -2725,16 +4103,15 @@ function runCheck(checkTask, dataset, refDatasets) {
|
|
|
2725
4103
|
return checkTask.action.run(dataset, opRefDatasets);
|
|
2726
4104
|
}
|
|
2727
4105
|
|
|
2728
|
-
// src/
|
|
2729
|
-
function
|
|
2730
|
-
const
|
|
2731
|
-
const
|
|
2732
|
-
|
|
2733
|
-
const datasetKeys = compareConfig.datasets.getDatasetKeysForScenario(scenario);
|
|
4106
|
+
// src/comparison/run/comparison-runner.ts
|
|
4107
|
+
function runComparisons(comparisonConfig, dataPlanner) {
|
|
4108
|
+
const testReports = [];
|
|
4109
|
+
for (const scenario of comparisonConfig.scenarios.getAllScenarios()) {
|
|
4110
|
+
const datasetKeys = comparisonConfig.datasets.getDatasetKeysForScenario(scenario);
|
|
2734
4111
|
for (const datasetKey of datasetKeys) {
|
|
2735
|
-
dataPlanner.addRequest(
|
|
4112
|
+
dataPlanner.addRequest(scenario.specL, scenario.specR, datasetKey, (datasets) => {
|
|
2736
4113
|
const diffReport = diffDatasets(datasets.datasetL, datasets.datasetR);
|
|
2737
|
-
|
|
4114
|
+
testReports.push({
|
|
2738
4115
|
scenarioKey: scenario.key,
|
|
2739
4116
|
datasetKey,
|
|
2740
4117
|
diffReport
|
|
@@ -2743,7 +4120,7 @@ function runCompare(compareConfig, dataPlanner, simplifyScenarios) {
|
|
|
2743
4120
|
}
|
|
2744
4121
|
}
|
|
2745
4122
|
return () => {
|
|
2746
|
-
return
|
|
4123
|
+
return testReports;
|
|
2747
4124
|
};
|
|
2748
4125
|
}
|
|
2749
4126
|
|
|
@@ -2781,9 +4158,9 @@ var SuiteRunner = class {
|
|
|
2781
4158
|
const checkSpec = checkSpecResult.value;
|
|
2782
4159
|
const simplifyScenarios = (options == null ? void 0 : options.simplifyScenarios) === true;
|
|
2783
4160
|
const buildCheckReport2 = runChecks(this.config.check, checkSpec, dataPlanner, refDataPlanner, simplifyScenarios);
|
|
2784
|
-
let
|
|
2785
|
-
if (this.config.
|
|
2786
|
-
|
|
4161
|
+
let buildComparisonTestReports;
|
|
4162
|
+
if (this.config.comparison) {
|
|
4163
|
+
buildComparisonTestReports = runComparisons(this.config.comparison, dataPlanner);
|
|
2787
4164
|
}
|
|
2788
4165
|
this.taskQueue.onIdle = (error) => {
|
|
2789
4166
|
var _a2, _b2, _c2, _d2;
|
|
@@ -2794,17 +4171,17 @@ var SuiteRunner = class {
|
|
|
2794
4171
|
(_b2 = (_a2 = this.callbacks).onError) == null ? void 0 : _b2.call(_a2, error);
|
|
2795
4172
|
} else {
|
|
2796
4173
|
const checkReport = buildCheckReport2();
|
|
2797
|
-
let
|
|
2798
|
-
if (this.config.
|
|
2799
|
-
|
|
2800
|
-
|
|
4174
|
+
let comparisonReport;
|
|
4175
|
+
if (this.config.comparison) {
|
|
4176
|
+
comparisonReport = {
|
|
4177
|
+
testReports: buildComparisonTestReports(),
|
|
2801
4178
|
perfReportL: this.perfStatsL.toReport(),
|
|
2802
4179
|
perfReportR: this.perfStatsR.toReport()
|
|
2803
4180
|
};
|
|
2804
4181
|
}
|
|
2805
4182
|
(_d2 = (_c2 = this.callbacks).onComplete) == null ? void 0 : _d2.call(_c2, {
|
|
2806
4183
|
checkReport,
|
|
2807
|
-
|
|
4184
|
+
comparisonReport
|
|
2808
4185
|
});
|
|
2809
4186
|
}
|
|
2810
4187
|
};
|
|
@@ -2813,10 +4190,10 @@ var SuiteRunner = class {
|
|
|
2813
4190
|
const dataRequests = [...refDataPlan.requests, ...dataPlan.requests];
|
|
2814
4191
|
const taskCount = dataRequests.length;
|
|
2815
4192
|
if (taskCount === 0) {
|
|
2816
|
-
let
|
|
2817
|
-
if (this.config.
|
|
2818
|
-
|
|
2819
|
-
|
|
4193
|
+
let comparisonReport;
|
|
4194
|
+
if (this.config.comparison) {
|
|
4195
|
+
comparisonReport = {
|
|
4196
|
+
testReports: [],
|
|
2820
4197
|
perfReportL: this.perfStatsL.toReport(),
|
|
2821
4198
|
perfReportR: this.perfStatsR.toReport()
|
|
2822
4199
|
};
|
|
@@ -2827,7 +4204,7 @@ var SuiteRunner = class {
|
|
|
2827
4204
|
checkReport: {
|
|
2828
4205
|
groups: []
|
|
2829
4206
|
},
|
|
2830
|
-
|
|
4207
|
+
comparisonReport
|
|
2831
4208
|
});
|
|
2832
4209
|
return;
|
|
2833
4210
|
}
|
|
@@ -2841,51 +4218,46 @@ var SuiteRunner = class {
|
|
|
2841
4218
|
});
|
|
2842
4219
|
}
|
|
2843
4220
|
}
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
datasetKeySet
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
const scenario = request.scenario;
|
|
2851
|
-
let datasetsResultL;
|
|
2852
|
-
let datasetsResultR;
|
|
2853
|
-
switch (request.kind) {
|
|
2854
|
-
case "check": {
|
|
2855
|
-
const bundleModel = this.config.check.bundle.model;
|
|
2856
|
-
datasetsResultR = await bundleModel.getDatasetsForScenario(scenario, datasetKeys);
|
|
2857
|
-
break;
|
|
4221
|
+
processRequest(request) {
|
|
4222
|
+
return __async(this, null, function* () {
|
|
4223
|
+
var _a, _b;
|
|
4224
|
+
const datasetKeySet = /* @__PURE__ */ new Set();
|
|
4225
|
+
for (const dataTask of request.dataTasks) {
|
|
4226
|
+
datasetKeySet.add(dataTask.datasetKey);
|
|
2858
4227
|
}
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
break;
|
|
4228
|
+
const datasetKeys = [...datasetKeySet];
|
|
4229
|
+
function getDatasets(bundleModel, scenarioSpec) {
|
|
4230
|
+
return __async(this, null, function* () {
|
|
4231
|
+
if (bundleModel && scenarioSpec) {
|
|
4232
|
+
return bundleModel.getDatasetsForScenario(scenarioSpec, datasetKeys);
|
|
4233
|
+
} else {
|
|
4234
|
+
return void 0;
|
|
4235
|
+
}
|
|
4236
|
+
});
|
|
2869
4237
|
}
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
const
|
|
2883
|
-
const
|
|
2884
|
-
dataTask.
|
|
2885
|
-
datasetL
|
|
2886
|
-
datasetR
|
|
2887
|
-
|
|
2888
|
-
|
|
4238
|
+
const bundleModelL = (_a = this.config.comparison) == null ? void 0 : _a.bundleL.model;
|
|
4239
|
+
const bundleModelR = ((_b = this.config.comparison) == null ? void 0 : _b.bundleR.model) || this.config.check.bundle.model;
|
|
4240
|
+
const [datasetsResultL, datasetsResultR] = yield Promise.all([
|
|
4241
|
+
getDatasets(bundleModelL, request.scenarioSpecL),
|
|
4242
|
+
getDatasets(bundleModelR, request.scenarioSpecR)
|
|
4243
|
+
]);
|
|
4244
|
+
if (datasetsResultL == null ? void 0 : datasetsResultL.modelRunTime) {
|
|
4245
|
+
this.perfStatsL.addRun(datasetsResultL == null ? void 0 : datasetsResultL.modelRunTime);
|
|
4246
|
+
}
|
|
4247
|
+
if (datasetsResultR == null ? void 0 : datasetsResultR.modelRunTime) {
|
|
4248
|
+
this.perfStatsR.addRun(datasetsResultR == null ? void 0 : datasetsResultR.modelRunTime);
|
|
4249
|
+
}
|
|
4250
|
+
const datasetMapL = datasetsResultL == null ? void 0 : datasetsResultL.datasetMap;
|
|
4251
|
+
const datasetMapR = datasetsResultR == null ? void 0 : datasetsResultR.datasetMap;
|
|
4252
|
+
for (const dataTask of request.dataTasks) {
|
|
4253
|
+
const datasetL = datasetMapL == null ? void 0 : datasetMapL.get(dataTask.datasetKey);
|
|
4254
|
+
const datasetR = datasetMapR == null ? void 0 : datasetMapR.get(dataTask.datasetKey);
|
|
4255
|
+
dataTask.dataAction({
|
|
4256
|
+
datasetL,
|
|
4257
|
+
datasetR
|
|
4258
|
+
});
|
|
4259
|
+
}
|
|
4260
|
+
});
|
|
2889
4261
|
}
|
|
2890
4262
|
};
|
|
2891
4263
|
function runSuite(config, callbacks, options) {
|
|
@@ -2896,43 +4268,34 @@ function runSuite(config, callbacks, options) {
|
|
|
2896
4268
|
};
|
|
2897
4269
|
}
|
|
2898
4270
|
|
|
2899
|
-
// src/suite/suite-
|
|
4271
|
+
// src/suite/suite-reporting.ts
|
|
2900
4272
|
function suiteSummaryFromReport(suiteReport) {
|
|
2901
4273
|
const checkSummary = checkSummaryFromReport(suiteReport.checkReport);
|
|
2902
|
-
let
|
|
2903
|
-
if (suiteReport.
|
|
2904
|
-
|
|
4274
|
+
let comparisonSummary;
|
|
4275
|
+
if (suiteReport.comparisonReport) {
|
|
4276
|
+
comparisonSummary = comparisonSummaryFromReport(suiteReport.comparisonReport);
|
|
2905
4277
|
}
|
|
2906
4278
|
return {
|
|
2907
4279
|
checkSummary,
|
|
2908
|
-
|
|
4280
|
+
comparisonSummary
|
|
2909
4281
|
};
|
|
2910
4282
|
}
|
|
2911
4283
|
export {
|
|
2912
4284
|
CheckDataCoordinator,
|
|
2913
|
-
|
|
2914
|
-
DatasetManager,
|
|
4285
|
+
ComparisonDataCoordinator,
|
|
2915
4286
|
PerfRunner,
|
|
2916
4287
|
PerfStats,
|
|
2917
|
-
|
|
2918
|
-
allInputsAtPositionScenario,
|
|
4288
|
+
categorizeComparisonTestSummaries,
|
|
2919
4289
|
checkReportFromSummary,
|
|
2920
4290
|
checkSummaryFromReport,
|
|
2921
|
-
|
|
2922
|
-
compareSummaryFromReport,
|
|
4291
|
+
comparisonSummaryFromReport,
|
|
2923
4292
|
createConfig,
|
|
2924
4293
|
datasetMessage,
|
|
2925
4294
|
diffDatasets,
|
|
2926
4295
|
diffGraphs,
|
|
2927
|
-
inputAtPositionScenario,
|
|
2928
|
-
inputAtValueScenario,
|
|
2929
|
-
matrixScenarios,
|
|
2930
|
-
positionSetting,
|
|
2931
4296
|
predicateMessage,
|
|
2932
4297
|
runSuite,
|
|
2933
4298
|
scenarioMessage,
|
|
2934
|
-
|
|
2935
|
-
suiteSummaryFromReport,
|
|
2936
|
-
valueSetting
|
|
4299
|
+
suiteSummaryFromReport
|
|
2937
4300
|
};
|
|
2938
4301
|
//# sourceMappingURL=index.js.map
|