@sdeverywhere/check-core 0.1.0 → 0.1.1
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/dist/index.cjs +1790 -664
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +625 -284
- package/dist/index.js +1785 -656
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
- package/schema/comparison.schema.json +456 -0
package/dist/index.js
CHANGED
|
@@ -1,93 +1,3 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __defProps = Object.defineProperties;
|
|
3
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
-
var __spreadValues = (a, b) => {
|
|
9
|
-
for (var prop in b || (b = {}))
|
|
10
|
-
if (__hasOwnProp.call(b, prop))
|
|
11
|
-
__defNormalProp(a, prop, b[prop]);
|
|
12
|
-
if (__getOwnPropSymbols)
|
|
13
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
-
if (__propIsEnum.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
}
|
|
17
|
-
return a;
|
|
18
|
-
};
|
|
19
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
|
|
21
|
-
// src/_shared/scenario.ts
|
|
22
|
-
import { assertNever } from "assert-never";
|
|
23
|
-
function positionSetting(inputVarId, position) {
|
|
24
|
-
return {
|
|
25
|
-
kind: "position",
|
|
26
|
-
inputVarId,
|
|
27
|
-
position
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function valueSetting(inputVarId, value) {
|
|
31
|
-
return {
|
|
32
|
-
kind: "value",
|
|
33
|
-
inputVarId,
|
|
34
|
-
value
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
function settingsScenario(key, groupKey, settings) {
|
|
38
|
-
return {
|
|
39
|
-
kind: "settings",
|
|
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
|
-
}
|
|
90
|
-
|
|
91
1
|
// src/_shared/task-queue.ts
|
|
92
2
|
var TaskQueue = class {
|
|
93
3
|
constructor(processor) {
|
|
@@ -174,7 +84,7 @@ var CheckDataCoordinator = class {
|
|
|
174
84
|
this.bundleModel = bundleModel;
|
|
175
85
|
this.taskQueue = new TaskQueue({
|
|
176
86
|
process: async (request) => {
|
|
177
|
-
const result = await this.bundleModel.getDatasetsForScenario(request.
|
|
87
|
+
const result = await this.bundleModel.getDatasetsForScenario(request.scenarioSpec, [request.datasetKey]);
|
|
178
88
|
const dataset = result.datasetMap.get(request.datasetKey);
|
|
179
89
|
return {
|
|
180
90
|
dataset
|
|
@@ -182,9 +92,9 @@ var CheckDataCoordinator = class {
|
|
|
182
92
|
}
|
|
183
93
|
});
|
|
184
94
|
}
|
|
185
|
-
requestDataset(requestKey,
|
|
95
|
+
requestDataset(requestKey, scenarioSpec, datasetKey, onResponse) {
|
|
186
96
|
const request = {
|
|
187
|
-
|
|
97
|
+
scenarioSpec,
|
|
188
98
|
datasetKey
|
|
189
99
|
};
|
|
190
100
|
this.taskQueue.addTask(requestKey, request, (response) => {
|
|
@@ -197,10 +107,10 @@ var CheckDataCoordinator = class {
|
|
|
197
107
|
};
|
|
198
108
|
|
|
199
109
|
// src/check/check-report.ts
|
|
200
|
-
import
|
|
110
|
+
import assertNever2 from "assert-never";
|
|
201
111
|
|
|
202
112
|
// src/check/check-predicate.ts
|
|
203
|
-
import
|
|
113
|
+
import assertNever from "assert-never";
|
|
204
114
|
function symbolForPredicateOp(op) {
|
|
205
115
|
switch (op) {
|
|
206
116
|
case "gt":
|
|
@@ -216,7 +126,7 @@ function symbolForPredicateOp(op) {
|
|
|
216
126
|
case "approx":
|
|
217
127
|
return "\u2248";
|
|
218
128
|
default:
|
|
219
|
-
|
|
129
|
+
assertNever(op);
|
|
220
130
|
}
|
|
221
131
|
}
|
|
222
132
|
|
|
@@ -230,7 +140,7 @@ function buildCheckReport(checkPlan, checkResults) {
|
|
|
230
140
|
const scenarioReports = [];
|
|
231
141
|
for (const scenarioPlan of testPlan.scenarios) {
|
|
232
142
|
let scenarioStatus = "passed";
|
|
233
|
-
if (scenarioPlan.checkScenario.
|
|
143
|
+
if (scenarioPlan.checkScenario.spec === void 0) {
|
|
234
144
|
testStatus = "error";
|
|
235
145
|
scenarioStatus = "error";
|
|
236
146
|
}
|
|
@@ -327,14 +237,14 @@ function predicateReport(predicatePlan, checkKey, result) {
|
|
|
327
237
|
};
|
|
328
238
|
opRef = opDataRef;
|
|
329
239
|
opValue = `${sym} '${dataRef.dataset.name}'`;
|
|
330
|
-
const
|
|
331
|
-
if (!
|
|
240
|
+
const refScenarioSpec = (_b = dataRef.scenario) == null ? void 0 : _b.spec;
|
|
241
|
+
if (!refScenarioSpec) {
|
|
332
242
|
return;
|
|
333
243
|
}
|
|
334
244
|
if (predOp.scenario === "inherit") {
|
|
335
245
|
opValue += ` (w/ same scenario)`;
|
|
336
246
|
} else {
|
|
337
|
-
if (
|
|
247
|
+
if (refScenarioSpec.kind === "all-inputs" && refScenarioSpec.position === "at-default") {
|
|
338
248
|
opValue += ` (w/ default scenario)`;
|
|
339
249
|
} else {
|
|
340
250
|
opValue += ` (w/ configured scenario)`;
|
|
@@ -369,7 +279,7 @@ function predicateReport(predicatePlan, checkKey, result) {
|
|
|
369
279
|
}
|
|
370
280
|
function scenarioMessage(scenario, bold) {
|
|
371
281
|
const checkScenario = scenario.checkScenario;
|
|
372
|
-
if (checkScenario.
|
|
282
|
+
if (checkScenario.spec === void 0) {
|
|
373
283
|
if (checkScenario.error) {
|
|
374
284
|
switch (checkScenario.error.kind) {
|
|
375
285
|
case "unknown-input-group":
|
|
@@ -377,7 +287,7 @@ function scenarioMessage(scenario, bold) {
|
|
|
377
287
|
case "empty-input-group":
|
|
378
288
|
return `error: input group ${bold(checkScenario.error.name)} is empty`;
|
|
379
289
|
default:
|
|
380
|
-
|
|
290
|
+
assertNever2(checkScenario.error.kind);
|
|
381
291
|
}
|
|
382
292
|
} else {
|
|
383
293
|
const badInputNames = checkScenario.inputDescs.filter((d) => d.inputVar === void 0).map((d) => bold(d.name));
|
|
@@ -394,7 +304,7 @@ function scenarioMessage(scenario, bold) {
|
|
|
394
304
|
case "at-maximum":
|
|
395
305
|
return "maximum";
|
|
396
306
|
default:
|
|
397
|
-
|
|
307
|
+
assertNever2(position);
|
|
398
308
|
}
|
|
399
309
|
}
|
|
400
310
|
function inputMessage(inputDesc) {
|
|
@@ -409,13 +319,13 @@ function scenarioMessage(scenario, bold) {
|
|
|
409
319
|
}
|
|
410
320
|
return msg;
|
|
411
321
|
}
|
|
412
|
-
if (checkScenario.
|
|
413
|
-
const position = checkScenario.
|
|
322
|
+
if (checkScenario.spec.kind === "all-inputs") {
|
|
323
|
+
const position = checkScenario.spec.position;
|
|
414
324
|
return `when ${bold("all inputs")} are at ${bold(positionName(position))}...`;
|
|
415
325
|
} else if (checkScenario.inputGroupName) {
|
|
416
326
|
let position = "at-default";
|
|
417
|
-
if (checkScenario.
|
|
418
|
-
position = checkScenario.
|
|
327
|
+
if (checkScenario.spec.settings[0].kind === "position") {
|
|
328
|
+
position = checkScenario.spec.settings[0].position;
|
|
419
329
|
}
|
|
420
330
|
const groupName = checkScenario.inputGroupName;
|
|
421
331
|
return `when all inputs in ${bold(groupName)} are at ${bold(positionName(position))}...`;
|
|
@@ -448,7 +358,7 @@ function predicateMessage(predicate, bold) {
|
|
|
448
358
|
case "empty-input-group":
|
|
449
359
|
return `error: referenced input group ${bold(result.errorInfo.name)} is empty`;
|
|
450
360
|
default:
|
|
451
|
-
|
|
361
|
+
assertNever2(result.errorInfo.kind);
|
|
452
362
|
}
|
|
453
363
|
} else {
|
|
454
364
|
return `unknown error`;
|
|
@@ -1019,7 +929,7 @@ function parseTestYaml(yamlStrings) {
|
|
|
1019
929
|
groups.push(group);
|
|
1020
930
|
}
|
|
1021
931
|
} else {
|
|
1022
|
-
let msg = "Failed to parse YAML
|
|
932
|
+
let msg = "Failed to parse YAML check definitions";
|
|
1023
933
|
for (const error of validate.errors || []) {
|
|
1024
934
|
if (error.message) {
|
|
1025
935
|
msg += `
|
|
@@ -1193,9 +1103,12 @@ function actionForPredicate(predicateSpec) {
|
|
|
1193
1103
|
|
|
1194
1104
|
// src/_shared/combo.ts
|
|
1195
1105
|
function cartesianProductOf(arr) {
|
|
1196
|
-
return arr.reduce(
|
|
1197
|
-
|
|
1198
|
-
|
|
1106
|
+
return arr.reduce(
|
|
1107
|
+
(a, b) => {
|
|
1108
|
+
return a.map((x) => b.map((y) => x.concat([y]))).reduce((v, w) => v.concat(w), []);
|
|
1109
|
+
},
|
|
1110
|
+
[[]]
|
|
1111
|
+
);
|
|
1199
1112
|
}
|
|
1200
1113
|
|
|
1201
1114
|
// src/check/check-dataset.ts
|
|
@@ -1286,14 +1199,16 @@ function matchByName(modelSpec, datasetName, datasetSource) {
|
|
|
1286
1199
|
};
|
|
1287
1200
|
}
|
|
1288
1201
|
function matchByGroup(modelSpec, groupName) {
|
|
1289
|
-
const groupToMatch = groupName.toLowerCase();
|
|
1290
1202
|
let matchedGroupName;
|
|
1291
1203
|
let matchedGroupDatasetKeys;
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1204
|
+
if (modelSpec.datasetGroups) {
|
|
1205
|
+
const groupToMatch = groupName.toLowerCase();
|
|
1206
|
+
for (const [group, datasetKeys] of modelSpec.datasetGroups) {
|
|
1207
|
+
if (group.toLowerCase() === groupToMatch) {
|
|
1208
|
+
matchedGroupName = group;
|
|
1209
|
+
matchedGroupDatasetKeys = datasetKeys;
|
|
1210
|
+
break;
|
|
1211
|
+
}
|
|
1297
1212
|
}
|
|
1298
1213
|
}
|
|
1299
1214
|
if (matchedGroupName === void 0) {
|
|
@@ -1370,6 +1285,65 @@ function matchByType(modelSpec, varTypeToMatch) {
|
|
|
1370
1285
|
|
|
1371
1286
|
// src/check/check-scenario.ts
|
|
1372
1287
|
import assertNever4 from "assert-never";
|
|
1288
|
+
|
|
1289
|
+
// src/_shared/scenario-specs.ts
|
|
1290
|
+
import { assertNever as assertNever3 } from "assert-never";
|
|
1291
|
+
function positionSetting(inputVarId, position) {
|
|
1292
|
+
return {
|
|
1293
|
+
kind: "position",
|
|
1294
|
+
inputVarId,
|
|
1295
|
+
position
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
function valueSetting(inputVarId, value) {
|
|
1299
|
+
return {
|
|
1300
|
+
kind: "value",
|
|
1301
|
+
inputVarId,
|
|
1302
|
+
value
|
|
1303
|
+
};
|
|
1304
|
+
}
|
|
1305
|
+
function inputSettingsSpec(settings) {
|
|
1306
|
+
const uidParts = settings.map((setting) => {
|
|
1307
|
+
switch (setting.kind) {
|
|
1308
|
+
case "position":
|
|
1309
|
+
return `${setting.inputVarId}_at_${keyForInputPosition(setting.position)}`;
|
|
1310
|
+
case "value":
|
|
1311
|
+
return `${setting.inputVarId}_at_${setting.value}`;
|
|
1312
|
+
default:
|
|
1313
|
+
assertNever3(setting);
|
|
1314
|
+
}
|
|
1315
|
+
});
|
|
1316
|
+
const uid = `inputs_${uidParts.sort().join("_")}`;
|
|
1317
|
+
return {
|
|
1318
|
+
kind: "input-settings",
|
|
1319
|
+
uid,
|
|
1320
|
+
settings
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
function inputAtPositionSpec(inputVarId, position) {
|
|
1324
|
+
return inputSettingsSpec([positionSetting(inputVarId, position)]);
|
|
1325
|
+
}
|
|
1326
|
+
function allInputsAtPositionSpec(position) {
|
|
1327
|
+
return {
|
|
1328
|
+
kind: "all-inputs",
|
|
1329
|
+
uid: `all_inputs_at_${keyForInputPosition(position)}`,
|
|
1330
|
+
position
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1333
|
+
function keyForInputPosition(position) {
|
|
1334
|
+
switch (position) {
|
|
1335
|
+
case "at-default":
|
|
1336
|
+
return "default";
|
|
1337
|
+
case "at-minimum":
|
|
1338
|
+
return "min";
|
|
1339
|
+
case "at-maximum":
|
|
1340
|
+
return "max";
|
|
1341
|
+
default:
|
|
1342
|
+
assertNever3(position);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
// src/check/check-scenario.ts
|
|
1373
1347
|
function expandScenarios(modelSpec, scenarioSpecs, simplify) {
|
|
1374
1348
|
if (scenarioSpecs.length === 0) {
|
|
1375
1349
|
const scenarioSpec = {
|
|
@@ -1446,10 +1420,12 @@ function inputDescForName(modelSpec, inputName, at) {
|
|
|
1446
1420
|
}
|
|
1447
1421
|
}
|
|
1448
1422
|
function groupForName(modelSpec, groupName) {
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1423
|
+
if (modelSpec.inputGroups) {
|
|
1424
|
+
const groupToMatch = groupName.toLowerCase();
|
|
1425
|
+
for (const [group, inputVars] of modelSpec.inputGroups) {
|
|
1426
|
+
if (group.toLowerCase() === groupToMatch) {
|
|
1427
|
+
return [group, inputVars];
|
|
1428
|
+
}
|
|
1453
1429
|
}
|
|
1454
1430
|
}
|
|
1455
1431
|
return void 0;
|
|
@@ -1464,56 +1440,35 @@ function errorScenarioForInputGroup(kind, groupName) {
|
|
|
1464
1440
|
};
|
|
1465
1441
|
}
|
|
1466
1442
|
function checkScenarioWithAllInputsAtPosition(position) {
|
|
1467
|
-
const scenario = allInputsAtPositionScenario(position);
|
|
1468
1443
|
return {
|
|
1469
|
-
|
|
1444
|
+
spec: allInputsAtPositionSpec(position),
|
|
1470
1445
|
inputDescs: []
|
|
1471
1446
|
};
|
|
1472
1447
|
}
|
|
1473
1448
|
function checkScenarioWithInputAtPosition(inputVar, position) {
|
|
1474
1449
|
const varId = inputVar.varId;
|
|
1475
|
-
const scenario = inputAtPositionScenario(varId, varId, position);
|
|
1476
1450
|
return {
|
|
1477
|
-
|
|
1451
|
+
spec: inputAtPositionSpec(varId, position),
|
|
1478
1452
|
inputDescs: [inputDescAtPosition(inputVar, position)]
|
|
1479
1453
|
};
|
|
1480
1454
|
}
|
|
1481
1455
|
function checkScenarioForInputDescs(groupName, inputDescs) {
|
|
1482
|
-
let
|
|
1456
|
+
let spec;
|
|
1483
1457
|
if (inputDescs.every((desc) => desc.inputVar !== void 0)) {
|
|
1484
|
-
const settings =
|
|
1485
|
-
const keyParts = [];
|
|
1486
|
-
for (const inputDesc of inputDescs) {
|
|
1458
|
+
const settings = inputDescs.map((inputDesc) => {
|
|
1487
1459
|
const varId = inputDesc.inputVar.varId;
|
|
1488
1460
|
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;
|
|
1461
|
+
return positionSetting(varId, inputDesc.position);
|
|
1506
1462
|
} else {
|
|
1507
|
-
|
|
1508
|
-
groupKey = scenarioKey;
|
|
1463
|
+
return valueSetting(varId, inputDesc.value);
|
|
1509
1464
|
}
|
|
1510
|
-
|
|
1511
|
-
|
|
1465
|
+
});
|
|
1466
|
+
spec = inputSettingsSpec(settings);
|
|
1512
1467
|
} else {
|
|
1513
|
-
|
|
1468
|
+
spec = void 0;
|
|
1514
1469
|
}
|
|
1515
1470
|
return {
|
|
1516
|
-
|
|
1471
|
+
spec,
|
|
1517
1472
|
inputGroupName: groupName,
|
|
1518
1473
|
inputDescs
|
|
1519
1474
|
};
|
|
@@ -1627,7 +1582,7 @@ var CheckPlanner = class {
|
|
|
1627
1582
|
}
|
|
1628
1583
|
const planScenarios = [];
|
|
1629
1584
|
for (const checkScenario of checkScenarios) {
|
|
1630
|
-
if (checkScenario.
|
|
1585
|
+
if (checkScenario.spec === void 0) {
|
|
1631
1586
|
planScenarios.push({
|
|
1632
1587
|
checkScenario,
|
|
1633
1588
|
datasets: []
|
|
@@ -1736,8 +1691,8 @@ var CheckPlanner = class {
|
|
|
1736
1691
|
}
|
|
1737
1692
|
}
|
|
1738
1693
|
let dataRefKey;
|
|
1739
|
-
if (refScenario.
|
|
1740
|
-
dataRefKey = `${refScenario.
|
|
1694
|
+
if (refScenario.spec && refDataset.datasetKey) {
|
|
1695
|
+
dataRefKey = `${refScenario.spec.uid}::${refDataset.datasetKey}`;
|
|
1741
1696
|
}
|
|
1742
1697
|
const dataRef = {
|
|
1743
1698
|
key: dataRefKey,
|
|
@@ -1792,14 +1747,14 @@ function checkSummaryFromReport(checkReport) {
|
|
|
1792
1747
|
predicateSummaries
|
|
1793
1748
|
};
|
|
1794
1749
|
}
|
|
1795
|
-
function checkReportFromSummary(checkConfig, checkSummary
|
|
1750
|
+
function checkReportFromSummary(checkConfig, checkSummary) {
|
|
1796
1751
|
const checkSpecResult = parseTestYaml(checkConfig.tests);
|
|
1797
1752
|
if (checkSpecResult.isErr()) {
|
|
1798
1753
|
return void 0;
|
|
1799
1754
|
}
|
|
1800
1755
|
const checkSpec = checkSpecResult.value;
|
|
1801
1756
|
const checkPlanner = new CheckPlanner(checkConfig.bundle.model.modelSpec);
|
|
1802
|
-
checkPlanner.addAllChecks(checkSpec,
|
|
1757
|
+
checkPlanner.addAllChecks(checkSpec, false);
|
|
1803
1758
|
const checkPlan = checkPlanner.buildPlan();
|
|
1804
1759
|
const checkResults = /* @__PURE__ */ new Map();
|
|
1805
1760
|
for (const predicateSummary of checkSummary.predicateSummaries) {
|
|
@@ -1808,44 +1763,66 @@ function checkReportFromSummary(checkConfig, checkSummary, simplifyScenarios) {
|
|
|
1808
1763
|
return buildCheckReport(checkPlan, checkResults);
|
|
1809
1764
|
}
|
|
1810
1765
|
|
|
1811
|
-
// src/
|
|
1766
|
+
// src/comparison/run/comparison-data-coordinator.ts
|
|
1812
1767
|
import { assertNever as assertNever7 } from "assert-never";
|
|
1813
|
-
var
|
|
1768
|
+
var ComparisonDataCoordinator = class {
|
|
1814
1769
|
constructor(bundleModelL, bundleModelR) {
|
|
1815
1770
|
this.bundleModelL = bundleModelL;
|
|
1816
1771
|
this.bundleModelR = bundleModelR;
|
|
1817
1772
|
this.taskQueue = new TaskQueue({
|
|
1818
1773
|
process: async (request) => {
|
|
1819
1774
|
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
|
-
}
|
|
1775
|
+
case "dataset":
|
|
1776
|
+
return this.processDatasetRequest(request);
|
|
1777
|
+
case "graph-data":
|
|
1778
|
+
return this.processGraphDataRequest(request);
|
|
1839
1779
|
default:
|
|
1840
1780
|
assertNever7(request);
|
|
1841
1781
|
}
|
|
1842
1782
|
}
|
|
1843
1783
|
});
|
|
1844
1784
|
}
|
|
1845
|
-
|
|
1785
|
+
async processDatasetRequest(request) {
|
|
1786
|
+
async function fetchDatasets(bundleModel, scenarioSpec) {
|
|
1787
|
+
if (scenarioSpec) {
|
|
1788
|
+
return bundleModel.getDatasetsForScenario(scenarioSpec, request.datasetKeys);
|
|
1789
|
+
} else {
|
|
1790
|
+
return void 0;
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
const [resultL, resultR] = await Promise.all([
|
|
1794
|
+
fetchDatasets(this.bundleModelL, request.scenarioSpecL),
|
|
1795
|
+
fetchDatasets(this.bundleModelR, request.scenarioSpecR)
|
|
1796
|
+
]);
|
|
1797
|
+
return {
|
|
1798
|
+
kind: "dataset",
|
|
1799
|
+
datasetMapL: resultL == null ? void 0 : resultL.datasetMap,
|
|
1800
|
+
datasetMapR: resultR == null ? void 0 : resultR.datasetMap
|
|
1801
|
+
};
|
|
1802
|
+
}
|
|
1803
|
+
async processGraphDataRequest(request) {
|
|
1804
|
+
async function fetchGraphData(bundleModel, scenarioSpec) {
|
|
1805
|
+
if (scenarioSpec) {
|
|
1806
|
+
return bundleModel.getGraphDataForScenario(scenarioSpec, request.graphId);
|
|
1807
|
+
} else {
|
|
1808
|
+
return void 0;
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
const [graphDataL, graphDataR] = await Promise.all([
|
|
1812
|
+
fetchGraphData(this.bundleModelL, request.scenarioSpecL),
|
|
1813
|
+
fetchGraphData(this.bundleModelR, request.scenarioSpecR)
|
|
1814
|
+
]);
|
|
1815
|
+
return {
|
|
1816
|
+
kind: "graph-data",
|
|
1817
|
+
graphDataL,
|
|
1818
|
+
graphDataR
|
|
1819
|
+
};
|
|
1820
|
+
}
|
|
1821
|
+
requestDatasetMaps(requestKey, scenarioSpecL, scenarioSpecR, datasetKeys, onResponse) {
|
|
1846
1822
|
const request = {
|
|
1847
1823
|
kind: "dataset",
|
|
1848
|
-
|
|
1824
|
+
scenarioSpecL,
|
|
1825
|
+
scenarioSpecR,
|
|
1849
1826
|
datasetKeys
|
|
1850
1827
|
};
|
|
1851
1828
|
this.taskQueue.addTask(requestKey, request, (response) => {
|
|
@@ -1854,16 +1831,16 @@ var CompareDataCoordinator = class {
|
|
|
1854
1831
|
}
|
|
1855
1832
|
});
|
|
1856
1833
|
}
|
|
1857
|
-
requestGraphData(requestKey,
|
|
1834
|
+
requestGraphData(requestKey, scenarioSpecL, scenarioSpecR, graphId, onResponse) {
|
|
1858
1835
|
const request = {
|
|
1859
1836
|
kind: "graph-data",
|
|
1860
|
-
|
|
1861
|
-
|
|
1837
|
+
scenarioSpecL,
|
|
1838
|
+
scenarioSpecR,
|
|
1862
1839
|
graphId
|
|
1863
1840
|
};
|
|
1864
1841
|
this.taskQueue.addTask(requestKey, request, (response) => {
|
|
1865
1842
|
if (response.kind === "graph-data") {
|
|
1866
|
-
onResponse(response.
|
|
1843
|
+
onResponse(response.graphDataL, response.graphDataR);
|
|
1867
1844
|
}
|
|
1868
1845
|
});
|
|
1869
1846
|
}
|
|
@@ -1872,7 +1849,7 @@ var CompareDataCoordinator = class {
|
|
|
1872
1849
|
}
|
|
1873
1850
|
};
|
|
1874
1851
|
|
|
1875
|
-
// src/
|
|
1852
|
+
// src/comparison/diff-datasets/diff-datasets.ts
|
|
1876
1853
|
function diffDatasets(datasetL, datasetR) {
|
|
1877
1854
|
let minValueL = Number.MAX_VALUE;
|
|
1878
1855
|
let maxValueL = Number.MIN_VALUE;
|
|
@@ -1967,19 +1944,9 @@ function diffDatasets(datasetL, datasetR) {
|
|
|
1967
1944
|
maxDiffPoint
|
|
1968
1945
|
};
|
|
1969
1946
|
}
|
|
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
1947
|
|
|
1981
|
-
// src/
|
|
1982
|
-
function diffGraphs(graphL, graphR, scenarioKey,
|
|
1948
|
+
// src/comparison/diff-graphs/diff-graphs.ts
|
|
1949
|
+
function diffGraphs(graphL, graphR, scenarioKey, testSummaries) {
|
|
1983
1950
|
let inclusion;
|
|
1984
1951
|
if (graphL && graphR) {
|
|
1985
1952
|
inclusion = "both";
|
|
@@ -2021,8 +1988,8 @@ function diffGraphs(graphL, graphR, scenarioKey, datasetSummaries) {
|
|
|
2021
1988
|
datasetKeys.add(dataset.datasetKey);
|
|
2022
1989
|
}
|
|
2023
1990
|
for (const datasetKey of datasetKeys) {
|
|
2024
|
-
const
|
|
2025
|
-
const maxDiff =
|
|
1991
|
+
const testSummary = testSummaries.find((summary) => summary.d === datasetKey && summary.s === scenarioKey);
|
|
1992
|
+
const maxDiff = testSummary == null ? void 0 : testSummary.md;
|
|
2026
1993
|
datasetReports.push({
|
|
2027
1994
|
datasetKey,
|
|
2028
1995
|
maxDiff
|
|
@@ -2036,12 +2003,12 @@ function diffGraphs(graphL, graphR, scenarioKey, datasetSummaries) {
|
|
|
2036
2003
|
};
|
|
2037
2004
|
}
|
|
2038
2005
|
|
|
2039
|
-
// src/
|
|
2040
|
-
function
|
|
2041
|
-
const
|
|
2042
|
-
for (const r of
|
|
2006
|
+
// src/comparison/report/comparison-reporting.ts
|
|
2007
|
+
function comparisonSummaryFromReport(comparisonReport) {
|
|
2008
|
+
const terseSummaries = [];
|
|
2009
|
+
for (const r of comparisonReport.testReports) {
|
|
2043
2010
|
if (r.diffReport.validity === "both" && r.diffReport.maxDiff > 0) {
|
|
2044
|
-
|
|
2011
|
+
terseSummaries.push({
|
|
2045
2012
|
s: r.scenarioKey,
|
|
2046
2013
|
d: r.datasetKey,
|
|
2047
2014
|
md: r.diffReport.maxDiff
|
|
@@ -2049,154 +2016,1319 @@ function compareSummaryFromReport(compareReport) {
|
|
|
2049
2016
|
}
|
|
2050
2017
|
}
|
|
2051
2018
|
return {
|
|
2052
|
-
|
|
2053
|
-
perfReportL:
|
|
2054
|
-
perfReportR:
|
|
2019
|
+
testSummaries: terseSummaries,
|
|
2020
|
+
perfReportL: comparisonReport.perfReportL,
|
|
2021
|
+
perfReportR: comparisonReport.perfReportR
|
|
2055
2022
|
};
|
|
2056
2023
|
}
|
|
2024
|
+
function restoreFromTerseSummaries(comparisonConfig, terseSummaries) {
|
|
2025
|
+
const existingSummaries = /* @__PURE__ */ new Map();
|
|
2026
|
+
for (const summary of terseSummaries) {
|
|
2027
|
+
const key = `${summary.s}::${summary.d}`;
|
|
2028
|
+
existingSummaries.set(key, summary);
|
|
2029
|
+
}
|
|
2030
|
+
const allTestSummaries = [];
|
|
2031
|
+
for (const scenario of comparisonConfig.scenarios.getAllScenarios()) {
|
|
2032
|
+
const datasetKeys = comparisonConfig.datasets.getDatasetKeysForScenario(scenario);
|
|
2033
|
+
for (const datasetKey of datasetKeys) {
|
|
2034
|
+
const key = `${scenario.key}::${datasetKey}`;
|
|
2035
|
+
const existingSummary = existingSummaries.get(key);
|
|
2036
|
+
const maxDiff = (existingSummary == null ? void 0 : existingSummary.md) || 0;
|
|
2037
|
+
allTestSummaries.push({
|
|
2038
|
+
s: scenario.key,
|
|
2039
|
+
d: datasetKey,
|
|
2040
|
+
md: maxDiff
|
|
2041
|
+
});
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
return allTestSummaries;
|
|
2045
|
+
}
|
|
2057
2046
|
|
|
2058
|
-
// src/
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2047
|
+
// src/comparison/report/comparison-grouping.ts
|
|
2048
|
+
import { assertNever as assertNever8 } from "assert-never";
|
|
2049
|
+
|
|
2050
|
+
// src/comparison/report/buckets.ts
|
|
2051
|
+
function getBucketIndex(diffPct, thresholds) {
|
|
2052
|
+
if (diffPct === 0) {
|
|
2053
|
+
return 0;
|
|
2054
|
+
}
|
|
2055
|
+
for (let i = 0; i < thresholds.length; i++) {
|
|
2056
|
+
if (diffPct < thresholds[i]) {
|
|
2057
|
+
return i + 1;
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
return thresholds.length + 1;
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
// src/comparison/report/comparison-grouping.ts
|
|
2064
|
+
function categorizeComparisonTestSummaries(comparisonConfig, terseSummaries) {
|
|
2065
|
+
const allTestSummaries = restoreFromTerseSummaries(comparisonConfig, terseSummaries);
|
|
2066
|
+
const groupsByScenario = groupComparisonTestSummaries(allTestSummaries, "by-scenario");
|
|
2067
|
+
const byScenario = categorizeComparisonGroups(comparisonConfig, [...groupsByScenario.values()]);
|
|
2068
|
+
const groupsByDataset = groupComparisonTestSummaries(allTestSummaries, "by-dataset");
|
|
2069
|
+
const byDataset = categorizeComparisonGroups(comparisonConfig, [...groupsByDataset.values()]);
|
|
2062
2070
|
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)
|
|
2071
|
+
byScenario,
|
|
2072
|
+
byDataset
|
|
2072
2073
|
};
|
|
2073
2074
|
}
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2075
|
+
function groupComparisonTestSummaries(testSummaries, groupKind) {
|
|
2076
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2077
|
+
for (const testSummary of testSummaries) {
|
|
2078
|
+
let groupKey;
|
|
2079
|
+
switch (groupKind) {
|
|
2080
|
+
case "by-dataset":
|
|
2081
|
+
groupKey = testSummary.d;
|
|
2082
|
+
break;
|
|
2083
|
+
case "by-scenario":
|
|
2084
|
+
groupKey = testSummary.s;
|
|
2085
|
+
break;
|
|
2086
|
+
default:
|
|
2087
|
+
assertNever8(groupKind);
|
|
2088
|
+
}
|
|
2089
|
+
const group = groups.get(groupKey);
|
|
2090
|
+
if (group) {
|
|
2091
|
+
group.testSummaries.push(testSummary);
|
|
2092
|
+
} else {
|
|
2093
|
+
groups.set(groupKey, {
|
|
2094
|
+
kind: groupKind,
|
|
2095
|
+
key: groupKey,
|
|
2096
|
+
testSummaries: [testSummary]
|
|
2097
|
+
});
|
|
2098
|
+
}
|
|
2078
2099
|
}
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2100
|
+
return groups;
|
|
2101
|
+
}
|
|
2102
|
+
function categorizeComparisonGroups(comparisonConfig, allGroups) {
|
|
2103
|
+
const allGroupSummaries = /* @__PURE__ */ new Map();
|
|
2104
|
+
const withErrors = [];
|
|
2105
|
+
const onlyInLeft = [];
|
|
2106
|
+
const onlyInRight = [];
|
|
2107
|
+
let withDiffs = [];
|
|
2108
|
+
const withoutDiffs = [];
|
|
2109
|
+
function addSummaryForGroup(group, root, validInL, validInR) {
|
|
2110
|
+
let scores;
|
|
2111
|
+
if (validInL && validInR) {
|
|
2112
|
+
scores = getScoresForGroup(group, comparisonConfig.thresholds);
|
|
2113
|
+
}
|
|
2114
|
+
const groupSummary = {
|
|
2115
|
+
root,
|
|
2116
|
+
group,
|
|
2117
|
+
scores
|
|
2118
|
+
};
|
|
2119
|
+
allGroupSummaries.set(group.key, groupSummary);
|
|
2120
|
+
if (validInL && validInR) {
|
|
2121
|
+
if (scores.totalDiffCount !== scores.diffCountByBucket[0]) {
|
|
2122
|
+
withDiffs.push(groupSummary);
|
|
2096
2123
|
} else {
|
|
2097
|
-
|
|
2124
|
+
withoutDiffs.push(groupSummary);
|
|
2098
2125
|
}
|
|
2099
|
-
})
|
|
2126
|
+
} else if (validInL) {
|
|
2127
|
+
onlyInLeft.push(groupSummary);
|
|
2128
|
+
} else if (validInR) {
|
|
2129
|
+
onlyInRight.push(groupSummary);
|
|
2130
|
+
} else {
|
|
2131
|
+
withErrors.push(groupSummary);
|
|
2132
|
+
}
|
|
2100
2133
|
}
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2134
|
+
for (const group of allGroups.values()) {
|
|
2135
|
+
switch (group.kind) {
|
|
2136
|
+
case "by-dataset": {
|
|
2137
|
+
const dataset = comparisonConfig.datasets.getDataset(group.key);
|
|
2138
|
+
const validInL = (dataset == null ? void 0 : dataset.outputVarL) !== void 0;
|
|
2139
|
+
const validInR = (dataset == null ? void 0 : dataset.outputVarR) !== void 0;
|
|
2140
|
+
addSummaryForGroup(group, dataset, validInL, validInR);
|
|
2141
|
+
break;
|
|
2142
|
+
}
|
|
2143
|
+
case "by-scenario": {
|
|
2144
|
+
const scenario = comparisonConfig.scenarios.getScenario(group.key);
|
|
2145
|
+
const validInL = (scenario == null ? void 0 : scenario.specL) !== void 0;
|
|
2146
|
+
const validInR = (scenario == null ? void 0 : scenario.specR) !== void 0;
|
|
2147
|
+
addSummaryForGroup(group, scenario, validInL, validInR);
|
|
2148
|
+
break;
|
|
2106
2149
|
}
|
|
2150
|
+
default:
|
|
2151
|
+
assertNever8(group.kind);
|
|
2107
2152
|
}
|
|
2108
2153
|
}
|
|
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
|
-
};
|
|
2154
|
+
if (withDiffs.length > 1) {
|
|
2155
|
+
if (withDiffs[0].group.kind === "by-dataset") {
|
|
2156
|
+
withDiffs = sortDatasetGroupSummaries(withDiffs);
|
|
2157
|
+
} else if (withDiffs[0].group.kind === "by-scenario") {
|
|
2158
|
+
withDiffs = sortScenarioGroupSummaries(withDiffs);
|
|
2159
|
+
}
|
|
2163
2160
|
}
|
|
2164
|
-
const checkConfig = {
|
|
2165
|
-
bundle: currentBundle,
|
|
2166
|
-
tests: options.check.tests
|
|
2167
|
-
};
|
|
2168
2161
|
return {
|
|
2169
|
-
|
|
2170
|
-
|
|
2162
|
+
allGroupSummaries,
|
|
2163
|
+
withErrors,
|
|
2164
|
+
onlyInLeft,
|
|
2165
|
+
onlyInRight,
|
|
2166
|
+
withDiffs,
|
|
2167
|
+
withoutDiffs
|
|
2171
2168
|
};
|
|
2172
2169
|
}
|
|
2173
|
-
|
|
2174
|
-
const
|
|
2175
|
-
const
|
|
2170
|
+
function getScoresForGroup(group, thresholds) {
|
|
2171
|
+
const diffCountByBucket = Array(thresholds.length + 2).fill(0);
|
|
2172
|
+
const totalMaxDiffByBucket = Array(thresholds.length + 2).fill(0);
|
|
2173
|
+
let totalDiffCount = 0;
|
|
2174
|
+
for (const testSummary of group.testSummaries) {
|
|
2175
|
+
const bucketIndex = getBucketIndex(testSummary.md, thresholds);
|
|
2176
|
+
diffCountByBucket[bucketIndex]++;
|
|
2177
|
+
totalMaxDiffByBucket[bucketIndex] += testSummary.md;
|
|
2178
|
+
totalDiffCount++;
|
|
2179
|
+
}
|
|
2180
|
+
let diffPercentByBucket;
|
|
2181
|
+
if (totalDiffCount > 0) {
|
|
2182
|
+
diffPercentByBucket = diffCountByBucket.map((count) => count / totalDiffCount * 100);
|
|
2183
|
+
} else {
|
|
2184
|
+
diffPercentByBucket = [];
|
|
2185
|
+
}
|
|
2176
2186
|
return {
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2187
|
+
totalDiffCount,
|
|
2188
|
+
totalMaxDiffByBucket,
|
|
2189
|
+
diffCountByBucket,
|
|
2190
|
+
diffPercentByBucket
|
|
2180
2191
|
};
|
|
2181
2192
|
}
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
var
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2193
|
+
function sortDatasetGroupSummaries(summaries) {
|
|
2194
|
+
return summaries.sort((a, b) => {
|
|
2195
|
+
var _a, _b;
|
|
2196
|
+
const scoreResult = compareScores(a.scores, b.scores);
|
|
2197
|
+
if (scoreResult !== 0) {
|
|
2198
|
+
return -scoreResult;
|
|
2199
|
+
} else {
|
|
2200
|
+
const aVar = a.root.outputVarL;
|
|
2201
|
+
const bVar = b.root.outputVarR;
|
|
2202
|
+
const aSource = ((_a = aVar.sourceName) == null ? void 0 : _a.toLowerCase()) || "";
|
|
2203
|
+
const bSource = ((_b = bVar.sourceName) == null ? void 0 : _b.toLowerCase()) || "";
|
|
2204
|
+
if (aSource !== bSource) {
|
|
2205
|
+
return aSource.localeCompare(bSource);
|
|
2206
|
+
} else {
|
|
2207
|
+
const aName = aVar.varName.toLowerCase();
|
|
2208
|
+
const bName = bVar.varName.toLowerCase();
|
|
2209
|
+
return aName.localeCompare(bName);
|
|
2210
|
+
}
|
|
2195
2211
|
}
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2212
|
+
});
|
|
2213
|
+
}
|
|
2214
|
+
function sortScenarioGroupSummaries(summaries) {
|
|
2215
|
+
return summaries.sort((a, b) => {
|
|
2216
|
+
var _a, _b;
|
|
2217
|
+
const scoreResult = compareScores(a.scores, b.scores);
|
|
2218
|
+
if (scoreResult !== 0) {
|
|
2219
|
+
return -scoreResult;
|
|
2220
|
+
} else {
|
|
2221
|
+
const aScenario = a.root;
|
|
2222
|
+
const bScenario = b.root;
|
|
2223
|
+
const aTitle = aScenario.title.toLowerCase();
|
|
2224
|
+
const bTitle = bScenario.title.toLowerCase();
|
|
2225
|
+
if (aTitle !== bTitle) {
|
|
2226
|
+
return aTitle.localeCompare(bTitle);
|
|
2227
|
+
} else {
|
|
2228
|
+
const aSubtitle = ((_a = aScenario.subtitle) == null ? void 0 : _a.toLowerCase()) || "";
|
|
2229
|
+
const bSubtitle = ((_b = bScenario.subtitle) == null ? void 0 : _b.toLowerCase()) || "";
|
|
2230
|
+
return aSubtitle.localeCompare(bSubtitle);
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
});
|
|
2234
|
+
}
|
|
2235
|
+
function compareScores(a, b) {
|
|
2236
|
+
if (a.totalMaxDiffByBucket.length !== b.totalMaxDiffByBucket.length) {
|
|
2237
|
+
return 0;
|
|
2238
|
+
}
|
|
2239
|
+
const len = a.totalMaxDiffByBucket.length;
|
|
2240
|
+
for (let i = len - 1; i >= 0; i--) {
|
|
2241
|
+
const aTotal = a.totalMaxDiffByBucket[i];
|
|
2242
|
+
const bTotal = b.totalMaxDiffByBucket[i];
|
|
2243
|
+
if (aTotal > bTotal) {
|
|
2244
|
+
return 1;
|
|
2245
|
+
} else if (aTotal < bTotal) {
|
|
2246
|
+
return -1;
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
return 0;
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
// src/bundle/model-inputs.ts
|
|
2253
|
+
var ModelInputs = class {
|
|
2254
|
+
constructor(modelSpec) {
|
|
2255
|
+
this.inputsByLookupName = /* @__PURE__ */ new Map();
|
|
2256
|
+
this.inputIdAliases = /* @__PURE__ */ new Set();
|
|
2257
|
+
for (const inputVar of modelSpec.inputVars.values()) {
|
|
2258
|
+
const varNameKey = inputVar.varName.toLowerCase();
|
|
2259
|
+
this.inputsByLookupName.set(varNameKey, inputVar);
|
|
2260
|
+
if (inputVar.inputId) {
|
|
2261
|
+
const idAlias = `id ${inputVar.inputId}`;
|
|
2262
|
+
this.inputIdAliases.add(idAlias);
|
|
2263
|
+
const idKey = idAlias.toLowerCase();
|
|
2264
|
+
this.inputsByLookupName.set(idKey, inputVar);
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
if (modelSpec.inputAliases) {
|
|
2268
|
+
for (const [alias, varId] of modelSpec.inputAliases.entries()) {
|
|
2269
|
+
const aliasKey = alias.toLowerCase();
|
|
2270
|
+
if (this.inputsByLookupName.has(aliasKey)) {
|
|
2271
|
+
console.warn(
|
|
2272
|
+
`WARNING: Input variable already defined with a name that collides with alias '${alias}', skipping`
|
|
2273
|
+
);
|
|
2274
|
+
continue;
|
|
2275
|
+
}
|
|
2276
|
+
const inputVar = modelSpec.inputVars.get(varId);
|
|
2277
|
+
if (inputVar === void 0) {
|
|
2278
|
+
console.warn(`WARNING: No input variable found for '${varId}' associated with alias '${alias}', skipping`);
|
|
2279
|
+
continue;
|
|
2280
|
+
}
|
|
2281
|
+
this.inputsByLookupName.set(aliasKey, inputVar);
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
getAllInputIdAliases() {
|
|
2286
|
+
return [...this.inputIdAliases];
|
|
2287
|
+
}
|
|
2288
|
+
getInputVarForName(name) {
|
|
2289
|
+
return this.inputsByLookupName.get(name.toLowerCase());
|
|
2290
|
+
}
|
|
2291
|
+
};
|
|
2292
|
+
|
|
2293
|
+
// src/comparison/config/parse/comparison-parser.ts
|
|
2294
|
+
import Ajv2 from "ajv";
|
|
2295
|
+
import assertNever9 from "assert-never";
|
|
2296
|
+
import { err as err2, ok as ok2 } from "neverthrow";
|
|
2297
|
+
import yaml2 from "yaml";
|
|
2298
|
+
|
|
2299
|
+
// src/comparison/config/parse/comparison.schema.js
|
|
2300
|
+
var comparison_schema_default = {
|
|
2301
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
2302
|
+
title: "Model Comparison Test",
|
|
2303
|
+
type: "array",
|
|
2304
|
+
description: "A group of model comparison scenarios and views.",
|
|
2305
|
+
items: {
|
|
2306
|
+
$ref: "#/$defs/top_level_array_item"
|
|
2307
|
+
},
|
|
2308
|
+
$defs: {
|
|
2309
|
+
top_level_array_item: {
|
|
2310
|
+
oneOf: [
|
|
2311
|
+
{ $ref: "#/$defs/scenario_array_item" },
|
|
2312
|
+
{ $ref: "#/$defs/scenario_group_array_item" },
|
|
2313
|
+
{ $ref: "#/$defs/view_group_array_item" }
|
|
2314
|
+
]
|
|
2315
|
+
},
|
|
2316
|
+
scenario_array_item: {
|
|
2317
|
+
type: "object",
|
|
2318
|
+
additionalProperties: false,
|
|
2319
|
+
properties: {
|
|
2320
|
+
scenario: {
|
|
2321
|
+
$ref: "#/$defs/scenario"
|
|
2322
|
+
}
|
|
2323
|
+
},
|
|
2324
|
+
required: ["scenario"]
|
|
2325
|
+
},
|
|
2326
|
+
scenario: {
|
|
2327
|
+
oneOf: [
|
|
2328
|
+
{ $ref: "#/$defs/scenario_with_input_at_position" },
|
|
2329
|
+
{ $ref: "#/$defs/scenario_with_input_at_value" },
|
|
2330
|
+
{ $ref: "#/$defs/scenario_with_multiple_input_settings" },
|
|
2331
|
+
{ $ref: "#/$defs/scenario_with_inputs_in_preset_at_position" },
|
|
2332
|
+
{ $ref: "#/$defs/scenario_preset" }
|
|
2333
|
+
]
|
|
2334
|
+
},
|
|
2335
|
+
scenario_position: {
|
|
2336
|
+
type: "string",
|
|
2337
|
+
enum: ["min", "max", "default"]
|
|
2338
|
+
},
|
|
2339
|
+
scenario_with_input_at_position: {
|
|
2340
|
+
type: "object",
|
|
2341
|
+
additionalProperties: false,
|
|
2342
|
+
properties: {
|
|
2343
|
+
id: {
|
|
2344
|
+
type: "string"
|
|
2345
|
+
},
|
|
2346
|
+
title: {
|
|
2347
|
+
type: "string"
|
|
2348
|
+
},
|
|
2349
|
+
subtitle: {
|
|
2350
|
+
type: "string"
|
|
2351
|
+
},
|
|
2352
|
+
with: {
|
|
2353
|
+
type: "string"
|
|
2354
|
+
},
|
|
2355
|
+
at: {
|
|
2356
|
+
$ref: "#/$defs/scenario_position"
|
|
2357
|
+
}
|
|
2358
|
+
},
|
|
2359
|
+
required: ["with", "at"]
|
|
2360
|
+
},
|
|
2361
|
+
scenario_with_input_at_value: {
|
|
2362
|
+
type: "object",
|
|
2363
|
+
additionalProperties: false,
|
|
2364
|
+
properties: {
|
|
2365
|
+
id: {
|
|
2366
|
+
type: "string"
|
|
2367
|
+
},
|
|
2368
|
+
title: {
|
|
2369
|
+
type: "string"
|
|
2370
|
+
},
|
|
2371
|
+
subtitle: {
|
|
2372
|
+
type: "string"
|
|
2373
|
+
},
|
|
2374
|
+
with: {
|
|
2375
|
+
type: "string"
|
|
2376
|
+
},
|
|
2377
|
+
at: {
|
|
2378
|
+
type: "number"
|
|
2379
|
+
}
|
|
2380
|
+
},
|
|
2381
|
+
required: ["with", "at"]
|
|
2382
|
+
},
|
|
2383
|
+
scenario_input_at_position: {
|
|
2384
|
+
type: "object",
|
|
2385
|
+
additionalProperties: false,
|
|
2386
|
+
properties: {
|
|
2387
|
+
input: {
|
|
2388
|
+
type: "string"
|
|
2389
|
+
},
|
|
2390
|
+
at: {
|
|
2391
|
+
$ref: "#/$defs/scenario_position"
|
|
2392
|
+
}
|
|
2393
|
+
},
|
|
2394
|
+
required: ["input", "at"]
|
|
2395
|
+
},
|
|
2396
|
+
scenario_input_at_value: {
|
|
2397
|
+
type: "object",
|
|
2398
|
+
additionalProperties: false,
|
|
2399
|
+
properties: {
|
|
2400
|
+
input: {
|
|
2401
|
+
type: "string"
|
|
2402
|
+
},
|
|
2403
|
+
at: {
|
|
2404
|
+
type: "number"
|
|
2405
|
+
}
|
|
2406
|
+
},
|
|
2407
|
+
required: ["input", "at"]
|
|
2408
|
+
},
|
|
2409
|
+
scenario_input_setting: {
|
|
2410
|
+
oneOf: [{ $ref: "#/$defs/scenario_input_at_position" }, { $ref: "#/$defs/scenario_input_at_value" }]
|
|
2411
|
+
},
|
|
2412
|
+
scenario_input_setting_array: {
|
|
2413
|
+
type: "array",
|
|
2414
|
+
items: {
|
|
2415
|
+
$ref: "#/$defs/scenario_input_setting"
|
|
2416
|
+
},
|
|
2417
|
+
minItems: 1
|
|
2418
|
+
},
|
|
2419
|
+
scenario_with_multiple_input_settings: {
|
|
2420
|
+
type: "object",
|
|
2421
|
+
additionalProperties: false,
|
|
2422
|
+
properties: {
|
|
2423
|
+
id: {
|
|
2424
|
+
type: "string"
|
|
2425
|
+
},
|
|
2426
|
+
title: {
|
|
2427
|
+
type: "string"
|
|
2428
|
+
},
|
|
2429
|
+
subtitle: {
|
|
2430
|
+
type: "string"
|
|
2431
|
+
},
|
|
2432
|
+
with: {
|
|
2433
|
+
$ref: "#/$defs/scenario_input_setting_array"
|
|
2434
|
+
}
|
|
2435
|
+
},
|
|
2436
|
+
required: ["with"]
|
|
2437
|
+
},
|
|
2438
|
+
scenario_with_inputs_in_preset_at_position: {
|
|
2439
|
+
type: "object",
|
|
2440
|
+
additionalProperties: false,
|
|
2441
|
+
properties: {
|
|
2442
|
+
id: {
|
|
2443
|
+
type: "string"
|
|
2444
|
+
},
|
|
2445
|
+
title: {
|
|
2446
|
+
type: "string"
|
|
2447
|
+
},
|
|
2448
|
+
subtitle: {
|
|
2449
|
+
type: "string"
|
|
2450
|
+
},
|
|
2451
|
+
with_inputs: {
|
|
2452
|
+
type: "string",
|
|
2453
|
+
enum: ["all"]
|
|
2454
|
+
},
|
|
2455
|
+
at: {
|
|
2456
|
+
$ref: "#/$defs/scenario_position"
|
|
2457
|
+
}
|
|
2458
|
+
},
|
|
2459
|
+
required: ["with_inputs", "at"]
|
|
2460
|
+
},
|
|
2461
|
+
scenario_preset: {
|
|
2462
|
+
type: "object",
|
|
2463
|
+
additionalProperties: false,
|
|
2464
|
+
properties: {
|
|
2465
|
+
preset: {
|
|
2466
|
+
type: "string",
|
|
2467
|
+
enum: ["matrix"]
|
|
2468
|
+
}
|
|
2469
|
+
},
|
|
2470
|
+
required: ["preset"]
|
|
2471
|
+
},
|
|
2472
|
+
scenario_group_array_item: {
|
|
2473
|
+
type: "object",
|
|
2474
|
+
additionalProperties: false,
|
|
2475
|
+
properties: {
|
|
2476
|
+
scenario_group: {
|
|
2477
|
+
$ref: "#/$defs/scenario_group"
|
|
2478
|
+
}
|
|
2479
|
+
},
|
|
2480
|
+
required: ["scenario_group"]
|
|
2481
|
+
},
|
|
2482
|
+
scenario_group: {
|
|
2483
|
+
type: "object",
|
|
2484
|
+
additionalProperties: false,
|
|
2485
|
+
properties: {
|
|
2486
|
+
id: {
|
|
2487
|
+
type: "string"
|
|
2488
|
+
},
|
|
2489
|
+
title: {
|
|
2490
|
+
type: "string"
|
|
2491
|
+
},
|
|
2492
|
+
scenarios: {
|
|
2493
|
+
type: "array",
|
|
2494
|
+
items: {
|
|
2495
|
+
$ref: "#/$defs/scenario_group_scenarios_array_item"
|
|
2496
|
+
},
|
|
2497
|
+
minItems: 1
|
|
2498
|
+
}
|
|
2499
|
+
},
|
|
2500
|
+
required: ["title", "scenarios"]
|
|
2501
|
+
},
|
|
2502
|
+
scenario_group_scenarios_array_item: {
|
|
2503
|
+
oneOf: [{ $ref: "#/$defs/scenario_array_item" }, { $ref: "#/$defs/scenario_ref_array_item" }]
|
|
2504
|
+
},
|
|
2505
|
+
scenario_ref_id: {
|
|
2506
|
+
type: "string"
|
|
2507
|
+
},
|
|
2508
|
+
scenario_ref_object: {
|
|
2509
|
+
type: "object",
|
|
2510
|
+
additionalProperties: false,
|
|
2511
|
+
properties: {
|
|
2512
|
+
id: {
|
|
2513
|
+
type: "string"
|
|
2514
|
+
},
|
|
2515
|
+
title: {
|
|
2516
|
+
type: "string"
|
|
2517
|
+
},
|
|
2518
|
+
subtitle: {
|
|
2519
|
+
type: "string"
|
|
2520
|
+
}
|
|
2521
|
+
},
|
|
2522
|
+
required: ["id"]
|
|
2523
|
+
},
|
|
2524
|
+
scenario_ref: {
|
|
2525
|
+
oneOf: [{ $ref: "#/$defs/scenario_ref_id" }, { $ref: "#/$defs/scenario_ref_object" }]
|
|
2526
|
+
},
|
|
2527
|
+
scenario_ref_array_item: {
|
|
2528
|
+
type: "object",
|
|
2529
|
+
additionalProperties: false,
|
|
2530
|
+
properties: {
|
|
2531
|
+
scenario_ref: {
|
|
2532
|
+
$ref: "#/$defs/scenario_ref"
|
|
2533
|
+
}
|
|
2534
|
+
},
|
|
2535
|
+
required: ["scenario_ref"]
|
|
2536
|
+
},
|
|
2537
|
+
scenario_group_ref: {
|
|
2538
|
+
type: "object",
|
|
2539
|
+
additionalProperties: false,
|
|
2540
|
+
properties: {
|
|
2541
|
+
scenario_group_ref: {
|
|
2542
|
+
type: "string"
|
|
2543
|
+
}
|
|
2544
|
+
},
|
|
2545
|
+
required: ["scenario_group_ref"]
|
|
2546
|
+
},
|
|
2547
|
+
view: {
|
|
2548
|
+
type: "object",
|
|
2549
|
+
additionalProperties: false,
|
|
2550
|
+
properties: {
|
|
2551
|
+
title: {
|
|
2552
|
+
type: "string"
|
|
2553
|
+
},
|
|
2554
|
+
subtitle: {
|
|
2555
|
+
type: "string"
|
|
2556
|
+
},
|
|
2557
|
+
scenario_ref: {
|
|
2558
|
+
type: "string"
|
|
2559
|
+
},
|
|
2560
|
+
graphs: {
|
|
2561
|
+
$ref: "#/$defs/view_graphs"
|
|
2562
|
+
}
|
|
2563
|
+
},
|
|
2564
|
+
required: ["scenario_ref", "graphs"]
|
|
2565
|
+
},
|
|
2566
|
+
view_graphs: {
|
|
2567
|
+
oneOf: [{ $ref: "#/$defs/view_graphs_preset" }, { $ref: "#/$defs/view_graphs_array" }]
|
|
2568
|
+
},
|
|
2569
|
+
view_graphs_preset: {
|
|
2570
|
+
type: "string",
|
|
2571
|
+
enum: ["all"]
|
|
2572
|
+
},
|
|
2573
|
+
view_graphs_array: {
|
|
2574
|
+
type: "array",
|
|
2575
|
+
items: {
|
|
2576
|
+
type: "string"
|
|
2577
|
+
},
|
|
2578
|
+
minItems: 1
|
|
2579
|
+
},
|
|
2580
|
+
view_group_array_item: {
|
|
2581
|
+
type: "object",
|
|
2582
|
+
additionalProperties: false,
|
|
2583
|
+
properties: {
|
|
2584
|
+
view_group: {
|
|
2585
|
+
$ref: "#/$defs/view_group"
|
|
2586
|
+
}
|
|
2587
|
+
},
|
|
2588
|
+
required: ["view_group"]
|
|
2589
|
+
},
|
|
2590
|
+
view_group: {
|
|
2591
|
+
oneOf: [
|
|
2592
|
+
{ $ref: "#/$defs/view_group_with_views_array" },
|
|
2593
|
+
{ $ref: "#/$defs/view_group_shorthand_with_scenarios_array" }
|
|
2594
|
+
]
|
|
2595
|
+
},
|
|
2596
|
+
view_group_with_views_array: {
|
|
2597
|
+
type: "object",
|
|
2598
|
+
additionalProperties: false,
|
|
2599
|
+
properties: {
|
|
2600
|
+
title: {
|
|
2601
|
+
type: "string"
|
|
2602
|
+
},
|
|
2603
|
+
views: {
|
|
2604
|
+
type: "array",
|
|
2605
|
+
items: {
|
|
2606
|
+
$ref: "#/$defs/view_group_views_array_item"
|
|
2607
|
+
},
|
|
2608
|
+
minItems: 1
|
|
2609
|
+
}
|
|
2610
|
+
},
|
|
2611
|
+
required: ["title", "views"]
|
|
2612
|
+
},
|
|
2613
|
+
view_group_views_array_item: {
|
|
2614
|
+
type: "object",
|
|
2615
|
+
additionalProperties: false,
|
|
2616
|
+
properties: {
|
|
2617
|
+
view: {
|
|
2618
|
+
$ref: "#/$defs/view"
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2621
|
+
},
|
|
2622
|
+
view_group_shorthand_with_scenarios_array: {
|
|
2623
|
+
type: "object",
|
|
2624
|
+
additionalProperties: false,
|
|
2625
|
+
properties: {
|
|
2626
|
+
title: {
|
|
2627
|
+
type: "string"
|
|
2628
|
+
},
|
|
2629
|
+
scenarios: {
|
|
2630
|
+
type: "array",
|
|
2631
|
+
items: {
|
|
2632
|
+
$ref: "#/$defs/view_group_scenarios_array_item"
|
|
2633
|
+
},
|
|
2634
|
+
minItems: 1
|
|
2635
|
+
},
|
|
2636
|
+
graphs: {
|
|
2637
|
+
$ref: "#/$defs/view_graphs"
|
|
2638
|
+
}
|
|
2639
|
+
},
|
|
2640
|
+
required: ["title", "scenarios", "graphs"]
|
|
2641
|
+
},
|
|
2642
|
+
view_group_scenarios_array_item: {
|
|
2643
|
+
oneOf: [{ $ref: "#/$defs/scenario_ref_array_item" }, { $ref: "#/$defs/scenario_group_ref" }]
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
};
|
|
2647
|
+
|
|
2648
|
+
// src/comparison/config/parse/comparison-parser.ts
|
|
2649
|
+
function parseComparisonSpecs(specSource) {
|
|
2650
|
+
const scenarios = [];
|
|
2651
|
+
const scenarioGroups = [];
|
|
2652
|
+
const viewGroups = [];
|
|
2653
|
+
const ajv = new Ajv2();
|
|
2654
|
+
const validate = ajv.compile(comparison_schema_default);
|
|
2655
|
+
let parsed;
|
|
2656
|
+
switch (specSource.kind) {
|
|
2657
|
+
case "json":
|
|
2658
|
+
parsed = JSON.parse(specSource.content);
|
|
2659
|
+
break;
|
|
2660
|
+
case "yaml":
|
|
2661
|
+
parsed = yaml2.parse(specSource.content);
|
|
2662
|
+
break;
|
|
2663
|
+
default:
|
|
2664
|
+
assertNever9(specSource.kind);
|
|
2665
|
+
}
|
|
2666
|
+
if (validate(parsed)) {
|
|
2667
|
+
for (const specItem of parsed) {
|
|
2668
|
+
if ("scenario" in specItem) {
|
|
2669
|
+
scenarios.push(scenarioSpecFromParsed(specItem.scenario));
|
|
2670
|
+
} else if ("scenario_group" in specItem) {
|
|
2671
|
+
scenarioGroups.push(scenarioGroupSpecFromParsed(specItem.scenario_group));
|
|
2672
|
+
} else if ("view_group" in specItem) {
|
|
2673
|
+
viewGroups.push(viewGroupSpecFromParsed(specItem.view_group));
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
} else {
|
|
2677
|
+
let msg = "Failed to parse YAML comparison definitions";
|
|
2678
|
+
for (const error of validate.errors || []) {
|
|
2679
|
+
if (error.message) {
|
|
2680
|
+
msg += `
|
|
2681
|
+
${error.message}`;
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
return err2(new Error(msg));
|
|
2685
|
+
}
|
|
2686
|
+
return ok2({
|
|
2687
|
+
scenarios,
|
|
2688
|
+
scenarioGroups,
|
|
2689
|
+
viewGroups
|
|
2690
|
+
});
|
|
2691
|
+
}
|
|
2692
|
+
function scenarioSpecFromParsed(parsedScenario) {
|
|
2693
|
+
if (parsedScenario.preset === "matrix") {
|
|
2694
|
+
return {
|
|
2695
|
+
kind: "scenario-matrix"
|
|
2696
|
+
};
|
|
2697
|
+
}
|
|
2698
|
+
if (parsedScenario.with !== void 0) {
|
|
2699
|
+
let inputSpecs;
|
|
2700
|
+
if (Array.isArray(parsedScenario.with)) {
|
|
2701
|
+
const parsedInputs = parsedScenario.with;
|
|
2702
|
+
inputSpecs = parsedInputs.map(inputSpecFromParsed);
|
|
2703
|
+
} else {
|
|
2704
|
+
inputSpecs = [
|
|
2705
|
+
inputSpecFromParsed({
|
|
2706
|
+
input: parsedScenario.with,
|
|
2707
|
+
at: parsedScenario.at
|
|
2708
|
+
})
|
|
2709
|
+
];
|
|
2710
|
+
}
|
|
2711
|
+
return {
|
|
2712
|
+
kind: "scenario-with-inputs",
|
|
2713
|
+
id: parsedScenario.id,
|
|
2714
|
+
title: parsedScenario.title,
|
|
2715
|
+
subtitle: parsedScenario.subtitle,
|
|
2716
|
+
inputs: inputSpecs
|
|
2717
|
+
};
|
|
2718
|
+
}
|
|
2719
|
+
if (parsedScenario.with_inputs === "all") {
|
|
2720
|
+
return {
|
|
2721
|
+
kind: "scenario-with-all-inputs",
|
|
2722
|
+
id: parsedScenario.id,
|
|
2723
|
+
title: parsedScenario.title,
|
|
2724
|
+
subtitle: parsedScenario.subtitle,
|
|
2725
|
+
position: parsedScenario.at
|
|
2726
|
+
};
|
|
2727
|
+
}
|
|
2728
|
+
throw new Error(`Unable to convert parsed scenario: ${JSON.stringify(parsedScenario)}`);
|
|
2729
|
+
}
|
|
2730
|
+
function inputSpecFromParsed(parsedInput) {
|
|
2731
|
+
if (typeof parsedInput.at === "number") {
|
|
2732
|
+
const value = parsedInput.at;
|
|
2733
|
+
return {
|
|
2734
|
+
kind: "input-at-value",
|
|
2735
|
+
inputName: parsedInput.input,
|
|
2736
|
+
value
|
|
2737
|
+
};
|
|
2738
|
+
} else {
|
|
2739
|
+
return {
|
|
2740
|
+
kind: "input-at-position",
|
|
2741
|
+
inputName: parsedInput.input,
|
|
2742
|
+
position: parsedInput.at
|
|
2743
|
+
};
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
function scenarioGroupSpecFromParsed(parsedScenarioGroup) {
|
|
2747
|
+
const scenarioSpecs = parsedScenarioGroup.scenarios.map(
|
|
2748
|
+
(parsedScenarioOrRef) => {
|
|
2749
|
+
if ("scenario_ref" in parsedScenarioOrRef) {
|
|
2750
|
+
return scenarioRefSpecFromParsed(parsedScenarioOrRef);
|
|
2751
|
+
} else {
|
|
2752
|
+
return scenarioSpecFromParsed(parsedScenarioOrRef.scenario);
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2755
|
+
);
|
|
2756
|
+
return {
|
|
2757
|
+
kind: "scenario-group",
|
|
2758
|
+
id: parsedScenarioGroup.id,
|
|
2759
|
+
title: parsedScenarioGroup.title,
|
|
2760
|
+
scenarios: scenarioSpecs
|
|
2761
|
+
};
|
|
2762
|
+
}
|
|
2763
|
+
function scenarioRefSpecFromParsed(parsedScenarioRef) {
|
|
2764
|
+
if (typeof parsedScenarioRef.scenario_ref === "string") {
|
|
2765
|
+
return {
|
|
2766
|
+
kind: "scenario-ref",
|
|
2767
|
+
scenarioId: parsedScenarioRef.scenario_ref
|
|
2768
|
+
};
|
|
2769
|
+
} else {
|
|
2770
|
+
return {
|
|
2771
|
+
kind: "scenario-ref",
|
|
2772
|
+
scenarioId: parsedScenarioRef.scenario_ref.id,
|
|
2773
|
+
title: parsedScenarioRef.scenario_ref.title,
|
|
2774
|
+
subtitle: parsedScenarioRef.scenario_ref.subtitle
|
|
2775
|
+
};
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
function scenarioGroupRefSpecFromParsed(parsedGroupRef) {
|
|
2779
|
+
return {
|
|
2780
|
+
kind: "scenario-group-ref",
|
|
2781
|
+
groupId: parsedGroupRef.scenario_group_ref
|
|
2782
|
+
};
|
|
2783
|
+
}
|
|
2784
|
+
function viewSpecFromParsed(parsedView) {
|
|
2785
|
+
return {
|
|
2786
|
+
kind: "view",
|
|
2787
|
+
title: parsedView.title,
|
|
2788
|
+
subtitle: parsedView.subtitle,
|
|
2789
|
+
scenarioId: parsedView.scenario_ref,
|
|
2790
|
+
graphs: viewGraphsSpecFromParsed(parsedView.graphs)
|
|
2791
|
+
};
|
|
2792
|
+
}
|
|
2793
|
+
function viewGraphsSpecFromParsed(parsedGraphs) {
|
|
2794
|
+
if (parsedGraphs === "all") {
|
|
2795
|
+
return {
|
|
2796
|
+
kind: "graphs-preset",
|
|
2797
|
+
preset: "all"
|
|
2798
|
+
};
|
|
2799
|
+
} else {
|
|
2800
|
+
return {
|
|
2801
|
+
kind: "graphs-array",
|
|
2802
|
+
graphIds: parsedGraphs
|
|
2803
|
+
};
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
function viewGroupSpecFromParsed(parsedViewGroup) {
|
|
2807
|
+
if (parsedViewGroup.views !== void 0) {
|
|
2808
|
+
return {
|
|
2809
|
+
kind: "view-group-with-views",
|
|
2810
|
+
title: parsedViewGroup.title,
|
|
2811
|
+
views: parsedViewGroup.views.map((item) => viewSpecFromParsed(item.view))
|
|
2812
|
+
};
|
|
2813
|
+
} else if (parsedViewGroup.scenarios !== void 0) {
|
|
2814
|
+
const scenarios = parsedViewGroup.scenarios.map(
|
|
2815
|
+
(parsedScenarioOrGroupRef) => {
|
|
2816
|
+
if ("scenario_ref" in parsedScenarioOrGroupRef) {
|
|
2817
|
+
return scenarioRefSpecFromParsed(parsedScenarioOrGroupRef);
|
|
2818
|
+
} else if ("scenario_group_ref" in parsedScenarioOrGroupRef) {
|
|
2819
|
+
return scenarioGroupRefSpecFromParsed(parsedScenarioOrGroupRef);
|
|
2820
|
+
} else {
|
|
2821
|
+
throw new Error("Invalid view group");
|
|
2822
|
+
}
|
|
2823
|
+
}
|
|
2824
|
+
);
|
|
2825
|
+
return {
|
|
2826
|
+
kind: "view-group-with-scenarios",
|
|
2827
|
+
title: parsedViewGroup.title,
|
|
2828
|
+
scenarios,
|
|
2829
|
+
graphs: viewGraphsSpecFromParsed(parsedViewGroup.graphs)
|
|
2830
|
+
};
|
|
2831
|
+
} else {
|
|
2832
|
+
throw new Error("Invalid view group");
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
|
|
2836
|
+
// src/comparison/config/resolve/comparison-resolver.ts
|
|
2837
|
+
import { assertNever as assertNever11 } from "assert-never";
|
|
2838
|
+
|
|
2839
|
+
// src/comparison/config/resolve/comparison-scenario-specs.ts
|
|
2840
|
+
import { assertNever as assertNever10 } from "assert-never";
|
|
2841
|
+
function scenarioSpecsFromSettings(settings) {
|
|
2842
|
+
switch (settings.kind) {
|
|
2843
|
+
case "all-inputs-settings": {
|
|
2844
|
+
const scenario = allInputsAtPositionSpec(settings.position);
|
|
2845
|
+
return [scenario, scenario];
|
|
2846
|
+
}
|
|
2847
|
+
case "input-settings": {
|
|
2848
|
+
const specL = scenarioSpecFromInputs(settings.inputs, "left");
|
|
2849
|
+
const specR = scenarioSpecFromInputs(settings.inputs, "right");
|
|
2850
|
+
return [specL, specR];
|
|
2851
|
+
}
|
|
2852
|
+
default:
|
|
2853
|
+
assertNever10(settings);
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2856
|
+
function scenarioSpecFromInputs(inputs, side) {
|
|
2857
|
+
const settings = [];
|
|
2858
|
+
for (const input of inputs) {
|
|
2859
|
+
const state = side === "left" ? input.stateL : input.stateR;
|
|
2860
|
+
if (state.inputVar === void 0) {
|
|
2861
|
+
return void 0;
|
|
2862
|
+
}
|
|
2863
|
+
const varId = state.inputVar.varId;
|
|
2864
|
+
if (state.position) {
|
|
2865
|
+
settings.push(positionSetting(varId, state.position));
|
|
2866
|
+
} else {
|
|
2867
|
+
settings.push(valueSetting(varId, state.value));
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
return inputSettingsSpec(settings);
|
|
2871
|
+
}
|
|
2872
|
+
|
|
2873
|
+
// src/comparison/config/resolve/comparison-resolver.ts
|
|
2874
|
+
function resolveComparisonSpecs(modelInputsL, modelInputsR, specs) {
|
|
2875
|
+
let key = 1;
|
|
2876
|
+
const genKey = () => {
|
|
2877
|
+
return `${key++}`;
|
|
2878
|
+
};
|
|
2879
|
+
const resolvedScenarios = new ResolvedScenarios();
|
|
2880
|
+
for (const scenarioSpec of specs.scenarios) {
|
|
2881
|
+
resolvedScenarios.add(resolveScenariosFromSpec(modelInputsL, modelInputsR, scenarioSpec, genKey));
|
|
2882
|
+
}
|
|
2883
|
+
const partiallyResolvedScenarioGroups = [];
|
|
2884
|
+
for (const scenarioGroupSpec of specs.scenarioGroups) {
|
|
2885
|
+
const scenariosForGroup = [];
|
|
2886
|
+
for (const scenarioItem of scenarioGroupSpec.scenarios) {
|
|
2887
|
+
if (scenarioItem.kind === "scenario-ref") {
|
|
2888
|
+
scenariosForGroup.push(scenarioItem);
|
|
2889
|
+
} else {
|
|
2890
|
+
const scenarios = resolveScenariosFromSpec(modelInputsL, modelInputsR, scenarioItem, genKey);
|
|
2891
|
+
resolvedScenarios.add(scenarios);
|
|
2892
|
+
scenariosForGroup.push(...scenarios);
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
partiallyResolvedScenarioGroups.push({
|
|
2896
|
+
spec: scenarioGroupSpec,
|
|
2897
|
+
scenarios: scenariosForGroup
|
|
2898
|
+
});
|
|
2899
|
+
}
|
|
2900
|
+
const resolvedScenarioGroups = new ResolvedScenarioGroups();
|
|
2901
|
+
for (const partiallyResolvedGroup of partiallyResolvedScenarioGroups) {
|
|
2902
|
+
const scenariosForGroup = [];
|
|
2903
|
+
for (const scenarioItem of partiallyResolvedGroup.scenarios) {
|
|
2904
|
+
if (scenarioItem.kind === "scenario-ref") {
|
|
2905
|
+
const referencedScenario = resolvedScenarios.getScenarioForId(scenarioItem.scenarioId);
|
|
2906
|
+
if (referencedScenario) {
|
|
2907
|
+
const resolvedScenario = { ...referencedScenario };
|
|
2908
|
+
if (scenarioItem.title) {
|
|
2909
|
+
resolvedScenario.title = scenarioItem.title;
|
|
2910
|
+
}
|
|
2911
|
+
if (scenarioItem.subtitle) {
|
|
2912
|
+
resolvedScenario.subtitle = scenarioItem.subtitle;
|
|
2913
|
+
}
|
|
2914
|
+
scenariosForGroup.push(resolvedScenario);
|
|
2915
|
+
} else {
|
|
2916
|
+
scenariosForGroup.push({
|
|
2917
|
+
kind: "unresolved-scenario-ref",
|
|
2918
|
+
scenarioId: scenarioItem.scenarioId
|
|
2919
|
+
});
|
|
2920
|
+
}
|
|
2921
|
+
} else {
|
|
2922
|
+
scenariosForGroup.push(scenarioItem);
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
resolvedScenarioGroups.add({
|
|
2926
|
+
kind: "scenario-group",
|
|
2927
|
+
id: partiallyResolvedGroup.spec.id,
|
|
2928
|
+
title: partiallyResolvedGroup.spec.title,
|
|
2929
|
+
scenarios: scenariosForGroup
|
|
2930
|
+
});
|
|
2931
|
+
}
|
|
2932
|
+
const resolvedViewGroups = [];
|
|
2933
|
+
for (const viewGroupSpec of specs.viewGroups) {
|
|
2934
|
+
const resolvedViewGroup = resolveViewGroupFromSpec(resolvedScenarios, resolvedScenarioGroups, viewGroupSpec);
|
|
2935
|
+
resolvedViewGroups.push(resolvedViewGroup);
|
|
2936
|
+
}
|
|
2937
|
+
return {
|
|
2938
|
+
scenarios: resolvedScenarios.getAll(),
|
|
2939
|
+
scenarioGroups: resolvedScenarioGroups.getAll(),
|
|
2940
|
+
viewGroups: resolvedViewGroups
|
|
2941
|
+
};
|
|
2942
|
+
}
|
|
2943
|
+
var ResolvedScenarios = class {
|
|
2944
|
+
constructor() {
|
|
2945
|
+
this.resolvedScenarios = [];
|
|
2946
|
+
this.resolvedScenariosById = /* @__PURE__ */ new Map();
|
|
2947
|
+
}
|
|
2948
|
+
add(scenarios) {
|
|
2949
|
+
for (const resolvedScenario of scenarios) {
|
|
2950
|
+
this.resolvedScenarios.push(resolvedScenario);
|
|
2951
|
+
if (resolvedScenario.id !== void 0) {
|
|
2952
|
+
if (this.resolvedScenariosById.has(resolvedScenario.id)) {
|
|
2953
|
+
throw new Error(`Multiple scenarios defined with the same id (${resolvedScenario.id})`);
|
|
2954
|
+
}
|
|
2955
|
+
this.resolvedScenariosById.set(resolvedScenario.id, resolvedScenario);
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2959
|
+
getAll() {
|
|
2960
|
+
return this.resolvedScenarios;
|
|
2961
|
+
}
|
|
2962
|
+
getScenarioForId(id) {
|
|
2963
|
+
return this.resolvedScenariosById.get(id);
|
|
2964
|
+
}
|
|
2965
|
+
};
|
|
2966
|
+
function resolveScenariosFromSpec(modelInputsL, modelInputsR, scenarioSpec, genKey) {
|
|
2967
|
+
switch (scenarioSpec.kind) {
|
|
2968
|
+
case "scenario-matrix":
|
|
2969
|
+
return resolveScenarioMatrix(modelInputsL, modelInputsR, genKey);
|
|
2970
|
+
case "scenario-with-all-inputs": {
|
|
2971
|
+
const position = inputPosition2(scenarioSpec.position);
|
|
2972
|
+
return [
|
|
2973
|
+
resolveScenarioWithAllInputsAtPosition(
|
|
2974
|
+
genKey(),
|
|
2975
|
+
scenarioSpec.id,
|
|
2976
|
+
scenarioSpec.title,
|
|
2977
|
+
scenarioSpec.subtitle,
|
|
2978
|
+
position
|
|
2979
|
+
)
|
|
2980
|
+
];
|
|
2981
|
+
}
|
|
2982
|
+
case "scenario-with-inputs": {
|
|
2983
|
+
return [
|
|
2984
|
+
resolveScenarioForInputSpecs(
|
|
2985
|
+
modelInputsL,
|
|
2986
|
+
modelInputsR,
|
|
2987
|
+
genKey(),
|
|
2988
|
+
scenarioSpec.id,
|
|
2989
|
+
scenarioSpec.title,
|
|
2990
|
+
scenarioSpec.subtitle,
|
|
2991
|
+
scenarioSpec.inputs
|
|
2992
|
+
)
|
|
2993
|
+
];
|
|
2994
|
+
}
|
|
2995
|
+
default:
|
|
2996
|
+
assertNever11(scenarioSpec);
|
|
2997
|
+
}
|
|
2998
|
+
}
|
|
2999
|
+
function resolveScenarioMatrix(modelInputsL, modelInputsR, genKey) {
|
|
3000
|
+
const resolvedScenarios = [];
|
|
3001
|
+
resolvedScenarios.push(
|
|
3002
|
+
resolveScenarioWithAllInputsAtPosition(genKey(), void 0, void 0, void 0, "at-default")
|
|
3003
|
+
);
|
|
3004
|
+
const inputIdAliases = /* @__PURE__ */ new Set();
|
|
3005
|
+
modelInputsL.getAllInputIdAliases().forEach((alias) => inputIdAliases.add(alias));
|
|
3006
|
+
modelInputsR.getAllInputIdAliases().forEach((alias) => inputIdAliases.add(alias));
|
|
3007
|
+
for (const inputIdAlias of inputIdAliases) {
|
|
3008
|
+
const inputAtMin = {
|
|
3009
|
+
kind: "input-at-position",
|
|
3010
|
+
inputName: inputIdAlias,
|
|
3011
|
+
position: "min"
|
|
3012
|
+
};
|
|
3013
|
+
const inputAtMax = {
|
|
3014
|
+
kind: "input-at-position",
|
|
3015
|
+
inputName: inputIdAlias,
|
|
3016
|
+
position: "max"
|
|
3017
|
+
};
|
|
3018
|
+
resolvedScenarios.push(
|
|
3019
|
+
resolveScenarioForInputSpecs(modelInputsL, modelInputsR, genKey(), void 0, void 0, void 0, [inputAtMin])
|
|
3020
|
+
);
|
|
3021
|
+
resolvedScenarios.push(
|
|
3022
|
+
resolveScenarioForInputSpecs(modelInputsL, modelInputsR, genKey(), void 0, void 0, void 0, [inputAtMax])
|
|
3023
|
+
);
|
|
3024
|
+
}
|
|
3025
|
+
return resolvedScenarios;
|
|
3026
|
+
}
|
|
3027
|
+
function resolveScenarioWithAllInputsAtPosition(key, id, title, subtitle, position) {
|
|
3028
|
+
const settings = {
|
|
3029
|
+
kind: "all-inputs-settings",
|
|
3030
|
+
position
|
|
3031
|
+
};
|
|
3032
|
+
const [specL, specR] = scenarioSpecsFromSettings(settings);
|
|
3033
|
+
return {
|
|
3034
|
+
kind: "scenario",
|
|
3035
|
+
key,
|
|
3036
|
+
id,
|
|
3037
|
+
title,
|
|
3038
|
+
subtitle,
|
|
3039
|
+
settings,
|
|
3040
|
+
specL,
|
|
3041
|
+
specR
|
|
3042
|
+
};
|
|
3043
|
+
}
|
|
3044
|
+
function resolveScenarioForInputSpecs(modelInputsL, modelInputsR, key, id, title, subtitle, inputSpecs) {
|
|
3045
|
+
const resolvedInputs = inputSpecs.map((inputSpec) => {
|
|
3046
|
+
switch (inputSpec.kind) {
|
|
3047
|
+
case "input-at-position":
|
|
3048
|
+
return resolveInputForName(modelInputsL, modelInputsR, inputSpec.inputName, inputSpec.position);
|
|
3049
|
+
case "input-at-value":
|
|
3050
|
+
return resolveInputForName(modelInputsL, modelInputsR, inputSpec.inputName, inputSpec.value);
|
|
3051
|
+
default:
|
|
3052
|
+
assertNever11(inputSpec);
|
|
3053
|
+
}
|
|
3054
|
+
});
|
|
3055
|
+
const settings = {
|
|
3056
|
+
kind: "input-settings",
|
|
3057
|
+
inputs: resolvedInputs
|
|
3058
|
+
};
|
|
3059
|
+
const [specL, specR] = scenarioSpecsFromSettings(settings);
|
|
3060
|
+
return {
|
|
3061
|
+
kind: "scenario",
|
|
3062
|
+
key,
|
|
3063
|
+
id,
|
|
3064
|
+
title,
|
|
3065
|
+
subtitle,
|
|
3066
|
+
settings,
|
|
3067
|
+
specL,
|
|
3068
|
+
specR
|
|
3069
|
+
};
|
|
3070
|
+
}
|
|
3071
|
+
function resolveInputForName(modelInputsL, modelInputsR, inputName, at) {
|
|
3072
|
+
return {
|
|
3073
|
+
requestedName: inputName,
|
|
3074
|
+
stateL: resolveInputForNameInModel(modelInputsL, inputName, at),
|
|
3075
|
+
stateR: resolveInputForNameInModel(modelInputsR, inputName, at)
|
|
3076
|
+
};
|
|
3077
|
+
}
|
|
3078
|
+
function resolveInputForNameInModel(modelInputs, inputName, at) {
|
|
3079
|
+
const inputVar = modelInputs.getInputVarForName(inputName);
|
|
3080
|
+
if (inputVar) {
|
|
3081
|
+
return resolveInputVar(inputVar, at);
|
|
3082
|
+
} else {
|
|
3083
|
+
return {
|
|
3084
|
+
error: {
|
|
3085
|
+
kind: "unknown-input"
|
|
3086
|
+
}
|
|
3087
|
+
};
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3090
|
+
function resolveInputVar(inputVar, at) {
|
|
3091
|
+
if (typeof at === "number") {
|
|
3092
|
+
const value = at;
|
|
3093
|
+
return resolveInputVarAtValue(inputVar, value);
|
|
3094
|
+
} else {
|
|
3095
|
+
const position = inputPosition2(at);
|
|
3096
|
+
return resolveInputVarAtPosition(inputVar, position);
|
|
3097
|
+
}
|
|
3098
|
+
}
|
|
3099
|
+
function resolveInputVarAtPosition(inputVar, position) {
|
|
3100
|
+
return {
|
|
3101
|
+
inputVar,
|
|
3102
|
+
position,
|
|
3103
|
+
value: inputValueAtPosition2(inputVar, position)
|
|
3104
|
+
};
|
|
3105
|
+
}
|
|
3106
|
+
function resolveInputVarAtValue(inputVar, value) {
|
|
3107
|
+
if (value >= inputVar.minValue && value <= inputVar.maxValue) {
|
|
3108
|
+
return {
|
|
3109
|
+
inputVar,
|
|
3110
|
+
value
|
|
3111
|
+
};
|
|
3112
|
+
} else {
|
|
3113
|
+
return {
|
|
3114
|
+
error: {
|
|
3115
|
+
kind: "invalid-value"
|
|
3116
|
+
}
|
|
3117
|
+
};
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3120
|
+
function inputPosition2(position) {
|
|
3121
|
+
switch (position) {
|
|
3122
|
+
case "default":
|
|
3123
|
+
return "at-default";
|
|
3124
|
+
case "min":
|
|
3125
|
+
return "at-minimum";
|
|
3126
|
+
case "max":
|
|
3127
|
+
return "at-maximum";
|
|
3128
|
+
default:
|
|
3129
|
+
return void 0;
|
|
3130
|
+
}
|
|
3131
|
+
}
|
|
3132
|
+
function inputValueAtPosition2(inputVar, position) {
|
|
3133
|
+
switch (position) {
|
|
3134
|
+
case "at-default":
|
|
3135
|
+
return inputVar.defaultValue;
|
|
3136
|
+
case "at-minimum":
|
|
3137
|
+
return inputVar.minValue;
|
|
3138
|
+
case "at-maximum":
|
|
3139
|
+
return inputVar.maxValue;
|
|
3140
|
+
default:
|
|
3141
|
+
assertNever11(position);
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
var ResolvedScenarioGroups = class {
|
|
3145
|
+
constructor() {
|
|
3146
|
+
this.resolvedGroups = [];
|
|
3147
|
+
this.resolvedGroupsById = /* @__PURE__ */ new Map();
|
|
3148
|
+
}
|
|
3149
|
+
add(group) {
|
|
3150
|
+
this.resolvedGroups.push(group);
|
|
3151
|
+
if (group.id !== void 0) {
|
|
3152
|
+
if (this.resolvedGroupsById.has(group.id)) {
|
|
3153
|
+
throw new Error(`Multiple scenario groups defined with the same id (${group.id})`);
|
|
3154
|
+
}
|
|
3155
|
+
this.resolvedGroupsById.set(group.id, group);
|
|
3156
|
+
}
|
|
3157
|
+
}
|
|
3158
|
+
getAll() {
|
|
3159
|
+
return this.resolvedGroups;
|
|
3160
|
+
}
|
|
3161
|
+
getGroupForId(id) {
|
|
3162
|
+
return this.resolvedGroupsById.get(id);
|
|
3163
|
+
}
|
|
3164
|
+
};
|
|
3165
|
+
function resolveGraphsFromSpec(graphsSpec) {
|
|
3166
|
+
switch (graphsSpec.kind) {
|
|
3167
|
+
case "graphs-preset":
|
|
3168
|
+
return "all";
|
|
3169
|
+
case "graphs-array":
|
|
3170
|
+
return graphsSpec.graphIds;
|
|
3171
|
+
default:
|
|
3172
|
+
assertNever11(graphsSpec);
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
3175
|
+
function resolveViewForScenarioId(resolvedScenarios, viewTitle, viewSubtitle, scenarioId, graphs) {
|
|
3176
|
+
const resolvedScenario = resolvedScenarios.getScenarioForId(scenarioId);
|
|
3177
|
+
if (resolvedScenario) {
|
|
3178
|
+
return resolveViewForScenario(viewTitle, viewSubtitle, resolvedScenario, graphs);
|
|
3179
|
+
} else {
|
|
3180
|
+
return unresolvedViewForScenarioId(viewTitle, viewSubtitle, scenarioId);
|
|
3181
|
+
}
|
|
3182
|
+
}
|
|
3183
|
+
function resolveViewForScenarioRefSpec(resolvedScenarios, refSpec, graphs) {
|
|
3184
|
+
const resolvedScenario = resolvedScenarios.getScenarioForId(refSpec.scenarioId);
|
|
3185
|
+
if (resolvedScenario) {
|
|
3186
|
+
return resolveViewForScenario(refSpec.title, refSpec.subtitle, resolvedScenario, graphs);
|
|
3187
|
+
} else {
|
|
3188
|
+
return unresolvedViewForScenarioId(void 0, void 0, refSpec.scenarioId);
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
3191
|
+
function resolveViewForScenario(viewTitle, viewSubtitle, resolvedScenario, graphs) {
|
|
3192
|
+
if (viewTitle === void 0) {
|
|
3193
|
+
viewTitle = resolvedScenario.title;
|
|
3194
|
+
if (viewTitle === void 0) {
|
|
3195
|
+
viewTitle = "Untitled view";
|
|
3196
|
+
}
|
|
3197
|
+
if (viewSubtitle === void 0) {
|
|
3198
|
+
viewSubtitle = resolvedScenario.subtitle;
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
return {
|
|
3202
|
+
kind: "view",
|
|
3203
|
+
title: viewTitle,
|
|
3204
|
+
subtitle: viewSubtitle,
|
|
3205
|
+
scenario: resolvedScenario,
|
|
3206
|
+
graphs
|
|
3207
|
+
};
|
|
3208
|
+
}
|
|
3209
|
+
function unresolvedViewForScenarioId(viewTitle, viewSubtitle, scenarioId) {
|
|
3210
|
+
return {
|
|
3211
|
+
kind: "unresolved-view",
|
|
3212
|
+
title: viewTitle,
|
|
3213
|
+
subtitle: viewSubtitle,
|
|
3214
|
+
scenarioId
|
|
3215
|
+
};
|
|
3216
|
+
}
|
|
3217
|
+
function unresolvedViewForScenarioGroupId(viewTitle, viewSubtitle, scenarioGroupId) {
|
|
3218
|
+
return {
|
|
3219
|
+
kind: "unresolved-view",
|
|
3220
|
+
title: viewTitle,
|
|
3221
|
+
subtitle: viewSubtitle,
|
|
3222
|
+
scenarioGroupId
|
|
3223
|
+
};
|
|
3224
|
+
}
|
|
3225
|
+
function resolveViewGroupFromSpec(resolvedScenarios, resolvedScenarioGroups, viewGroupSpec) {
|
|
3226
|
+
let views;
|
|
3227
|
+
switch (viewGroupSpec.kind) {
|
|
3228
|
+
case "view-group-with-views": {
|
|
3229
|
+
views = viewGroupSpec.views.map((viewSpec) => {
|
|
3230
|
+
const graphs = resolveGraphsFromSpec(viewSpec.graphs);
|
|
3231
|
+
return resolveViewForScenarioId(
|
|
3232
|
+
resolvedScenarios,
|
|
3233
|
+
viewSpec.title,
|
|
3234
|
+
viewSpec.subtitle,
|
|
3235
|
+
viewSpec.scenarioId,
|
|
3236
|
+
graphs
|
|
3237
|
+
);
|
|
3238
|
+
});
|
|
3239
|
+
break;
|
|
3240
|
+
}
|
|
3241
|
+
case "view-group-with-scenarios": {
|
|
3242
|
+
const graphs = resolveGraphsFromSpec(viewGroupSpec.graphs);
|
|
3243
|
+
views = [];
|
|
3244
|
+
for (const refSpec of viewGroupSpec.scenarios) {
|
|
3245
|
+
switch (refSpec.kind) {
|
|
3246
|
+
case "scenario-ref":
|
|
3247
|
+
views.push(resolveViewForScenarioRefSpec(resolvedScenarios, refSpec, graphs));
|
|
3248
|
+
break;
|
|
3249
|
+
case "scenario-group-ref": {
|
|
3250
|
+
const resolvedGroup = resolvedScenarioGroups.getGroupForId(refSpec.groupId);
|
|
3251
|
+
if (resolvedGroup) {
|
|
3252
|
+
for (const scenario of resolvedGroup.scenarios) {
|
|
3253
|
+
switch (scenario.kind) {
|
|
3254
|
+
case "unresolved-scenario-ref":
|
|
3255
|
+
views.push(unresolvedViewForScenarioId(void 0, void 0, scenario.scenarioId));
|
|
3256
|
+
break;
|
|
3257
|
+
case "scenario":
|
|
3258
|
+
views.push(resolveViewForScenario(void 0, void 0, scenario, graphs));
|
|
3259
|
+
break;
|
|
3260
|
+
default:
|
|
3261
|
+
assertNever11(scenario);
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
} else {
|
|
3265
|
+
views.push(unresolvedViewForScenarioGroupId(void 0, void 0, refSpec.groupId));
|
|
3266
|
+
}
|
|
3267
|
+
break;
|
|
3268
|
+
}
|
|
3269
|
+
default:
|
|
3270
|
+
assertNever11(refSpec);
|
|
3271
|
+
}
|
|
3272
|
+
}
|
|
3273
|
+
break;
|
|
3274
|
+
}
|
|
3275
|
+
default:
|
|
3276
|
+
assertNever11(viewGroupSpec);
|
|
3277
|
+
}
|
|
3278
|
+
return {
|
|
3279
|
+
kind: "view-group",
|
|
3280
|
+
title: viewGroupSpec.title,
|
|
3281
|
+
views
|
|
3282
|
+
};
|
|
3283
|
+
}
|
|
3284
|
+
|
|
3285
|
+
// src/comparison/config/comparison-config.ts
|
|
3286
|
+
function resolveComparisonSpecsFromSources(modelInputsL, modelInputsR, specSources) {
|
|
3287
|
+
const combinedSpecs = {
|
|
3288
|
+
scenarios: [],
|
|
3289
|
+
scenarioGroups: [],
|
|
3290
|
+
viewGroups: []
|
|
3291
|
+
};
|
|
3292
|
+
for (const specSource of specSources) {
|
|
3293
|
+
let specs;
|
|
3294
|
+
if ("kind" in specSource) {
|
|
3295
|
+
const parseResult = parseComparisonSpecs(specSource);
|
|
3296
|
+
if (parseResult.isOk()) {
|
|
3297
|
+
specs = parseResult.value;
|
|
3298
|
+
} else {
|
|
3299
|
+
const filenamePart = specSource.filename ? ` in ${specSource.filename}` : "";
|
|
3300
|
+
console.error(`ERROR: Failed to parse comparison spec${filenamePart}, skipping`);
|
|
3301
|
+
continue;
|
|
3302
|
+
}
|
|
3303
|
+
} else {
|
|
3304
|
+
specs = specSource;
|
|
3305
|
+
}
|
|
3306
|
+
combinedSpecs.scenarios.push(...specs.scenarios);
|
|
3307
|
+
combinedSpecs.scenarioGroups.push(...specs.scenarioGroups);
|
|
3308
|
+
combinedSpecs.viewGroups.push(...specs.viewGroups);
|
|
3309
|
+
}
|
|
3310
|
+
return resolveComparisonSpecs(modelInputsL, modelInputsR, combinedSpecs);
|
|
3311
|
+
}
|
|
3312
|
+
|
|
3313
|
+
// src/comparison/config/comparison-datasets.ts
|
|
3314
|
+
function getComparisonDatasets(modelSpecL, modelSpecR, datasetOptions) {
|
|
3315
|
+
return new ComparisonDatasetsImpl(modelSpecL, modelSpecR, datasetOptions);
|
|
3316
|
+
}
|
|
3317
|
+
var ComparisonDatasetsImpl = class {
|
|
3318
|
+
constructor(modelSpecL, modelSpecR, datasetOptions) {
|
|
3319
|
+
this.datasetOptions = datasetOptions;
|
|
3320
|
+
const renamedDatasetKeys = datasetOptions == null ? void 0 : datasetOptions.renamedDatasetKeys;
|
|
3321
|
+
const invertedRenamedKeys = /* @__PURE__ */ new Map();
|
|
3322
|
+
renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.forEach((newKey, oldKey) => {
|
|
3323
|
+
invertedRenamedKeys.set(newKey, oldKey);
|
|
3324
|
+
});
|
|
3325
|
+
function leftKeyForRightKey(rightKey) {
|
|
3326
|
+
return invertedRenamedKeys.get(rightKey) || rightKey;
|
|
3327
|
+
}
|
|
3328
|
+
const allOutputVarKeysSet = /* @__PURE__ */ new Set();
|
|
3329
|
+
const modelOutputVarKeysSet = /* @__PURE__ */ new Set();
|
|
3330
|
+
function addOutputVars(outputVars, handleRenames) {
|
|
3331
|
+
outputVars.forEach((outputVar, key) => {
|
|
2200
3332
|
const remappedKey = handleRenames ? leftKeyForRightKey(key) : key;
|
|
2201
3333
|
allOutputVarKeysSet.add(remappedKey);
|
|
2202
3334
|
if (outputVar.sourceName === void 0) {
|
|
@@ -2204,239 +3336,193 @@ var DatasetManager = class {
|
|
|
2204
3336
|
}
|
|
2205
3337
|
});
|
|
2206
3338
|
}
|
|
2207
|
-
addOutputVars(
|
|
2208
|
-
addOutputVars(
|
|
3339
|
+
addOutputVars(modelSpecL.outputVars, false);
|
|
3340
|
+
addOutputVars(modelSpecR.outputVars, true);
|
|
2209
3341
|
this.allOutputVarKeys = Array.from(allOutputVarKeysSet);
|
|
2210
3342
|
this.modelOutputVarKeys = Array.from(modelOutputVarKeysSet);
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
3343
|
+
this.allDatasets = /* @__PURE__ */ new Map();
|
|
3344
|
+
for (const datasetKeyL of this.allOutputVarKeys) {
|
|
3345
|
+
const datasetKeyR = (renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.get(datasetKeyL)) || datasetKeyL;
|
|
3346
|
+
const outputVarL = modelSpecL.outputVars.get(datasetKeyL);
|
|
3347
|
+
const outputVarR = modelSpecR.outputVars.get(datasetKeyR);
|
|
3348
|
+
this.allDatasets.set(datasetKeyL, {
|
|
3349
|
+
kind: "dataset",
|
|
3350
|
+
key: datasetKeyL,
|
|
3351
|
+
outputVarL,
|
|
3352
|
+
outputVarR
|
|
3353
|
+
});
|
|
2217
3354
|
}
|
|
2218
3355
|
}
|
|
2219
|
-
|
|
3356
|
+
getAllDatasets() {
|
|
3357
|
+
return this.allDatasets.values();
|
|
3358
|
+
}
|
|
3359
|
+
getDataset(datasetKey) {
|
|
3360
|
+
return this.allDatasets.get(datasetKey);
|
|
3361
|
+
}
|
|
3362
|
+
getDatasetKeysForScenario(scenario) {
|
|
2220
3363
|
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;
|
|
3364
|
+
if (((_a = this.datasetOptions) == null ? void 0 : _a.datasetKeysForScenario) !== void 0) {
|
|
3365
|
+
return this.datasetOptions.datasetKeysForScenario(this.allOutputVarKeys, scenario);
|
|
2241
3366
|
} else {
|
|
2242
|
-
|
|
2243
|
-
|
|
3367
|
+
if (scenario.settings.kind === "all-inputs-settings" && scenario.settings.position === "at-default") {
|
|
3368
|
+
return this.allOutputVarKeys;
|
|
3369
|
+
} else {
|
|
3370
|
+
return this.modelOutputVarKeys;
|
|
3371
|
+
}
|
|
2244
3372
|
}
|
|
2245
|
-
return {
|
|
2246
|
-
varName,
|
|
2247
|
-
newVarName,
|
|
2248
|
-
sourceName,
|
|
2249
|
-
newSourceName,
|
|
2250
|
-
relatedItems: (outputVarR == null ? void 0 : outputVarR.relatedItems) || []
|
|
2251
|
-
};
|
|
2252
3373
|
}
|
|
2253
3374
|
};
|
|
2254
3375
|
|
|
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);
|
|
3376
|
+
// src/comparison/config/comparison-scenarios.ts
|
|
3377
|
+
function getComparisonScenarios(scenarios) {
|
|
3378
|
+
return new ComparisonScenariosImpl(scenarios);
|
|
3379
|
+
}
|
|
3380
|
+
var ComparisonScenariosImpl = class {
|
|
3381
|
+
constructor(scenarios) {
|
|
3382
|
+
this.scenarioDefs = /* @__PURE__ */ new Map();
|
|
3383
|
+
for (const scenario of scenarios) {
|
|
3384
|
+
this.scenarioDefs.set(scenario.key, scenario);
|
|
2342
3385
|
}
|
|
2343
3386
|
}
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
case "all-inputs":
|
|
2347
|
-
return this.getInfoForPositionSetting(void 0, scenario.position);
|
|
2348
|
-
case "settings":
|
|
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
|
-
}
|
|
3387
|
+
getAllScenarios() {
|
|
3388
|
+
return this.scenarioDefs.values();
|
|
2361
3389
|
}
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
3390
|
+
getScenario(key) {
|
|
3391
|
+
return this.scenarioDefs.get(key);
|
|
3392
|
+
}
|
|
3393
|
+
};
|
|
3394
|
+
|
|
3395
|
+
// src/config/synchronized-model.ts
|
|
3396
|
+
function synchronizedBundleModel(sourceModel) {
|
|
3397
|
+
const promiseQueue = new PromiseQueue();
|
|
3398
|
+
return {
|
|
3399
|
+
modelSpec: sourceModel.modelSpec,
|
|
3400
|
+
getDatasetsForScenario: (scenarioSpec, datasetKeys) => {
|
|
3401
|
+
return promiseQueue.add(() => sourceModel.getDatasetsForScenario(scenarioSpec, datasetKeys));
|
|
3402
|
+
},
|
|
3403
|
+
getGraphDataForScenario: (scenarioSpec, graphId) => {
|
|
3404
|
+
return promiseQueue.add(() => sourceModel.getGraphDataForScenario(scenarioSpec, graphId));
|
|
3405
|
+
},
|
|
3406
|
+
getGraphLinksForScenario: sourceModel.getGraphLinksForScenario.bind(sourceModel)
|
|
3407
|
+
};
|
|
3408
|
+
}
|
|
3409
|
+
var PromiseQueue = class {
|
|
3410
|
+
constructor() {
|
|
3411
|
+
this.tasks = [];
|
|
3412
|
+
this.runningCount = 0;
|
|
3413
|
+
}
|
|
3414
|
+
add(f) {
|
|
3415
|
+
return new Promise((resolve, reject) => {
|
|
3416
|
+
const run = async () => {
|
|
3417
|
+
this.runningCount++;
|
|
3418
|
+
const promise = f();
|
|
3419
|
+
try {
|
|
3420
|
+
const result = await promise;
|
|
3421
|
+
resolve(result);
|
|
3422
|
+
} catch (e) {
|
|
3423
|
+
reject(e);
|
|
3424
|
+
} finally {
|
|
3425
|
+
this.runningCount--;
|
|
3426
|
+
this.runNext();
|
|
3427
|
+
}
|
|
3428
|
+
};
|
|
3429
|
+
if (this.runningCount < 1) {
|
|
3430
|
+
run();
|
|
2378
3431
|
} else {
|
|
2379
|
-
|
|
3432
|
+
this.tasks.push(run);
|
|
2380
3433
|
}
|
|
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
|
-
};
|
|
3434
|
+
});
|
|
2403
3435
|
}
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
relatedItems.push(inputVar.relatedItem);
|
|
3436
|
+
runNext() {
|
|
3437
|
+
if (this.tasks.length > 0) {
|
|
3438
|
+
const task = this.tasks.shift();
|
|
3439
|
+
if (task) {
|
|
3440
|
+
task();
|
|
2410
3441
|
}
|
|
2411
3442
|
}
|
|
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
3443
|
}
|
|
2420
3444
|
};
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
default:
|
|
2431
|
-
assertNever8(position);
|
|
2432
|
-
}
|
|
3445
|
+
|
|
3446
|
+
// src/config/config.ts
|
|
3447
|
+
async function createConfig(options) {
|
|
3448
|
+
var _a;
|
|
3449
|
+
const origCurrentBundle = await loadSynchronized(options.current);
|
|
3450
|
+
let currentBundle;
|
|
3451
|
+
let comparisonConfig;
|
|
3452
|
+
if (options.comparison === void 0) {
|
|
3453
|
+
currentBundle = origCurrentBundle;
|
|
2433
3454
|
} else {
|
|
2434
|
-
|
|
3455
|
+
const baselineBundle = await loadSynchronized(options.comparison.baseline);
|
|
3456
|
+
const renamedDatasetKeys = (_a = options.comparison.datasets) == null ? void 0 : _a.renamedDatasetKeys;
|
|
3457
|
+
const invertedRenamedKeys = /* @__PURE__ */ new Map();
|
|
3458
|
+
renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.forEach((newKey, oldKey) => {
|
|
3459
|
+
invertedRenamedKeys.set(newKey, oldKey);
|
|
3460
|
+
});
|
|
3461
|
+
const rightKeyForLeftKey = (leftKey) => {
|
|
3462
|
+
return (renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.get(leftKey)) || leftKey;
|
|
3463
|
+
};
|
|
3464
|
+
const leftKeyForRightKey = (rightKey) => {
|
|
3465
|
+
return invertedRenamedKeys.get(rightKey) || rightKey;
|
|
3466
|
+
};
|
|
3467
|
+
const origBundleModelR = origCurrentBundle.model;
|
|
3468
|
+
const adjBundleModelR = {
|
|
3469
|
+
modelSpec: origBundleModelR.modelSpec,
|
|
3470
|
+
getDatasetsForScenario: async (scenarioSpec, datasetKeys) => {
|
|
3471
|
+
const rightKeys = datasetKeys.map(rightKeyForLeftKey);
|
|
3472
|
+
const result = await origBundleModelR.getDatasetsForScenario(scenarioSpec, rightKeys);
|
|
3473
|
+
const mapWithRightKeys = result.datasetMap;
|
|
3474
|
+
const mapWithLeftKeys = /* @__PURE__ */ new Map();
|
|
3475
|
+
for (const [rightKey, dataset] of mapWithRightKeys.entries()) {
|
|
3476
|
+
const leftKey = leftKeyForRightKey(rightKey);
|
|
3477
|
+
mapWithLeftKeys.set(leftKey, dataset);
|
|
3478
|
+
}
|
|
3479
|
+
return {
|
|
3480
|
+
datasetMap: mapWithLeftKeys,
|
|
3481
|
+
modelRunTime: result.modelRunTime
|
|
3482
|
+
};
|
|
3483
|
+
},
|
|
3484
|
+
getGraphDataForScenario: origBundleModelR.getGraphDataForScenario.bind(origBundleModelR),
|
|
3485
|
+
getGraphLinksForScenario: origBundleModelR.getGraphLinksForScenario.bind(origBundleModelR)
|
|
3486
|
+
};
|
|
3487
|
+
currentBundle = {
|
|
3488
|
+
...origCurrentBundle,
|
|
3489
|
+
model: adjBundleModelR
|
|
3490
|
+
};
|
|
3491
|
+
const modelSpecL = baselineBundle.model.modelSpec;
|
|
3492
|
+
const modelSpecR = currentBundle.model.modelSpec;
|
|
3493
|
+
const modelInputsL = new ModelInputs(modelSpecL);
|
|
3494
|
+
const modelInputsR = new ModelInputs(modelSpecR);
|
|
3495
|
+
const comparisonDefs = resolveComparisonSpecsFromSources(modelInputsL, modelInputsR, options.comparison.specs);
|
|
3496
|
+
comparisonConfig = {
|
|
3497
|
+
bundleL: baselineBundle,
|
|
3498
|
+
bundleR: currentBundle,
|
|
3499
|
+
thresholds: options.comparison.thresholds,
|
|
3500
|
+
scenarios: getComparisonScenarios(comparisonDefs.scenarios),
|
|
3501
|
+
datasets: getComparisonDatasets(modelSpecL, modelSpecR, options.comparison.datasets),
|
|
3502
|
+
viewGroups: comparisonDefs.viewGroups
|
|
3503
|
+
};
|
|
2435
3504
|
}
|
|
3505
|
+
const checkConfig = {
|
|
3506
|
+
bundle: currentBundle,
|
|
3507
|
+
tests: options.check.tests
|
|
3508
|
+
};
|
|
3509
|
+
return {
|
|
3510
|
+
check: checkConfig,
|
|
3511
|
+
comparison: comparisonConfig
|
|
3512
|
+
};
|
|
3513
|
+
}
|
|
3514
|
+
async function loadSynchronized(sourceBundle) {
|
|
3515
|
+
const sourceModel = await sourceBundle.bundle.initModel();
|
|
3516
|
+
const synchronizedModel = synchronizedBundleModel(sourceModel);
|
|
3517
|
+
return {
|
|
3518
|
+
name: sourceBundle.name,
|
|
3519
|
+
version: sourceBundle.bundle.version,
|
|
3520
|
+
model: synchronizedModel
|
|
3521
|
+
};
|
|
2436
3522
|
}
|
|
2437
3523
|
|
|
2438
3524
|
// src/perf/perf-runner.ts
|
|
2439
|
-
import { assertNever as
|
|
3525
|
+
import { assertNever as assertNever12 } from "assert-never";
|
|
2440
3526
|
|
|
2441
3527
|
// src/perf/perf-stats.ts
|
|
2442
3528
|
var PerfStats = class {
|
|
@@ -2480,26 +3566,26 @@ var PerfRunner = class {
|
|
|
2480
3566
|
this.bundleModelL = bundleModelL;
|
|
2481
3567
|
this.bundleModelR = bundleModelR;
|
|
2482
3568
|
this.mode = mode;
|
|
2483
|
-
const
|
|
3569
|
+
const scenarioSpec = allInputsAtPositionSpec("at-default");
|
|
2484
3570
|
this.taskQueue = new TaskQueue({
|
|
2485
3571
|
process: async (request) => {
|
|
2486
3572
|
switch (request.kind) {
|
|
2487
3573
|
case "left": {
|
|
2488
|
-
const result = await bundleModelL.getDatasetsForScenario(
|
|
3574
|
+
const result = await bundleModelL.getDatasetsForScenario(scenarioSpec, []);
|
|
2489
3575
|
return {
|
|
2490
3576
|
runTimeL: result.modelRunTime
|
|
2491
3577
|
};
|
|
2492
3578
|
}
|
|
2493
3579
|
case "right": {
|
|
2494
|
-
const result = await bundleModelR.getDatasetsForScenario(
|
|
3580
|
+
const result = await bundleModelR.getDatasetsForScenario(scenarioSpec, []);
|
|
2495
3581
|
return {
|
|
2496
3582
|
runTimeR: result.modelRunTime
|
|
2497
3583
|
};
|
|
2498
3584
|
}
|
|
2499
3585
|
case "both": {
|
|
2500
3586
|
const [resultL, resultR] = await Promise.all([
|
|
2501
|
-
bundleModelL.getDatasetsForScenario(
|
|
2502
|
-
bundleModelR.getDatasetsForScenario(
|
|
3587
|
+
bundleModelL.getDatasetsForScenario(scenarioSpec, []),
|
|
3588
|
+
bundleModelR.getDatasetsForScenario(scenarioSpec, [])
|
|
2503
3589
|
]);
|
|
2504
3590
|
return {
|
|
2505
3591
|
runTimeL: resultL.modelRunTime,
|
|
@@ -2507,7 +3593,7 @@ var PerfRunner = class {
|
|
|
2507
3593
|
};
|
|
2508
3594
|
}
|
|
2509
3595
|
default:
|
|
2510
|
-
|
|
3596
|
+
assertNever12(request.kind);
|
|
2511
3597
|
}
|
|
2512
3598
|
}
|
|
2513
3599
|
});
|
|
@@ -2555,46 +3641,126 @@ var PerfRunner = class {
|
|
|
2555
3641
|
}
|
|
2556
3642
|
};
|
|
2557
3643
|
|
|
2558
|
-
// src/suite/suite-runner.ts
|
|
2559
|
-
import assertNever10 from "assert-never";
|
|
2560
|
-
|
|
2561
3644
|
// src/data/data-planner.ts
|
|
2562
|
-
var
|
|
2563
|
-
constructor(
|
|
2564
|
-
this.
|
|
2565
|
-
this.
|
|
2566
|
-
this.
|
|
2567
|
-
this.
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
3645
|
+
var DataPlanner = class {
|
|
3646
|
+
constructor(batchSize) {
|
|
3647
|
+
this.batchSize = batchSize;
|
|
3648
|
+
this.taskSetsLR = /* @__PURE__ */ new Map();
|
|
3649
|
+
this.taskSetsL = /* @__PURE__ */ new Map();
|
|
3650
|
+
this.taskSetsR = /* @__PURE__ */ new Map();
|
|
3651
|
+
this.complete = false;
|
|
3652
|
+
}
|
|
3653
|
+
addRequest(scenarioSpecL, scenarioSpecR, datasetKey, dataAction) {
|
|
3654
|
+
if (scenarioSpecL === void 0 && scenarioSpecR === void 0) {
|
|
3655
|
+
console.warn("WARNING: Both scenario specs are undefined for DataPlanner request, skipping");
|
|
3656
|
+
return;
|
|
3657
|
+
}
|
|
3658
|
+
let taskSetsMap;
|
|
3659
|
+
let uid;
|
|
3660
|
+
if (scenarioSpecL && scenarioSpecR) {
|
|
3661
|
+
taskSetsMap = this.taskSetsLR;
|
|
3662
|
+
uid = scenarioPairUid(scenarioSpecL, scenarioSpecR);
|
|
3663
|
+
} else if (scenarioSpecR) {
|
|
3664
|
+
taskSetsMap = this.taskSetsR;
|
|
3665
|
+
uid = scenarioSpecR.uid;
|
|
3666
|
+
} else {
|
|
3667
|
+
taskSetsMap = this.taskSetsL;
|
|
3668
|
+
uid = scenarioSpecL.uid;
|
|
3669
|
+
}
|
|
3670
|
+
let taskSet = taskSetsMap.get(uid);
|
|
3671
|
+
if (!taskSet) {
|
|
3672
|
+
taskSet = new DataTaskSet(scenarioSpecL, scenarioSpecR);
|
|
3673
|
+
taskSetsMap.set(uid, taskSet);
|
|
2572
3674
|
}
|
|
2573
|
-
|
|
3675
|
+
taskSet.addTask({
|
|
2574
3676
|
datasetKey,
|
|
2575
|
-
|
|
3677
|
+
dataAction
|
|
3678
|
+
});
|
|
3679
|
+
}
|
|
3680
|
+
buildPlan() {
|
|
3681
|
+
if (this.complete) {
|
|
3682
|
+
throw new Error("DataPlanner.buildPlan() can only be called once");
|
|
3683
|
+
}
|
|
3684
|
+
this.complete = true;
|
|
3685
|
+
const lKeyMappings = /* @__PURE__ */ new Map();
|
|
3686
|
+
const rKeyMappings = /* @__PURE__ */ new Map();
|
|
3687
|
+
for (const lrUid of this.taskSetsLR.keys()) {
|
|
3688
|
+
const [lUid, rUid] = lrUid.split("::");
|
|
3689
|
+
if (!lKeyMappings.has(lUid)) {
|
|
3690
|
+
lKeyMappings.set(lUid, lrUid);
|
|
3691
|
+
}
|
|
3692
|
+
if (!rKeyMappings.has(rUid)) {
|
|
3693
|
+
rKeyMappings.set(rUid, lrUid);
|
|
3694
|
+
}
|
|
3695
|
+
}
|
|
3696
|
+
function merge(taskSetsLR, taskSetsForSide, keyMappingsForSide) {
|
|
3697
|
+
for (const [keyForSide, taskSetForSide] of taskSetsForSide.entries()) {
|
|
3698
|
+
const lrKey = keyMappingsForSide.get(keyForSide);
|
|
3699
|
+
if (lrKey) {
|
|
3700
|
+
const taskSetLR = taskSetsLR.get(lrKey);
|
|
3701
|
+
taskSetLR.merge(taskSetForSide);
|
|
3702
|
+
taskSetsForSide.delete(keyForSide);
|
|
3703
|
+
}
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3706
|
+
merge(this.taskSetsLR, this.taskSetsL, lKeyMappings);
|
|
3707
|
+
merge(this.taskSetsLR, this.taskSetsR, rKeyMappings);
|
|
3708
|
+
const requests = [];
|
|
3709
|
+
const batchSize = this.batchSize;
|
|
3710
|
+
function addRequests(taskSets) {
|
|
3711
|
+
for (const taskSet of taskSets) {
|
|
3712
|
+
requests.push(...taskSet.buildRequests(batchSize));
|
|
3713
|
+
}
|
|
3714
|
+
}
|
|
3715
|
+
addRequests(this.taskSetsLR.values());
|
|
3716
|
+
addRequests(this.taskSetsL.values());
|
|
3717
|
+
addRequests(this.taskSetsR.values());
|
|
3718
|
+
return {
|
|
3719
|
+
requests
|
|
2576
3720
|
};
|
|
3721
|
+
}
|
|
3722
|
+
};
|
|
3723
|
+
var DataTaskSet = class {
|
|
3724
|
+
constructor(scenarioSpecL, scenarioSpecR) {
|
|
3725
|
+
this.scenarioSpecL = scenarioSpecL;
|
|
3726
|
+
this.scenarioSpecR = scenarioSpecR;
|
|
3727
|
+
this.modelTasks = /* @__PURE__ */ new Map();
|
|
3728
|
+
this.modelImplTasks = /* @__PURE__ */ new Map();
|
|
3729
|
+
}
|
|
3730
|
+
addTask(dataTask) {
|
|
2577
3731
|
let taskMap;
|
|
2578
|
-
if (datasetKey.startsWith("ModelImpl")) {
|
|
3732
|
+
if (dataTask.datasetKey.startsWith("ModelImpl")) {
|
|
2579
3733
|
taskMap = this.modelImplTasks;
|
|
2580
3734
|
} else {
|
|
2581
3735
|
taskMap = this.modelTasks;
|
|
2582
3736
|
}
|
|
2583
|
-
let tasks = taskMap.get(datasetKey);
|
|
3737
|
+
let tasks = taskMap.get(dataTask.datasetKey);
|
|
2584
3738
|
if (!tasks) {
|
|
2585
3739
|
tasks = [];
|
|
2586
|
-
taskMap.set(datasetKey, tasks);
|
|
3740
|
+
taskMap.set(dataTask.datasetKey, tasks);
|
|
2587
3741
|
}
|
|
2588
3742
|
tasks.push(dataTask);
|
|
2589
3743
|
}
|
|
3744
|
+
merge(otherTaskSet) {
|
|
3745
|
+
for (const tasks of otherTaskSet.modelTasks.values()) {
|
|
3746
|
+
for (const task of tasks) {
|
|
3747
|
+
this.addTask(task);
|
|
3748
|
+
}
|
|
3749
|
+
}
|
|
3750
|
+
for (const tasks of otherTaskSet.modelImplTasks.values()) {
|
|
3751
|
+
for (const task of tasks) {
|
|
3752
|
+
this.addTask(task);
|
|
3753
|
+
}
|
|
3754
|
+
}
|
|
3755
|
+
}
|
|
2590
3756
|
buildRequests(batchSize) {
|
|
2591
3757
|
const dataRequests = [];
|
|
2592
3758
|
if (this.modelTasks.size > 0) {
|
|
2593
3759
|
const dataTasks = [];
|
|
2594
3760
|
this.modelTasks.forEach((tasks) => dataTasks.push(...tasks));
|
|
2595
3761
|
dataRequests.push({
|
|
2596
|
-
|
|
2597
|
-
|
|
3762
|
+
scenarioSpecL: this.scenarioSpecL,
|
|
3763
|
+
scenarioSpecR: this.scenarioSpecR,
|
|
2598
3764
|
dataTasks
|
|
2599
3765
|
});
|
|
2600
3766
|
}
|
|
@@ -2607,8 +3773,8 @@ var ScenarioTaskSet = class {
|
|
|
2607
3773
|
dataTasks.push(...this.modelImplTasks.get(datasetKey));
|
|
2608
3774
|
}
|
|
2609
3775
|
dataRequests.push({
|
|
2610
|
-
|
|
2611
|
-
|
|
3776
|
+
scenarioSpecL: this.scenarioSpecL,
|
|
3777
|
+
scenarioSpecR: this.scenarioSpecR,
|
|
2612
3778
|
dataTasks
|
|
2613
3779
|
});
|
|
2614
3780
|
}
|
|
@@ -2616,29 +3782,11 @@ var ScenarioTaskSet = class {
|
|
|
2616
3782
|
return dataRequests;
|
|
2617
3783
|
}
|
|
2618
3784
|
};
|
|
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
|
-
};
|
|
3785
|
+
function scenarioPairUid(scenarioSpecL, scenarioSpecR) {
|
|
3786
|
+
const uidL = (scenarioSpecL == null ? void 0 : scenarioSpecL.uid) || "";
|
|
3787
|
+
const uidR = (scenarioSpecR == null ? void 0 : scenarioSpecR.uid) || "";
|
|
3788
|
+
return `${uidL}::${uidR}`;
|
|
3789
|
+
}
|
|
2642
3790
|
|
|
2643
3791
|
// src/check/check-runner.ts
|
|
2644
3792
|
function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner, simplifyScenarios) {
|
|
@@ -2648,7 +3796,7 @@ function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner, simplify
|
|
|
2648
3796
|
const checkPlan = checkPlanner.buildPlan();
|
|
2649
3797
|
const refDatasets = /* @__PURE__ */ new Map();
|
|
2650
3798
|
for (const [dataRefKey, dataRef] of checkPlan.dataRefs.entries()) {
|
|
2651
|
-
refDataPlanner.addRequest(
|
|
3799
|
+
refDataPlanner.addRequest(void 0, dataRef.scenario.spec, dataRef.dataset.datasetKey, (datasets) => {
|
|
2652
3800
|
const dataset = datasets.datasetR;
|
|
2653
3801
|
if (dataset) {
|
|
2654
3802
|
refDatasets.set(dataRefKey, dataset);
|
|
@@ -2657,7 +3805,7 @@ function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner, simplify
|
|
|
2657
3805
|
}
|
|
2658
3806
|
const checkResults = /* @__PURE__ */ new Map();
|
|
2659
3807
|
for (const [checkKey, checkTask] of checkPlan.tasks.entries()) {
|
|
2660
|
-
dataPlanner.addRequest(
|
|
3808
|
+
dataPlanner.addRequest(void 0, checkTask.scenario.spec, checkTask.dataset.datasetKey, (datasets) => {
|
|
2661
3809
|
const dataset = datasets.datasetR;
|
|
2662
3810
|
const checkResult = runCheck(checkTask, dataset, refDatasets);
|
|
2663
3811
|
checkResults.set(checkKey, checkResult);
|
|
@@ -2688,7 +3836,7 @@ function runCheck(checkTask, dataset, refDatasets) {
|
|
|
2688
3836
|
name: dataRef.dataset.name
|
|
2689
3837
|
}
|
|
2690
3838
|
};
|
|
2691
|
-
} else if (dataRef.scenario.
|
|
3839
|
+
} else if (dataRef.scenario.spec === void 0) {
|
|
2692
3840
|
if (dataRef.scenario.error) {
|
|
2693
3841
|
return {
|
|
2694
3842
|
status: "error",
|
|
@@ -2725,16 +3873,15 @@ function runCheck(checkTask, dataset, refDatasets) {
|
|
|
2725
3873
|
return checkTask.action.run(dataset, opRefDatasets);
|
|
2726
3874
|
}
|
|
2727
3875
|
|
|
2728
|
-
// src/
|
|
2729
|
-
function
|
|
2730
|
-
const
|
|
2731
|
-
const
|
|
2732
|
-
|
|
2733
|
-
const datasetKeys = compareConfig.datasets.getDatasetKeysForScenario(scenario);
|
|
3876
|
+
// src/comparison/run/comparison-runner.ts
|
|
3877
|
+
function runComparisons(comparisonConfig, dataPlanner) {
|
|
3878
|
+
const testReports = [];
|
|
3879
|
+
for (const scenario of comparisonConfig.scenarios.getAllScenarios()) {
|
|
3880
|
+
const datasetKeys = comparisonConfig.datasets.getDatasetKeysForScenario(scenario);
|
|
2734
3881
|
for (const datasetKey of datasetKeys) {
|
|
2735
|
-
dataPlanner.addRequest(
|
|
3882
|
+
dataPlanner.addRequest(scenario.specL, scenario.specR, datasetKey, (datasets) => {
|
|
2736
3883
|
const diffReport = diffDatasets(datasets.datasetL, datasets.datasetR);
|
|
2737
|
-
|
|
3884
|
+
testReports.push({
|
|
2738
3885
|
scenarioKey: scenario.key,
|
|
2739
3886
|
datasetKey,
|
|
2740
3887
|
diffReport
|
|
@@ -2743,7 +3890,7 @@ function runCompare(compareConfig, dataPlanner, simplifyScenarios) {
|
|
|
2743
3890
|
}
|
|
2744
3891
|
}
|
|
2745
3892
|
return () => {
|
|
2746
|
-
return
|
|
3893
|
+
return testReports;
|
|
2747
3894
|
};
|
|
2748
3895
|
}
|
|
2749
3896
|
|
|
@@ -2781,9 +3928,9 @@ var SuiteRunner = class {
|
|
|
2781
3928
|
const checkSpec = checkSpecResult.value;
|
|
2782
3929
|
const simplifyScenarios = (options == null ? void 0 : options.simplifyScenarios) === true;
|
|
2783
3930
|
const buildCheckReport2 = runChecks(this.config.check, checkSpec, dataPlanner, refDataPlanner, simplifyScenarios);
|
|
2784
|
-
let
|
|
2785
|
-
if (this.config.
|
|
2786
|
-
|
|
3931
|
+
let buildComparisonTestReports;
|
|
3932
|
+
if (this.config.comparison) {
|
|
3933
|
+
buildComparisonTestReports = runComparisons(this.config.comparison, dataPlanner);
|
|
2787
3934
|
}
|
|
2788
3935
|
this.taskQueue.onIdle = (error) => {
|
|
2789
3936
|
var _a2, _b2, _c2, _d2;
|
|
@@ -2794,17 +3941,17 @@ var SuiteRunner = class {
|
|
|
2794
3941
|
(_b2 = (_a2 = this.callbacks).onError) == null ? void 0 : _b2.call(_a2, error);
|
|
2795
3942
|
} else {
|
|
2796
3943
|
const checkReport = buildCheckReport2();
|
|
2797
|
-
let
|
|
2798
|
-
if (this.config.
|
|
2799
|
-
|
|
2800
|
-
|
|
3944
|
+
let comparisonReport;
|
|
3945
|
+
if (this.config.comparison) {
|
|
3946
|
+
comparisonReport = {
|
|
3947
|
+
testReports: buildComparisonTestReports(),
|
|
2801
3948
|
perfReportL: this.perfStatsL.toReport(),
|
|
2802
3949
|
perfReportR: this.perfStatsR.toReport()
|
|
2803
3950
|
};
|
|
2804
3951
|
}
|
|
2805
3952
|
(_d2 = (_c2 = this.callbacks).onComplete) == null ? void 0 : _d2.call(_c2, {
|
|
2806
3953
|
checkReport,
|
|
2807
|
-
|
|
3954
|
+
comparisonReport
|
|
2808
3955
|
});
|
|
2809
3956
|
}
|
|
2810
3957
|
};
|
|
@@ -2813,10 +3960,10 @@ var SuiteRunner = class {
|
|
|
2813
3960
|
const dataRequests = [...refDataPlan.requests, ...dataPlan.requests];
|
|
2814
3961
|
const taskCount = dataRequests.length;
|
|
2815
3962
|
if (taskCount === 0) {
|
|
2816
|
-
let
|
|
2817
|
-
if (this.config.
|
|
2818
|
-
|
|
2819
|
-
|
|
3963
|
+
let comparisonReport;
|
|
3964
|
+
if (this.config.comparison) {
|
|
3965
|
+
comparisonReport = {
|
|
3966
|
+
testReports: [],
|
|
2820
3967
|
perfReportL: this.perfStatsL.toReport(),
|
|
2821
3968
|
perfReportR: this.perfStatsR.toReport()
|
|
2822
3969
|
};
|
|
@@ -2827,7 +3974,7 @@ var SuiteRunner = class {
|
|
|
2827
3974
|
checkReport: {
|
|
2828
3975
|
groups: []
|
|
2829
3976
|
},
|
|
2830
|
-
|
|
3977
|
+
comparisonReport
|
|
2831
3978
|
});
|
|
2832
3979
|
return;
|
|
2833
3980
|
}
|
|
@@ -2842,34 +3989,25 @@ var SuiteRunner = class {
|
|
|
2842
3989
|
}
|
|
2843
3990
|
}
|
|
2844
3991
|
async processRequest(request) {
|
|
3992
|
+
var _a, _b;
|
|
2845
3993
|
const datasetKeySet = /* @__PURE__ */ new Set();
|
|
2846
3994
|
for (const dataTask of request.dataTasks) {
|
|
2847
3995
|
datasetKeySet.add(dataTask.datasetKey);
|
|
2848
3996
|
}
|
|
2849
3997
|
const datasetKeys = [...datasetKeySet];
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
const bundleModel = this.config.check.bundle.model;
|
|
2856
|
-
datasetsResultR = await bundleModel.getDatasetsForScenario(scenario, datasetKeys);
|
|
2857
|
-
break;
|
|
2858
|
-
}
|
|
2859
|
-
case "compare": {
|
|
2860
|
-
const bundleModelL = this.config.compare.bundleL.model;
|
|
2861
|
-
const bundleModelR = this.config.compare.bundleR.model;
|
|
2862
|
-
const [resultL, resultR] = await Promise.all([
|
|
2863
|
-
bundleModelL.getDatasetsForScenario(scenario, datasetKeys),
|
|
2864
|
-
bundleModelR.getDatasetsForScenario(scenario, datasetKeys)
|
|
2865
|
-
]);
|
|
2866
|
-
datasetsResultL = resultL;
|
|
2867
|
-
datasetsResultR = resultR;
|
|
2868
|
-
break;
|
|
3998
|
+
async function getDatasets(bundleModel, scenarioSpec) {
|
|
3999
|
+
if (bundleModel && scenarioSpec) {
|
|
4000
|
+
return bundleModel.getDatasetsForScenario(scenarioSpec, datasetKeys);
|
|
4001
|
+
} else {
|
|
4002
|
+
return void 0;
|
|
2869
4003
|
}
|
|
2870
|
-
default:
|
|
2871
|
-
assertNever10(request.kind);
|
|
2872
4004
|
}
|
|
4005
|
+
const bundleModelL = (_a = this.config.comparison) == null ? void 0 : _a.bundleL.model;
|
|
4006
|
+
const bundleModelR = ((_b = this.config.comparison) == null ? void 0 : _b.bundleR.model) || this.config.check.bundle.model;
|
|
4007
|
+
const [datasetsResultL, datasetsResultR] = await Promise.all([
|
|
4008
|
+
getDatasets(bundleModelL, request.scenarioSpecL),
|
|
4009
|
+
getDatasets(bundleModelR, request.scenarioSpecR)
|
|
4010
|
+
]);
|
|
2873
4011
|
if (datasetsResultL == null ? void 0 : datasetsResultL.modelRunTime) {
|
|
2874
4012
|
this.perfStatsL.addRun(datasetsResultL == null ? void 0 : datasetsResultL.modelRunTime);
|
|
2875
4013
|
}
|
|
@@ -2881,7 +4019,7 @@ var SuiteRunner = class {
|
|
|
2881
4019
|
for (const dataTask of request.dataTasks) {
|
|
2882
4020
|
const datasetL = datasetMapL == null ? void 0 : datasetMapL.get(dataTask.datasetKey);
|
|
2883
4021
|
const datasetR = datasetMapR == null ? void 0 : datasetMapR.get(dataTask.datasetKey);
|
|
2884
|
-
dataTask.
|
|
4022
|
+
dataTask.dataAction({
|
|
2885
4023
|
datasetL,
|
|
2886
4024
|
datasetR
|
|
2887
4025
|
});
|
|
@@ -2896,43 +4034,34 @@ function runSuite(config, callbacks, options) {
|
|
|
2896
4034
|
};
|
|
2897
4035
|
}
|
|
2898
4036
|
|
|
2899
|
-
// src/suite/suite-
|
|
4037
|
+
// src/suite/suite-reporting.ts
|
|
2900
4038
|
function suiteSummaryFromReport(suiteReport) {
|
|
2901
4039
|
const checkSummary = checkSummaryFromReport(suiteReport.checkReport);
|
|
2902
|
-
let
|
|
2903
|
-
if (suiteReport.
|
|
2904
|
-
|
|
4040
|
+
let comparisonSummary;
|
|
4041
|
+
if (suiteReport.comparisonReport) {
|
|
4042
|
+
comparisonSummary = comparisonSummaryFromReport(suiteReport.comparisonReport);
|
|
2905
4043
|
}
|
|
2906
4044
|
return {
|
|
2907
4045
|
checkSummary,
|
|
2908
|
-
|
|
4046
|
+
comparisonSummary
|
|
2909
4047
|
};
|
|
2910
4048
|
}
|
|
2911
4049
|
export {
|
|
2912
4050
|
CheckDataCoordinator,
|
|
2913
|
-
|
|
2914
|
-
DatasetManager,
|
|
4051
|
+
ComparisonDataCoordinator,
|
|
2915
4052
|
PerfRunner,
|
|
2916
4053
|
PerfStats,
|
|
2917
|
-
|
|
2918
|
-
allInputsAtPositionScenario,
|
|
4054
|
+
categorizeComparisonTestSummaries,
|
|
2919
4055
|
checkReportFromSummary,
|
|
2920
4056
|
checkSummaryFromReport,
|
|
2921
|
-
|
|
2922
|
-
compareSummaryFromReport,
|
|
4057
|
+
comparisonSummaryFromReport,
|
|
2923
4058
|
createConfig,
|
|
2924
4059
|
datasetMessage,
|
|
2925
4060
|
diffDatasets,
|
|
2926
4061
|
diffGraphs,
|
|
2927
|
-
inputAtPositionScenario,
|
|
2928
|
-
inputAtValueScenario,
|
|
2929
|
-
matrixScenarios,
|
|
2930
|
-
positionSetting,
|
|
2931
4062
|
predicateMessage,
|
|
2932
4063
|
runSuite,
|
|
2933
4064
|
scenarioMessage,
|
|
2934
|
-
|
|
2935
|
-
suiteSummaryFromReport,
|
|
2936
|
-
valueSetting
|
|
4065
|
+
suiteSummaryFromReport
|
|
2937
4066
|
};
|
|
2938
4067
|
//# sourceMappingURL=index.js.map
|