@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.cjs
CHANGED
|
@@ -1,26 +1,9 @@
|
|
|
1
1
|
var __create = Object.create;
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
-
var __defProps = Object.defineProperties;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
5
|
var __getProtoOf = Object.getPrototypeOf;
|
|
9
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
-
var __spreadValues = (a, b) => {
|
|
13
|
-
for (var prop in b || (b = {}))
|
|
14
|
-
if (__hasOwnProp.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
if (__getOwnPropSymbols)
|
|
17
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
-
if (__propIsEnum.call(b, prop))
|
|
19
|
-
__defNormalProp(a, prop, b[prop]);
|
|
20
|
-
}
|
|
21
|
-
return a;
|
|
22
|
-
};
|
|
23
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
7
|
var __export = (target, all) => {
|
|
25
8
|
for (var name in all)
|
|
26
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -33,110 +16,34 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
33
16
|
}
|
|
34
17
|
return to;
|
|
35
18
|
};
|
|
36
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
21
|
+
mod
|
|
22
|
+
));
|
|
37
23
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
38
24
|
|
|
39
25
|
// src/index.ts
|
|
40
26
|
var src_exports = {};
|
|
41
27
|
__export(src_exports, {
|
|
42
28
|
CheckDataCoordinator: () => CheckDataCoordinator,
|
|
43
|
-
|
|
44
|
-
DatasetManager: () => DatasetManager,
|
|
29
|
+
ComparisonDataCoordinator: () => ComparisonDataCoordinator,
|
|
45
30
|
PerfRunner: () => PerfRunner,
|
|
46
31
|
PerfStats: () => PerfStats,
|
|
47
|
-
|
|
48
|
-
allInputsAtPositionScenario: () => allInputsAtPositionScenario,
|
|
32
|
+
categorizeComparisonTestSummaries: () => categorizeComparisonTestSummaries,
|
|
49
33
|
checkReportFromSummary: () => checkReportFromSummary,
|
|
50
34
|
checkSummaryFromReport: () => checkSummaryFromReport,
|
|
51
|
-
|
|
52
|
-
compareSummaryFromReport: () => compareSummaryFromReport,
|
|
35
|
+
comparisonSummaryFromReport: () => comparisonSummaryFromReport,
|
|
53
36
|
createConfig: () => createConfig,
|
|
54
37
|
datasetMessage: () => datasetMessage,
|
|
55
38
|
diffDatasets: () => diffDatasets,
|
|
56
39
|
diffGraphs: () => diffGraphs,
|
|
57
|
-
inputAtPositionScenario: () => inputAtPositionScenario,
|
|
58
|
-
inputAtValueScenario: () => inputAtValueScenario,
|
|
59
|
-
matrixScenarios: () => matrixScenarios,
|
|
60
|
-
positionSetting: () => positionSetting,
|
|
61
40
|
predicateMessage: () => predicateMessage,
|
|
62
41
|
runSuite: () => runSuite,
|
|
63
42
|
scenarioMessage: () => scenarioMessage,
|
|
64
|
-
|
|
65
|
-
suiteSummaryFromReport: () => suiteSummaryFromReport,
|
|
66
|
-
valueSetting: () => valueSetting
|
|
43
|
+
suiteSummaryFromReport: () => suiteSummaryFromReport
|
|
67
44
|
});
|
|
68
45
|
module.exports = __toCommonJS(src_exports);
|
|
69
46
|
|
|
70
|
-
// src/_shared/scenario.ts
|
|
71
|
-
var import_assert_never = require("assert-never");
|
|
72
|
-
function positionSetting(inputVarId, position) {
|
|
73
|
-
return {
|
|
74
|
-
kind: "position",
|
|
75
|
-
inputVarId,
|
|
76
|
-
position
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
function valueSetting(inputVarId, value) {
|
|
80
|
-
return {
|
|
81
|
-
kind: "value",
|
|
82
|
-
inputVarId,
|
|
83
|
-
value
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
function settingsScenario(key, groupKey, settings) {
|
|
87
|
-
return {
|
|
88
|
-
kind: "settings",
|
|
89
|
-
key,
|
|
90
|
-
groupKey,
|
|
91
|
-
settings
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
function inputAtPositionScenario(inputVarId, groupKey, position) {
|
|
95
|
-
const key = keyForInputAtPosition(`input${inputVarId}`, position);
|
|
96
|
-
return settingsScenario(key, groupKey, [positionSetting(inputVarId, position)]);
|
|
97
|
-
}
|
|
98
|
-
function inputAtValueScenario(inputVarId, groupKey, value) {
|
|
99
|
-
const key = keyForInputAtValue(`input${inputVarId}`, value);
|
|
100
|
-
return settingsScenario(key, groupKey, [valueSetting(inputVarId, value)]);
|
|
101
|
-
}
|
|
102
|
-
function allInputsAtPositionScenario(position) {
|
|
103
|
-
return {
|
|
104
|
-
kind: "all-inputs",
|
|
105
|
-
key: keyForInputAtPosition("all_inputs", position),
|
|
106
|
-
groupKey: "all_inputs",
|
|
107
|
-
position
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
function matrixScenarios(inputVarIds) {
|
|
111
|
-
const scenarios = [];
|
|
112
|
-
scenarios.push(allInputsAtPositionScenario("at-default"));
|
|
113
|
-
scenarios.push(allInputsAtPositionScenario("at-minimum"));
|
|
114
|
-
scenarios.push(allInputsAtPositionScenario("at-maximum"));
|
|
115
|
-
for (const inputVarId of inputVarIds) {
|
|
116
|
-
scenarios.push(inputAtPositionScenario(inputVarId, inputVarId, "at-minimum"));
|
|
117
|
-
scenarios.push(inputAtPositionScenario(inputVarId, inputVarId, "at-maximum"));
|
|
118
|
-
}
|
|
119
|
-
return scenarios;
|
|
120
|
-
}
|
|
121
|
-
function keyForInputPosition(position) {
|
|
122
|
-
switch (position) {
|
|
123
|
-
case "at-default":
|
|
124
|
-
return "default";
|
|
125
|
-
case "at-minimum":
|
|
126
|
-
return "min";
|
|
127
|
-
case "at-maximum":
|
|
128
|
-
return "max";
|
|
129
|
-
default:
|
|
130
|
-
(0, import_assert_never.assertNever)(position);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
function keyForInputAtPosition(inputKey, position) {
|
|
134
|
-
return `${inputKey}_at_${keyForInputPosition(position)}`;
|
|
135
|
-
}
|
|
136
|
-
function keyForInputAtValue(inputKey, value) {
|
|
137
|
-
return `${inputKey}_at_${value}`;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
47
|
// src/_shared/task-queue.ts
|
|
141
48
|
var TaskQueue = class {
|
|
142
49
|
constructor(processor) {
|
|
@@ -223,7 +130,7 @@ var CheckDataCoordinator = class {
|
|
|
223
130
|
this.bundleModel = bundleModel;
|
|
224
131
|
this.taskQueue = new TaskQueue({
|
|
225
132
|
process: async (request) => {
|
|
226
|
-
const result = await this.bundleModel.getDatasetsForScenario(request.
|
|
133
|
+
const result = await this.bundleModel.getDatasetsForScenario(request.scenarioSpec, [request.datasetKey]);
|
|
227
134
|
const dataset = result.datasetMap.get(request.datasetKey);
|
|
228
135
|
return {
|
|
229
136
|
dataset
|
|
@@ -231,9 +138,9 @@ var CheckDataCoordinator = class {
|
|
|
231
138
|
}
|
|
232
139
|
});
|
|
233
140
|
}
|
|
234
|
-
requestDataset(requestKey,
|
|
141
|
+
requestDataset(requestKey, scenarioSpec, datasetKey, onResponse) {
|
|
235
142
|
const request = {
|
|
236
|
-
|
|
143
|
+
scenarioSpec,
|
|
237
144
|
datasetKey
|
|
238
145
|
};
|
|
239
146
|
this.taskQueue.addTask(requestKey, request, (response) => {
|
|
@@ -246,10 +153,10 @@ var CheckDataCoordinator = class {
|
|
|
246
153
|
};
|
|
247
154
|
|
|
248
155
|
// src/check/check-report.ts
|
|
249
|
-
var
|
|
156
|
+
var import_assert_never2 = __toESM(require("assert-never"), 1);
|
|
250
157
|
|
|
251
158
|
// src/check/check-predicate.ts
|
|
252
|
-
var
|
|
159
|
+
var import_assert_never = __toESM(require("assert-never"), 1);
|
|
253
160
|
function symbolForPredicateOp(op) {
|
|
254
161
|
switch (op) {
|
|
255
162
|
case "gt":
|
|
@@ -265,7 +172,7 @@ function symbolForPredicateOp(op) {
|
|
|
265
172
|
case "approx":
|
|
266
173
|
return "\u2248";
|
|
267
174
|
default:
|
|
268
|
-
(0,
|
|
175
|
+
(0, import_assert_never.default)(op);
|
|
269
176
|
}
|
|
270
177
|
}
|
|
271
178
|
|
|
@@ -279,7 +186,7 @@ function buildCheckReport(checkPlan, checkResults) {
|
|
|
279
186
|
const scenarioReports = [];
|
|
280
187
|
for (const scenarioPlan of testPlan.scenarios) {
|
|
281
188
|
let scenarioStatus = "passed";
|
|
282
|
-
if (scenarioPlan.checkScenario.
|
|
189
|
+
if (scenarioPlan.checkScenario.spec === void 0) {
|
|
283
190
|
testStatus = "error";
|
|
284
191
|
scenarioStatus = "error";
|
|
285
192
|
}
|
|
@@ -376,14 +283,14 @@ function predicateReport(predicatePlan, checkKey, result) {
|
|
|
376
283
|
};
|
|
377
284
|
opRef = opDataRef;
|
|
378
285
|
opValue = `${sym} '${dataRef.dataset.name}'`;
|
|
379
|
-
const
|
|
380
|
-
if (!
|
|
286
|
+
const refScenarioSpec = (_b = dataRef.scenario) == null ? void 0 : _b.spec;
|
|
287
|
+
if (!refScenarioSpec) {
|
|
381
288
|
return;
|
|
382
289
|
}
|
|
383
290
|
if (predOp.scenario === "inherit") {
|
|
384
291
|
opValue += ` (w/ same scenario)`;
|
|
385
292
|
} else {
|
|
386
|
-
if (
|
|
293
|
+
if (refScenarioSpec.kind === "all-inputs" && refScenarioSpec.position === "at-default") {
|
|
387
294
|
opValue += ` (w/ default scenario)`;
|
|
388
295
|
} else {
|
|
389
296
|
opValue += ` (w/ configured scenario)`;
|
|
@@ -418,7 +325,7 @@ function predicateReport(predicatePlan, checkKey, result) {
|
|
|
418
325
|
}
|
|
419
326
|
function scenarioMessage(scenario, bold) {
|
|
420
327
|
const checkScenario = scenario.checkScenario;
|
|
421
|
-
if (checkScenario.
|
|
328
|
+
if (checkScenario.spec === void 0) {
|
|
422
329
|
if (checkScenario.error) {
|
|
423
330
|
switch (checkScenario.error.kind) {
|
|
424
331
|
case "unknown-input-group":
|
|
@@ -426,7 +333,7 @@ function scenarioMessage(scenario, bold) {
|
|
|
426
333
|
case "empty-input-group":
|
|
427
334
|
return `error: input group ${bold(checkScenario.error.name)} is empty`;
|
|
428
335
|
default:
|
|
429
|
-
(0,
|
|
336
|
+
(0, import_assert_never2.default)(checkScenario.error.kind);
|
|
430
337
|
}
|
|
431
338
|
} else {
|
|
432
339
|
const badInputNames = checkScenario.inputDescs.filter((d) => d.inputVar === void 0).map((d) => bold(d.name));
|
|
@@ -443,7 +350,7 @@ function scenarioMessage(scenario, bold) {
|
|
|
443
350
|
case "at-maximum":
|
|
444
351
|
return "maximum";
|
|
445
352
|
default:
|
|
446
|
-
(0,
|
|
353
|
+
(0, import_assert_never2.default)(position);
|
|
447
354
|
}
|
|
448
355
|
}
|
|
449
356
|
function inputMessage(inputDesc) {
|
|
@@ -458,13 +365,13 @@ function scenarioMessage(scenario, bold) {
|
|
|
458
365
|
}
|
|
459
366
|
return msg;
|
|
460
367
|
}
|
|
461
|
-
if (checkScenario.
|
|
462
|
-
const position = checkScenario.
|
|
368
|
+
if (checkScenario.spec.kind === "all-inputs") {
|
|
369
|
+
const position = checkScenario.spec.position;
|
|
463
370
|
return `when ${bold("all inputs")} are at ${bold(positionName(position))}...`;
|
|
464
371
|
} else if (checkScenario.inputGroupName) {
|
|
465
372
|
let position = "at-default";
|
|
466
|
-
if (checkScenario.
|
|
467
|
-
position = checkScenario.
|
|
373
|
+
if (checkScenario.spec.settings[0].kind === "position") {
|
|
374
|
+
position = checkScenario.spec.settings[0].position;
|
|
468
375
|
}
|
|
469
376
|
const groupName = checkScenario.inputGroupName;
|
|
470
377
|
return `when all inputs in ${bold(groupName)} are at ${bold(positionName(position))}...`;
|
|
@@ -497,7 +404,7 @@ function predicateMessage(predicate, bold) {
|
|
|
497
404
|
case "empty-input-group":
|
|
498
405
|
return `error: referenced input group ${bold(result.errorInfo.name)} is empty`;
|
|
499
406
|
default:
|
|
500
|
-
(0,
|
|
407
|
+
(0, import_assert_never2.default)(result.errorInfo.kind);
|
|
501
408
|
}
|
|
502
409
|
} else {
|
|
503
410
|
return `unknown error`;
|
|
@@ -1068,7 +975,7 @@ function parseTestYaml(yamlStrings) {
|
|
|
1068
975
|
groups.push(group);
|
|
1069
976
|
}
|
|
1070
977
|
} else {
|
|
1071
|
-
let msg = "Failed to parse YAML
|
|
978
|
+
let msg = "Failed to parse YAML check definitions";
|
|
1072
979
|
for (const error of validate.errors || []) {
|
|
1073
980
|
if (error.message) {
|
|
1074
981
|
msg += `
|
|
@@ -1242,9 +1149,12 @@ function actionForPredicate(predicateSpec) {
|
|
|
1242
1149
|
|
|
1243
1150
|
// src/_shared/combo.ts
|
|
1244
1151
|
function cartesianProductOf(arr) {
|
|
1245
|
-
return arr.reduce(
|
|
1246
|
-
|
|
1247
|
-
|
|
1152
|
+
return arr.reduce(
|
|
1153
|
+
(a, b) => {
|
|
1154
|
+
return a.map((x) => b.map((y) => x.concat([y]))).reduce((v, w) => v.concat(w), []);
|
|
1155
|
+
},
|
|
1156
|
+
[[]]
|
|
1157
|
+
);
|
|
1248
1158
|
}
|
|
1249
1159
|
|
|
1250
1160
|
// src/check/check-dataset.ts
|
|
@@ -1335,14 +1245,16 @@ function matchByName(modelSpec, datasetName, datasetSource) {
|
|
|
1335
1245
|
};
|
|
1336
1246
|
}
|
|
1337
1247
|
function matchByGroup(modelSpec, groupName) {
|
|
1338
|
-
const groupToMatch = groupName.toLowerCase();
|
|
1339
1248
|
let matchedGroupName;
|
|
1340
1249
|
let matchedGroupDatasetKeys;
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1250
|
+
if (modelSpec.datasetGroups) {
|
|
1251
|
+
const groupToMatch = groupName.toLowerCase();
|
|
1252
|
+
for (const [group, datasetKeys] of modelSpec.datasetGroups) {
|
|
1253
|
+
if (group.toLowerCase() === groupToMatch) {
|
|
1254
|
+
matchedGroupName = group;
|
|
1255
|
+
matchedGroupDatasetKeys = datasetKeys;
|
|
1256
|
+
break;
|
|
1257
|
+
}
|
|
1346
1258
|
}
|
|
1347
1259
|
}
|
|
1348
1260
|
if (matchedGroupName === void 0) {
|
|
@@ -1419,6 +1331,65 @@ function matchByType(modelSpec, varTypeToMatch) {
|
|
|
1419
1331
|
|
|
1420
1332
|
// src/check/check-scenario.ts
|
|
1421
1333
|
var import_assert_never4 = __toESM(require("assert-never"), 1);
|
|
1334
|
+
|
|
1335
|
+
// src/_shared/scenario-specs.ts
|
|
1336
|
+
var import_assert_never3 = require("assert-never");
|
|
1337
|
+
function positionSetting(inputVarId, position) {
|
|
1338
|
+
return {
|
|
1339
|
+
kind: "position",
|
|
1340
|
+
inputVarId,
|
|
1341
|
+
position
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
function valueSetting(inputVarId, value) {
|
|
1345
|
+
return {
|
|
1346
|
+
kind: "value",
|
|
1347
|
+
inputVarId,
|
|
1348
|
+
value
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
function inputSettingsSpec(settings) {
|
|
1352
|
+
const uidParts = settings.map((setting) => {
|
|
1353
|
+
switch (setting.kind) {
|
|
1354
|
+
case "position":
|
|
1355
|
+
return `${setting.inputVarId}_at_${keyForInputPosition(setting.position)}`;
|
|
1356
|
+
case "value":
|
|
1357
|
+
return `${setting.inputVarId}_at_${setting.value}`;
|
|
1358
|
+
default:
|
|
1359
|
+
(0, import_assert_never3.assertNever)(setting);
|
|
1360
|
+
}
|
|
1361
|
+
});
|
|
1362
|
+
const uid = `inputs_${uidParts.sort().join("_")}`;
|
|
1363
|
+
return {
|
|
1364
|
+
kind: "input-settings",
|
|
1365
|
+
uid,
|
|
1366
|
+
settings
|
|
1367
|
+
};
|
|
1368
|
+
}
|
|
1369
|
+
function inputAtPositionSpec(inputVarId, position) {
|
|
1370
|
+
return inputSettingsSpec([positionSetting(inputVarId, position)]);
|
|
1371
|
+
}
|
|
1372
|
+
function allInputsAtPositionSpec(position) {
|
|
1373
|
+
return {
|
|
1374
|
+
kind: "all-inputs",
|
|
1375
|
+
uid: `all_inputs_at_${keyForInputPosition(position)}`,
|
|
1376
|
+
position
|
|
1377
|
+
};
|
|
1378
|
+
}
|
|
1379
|
+
function keyForInputPosition(position) {
|
|
1380
|
+
switch (position) {
|
|
1381
|
+
case "at-default":
|
|
1382
|
+
return "default";
|
|
1383
|
+
case "at-minimum":
|
|
1384
|
+
return "min";
|
|
1385
|
+
case "at-maximum":
|
|
1386
|
+
return "max";
|
|
1387
|
+
default:
|
|
1388
|
+
(0, import_assert_never3.assertNever)(position);
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
// src/check/check-scenario.ts
|
|
1422
1393
|
function expandScenarios(modelSpec, scenarioSpecs, simplify) {
|
|
1423
1394
|
if (scenarioSpecs.length === 0) {
|
|
1424
1395
|
const scenarioSpec = {
|
|
@@ -1495,10 +1466,12 @@ function inputDescForName(modelSpec, inputName, at) {
|
|
|
1495
1466
|
}
|
|
1496
1467
|
}
|
|
1497
1468
|
function groupForName(modelSpec, groupName) {
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1469
|
+
if (modelSpec.inputGroups) {
|
|
1470
|
+
const groupToMatch = groupName.toLowerCase();
|
|
1471
|
+
for (const [group, inputVars] of modelSpec.inputGroups) {
|
|
1472
|
+
if (group.toLowerCase() === groupToMatch) {
|
|
1473
|
+
return [group, inputVars];
|
|
1474
|
+
}
|
|
1502
1475
|
}
|
|
1503
1476
|
}
|
|
1504
1477
|
return void 0;
|
|
@@ -1513,56 +1486,35 @@ function errorScenarioForInputGroup(kind, groupName) {
|
|
|
1513
1486
|
};
|
|
1514
1487
|
}
|
|
1515
1488
|
function checkScenarioWithAllInputsAtPosition(position) {
|
|
1516
|
-
const scenario = allInputsAtPositionScenario(position);
|
|
1517
1489
|
return {
|
|
1518
|
-
|
|
1490
|
+
spec: allInputsAtPositionSpec(position),
|
|
1519
1491
|
inputDescs: []
|
|
1520
1492
|
};
|
|
1521
1493
|
}
|
|
1522
1494
|
function checkScenarioWithInputAtPosition(inputVar, position) {
|
|
1523
1495
|
const varId = inputVar.varId;
|
|
1524
|
-
const scenario = inputAtPositionScenario(varId, varId, position);
|
|
1525
1496
|
return {
|
|
1526
|
-
|
|
1497
|
+
spec: inputAtPositionSpec(varId, position),
|
|
1527
1498
|
inputDescs: [inputDescAtPosition(inputVar, position)]
|
|
1528
1499
|
};
|
|
1529
1500
|
}
|
|
1530
1501
|
function checkScenarioForInputDescs(groupName, inputDescs) {
|
|
1531
|
-
let
|
|
1502
|
+
let spec;
|
|
1532
1503
|
if (inputDescs.every((desc) => desc.inputVar !== void 0)) {
|
|
1533
|
-
const settings =
|
|
1534
|
-
const keyParts = [];
|
|
1535
|
-
for (const inputDesc of inputDescs) {
|
|
1504
|
+
const settings = inputDescs.map((inputDesc) => {
|
|
1536
1505
|
const varId = inputDesc.inputVar.varId;
|
|
1537
1506
|
if (inputDesc.position) {
|
|
1538
|
-
|
|
1539
|
-
keyParts.push(keyForInputAtPosition(varId, inputDesc.position));
|
|
1507
|
+
return positionSetting(varId, inputDesc.position);
|
|
1540
1508
|
} else {
|
|
1541
|
-
|
|
1542
|
-
keyParts.push(keyForInputAtValue(varId, inputDesc.value));
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
|
-
if (settings.length === 1) {
|
|
1546
|
-
const scenarioKey = `input${keyParts[0]}`;
|
|
1547
|
-
const groupKey = settings[0].inputVarId;
|
|
1548
|
-
scenario = settingsScenario(scenarioKey, groupKey, settings);
|
|
1549
|
-
} else if (settings.length > 1) {
|
|
1550
|
-
let scenarioKey;
|
|
1551
|
-
let groupKey;
|
|
1552
|
-
if (groupName) {
|
|
1553
|
-
scenarioKey = `group_${groupName.toLowerCase().replace(/ /g, "_")}`;
|
|
1554
|
-
groupKey = scenarioKey;
|
|
1555
|
-
} else {
|
|
1556
|
-
scenarioKey = "multi" + keyParts.join("_");
|
|
1557
|
-
groupKey = scenarioKey;
|
|
1509
|
+
return valueSetting(varId, inputDesc.value);
|
|
1558
1510
|
}
|
|
1559
|
-
|
|
1560
|
-
|
|
1511
|
+
});
|
|
1512
|
+
spec = inputSettingsSpec(settings);
|
|
1561
1513
|
} else {
|
|
1562
|
-
|
|
1514
|
+
spec = void 0;
|
|
1563
1515
|
}
|
|
1564
1516
|
return {
|
|
1565
|
-
|
|
1517
|
+
spec,
|
|
1566
1518
|
inputGroupName: groupName,
|
|
1567
1519
|
inputDescs
|
|
1568
1520
|
};
|
|
@@ -1676,7 +1628,7 @@ var CheckPlanner = class {
|
|
|
1676
1628
|
}
|
|
1677
1629
|
const planScenarios = [];
|
|
1678
1630
|
for (const checkScenario of checkScenarios) {
|
|
1679
|
-
if (checkScenario.
|
|
1631
|
+
if (checkScenario.spec === void 0) {
|
|
1680
1632
|
planScenarios.push({
|
|
1681
1633
|
checkScenario,
|
|
1682
1634
|
datasets: []
|
|
@@ -1785,8 +1737,8 @@ var CheckPlanner = class {
|
|
|
1785
1737
|
}
|
|
1786
1738
|
}
|
|
1787
1739
|
let dataRefKey;
|
|
1788
|
-
if (refScenario.
|
|
1789
|
-
dataRefKey = `${refScenario.
|
|
1740
|
+
if (refScenario.spec && refDataset.datasetKey) {
|
|
1741
|
+
dataRefKey = `${refScenario.spec.uid}::${refDataset.datasetKey}`;
|
|
1790
1742
|
}
|
|
1791
1743
|
const dataRef = {
|
|
1792
1744
|
key: dataRefKey,
|
|
@@ -1841,14 +1793,14 @@ function checkSummaryFromReport(checkReport) {
|
|
|
1841
1793
|
predicateSummaries
|
|
1842
1794
|
};
|
|
1843
1795
|
}
|
|
1844
|
-
function checkReportFromSummary(checkConfig, checkSummary
|
|
1796
|
+
function checkReportFromSummary(checkConfig, checkSummary) {
|
|
1845
1797
|
const checkSpecResult = parseTestYaml(checkConfig.tests);
|
|
1846
1798
|
if (checkSpecResult.isErr()) {
|
|
1847
1799
|
return void 0;
|
|
1848
1800
|
}
|
|
1849
1801
|
const checkSpec = checkSpecResult.value;
|
|
1850
1802
|
const checkPlanner = new CheckPlanner(checkConfig.bundle.model.modelSpec);
|
|
1851
|
-
checkPlanner.addAllChecks(checkSpec,
|
|
1803
|
+
checkPlanner.addAllChecks(checkSpec, false);
|
|
1852
1804
|
const checkPlan = checkPlanner.buildPlan();
|
|
1853
1805
|
const checkResults = /* @__PURE__ */ new Map();
|
|
1854
1806
|
for (const predicateSummary of checkSummary.predicateSummaries) {
|
|
@@ -1857,44 +1809,66 @@ function checkReportFromSummary(checkConfig, checkSummary, simplifyScenarios) {
|
|
|
1857
1809
|
return buildCheckReport(checkPlan, checkResults);
|
|
1858
1810
|
}
|
|
1859
1811
|
|
|
1860
|
-
// src/
|
|
1812
|
+
// src/comparison/run/comparison-data-coordinator.ts
|
|
1861
1813
|
var import_assert_never7 = require("assert-never");
|
|
1862
|
-
var
|
|
1814
|
+
var ComparisonDataCoordinator = class {
|
|
1863
1815
|
constructor(bundleModelL, bundleModelR) {
|
|
1864
1816
|
this.bundleModelL = bundleModelL;
|
|
1865
1817
|
this.bundleModelR = bundleModelR;
|
|
1866
1818
|
this.taskQueue = new TaskQueue({
|
|
1867
1819
|
process: async (request) => {
|
|
1868
1820
|
switch (request.kind) {
|
|
1869
|
-
case "dataset":
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
]);
|
|
1874
|
-
return {
|
|
1875
|
-
kind: "dataset",
|
|
1876
|
-
datasetMapL: resultL.datasetMap,
|
|
1877
|
-
datasetMapR: resultR.datasetMap
|
|
1878
|
-
};
|
|
1879
|
-
}
|
|
1880
|
-
case "graph-data": {
|
|
1881
|
-
const bundleModel = request.bundle === "right" ? this.bundleModelR : this.bundleModelL;
|
|
1882
|
-
const graphData = await bundleModel.getGraphDataForScenario(request.scenario, request.graphId);
|
|
1883
|
-
return {
|
|
1884
|
-
kind: "graph-data",
|
|
1885
|
-
graphData
|
|
1886
|
-
};
|
|
1887
|
-
}
|
|
1821
|
+
case "dataset":
|
|
1822
|
+
return this.processDatasetRequest(request);
|
|
1823
|
+
case "graph-data":
|
|
1824
|
+
return this.processGraphDataRequest(request);
|
|
1888
1825
|
default:
|
|
1889
1826
|
(0, import_assert_never7.assertNever)(request);
|
|
1890
1827
|
}
|
|
1891
1828
|
}
|
|
1892
1829
|
});
|
|
1893
1830
|
}
|
|
1894
|
-
|
|
1831
|
+
async processDatasetRequest(request) {
|
|
1832
|
+
async function fetchDatasets(bundleModel, scenarioSpec) {
|
|
1833
|
+
if (scenarioSpec) {
|
|
1834
|
+
return bundleModel.getDatasetsForScenario(scenarioSpec, request.datasetKeys);
|
|
1835
|
+
} else {
|
|
1836
|
+
return void 0;
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
const [resultL, resultR] = await Promise.all([
|
|
1840
|
+
fetchDatasets(this.bundleModelL, request.scenarioSpecL),
|
|
1841
|
+
fetchDatasets(this.bundleModelR, request.scenarioSpecR)
|
|
1842
|
+
]);
|
|
1843
|
+
return {
|
|
1844
|
+
kind: "dataset",
|
|
1845
|
+
datasetMapL: resultL == null ? void 0 : resultL.datasetMap,
|
|
1846
|
+
datasetMapR: resultR == null ? void 0 : resultR.datasetMap
|
|
1847
|
+
};
|
|
1848
|
+
}
|
|
1849
|
+
async processGraphDataRequest(request) {
|
|
1850
|
+
async function fetchGraphData(bundleModel, scenarioSpec) {
|
|
1851
|
+
if (scenarioSpec) {
|
|
1852
|
+
return bundleModel.getGraphDataForScenario(scenarioSpec, request.graphId);
|
|
1853
|
+
} else {
|
|
1854
|
+
return void 0;
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
const [graphDataL, graphDataR] = await Promise.all([
|
|
1858
|
+
fetchGraphData(this.bundleModelL, request.scenarioSpecL),
|
|
1859
|
+
fetchGraphData(this.bundleModelR, request.scenarioSpecR)
|
|
1860
|
+
]);
|
|
1861
|
+
return {
|
|
1862
|
+
kind: "graph-data",
|
|
1863
|
+
graphDataL,
|
|
1864
|
+
graphDataR
|
|
1865
|
+
};
|
|
1866
|
+
}
|
|
1867
|
+
requestDatasetMaps(requestKey, scenarioSpecL, scenarioSpecR, datasetKeys, onResponse) {
|
|
1895
1868
|
const request = {
|
|
1896
1869
|
kind: "dataset",
|
|
1897
|
-
|
|
1870
|
+
scenarioSpecL,
|
|
1871
|
+
scenarioSpecR,
|
|
1898
1872
|
datasetKeys
|
|
1899
1873
|
};
|
|
1900
1874
|
this.taskQueue.addTask(requestKey, request, (response) => {
|
|
@@ -1903,16 +1877,16 @@ var CompareDataCoordinator = class {
|
|
|
1903
1877
|
}
|
|
1904
1878
|
});
|
|
1905
1879
|
}
|
|
1906
|
-
requestGraphData(requestKey,
|
|
1880
|
+
requestGraphData(requestKey, scenarioSpecL, scenarioSpecR, graphId, onResponse) {
|
|
1907
1881
|
const request = {
|
|
1908
1882
|
kind: "graph-data",
|
|
1909
|
-
|
|
1910
|
-
|
|
1883
|
+
scenarioSpecL,
|
|
1884
|
+
scenarioSpecR,
|
|
1911
1885
|
graphId
|
|
1912
1886
|
};
|
|
1913
1887
|
this.taskQueue.addTask(requestKey, request, (response) => {
|
|
1914
1888
|
if (response.kind === "graph-data") {
|
|
1915
|
-
onResponse(response.
|
|
1889
|
+
onResponse(response.graphDataL, response.graphDataR);
|
|
1916
1890
|
}
|
|
1917
1891
|
});
|
|
1918
1892
|
}
|
|
@@ -1921,7 +1895,7 @@ var CompareDataCoordinator = class {
|
|
|
1921
1895
|
}
|
|
1922
1896
|
};
|
|
1923
1897
|
|
|
1924
|
-
// src/
|
|
1898
|
+
// src/comparison/diff-datasets/diff-datasets.ts
|
|
1925
1899
|
function diffDatasets(datasetL, datasetR) {
|
|
1926
1900
|
let minValueL = Number.MAX_VALUE;
|
|
1927
1901
|
let maxValueL = Number.MIN_VALUE;
|
|
@@ -2016,19 +1990,9 @@ function diffDatasets(datasetL, datasetR) {
|
|
|
2016
1990
|
maxDiffPoint
|
|
2017
1991
|
};
|
|
2018
1992
|
}
|
|
2019
|
-
function compareDatasets(scenarioKey, datasetKey, datasetMapL, datasetMapR) {
|
|
2020
|
-
const datasetL = datasetMapL.get(datasetKey);
|
|
2021
|
-
const datasetR = datasetMapR.get(datasetKey);
|
|
2022
|
-
const diffReport = diffDatasets(datasetL, datasetR);
|
|
2023
|
-
return {
|
|
2024
|
-
scenarioKey,
|
|
2025
|
-
datasetKey,
|
|
2026
|
-
diffReport
|
|
2027
|
-
};
|
|
2028
|
-
}
|
|
2029
1993
|
|
|
2030
|
-
// src/
|
|
2031
|
-
function diffGraphs(graphL, graphR, scenarioKey,
|
|
1994
|
+
// src/comparison/diff-graphs/diff-graphs.ts
|
|
1995
|
+
function diffGraphs(graphL, graphR, scenarioKey, testSummaries) {
|
|
2032
1996
|
let inclusion;
|
|
2033
1997
|
if (graphL && graphR) {
|
|
2034
1998
|
inclusion = "both";
|
|
@@ -2070,8 +2034,8 @@ function diffGraphs(graphL, graphR, scenarioKey, datasetSummaries) {
|
|
|
2070
2034
|
datasetKeys.add(dataset.datasetKey);
|
|
2071
2035
|
}
|
|
2072
2036
|
for (const datasetKey of datasetKeys) {
|
|
2073
|
-
const
|
|
2074
|
-
const maxDiff =
|
|
2037
|
+
const testSummary = testSummaries.find((summary) => summary.d === datasetKey && summary.s === scenarioKey);
|
|
2038
|
+
const maxDiff = testSummary == null ? void 0 : testSummary.md;
|
|
2075
2039
|
datasetReports.push({
|
|
2076
2040
|
datasetKey,
|
|
2077
2041
|
maxDiff
|
|
@@ -2085,12 +2049,12 @@ function diffGraphs(graphL, graphR, scenarioKey, datasetSummaries) {
|
|
|
2085
2049
|
};
|
|
2086
2050
|
}
|
|
2087
2051
|
|
|
2088
|
-
// src/
|
|
2089
|
-
function
|
|
2090
|
-
const
|
|
2091
|
-
for (const r of
|
|
2052
|
+
// src/comparison/report/comparison-reporting.ts
|
|
2053
|
+
function comparisonSummaryFromReport(comparisonReport) {
|
|
2054
|
+
const terseSummaries = [];
|
|
2055
|
+
for (const r of comparisonReport.testReports) {
|
|
2092
2056
|
if (r.diffReport.validity === "both" && r.diffReport.maxDiff > 0) {
|
|
2093
|
-
|
|
2057
|
+
terseSummaries.push({
|
|
2094
2058
|
s: r.scenarioKey,
|
|
2095
2059
|
d: r.datasetKey,
|
|
2096
2060
|
md: r.diffReport.maxDiff
|
|
@@ -2098,152 +2062,1317 @@ function compareSummaryFromReport(compareReport) {
|
|
|
2098
2062
|
}
|
|
2099
2063
|
}
|
|
2100
2064
|
return {
|
|
2101
|
-
|
|
2102
|
-
perfReportL:
|
|
2103
|
-
perfReportR:
|
|
2065
|
+
testSummaries: terseSummaries,
|
|
2066
|
+
perfReportL: comparisonReport.perfReportL,
|
|
2067
|
+
perfReportR: comparisonReport.perfReportR
|
|
2104
2068
|
};
|
|
2105
2069
|
}
|
|
2070
|
+
function restoreFromTerseSummaries(comparisonConfig, terseSummaries) {
|
|
2071
|
+
const existingSummaries = /* @__PURE__ */ new Map();
|
|
2072
|
+
for (const summary of terseSummaries) {
|
|
2073
|
+
const key = `${summary.s}::${summary.d}`;
|
|
2074
|
+
existingSummaries.set(key, summary);
|
|
2075
|
+
}
|
|
2076
|
+
const allTestSummaries = [];
|
|
2077
|
+
for (const scenario of comparisonConfig.scenarios.getAllScenarios()) {
|
|
2078
|
+
const datasetKeys = comparisonConfig.datasets.getDatasetKeysForScenario(scenario);
|
|
2079
|
+
for (const datasetKey of datasetKeys) {
|
|
2080
|
+
const key = `${scenario.key}::${datasetKey}`;
|
|
2081
|
+
const existingSummary = existingSummaries.get(key);
|
|
2082
|
+
const maxDiff = (existingSummary == null ? void 0 : existingSummary.md) || 0;
|
|
2083
|
+
allTestSummaries.push({
|
|
2084
|
+
s: scenario.key,
|
|
2085
|
+
d: datasetKey,
|
|
2086
|
+
md: maxDiff
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
return allTestSummaries;
|
|
2091
|
+
}
|
|
2106
2092
|
|
|
2107
|
-
// src/
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2093
|
+
// src/comparison/report/comparison-grouping.ts
|
|
2094
|
+
var import_assert_never8 = require("assert-never");
|
|
2095
|
+
|
|
2096
|
+
// src/comparison/report/buckets.ts
|
|
2097
|
+
function getBucketIndex(diffPct, thresholds) {
|
|
2098
|
+
if (diffPct === 0) {
|
|
2099
|
+
return 0;
|
|
2100
|
+
}
|
|
2101
|
+
for (let i = 0; i < thresholds.length; i++) {
|
|
2102
|
+
if (diffPct < thresholds[i]) {
|
|
2103
|
+
return i + 1;
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
return thresholds.length + 1;
|
|
2107
|
+
}
|
|
2108
|
+
|
|
2109
|
+
// src/comparison/report/comparison-grouping.ts
|
|
2110
|
+
function categorizeComparisonTestSummaries(comparisonConfig, terseSummaries) {
|
|
2111
|
+
const allTestSummaries = restoreFromTerseSummaries(comparisonConfig, terseSummaries);
|
|
2112
|
+
const groupsByScenario = groupComparisonTestSummaries(allTestSummaries, "by-scenario");
|
|
2113
|
+
const byScenario = categorizeComparisonGroups(comparisonConfig, [...groupsByScenario.values()]);
|
|
2114
|
+
const groupsByDataset = groupComparisonTestSummaries(allTestSummaries, "by-dataset");
|
|
2115
|
+
const byDataset = categorizeComparisonGroups(comparisonConfig, [...groupsByDataset.values()]);
|
|
2111
2116
|
return {
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
return promiseQueue.add(() => sourceModel.getDatasetsForScenario(scenario, datasetKeys));
|
|
2115
|
-
},
|
|
2116
|
-
getGraphsForDataset: (_a = sourceModel.getGraphsForDataset) == null ? void 0 : _a.bind(sourceModel),
|
|
2117
|
-
getGraphDataForScenario: (scenario, graphId) => {
|
|
2118
|
-
return promiseQueue.add(() => sourceModel.getGraphDataForScenario(scenario, graphId));
|
|
2119
|
-
},
|
|
2120
|
-
getGraphLinksForScenario: sourceModel.getGraphLinksForScenario.bind(sourceModel)
|
|
2117
|
+
byScenario,
|
|
2118
|
+
byDataset
|
|
2121
2119
|
};
|
|
2122
2120
|
}
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2121
|
+
function groupComparisonTestSummaries(testSummaries, groupKind) {
|
|
2122
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2123
|
+
for (const testSummary of testSummaries) {
|
|
2124
|
+
let groupKey;
|
|
2125
|
+
switch (groupKind) {
|
|
2126
|
+
case "by-dataset":
|
|
2127
|
+
groupKey = testSummary.d;
|
|
2128
|
+
break;
|
|
2129
|
+
case "by-scenario":
|
|
2130
|
+
groupKey = testSummary.s;
|
|
2131
|
+
break;
|
|
2132
|
+
default:
|
|
2133
|
+
(0, import_assert_never8.assertNever)(groupKind);
|
|
2134
|
+
}
|
|
2135
|
+
const group = groups.get(groupKey);
|
|
2136
|
+
if (group) {
|
|
2137
|
+
group.testSummaries.push(testSummary);
|
|
2138
|
+
} else {
|
|
2139
|
+
groups.set(groupKey, {
|
|
2140
|
+
kind: groupKind,
|
|
2141
|
+
key: groupKey,
|
|
2142
|
+
testSummaries: [testSummary]
|
|
2143
|
+
});
|
|
2144
|
+
}
|
|
2127
2145
|
}
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2146
|
+
return groups;
|
|
2147
|
+
}
|
|
2148
|
+
function categorizeComparisonGroups(comparisonConfig, allGroups) {
|
|
2149
|
+
const allGroupSummaries = /* @__PURE__ */ new Map();
|
|
2150
|
+
const withErrors = [];
|
|
2151
|
+
const onlyInLeft = [];
|
|
2152
|
+
const onlyInRight = [];
|
|
2153
|
+
let withDiffs = [];
|
|
2154
|
+
const withoutDiffs = [];
|
|
2155
|
+
function addSummaryForGroup(group, root, validInL, validInR) {
|
|
2156
|
+
let scores;
|
|
2157
|
+
if (validInL && validInR) {
|
|
2158
|
+
scores = getScoresForGroup(group, comparisonConfig.thresholds);
|
|
2159
|
+
}
|
|
2160
|
+
const groupSummary = {
|
|
2161
|
+
root,
|
|
2162
|
+
group,
|
|
2163
|
+
scores
|
|
2164
|
+
};
|
|
2165
|
+
allGroupSummaries.set(group.key, groupSummary);
|
|
2166
|
+
if (validInL && validInR) {
|
|
2167
|
+
if (scores.totalDiffCount !== scores.diffCountByBucket[0]) {
|
|
2168
|
+
withDiffs.push(groupSummary);
|
|
2145
2169
|
} else {
|
|
2146
|
-
|
|
2170
|
+
withoutDiffs.push(groupSummary);
|
|
2147
2171
|
}
|
|
2148
|
-
})
|
|
2172
|
+
} else if (validInL) {
|
|
2173
|
+
onlyInLeft.push(groupSummary);
|
|
2174
|
+
} else if (validInR) {
|
|
2175
|
+
onlyInRight.push(groupSummary);
|
|
2176
|
+
} else {
|
|
2177
|
+
withErrors.push(groupSummary);
|
|
2178
|
+
}
|
|
2149
2179
|
}
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2180
|
+
for (const group of allGroups.values()) {
|
|
2181
|
+
switch (group.kind) {
|
|
2182
|
+
case "by-dataset": {
|
|
2183
|
+
const dataset = comparisonConfig.datasets.getDataset(group.key);
|
|
2184
|
+
const validInL = (dataset == null ? void 0 : dataset.outputVarL) !== void 0;
|
|
2185
|
+
const validInR = (dataset == null ? void 0 : dataset.outputVarR) !== void 0;
|
|
2186
|
+
addSummaryForGroup(group, dataset, validInL, validInR);
|
|
2187
|
+
break;
|
|
2188
|
+
}
|
|
2189
|
+
case "by-scenario": {
|
|
2190
|
+
const scenario = comparisonConfig.scenarios.getScenario(group.key);
|
|
2191
|
+
const validInL = (scenario == null ? void 0 : scenario.specL) !== void 0;
|
|
2192
|
+
const validInR = (scenario == null ? void 0 : scenario.specR) !== void 0;
|
|
2193
|
+
addSummaryForGroup(group, scenario, validInL, validInR);
|
|
2194
|
+
break;
|
|
2155
2195
|
}
|
|
2196
|
+
default:
|
|
2197
|
+
(0, import_assert_never8.assertNever)(group.kind);
|
|
2156
2198
|
}
|
|
2157
2199
|
}
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
let currentBundle;
|
|
2165
|
-
let compareConfig;
|
|
2166
|
-
if (options.compare === void 0) {
|
|
2167
|
-
currentBundle = origCurrentBundle;
|
|
2168
|
-
} else {
|
|
2169
|
-
const baselineBundle = await loadSynchronized(options.compare.baseline);
|
|
2170
|
-
const renamedDatasetKeys = options.compare.datasets.renamedDatasetKeys;
|
|
2171
|
-
const invertedRenamedKeys = /* @__PURE__ */ new Map();
|
|
2172
|
-
renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.forEach((newKey, oldKey) => {
|
|
2173
|
-
invertedRenamedKeys.set(newKey, oldKey);
|
|
2174
|
-
});
|
|
2175
|
-
const rightKeyForLeftKey = (leftKey) => {
|
|
2176
|
-
return (renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.get(leftKey)) || leftKey;
|
|
2177
|
-
};
|
|
2178
|
-
const leftKeyForRightKey = (rightKey) => {
|
|
2179
|
-
return invertedRenamedKeys.get(rightKey) || rightKey;
|
|
2180
|
-
};
|
|
2181
|
-
const origBundleModelR = origCurrentBundle.model;
|
|
2182
|
-
const adjBundleModelR = {
|
|
2183
|
-
modelSpec: origBundleModelR.modelSpec,
|
|
2184
|
-
getDatasetsForScenario: async (scenario, datasetKeys) => {
|
|
2185
|
-
const rightKeys = datasetKeys.map(rightKeyForLeftKey);
|
|
2186
|
-
const result = await origBundleModelR.getDatasetsForScenario(scenario, rightKeys);
|
|
2187
|
-
const mapWithRightKeys = result.datasetMap;
|
|
2188
|
-
const mapWithLeftKeys = /* @__PURE__ */ new Map();
|
|
2189
|
-
for (const [rightKey, dataset] of mapWithRightKeys.entries()) {
|
|
2190
|
-
const leftKey = leftKeyForRightKey(rightKey);
|
|
2191
|
-
mapWithLeftKeys.set(leftKey, dataset);
|
|
2192
|
-
}
|
|
2193
|
-
return {
|
|
2194
|
-
datasetMap: mapWithLeftKeys,
|
|
2195
|
-
modelRunTime: result.modelRunTime
|
|
2196
|
-
};
|
|
2197
|
-
},
|
|
2198
|
-
getGraphsForDataset: (_a = origBundleModelR.getGraphsForDataset) == null ? void 0 : _a.bind(origBundleModelR),
|
|
2199
|
-
getGraphDataForScenario: origBundleModelR.getGraphDataForScenario.bind(origBundleModelR),
|
|
2200
|
-
getGraphLinksForScenario: origBundleModelR.getGraphLinksForScenario.bind(origBundleModelR)
|
|
2201
|
-
};
|
|
2202
|
-
currentBundle = __spreadProps(__spreadValues({}, origCurrentBundle), {
|
|
2203
|
-
model: adjBundleModelR
|
|
2204
|
-
});
|
|
2205
|
-
compareConfig = {
|
|
2206
|
-
bundleL: baselineBundle,
|
|
2207
|
-
bundleR: currentBundle,
|
|
2208
|
-
thresholds: options.compare.thresholds,
|
|
2209
|
-
scenarios: options.compare.scenarios,
|
|
2210
|
-
datasets: options.compare.datasets
|
|
2211
|
-
};
|
|
2200
|
+
if (withDiffs.length > 1) {
|
|
2201
|
+
if (withDiffs[0].group.kind === "by-dataset") {
|
|
2202
|
+
withDiffs = sortDatasetGroupSummaries(withDiffs);
|
|
2203
|
+
} else if (withDiffs[0].group.kind === "by-scenario") {
|
|
2204
|
+
withDiffs = sortScenarioGroupSummaries(withDiffs);
|
|
2205
|
+
}
|
|
2212
2206
|
}
|
|
2213
|
-
const checkConfig = {
|
|
2214
|
-
bundle: currentBundle,
|
|
2215
|
-
tests: options.check.tests
|
|
2216
|
-
};
|
|
2217
2207
|
return {
|
|
2218
|
-
|
|
2219
|
-
|
|
2208
|
+
allGroupSummaries,
|
|
2209
|
+
withErrors,
|
|
2210
|
+
onlyInLeft,
|
|
2211
|
+
onlyInRight,
|
|
2212
|
+
withDiffs,
|
|
2213
|
+
withoutDiffs
|
|
2220
2214
|
};
|
|
2221
2215
|
}
|
|
2222
|
-
|
|
2223
|
-
const
|
|
2224
|
-
const
|
|
2216
|
+
function getScoresForGroup(group, thresholds) {
|
|
2217
|
+
const diffCountByBucket = Array(thresholds.length + 2).fill(0);
|
|
2218
|
+
const totalMaxDiffByBucket = Array(thresholds.length + 2).fill(0);
|
|
2219
|
+
let totalDiffCount = 0;
|
|
2220
|
+
for (const testSummary of group.testSummaries) {
|
|
2221
|
+
const bucketIndex = getBucketIndex(testSummary.md, thresholds);
|
|
2222
|
+
diffCountByBucket[bucketIndex]++;
|
|
2223
|
+
totalMaxDiffByBucket[bucketIndex] += testSummary.md;
|
|
2224
|
+
totalDiffCount++;
|
|
2225
|
+
}
|
|
2226
|
+
let diffPercentByBucket;
|
|
2227
|
+
if (totalDiffCount > 0) {
|
|
2228
|
+
diffPercentByBucket = diffCountByBucket.map((count) => count / totalDiffCount * 100);
|
|
2229
|
+
} else {
|
|
2230
|
+
diffPercentByBucket = [];
|
|
2231
|
+
}
|
|
2225
2232
|
return {
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2233
|
+
totalDiffCount,
|
|
2234
|
+
totalMaxDiffByBucket,
|
|
2235
|
+
diffCountByBucket,
|
|
2236
|
+
diffPercentByBucket
|
|
2229
2237
|
};
|
|
2230
2238
|
}
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
var
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2239
|
+
function sortDatasetGroupSummaries(summaries) {
|
|
2240
|
+
return summaries.sort((a, b) => {
|
|
2241
|
+
var _a, _b;
|
|
2242
|
+
const scoreResult = compareScores(a.scores, b.scores);
|
|
2243
|
+
if (scoreResult !== 0) {
|
|
2244
|
+
return -scoreResult;
|
|
2245
|
+
} else {
|
|
2246
|
+
const aVar = a.root.outputVarL;
|
|
2247
|
+
const bVar = b.root.outputVarR;
|
|
2248
|
+
const aSource = ((_a = aVar.sourceName) == null ? void 0 : _a.toLowerCase()) || "";
|
|
2249
|
+
const bSource = ((_b = bVar.sourceName) == null ? void 0 : _b.toLowerCase()) || "";
|
|
2250
|
+
if (aSource !== bSource) {
|
|
2251
|
+
return aSource.localeCompare(bSource);
|
|
2252
|
+
} else {
|
|
2253
|
+
const aName = aVar.varName.toLowerCase();
|
|
2254
|
+
const bName = bVar.varName.toLowerCase();
|
|
2255
|
+
return aName.localeCompare(bName);
|
|
2256
|
+
}
|
|
2244
2257
|
}
|
|
2245
|
-
|
|
2246
|
-
|
|
2258
|
+
});
|
|
2259
|
+
}
|
|
2260
|
+
function sortScenarioGroupSummaries(summaries) {
|
|
2261
|
+
return summaries.sort((a, b) => {
|
|
2262
|
+
var _a, _b;
|
|
2263
|
+
const scoreResult = compareScores(a.scores, b.scores);
|
|
2264
|
+
if (scoreResult !== 0) {
|
|
2265
|
+
return -scoreResult;
|
|
2266
|
+
} else {
|
|
2267
|
+
const aScenario = a.root;
|
|
2268
|
+
const bScenario = b.root;
|
|
2269
|
+
const aTitle = aScenario.title.toLowerCase();
|
|
2270
|
+
const bTitle = bScenario.title.toLowerCase();
|
|
2271
|
+
if (aTitle !== bTitle) {
|
|
2272
|
+
return aTitle.localeCompare(bTitle);
|
|
2273
|
+
} else {
|
|
2274
|
+
const aSubtitle = ((_a = aScenario.subtitle) == null ? void 0 : _a.toLowerCase()) || "";
|
|
2275
|
+
const bSubtitle = ((_b = bScenario.subtitle) == null ? void 0 : _b.toLowerCase()) || "";
|
|
2276
|
+
return aSubtitle.localeCompare(bSubtitle);
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
});
|
|
2280
|
+
}
|
|
2281
|
+
function compareScores(a, b) {
|
|
2282
|
+
if (a.totalMaxDiffByBucket.length !== b.totalMaxDiffByBucket.length) {
|
|
2283
|
+
return 0;
|
|
2284
|
+
}
|
|
2285
|
+
const len = a.totalMaxDiffByBucket.length;
|
|
2286
|
+
for (let i = len - 1; i >= 0; i--) {
|
|
2287
|
+
const aTotal = a.totalMaxDiffByBucket[i];
|
|
2288
|
+
const bTotal = b.totalMaxDiffByBucket[i];
|
|
2289
|
+
if (aTotal > bTotal) {
|
|
2290
|
+
return 1;
|
|
2291
|
+
} else if (aTotal < bTotal) {
|
|
2292
|
+
return -1;
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
return 0;
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2298
|
+
// src/bundle/model-inputs.ts
|
|
2299
|
+
var ModelInputs = class {
|
|
2300
|
+
constructor(modelSpec) {
|
|
2301
|
+
this.inputsByLookupName = /* @__PURE__ */ new Map();
|
|
2302
|
+
this.inputIdAliases = /* @__PURE__ */ new Set();
|
|
2303
|
+
for (const inputVar of modelSpec.inputVars.values()) {
|
|
2304
|
+
const varNameKey = inputVar.varName.toLowerCase();
|
|
2305
|
+
this.inputsByLookupName.set(varNameKey, inputVar);
|
|
2306
|
+
if (inputVar.inputId) {
|
|
2307
|
+
const idAlias = `id ${inputVar.inputId}`;
|
|
2308
|
+
this.inputIdAliases.add(idAlias);
|
|
2309
|
+
const idKey = idAlias.toLowerCase();
|
|
2310
|
+
this.inputsByLookupName.set(idKey, inputVar);
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
if (modelSpec.inputAliases) {
|
|
2314
|
+
for (const [alias, varId] of modelSpec.inputAliases.entries()) {
|
|
2315
|
+
const aliasKey = alias.toLowerCase();
|
|
2316
|
+
if (this.inputsByLookupName.has(aliasKey)) {
|
|
2317
|
+
console.warn(
|
|
2318
|
+
`WARNING: Input variable already defined with a name that collides with alias '${alias}', skipping`
|
|
2319
|
+
);
|
|
2320
|
+
continue;
|
|
2321
|
+
}
|
|
2322
|
+
const inputVar = modelSpec.inputVars.get(varId);
|
|
2323
|
+
if (inputVar === void 0) {
|
|
2324
|
+
console.warn(`WARNING: No input variable found for '${varId}' associated with alias '${alias}', skipping`);
|
|
2325
|
+
continue;
|
|
2326
|
+
}
|
|
2327
|
+
this.inputsByLookupName.set(aliasKey, inputVar);
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
getAllInputIdAliases() {
|
|
2332
|
+
return [...this.inputIdAliases];
|
|
2333
|
+
}
|
|
2334
|
+
getInputVarForName(name) {
|
|
2335
|
+
return this.inputsByLookupName.get(name.toLowerCase());
|
|
2336
|
+
}
|
|
2337
|
+
};
|
|
2338
|
+
|
|
2339
|
+
// src/comparison/config/parse/comparison-parser.ts
|
|
2340
|
+
var import_ajv2 = __toESM(require("ajv"), 1);
|
|
2341
|
+
var import_assert_never9 = __toESM(require("assert-never"), 1);
|
|
2342
|
+
var import_neverthrow2 = require("neverthrow");
|
|
2343
|
+
var import_yaml2 = __toESM(require("yaml"), 1);
|
|
2344
|
+
|
|
2345
|
+
// src/comparison/config/parse/comparison.schema.js
|
|
2346
|
+
var comparison_schema_default = {
|
|
2347
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
2348
|
+
title: "Model Comparison Test",
|
|
2349
|
+
type: "array",
|
|
2350
|
+
description: "A group of model comparison scenarios and views.",
|
|
2351
|
+
items: {
|
|
2352
|
+
$ref: "#/$defs/top_level_array_item"
|
|
2353
|
+
},
|
|
2354
|
+
$defs: {
|
|
2355
|
+
top_level_array_item: {
|
|
2356
|
+
oneOf: [
|
|
2357
|
+
{ $ref: "#/$defs/scenario_array_item" },
|
|
2358
|
+
{ $ref: "#/$defs/scenario_group_array_item" },
|
|
2359
|
+
{ $ref: "#/$defs/view_group_array_item" }
|
|
2360
|
+
]
|
|
2361
|
+
},
|
|
2362
|
+
scenario_array_item: {
|
|
2363
|
+
type: "object",
|
|
2364
|
+
additionalProperties: false,
|
|
2365
|
+
properties: {
|
|
2366
|
+
scenario: {
|
|
2367
|
+
$ref: "#/$defs/scenario"
|
|
2368
|
+
}
|
|
2369
|
+
},
|
|
2370
|
+
required: ["scenario"]
|
|
2371
|
+
},
|
|
2372
|
+
scenario: {
|
|
2373
|
+
oneOf: [
|
|
2374
|
+
{ $ref: "#/$defs/scenario_with_input_at_position" },
|
|
2375
|
+
{ $ref: "#/$defs/scenario_with_input_at_value" },
|
|
2376
|
+
{ $ref: "#/$defs/scenario_with_multiple_input_settings" },
|
|
2377
|
+
{ $ref: "#/$defs/scenario_with_inputs_in_preset_at_position" },
|
|
2378
|
+
{ $ref: "#/$defs/scenario_preset" }
|
|
2379
|
+
]
|
|
2380
|
+
},
|
|
2381
|
+
scenario_position: {
|
|
2382
|
+
type: "string",
|
|
2383
|
+
enum: ["min", "max", "default"]
|
|
2384
|
+
},
|
|
2385
|
+
scenario_with_input_at_position: {
|
|
2386
|
+
type: "object",
|
|
2387
|
+
additionalProperties: false,
|
|
2388
|
+
properties: {
|
|
2389
|
+
id: {
|
|
2390
|
+
type: "string"
|
|
2391
|
+
},
|
|
2392
|
+
title: {
|
|
2393
|
+
type: "string"
|
|
2394
|
+
},
|
|
2395
|
+
subtitle: {
|
|
2396
|
+
type: "string"
|
|
2397
|
+
},
|
|
2398
|
+
with: {
|
|
2399
|
+
type: "string"
|
|
2400
|
+
},
|
|
2401
|
+
at: {
|
|
2402
|
+
$ref: "#/$defs/scenario_position"
|
|
2403
|
+
}
|
|
2404
|
+
},
|
|
2405
|
+
required: ["with", "at"]
|
|
2406
|
+
},
|
|
2407
|
+
scenario_with_input_at_value: {
|
|
2408
|
+
type: "object",
|
|
2409
|
+
additionalProperties: false,
|
|
2410
|
+
properties: {
|
|
2411
|
+
id: {
|
|
2412
|
+
type: "string"
|
|
2413
|
+
},
|
|
2414
|
+
title: {
|
|
2415
|
+
type: "string"
|
|
2416
|
+
},
|
|
2417
|
+
subtitle: {
|
|
2418
|
+
type: "string"
|
|
2419
|
+
},
|
|
2420
|
+
with: {
|
|
2421
|
+
type: "string"
|
|
2422
|
+
},
|
|
2423
|
+
at: {
|
|
2424
|
+
type: "number"
|
|
2425
|
+
}
|
|
2426
|
+
},
|
|
2427
|
+
required: ["with", "at"]
|
|
2428
|
+
},
|
|
2429
|
+
scenario_input_at_position: {
|
|
2430
|
+
type: "object",
|
|
2431
|
+
additionalProperties: false,
|
|
2432
|
+
properties: {
|
|
2433
|
+
input: {
|
|
2434
|
+
type: "string"
|
|
2435
|
+
},
|
|
2436
|
+
at: {
|
|
2437
|
+
$ref: "#/$defs/scenario_position"
|
|
2438
|
+
}
|
|
2439
|
+
},
|
|
2440
|
+
required: ["input", "at"]
|
|
2441
|
+
},
|
|
2442
|
+
scenario_input_at_value: {
|
|
2443
|
+
type: "object",
|
|
2444
|
+
additionalProperties: false,
|
|
2445
|
+
properties: {
|
|
2446
|
+
input: {
|
|
2447
|
+
type: "string"
|
|
2448
|
+
},
|
|
2449
|
+
at: {
|
|
2450
|
+
type: "number"
|
|
2451
|
+
}
|
|
2452
|
+
},
|
|
2453
|
+
required: ["input", "at"]
|
|
2454
|
+
},
|
|
2455
|
+
scenario_input_setting: {
|
|
2456
|
+
oneOf: [{ $ref: "#/$defs/scenario_input_at_position" }, { $ref: "#/$defs/scenario_input_at_value" }]
|
|
2457
|
+
},
|
|
2458
|
+
scenario_input_setting_array: {
|
|
2459
|
+
type: "array",
|
|
2460
|
+
items: {
|
|
2461
|
+
$ref: "#/$defs/scenario_input_setting"
|
|
2462
|
+
},
|
|
2463
|
+
minItems: 1
|
|
2464
|
+
},
|
|
2465
|
+
scenario_with_multiple_input_settings: {
|
|
2466
|
+
type: "object",
|
|
2467
|
+
additionalProperties: false,
|
|
2468
|
+
properties: {
|
|
2469
|
+
id: {
|
|
2470
|
+
type: "string"
|
|
2471
|
+
},
|
|
2472
|
+
title: {
|
|
2473
|
+
type: "string"
|
|
2474
|
+
},
|
|
2475
|
+
subtitle: {
|
|
2476
|
+
type: "string"
|
|
2477
|
+
},
|
|
2478
|
+
with: {
|
|
2479
|
+
$ref: "#/$defs/scenario_input_setting_array"
|
|
2480
|
+
}
|
|
2481
|
+
},
|
|
2482
|
+
required: ["with"]
|
|
2483
|
+
},
|
|
2484
|
+
scenario_with_inputs_in_preset_at_position: {
|
|
2485
|
+
type: "object",
|
|
2486
|
+
additionalProperties: false,
|
|
2487
|
+
properties: {
|
|
2488
|
+
id: {
|
|
2489
|
+
type: "string"
|
|
2490
|
+
},
|
|
2491
|
+
title: {
|
|
2492
|
+
type: "string"
|
|
2493
|
+
},
|
|
2494
|
+
subtitle: {
|
|
2495
|
+
type: "string"
|
|
2496
|
+
},
|
|
2497
|
+
with_inputs: {
|
|
2498
|
+
type: "string",
|
|
2499
|
+
enum: ["all"]
|
|
2500
|
+
},
|
|
2501
|
+
at: {
|
|
2502
|
+
$ref: "#/$defs/scenario_position"
|
|
2503
|
+
}
|
|
2504
|
+
},
|
|
2505
|
+
required: ["with_inputs", "at"]
|
|
2506
|
+
},
|
|
2507
|
+
scenario_preset: {
|
|
2508
|
+
type: "object",
|
|
2509
|
+
additionalProperties: false,
|
|
2510
|
+
properties: {
|
|
2511
|
+
preset: {
|
|
2512
|
+
type: "string",
|
|
2513
|
+
enum: ["matrix"]
|
|
2514
|
+
}
|
|
2515
|
+
},
|
|
2516
|
+
required: ["preset"]
|
|
2517
|
+
},
|
|
2518
|
+
scenario_group_array_item: {
|
|
2519
|
+
type: "object",
|
|
2520
|
+
additionalProperties: false,
|
|
2521
|
+
properties: {
|
|
2522
|
+
scenario_group: {
|
|
2523
|
+
$ref: "#/$defs/scenario_group"
|
|
2524
|
+
}
|
|
2525
|
+
},
|
|
2526
|
+
required: ["scenario_group"]
|
|
2527
|
+
},
|
|
2528
|
+
scenario_group: {
|
|
2529
|
+
type: "object",
|
|
2530
|
+
additionalProperties: false,
|
|
2531
|
+
properties: {
|
|
2532
|
+
id: {
|
|
2533
|
+
type: "string"
|
|
2534
|
+
},
|
|
2535
|
+
title: {
|
|
2536
|
+
type: "string"
|
|
2537
|
+
},
|
|
2538
|
+
scenarios: {
|
|
2539
|
+
type: "array",
|
|
2540
|
+
items: {
|
|
2541
|
+
$ref: "#/$defs/scenario_group_scenarios_array_item"
|
|
2542
|
+
},
|
|
2543
|
+
minItems: 1
|
|
2544
|
+
}
|
|
2545
|
+
},
|
|
2546
|
+
required: ["title", "scenarios"]
|
|
2547
|
+
},
|
|
2548
|
+
scenario_group_scenarios_array_item: {
|
|
2549
|
+
oneOf: [{ $ref: "#/$defs/scenario_array_item" }, { $ref: "#/$defs/scenario_ref_array_item" }]
|
|
2550
|
+
},
|
|
2551
|
+
scenario_ref_id: {
|
|
2552
|
+
type: "string"
|
|
2553
|
+
},
|
|
2554
|
+
scenario_ref_object: {
|
|
2555
|
+
type: "object",
|
|
2556
|
+
additionalProperties: false,
|
|
2557
|
+
properties: {
|
|
2558
|
+
id: {
|
|
2559
|
+
type: "string"
|
|
2560
|
+
},
|
|
2561
|
+
title: {
|
|
2562
|
+
type: "string"
|
|
2563
|
+
},
|
|
2564
|
+
subtitle: {
|
|
2565
|
+
type: "string"
|
|
2566
|
+
}
|
|
2567
|
+
},
|
|
2568
|
+
required: ["id"]
|
|
2569
|
+
},
|
|
2570
|
+
scenario_ref: {
|
|
2571
|
+
oneOf: [{ $ref: "#/$defs/scenario_ref_id" }, { $ref: "#/$defs/scenario_ref_object" }]
|
|
2572
|
+
},
|
|
2573
|
+
scenario_ref_array_item: {
|
|
2574
|
+
type: "object",
|
|
2575
|
+
additionalProperties: false,
|
|
2576
|
+
properties: {
|
|
2577
|
+
scenario_ref: {
|
|
2578
|
+
$ref: "#/$defs/scenario_ref"
|
|
2579
|
+
}
|
|
2580
|
+
},
|
|
2581
|
+
required: ["scenario_ref"]
|
|
2582
|
+
},
|
|
2583
|
+
scenario_group_ref: {
|
|
2584
|
+
type: "object",
|
|
2585
|
+
additionalProperties: false,
|
|
2586
|
+
properties: {
|
|
2587
|
+
scenario_group_ref: {
|
|
2588
|
+
type: "string"
|
|
2589
|
+
}
|
|
2590
|
+
},
|
|
2591
|
+
required: ["scenario_group_ref"]
|
|
2592
|
+
},
|
|
2593
|
+
view: {
|
|
2594
|
+
type: "object",
|
|
2595
|
+
additionalProperties: false,
|
|
2596
|
+
properties: {
|
|
2597
|
+
title: {
|
|
2598
|
+
type: "string"
|
|
2599
|
+
},
|
|
2600
|
+
subtitle: {
|
|
2601
|
+
type: "string"
|
|
2602
|
+
},
|
|
2603
|
+
scenario_ref: {
|
|
2604
|
+
type: "string"
|
|
2605
|
+
},
|
|
2606
|
+
graphs: {
|
|
2607
|
+
$ref: "#/$defs/view_graphs"
|
|
2608
|
+
}
|
|
2609
|
+
},
|
|
2610
|
+
required: ["scenario_ref", "graphs"]
|
|
2611
|
+
},
|
|
2612
|
+
view_graphs: {
|
|
2613
|
+
oneOf: [{ $ref: "#/$defs/view_graphs_preset" }, { $ref: "#/$defs/view_graphs_array" }]
|
|
2614
|
+
},
|
|
2615
|
+
view_graphs_preset: {
|
|
2616
|
+
type: "string",
|
|
2617
|
+
enum: ["all"]
|
|
2618
|
+
},
|
|
2619
|
+
view_graphs_array: {
|
|
2620
|
+
type: "array",
|
|
2621
|
+
items: {
|
|
2622
|
+
type: "string"
|
|
2623
|
+
},
|
|
2624
|
+
minItems: 1
|
|
2625
|
+
},
|
|
2626
|
+
view_group_array_item: {
|
|
2627
|
+
type: "object",
|
|
2628
|
+
additionalProperties: false,
|
|
2629
|
+
properties: {
|
|
2630
|
+
view_group: {
|
|
2631
|
+
$ref: "#/$defs/view_group"
|
|
2632
|
+
}
|
|
2633
|
+
},
|
|
2634
|
+
required: ["view_group"]
|
|
2635
|
+
},
|
|
2636
|
+
view_group: {
|
|
2637
|
+
oneOf: [
|
|
2638
|
+
{ $ref: "#/$defs/view_group_with_views_array" },
|
|
2639
|
+
{ $ref: "#/$defs/view_group_shorthand_with_scenarios_array" }
|
|
2640
|
+
]
|
|
2641
|
+
},
|
|
2642
|
+
view_group_with_views_array: {
|
|
2643
|
+
type: "object",
|
|
2644
|
+
additionalProperties: false,
|
|
2645
|
+
properties: {
|
|
2646
|
+
title: {
|
|
2647
|
+
type: "string"
|
|
2648
|
+
},
|
|
2649
|
+
views: {
|
|
2650
|
+
type: "array",
|
|
2651
|
+
items: {
|
|
2652
|
+
$ref: "#/$defs/view_group_views_array_item"
|
|
2653
|
+
},
|
|
2654
|
+
minItems: 1
|
|
2655
|
+
}
|
|
2656
|
+
},
|
|
2657
|
+
required: ["title", "views"]
|
|
2658
|
+
},
|
|
2659
|
+
view_group_views_array_item: {
|
|
2660
|
+
type: "object",
|
|
2661
|
+
additionalProperties: false,
|
|
2662
|
+
properties: {
|
|
2663
|
+
view: {
|
|
2664
|
+
$ref: "#/$defs/view"
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
},
|
|
2668
|
+
view_group_shorthand_with_scenarios_array: {
|
|
2669
|
+
type: "object",
|
|
2670
|
+
additionalProperties: false,
|
|
2671
|
+
properties: {
|
|
2672
|
+
title: {
|
|
2673
|
+
type: "string"
|
|
2674
|
+
},
|
|
2675
|
+
scenarios: {
|
|
2676
|
+
type: "array",
|
|
2677
|
+
items: {
|
|
2678
|
+
$ref: "#/$defs/view_group_scenarios_array_item"
|
|
2679
|
+
},
|
|
2680
|
+
minItems: 1
|
|
2681
|
+
},
|
|
2682
|
+
graphs: {
|
|
2683
|
+
$ref: "#/$defs/view_graphs"
|
|
2684
|
+
}
|
|
2685
|
+
},
|
|
2686
|
+
required: ["title", "scenarios", "graphs"]
|
|
2687
|
+
},
|
|
2688
|
+
view_group_scenarios_array_item: {
|
|
2689
|
+
oneOf: [{ $ref: "#/$defs/scenario_ref_array_item" }, { $ref: "#/$defs/scenario_group_ref" }]
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
};
|
|
2693
|
+
|
|
2694
|
+
// src/comparison/config/parse/comparison-parser.ts
|
|
2695
|
+
function parseComparisonSpecs(specSource) {
|
|
2696
|
+
const scenarios = [];
|
|
2697
|
+
const scenarioGroups = [];
|
|
2698
|
+
const viewGroups = [];
|
|
2699
|
+
const ajv = new import_ajv2.default();
|
|
2700
|
+
const validate = ajv.compile(comparison_schema_default);
|
|
2701
|
+
let parsed;
|
|
2702
|
+
switch (specSource.kind) {
|
|
2703
|
+
case "json":
|
|
2704
|
+
parsed = JSON.parse(specSource.content);
|
|
2705
|
+
break;
|
|
2706
|
+
case "yaml":
|
|
2707
|
+
parsed = import_yaml2.default.parse(specSource.content);
|
|
2708
|
+
break;
|
|
2709
|
+
default:
|
|
2710
|
+
(0, import_assert_never9.default)(specSource.kind);
|
|
2711
|
+
}
|
|
2712
|
+
if (validate(parsed)) {
|
|
2713
|
+
for (const specItem of parsed) {
|
|
2714
|
+
if ("scenario" in specItem) {
|
|
2715
|
+
scenarios.push(scenarioSpecFromParsed(specItem.scenario));
|
|
2716
|
+
} else if ("scenario_group" in specItem) {
|
|
2717
|
+
scenarioGroups.push(scenarioGroupSpecFromParsed(specItem.scenario_group));
|
|
2718
|
+
} else if ("view_group" in specItem) {
|
|
2719
|
+
viewGroups.push(viewGroupSpecFromParsed(specItem.view_group));
|
|
2720
|
+
}
|
|
2721
|
+
}
|
|
2722
|
+
} else {
|
|
2723
|
+
let msg = "Failed to parse YAML comparison definitions";
|
|
2724
|
+
for (const error of validate.errors || []) {
|
|
2725
|
+
if (error.message) {
|
|
2726
|
+
msg += `
|
|
2727
|
+
${error.message}`;
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
return (0, import_neverthrow2.err)(new Error(msg));
|
|
2731
|
+
}
|
|
2732
|
+
return (0, import_neverthrow2.ok)({
|
|
2733
|
+
scenarios,
|
|
2734
|
+
scenarioGroups,
|
|
2735
|
+
viewGroups
|
|
2736
|
+
});
|
|
2737
|
+
}
|
|
2738
|
+
function scenarioSpecFromParsed(parsedScenario) {
|
|
2739
|
+
if (parsedScenario.preset === "matrix") {
|
|
2740
|
+
return {
|
|
2741
|
+
kind: "scenario-matrix"
|
|
2742
|
+
};
|
|
2743
|
+
}
|
|
2744
|
+
if (parsedScenario.with !== void 0) {
|
|
2745
|
+
let inputSpecs;
|
|
2746
|
+
if (Array.isArray(parsedScenario.with)) {
|
|
2747
|
+
const parsedInputs = parsedScenario.with;
|
|
2748
|
+
inputSpecs = parsedInputs.map(inputSpecFromParsed);
|
|
2749
|
+
} else {
|
|
2750
|
+
inputSpecs = [
|
|
2751
|
+
inputSpecFromParsed({
|
|
2752
|
+
input: parsedScenario.with,
|
|
2753
|
+
at: parsedScenario.at
|
|
2754
|
+
})
|
|
2755
|
+
];
|
|
2756
|
+
}
|
|
2757
|
+
return {
|
|
2758
|
+
kind: "scenario-with-inputs",
|
|
2759
|
+
id: parsedScenario.id,
|
|
2760
|
+
title: parsedScenario.title,
|
|
2761
|
+
subtitle: parsedScenario.subtitle,
|
|
2762
|
+
inputs: inputSpecs
|
|
2763
|
+
};
|
|
2764
|
+
}
|
|
2765
|
+
if (parsedScenario.with_inputs === "all") {
|
|
2766
|
+
return {
|
|
2767
|
+
kind: "scenario-with-all-inputs",
|
|
2768
|
+
id: parsedScenario.id,
|
|
2769
|
+
title: parsedScenario.title,
|
|
2770
|
+
subtitle: parsedScenario.subtitle,
|
|
2771
|
+
position: parsedScenario.at
|
|
2772
|
+
};
|
|
2773
|
+
}
|
|
2774
|
+
throw new Error(`Unable to convert parsed scenario: ${JSON.stringify(parsedScenario)}`);
|
|
2775
|
+
}
|
|
2776
|
+
function inputSpecFromParsed(parsedInput) {
|
|
2777
|
+
if (typeof parsedInput.at === "number") {
|
|
2778
|
+
const value = parsedInput.at;
|
|
2779
|
+
return {
|
|
2780
|
+
kind: "input-at-value",
|
|
2781
|
+
inputName: parsedInput.input,
|
|
2782
|
+
value
|
|
2783
|
+
};
|
|
2784
|
+
} else {
|
|
2785
|
+
return {
|
|
2786
|
+
kind: "input-at-position",
|
|
2787
|
+
inputName: parsedInput.input,
|
|
2788
|
+
position: parsedInput.at
|
|
2789
|
+
};
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
function scenarioGroupSpecFromParsed(parsedScenarioGroup) {
|
|
2793
|
+
const scenarioSpecs = parsedScenarioGroup.scenarios.map(
|
|
2794
|
+
(parsedScenarioOrRef) => {
|
|
2795
|
+
if ("scenario_ref" in parsedScenarioOrRef) {
|
|
2796
|
+
return scenarioRefSpecFromParsed(parsedScenarioOrRef);
|
|
2797
|
+
} else {
|
|
2798
|
+
return scenarioSpecFromParsed(parsedScenarioOrRef.scenario);
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
);
|
|
2802
|
+
return {
|
|
2803
|
+
kind: "scenario-group",
|
|
2804
|
+
id: parsedScenarioGroup.id,
|
|
2805
|
+
title: parsedScenarioGroup.title,
|
|
2806
|
+
scenarios: scenarioSpecs
|
|
2807
|
+
};
|
|
2808
|
+
}
|
|
2809
|
+
function scenarioRefSpecFromParsed(parsedScenarioRef) {
|
|
2810
|
+
if (typeof parsedScenarioRef.scenario_ref === "string") {
|
|
2811
|
+
return {
|
|
2812
|
+
kind: "scenario-ref",
|
|
2813
|
+
scenarioId: parsedScenarioRef.scenario_ref
|
|
2814
|
+
};
|
|
2815
|
+
} else {
|
|
2816
|
+
return {
|
|
2817
|
+
kind: "scenario-ref",
|
|
2818
|
+
scenarioId: parsedScenarioRef.scenario_ref.id,
|
|
2819
|
+
title: parsedScenarioRef.scenario_ref.title,
|
|
2820
|
+
subtitle: parsedScenarioRef.scenario_ref.subtitle
|
|
2821
|
+
};
|
|
2822
|
+
}
|
|
2823
|
+
}
|
|
2824
|
+
function scenarioGroupRefSpecFromParsed(parsedGroupRef) {
|
|
2825
|
+
return {
|
|
2826
|
+
kind: "scenario-group-ref",
|
|
2827
|
+
groupId: parsedGroupRef.scenario_group_ref
|
|
2828
|
+
};
|
|
2829
|
+
}
|
|
2830
|
+
function viewSpecFromParsed(parsedView) {
|
|
2831
|
+
return {
|
|
2832
|
+
kind: "view",
|
|
2833
|
+
title: parsedView.title,
|
|
2834
|
+
subtitle: parsedView.subtitle,
|
|
2835
|
+
scenarioId: parsedView.scenario_ref,
|
|
2836
|
+
graphs: viewGraphsSpecFromParsed(parsedView.graphs)
|
|
2837
|
+
};
|
|
2838
|
+
}
|
|
2839
|
+
function viewGraphsSpecFromParsed(parsedGraphs) {
|
|
2840
|
+
if (parsedGraphs === "all") {
|
|
2841
|
+
return {
|
|
2842
|
+
kind: "graphs-preset",
|
|
2843
|
+
preset: "all"
|
|
2844
|
+
};
|
|
2845
|
+
} else {
|
|
2846
|
+
return {
|
|
2847
|
+
kind: "graphs-array",
|
|
2848
|
+
graphIds: parsedGraphs
|
|
2849
|
+
};
|
|
2850
|
+
}
|
|
2851
|
+
}
|
|
2852
|
+
function viewGroupSpecFromParsed(parsedViewGroup) {
|
|
2853
|
+
if (parsedViewGroup.views !== void 0) {
|
|
2854
|
+
return {
|
|
2855
|
+
kind: "view-group-with-views",
|
|
2856
|
+
title: parsedViewGroup.title,
|
|
2857
|
+
views: parsedViewGroup.views.map((item) => viewSpecFromParsed(item.view))
|
|
2858
|
+
};
|
|
2859
|
+
} else if (parsedViewGroup.scenarios !== void 0) {
|
|
2860
|
+
const scenarios = parsedViewGroup.scenarios.map(
|
|
2861
|
+
(parsedScenarioOrGroupRef) => {
|
|
2862
|
+
if ("scenario_ref" in parsedScenarioOrGroupRef) {
|
|
2863
|
+
return scenarioRefSpecFromParsed(parsedScenarioOrGroupRef);
|
|
2864
|
+
} else if ("scenario_group_ref" in parsedScenarioOrGroupRef) {
|
|
2865
|
+
return scenarioGroupRefSpecFromParsed(parsedScenarioOrGroupRef);
|
|
2866
|
+
} else {
|
|
2867
|
+
throw new Error("Invalid view group");
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
);
|
|
2871
|
+
return {
|
|
2872
|
+
kind: "view-group-with-scenarios",
|
|
2873
|
+
title: parsedViewGroup.title,
|
|
2874
|
+
scenarios,
|
|
2875
|
+
graphs: viewGraphsSpecFromParsed(parsedViewGroup.graphs)
|
|
2876
|
+
};
|
|
2877
|
+
} else {
|
|
2878
|
+
throw new Error("Invalid view group");
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2882
|
+
// src/comparison/config/resolve/comparison-resolver.ts
|
|
2883
|
+
var import_assert_never11 = require("assert-never");
|
|
2884
|
+
|
|
2885
|
+
// src/comparison/config/resolve/comparison-scenario-specs.ts
|
|
2886
|
+
var import_assert_never10 = require("assert-never");
|
|
2887
|
+
function scenarioSpecsFromSettings(settings) {
|
|
2888
|
+
switch (settings.kind) {
|
|
2889
|
+
case "all-inputs-settings": {
|
|
2890
|
+
const scenario = allInputsAtPositionSpec(settings.position);
|
|
2891
|
+
return [scenario, scenario];
|
|
2892
|
+
}
|
|
2893
|
+
case "input-settings": {
|
|
2894
|
+
const specL = scenarioSpecFromInputs(settings.inputs, "left");
|
|
2895
|
+
const specR = scenarioSpecFromInputs(settings.inputs, "right");
|
|
2896
|
+
return [specL, specR];
|
|
2897
|
+
}
|
|
2898
|
+
default:
|
|
2899
|
+
(0, import_assert_never10.assertNever)(settings);
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
function scenarioSpecFromInputs(inputs, side) {
|
|
2903
|
+
const settings = [];
|
|
2904
|
+
for (const input of inputs) {
|
|
2905
|
+
const state = side === "left" ? input.stateL : input.stateR;
|
|
2906
|
+
if (state.inputVar === void 0) {
|
|
2907
|
+
return void 0;
|
|
2908
|
+
}
|
|
2909
|
+
const varId = state.inputVar.varId;
|
|
2910
|
+
if (state.position) {
|
|
2911
|
+
settings.push(positionSetting(varId, state.position));
|
|
2912
|
+
} else {
|
|
2913
|
+
settings.push(valueSetting(varId, state.value));
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
return inputSettingsSpec(settings);
|
|
2917
|
+
}
|
|
2918
|
+
|
|
2919
|
+
// src/comparison/config/resolve/comparison-resolver.ts
|
|
2920
|
+
function resolveComparisonSpecs(modelInputsL, modelInputsR, specs) {
|
|
2921
|
+
let key = 1;
|
|
2922
|
+
const genKey = () => {
|
|
2923
|
+
return `${key++}`;
|
|
2924
|
+
};
|
|
2925
|
+
const resolvedScenarios = new ResolvedScenarios();
|
|
2926
|
+
for (const scenarioSpec of specs.scenarios) {
|
|
2927
|
+
resolvedScenarios.add(resolveScenariosFromSpec(modelInputsL, modelInputsR, scenarioSpec, genKey));
|
|
2928
|
+
}
|
|
2929
|
+
const partiallyResolvedScenarioGroups = [];
|
|
2930
|
+
for (const scenarioGroupSpec of specs.scenarioGroups) {
|
|
2931
|
+
const scenariosForGroup = [];
|
|
2932
|
+
for (const scenarioItem of scenarioGroupSpec.scenarios) {
|
|
2933
|
+
if (scenarioItem.kind === "scenario-ref") {
|
|
2934
|
+
scenariosForGroup.push(scenarioItem);
|
|
2935
|
+
} else {
|
|
2936
|
+
const scenarios = resolveScenariosFromSpec(modelInputsL, modelInputsR, scenarioItem, genKey);
|
|
2937
|
+
resolvedScenarios.add(scenarios);
|
|
2938
|
+
scenariosForGroup.push(...scenarios);
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
partiallyResolvedScenarioGroups.push({
|
|
2942
|
+
spec: scenarioGroupSpec,
|
|
2943
|
+
scenarios: scenariosForGroup
|
|
2944
|
+
});
|
|
2945
|
+
}
|
|
2946
|
+
const resolvedScenarioGroups = new ResolvedScenarioGroups();
|
|
2947
|
+
for (const partiallyResolvedGroup of partiallyResolvedScenarioGroups) {
|
|
2948
|
+
const scenariosForGroup = [];
|
|
2949
|
+
for (const scenarioItem of partiallyResolvedGroup.scenarios) {
|
|
2950
|
+
if (scenarioItem.kind === "scenario-ref") {
|
|
2951
|
+
const referencedScenario = resolvedScenarios.getScenarioForId(scenarioItem.scenarioId);
|
|
2952
|
+
if (referencedScenario) {
|
|
2953
|
+
const resolvedScenario = { ...referencedScenario };
|
|
2954
|
+
if (scenarioItem.title) {
|
|
2955
|
+
resolvedScenario.title = scenarioItem.title;
|
|
2956
|
+
}
|
|
2957
|
+
if (scenarioItem.subtitle) {
|
|
2958
|
+
resolvedScenario.subtitle = scenarioItem.subtitle;
|
|
2959
|
+
}
|
|
2960
|
+
scenariosForGroup.push(resolvedScenario);
|
|
2961
|
+
} else {
|
|
2962
|
+
scenariosForGroup.push({
|
|
2963
|
+
kind: "unresolved-scenario-ref",
|
|
2964
|
+
scenarioId: scenarioItem.scenarioId
|
|
2965
|
+
});
|
|
2966
|
+
}
|
|
2967
|
+
} else {
|
|
2968
|
+
scenariosForGroup.push(scenarioItem);
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2971
|
+
resolvedScenarioGroups.add({
|
|
2972
|
+
kind: "scenario-group",
|
|
2973
|
+
id: partiallyResolvedGroup.spec.id,
|
|
2974
|
+
title: partiallyResolvedGroup.spec.title,
|
|
2975
|
+
scenarios: scenariosForGroup
|
|
2976
|
+
});
|
|
2977
|
+
}
|
|
2978
|
+
const resolvedViewGroups = [];
|
|
2979
|
+
for (const viewGroupSpec of specs.viewGroups) {
|
|
2980
|
+
const resolvedViewGroup = resolveViewGroupFromSpec(resolvedScenarios, resolvedScenarioGroups, viewGroupSpec);
|
|
2981
|
+
resolvedViewGroups.push(resolvedViewGroup);
|
|
2982
|
+
}
|
|
2983
|
+
return {
|
|
2984
|
+
scenarios: resolvedScenarios.getAll(),
|
|
2985
|
+
scenarioGroups: resolvedScenarioGroups.getAll(),
|
|
2986
|
+
viewGroups: resolvedViewGroups
|
|
2987
|
+
};
|
|
2988
|
+
}
|
|
2989
|
+
var ResolvedScenarios = class {
|
|
2990
|
+
constructor() {
|
|
2991
|
+
this.resolvedScenarios = [];
|
|
2992
|
+
this.resolvedScenariosById = /* @__PURE__ */ new Map();
|
|
2993
|
+
}
|
|
2994
|
+
add(scenarios) {
|
|
2995
|
+
for (const resolvedScenario of scenarios) {
|
|
2996
|
+
this.resolvedScenarios.push(resolvedScenario);
|
|
2997
|
+
if (resolvedScenario.id !== void 0) {
|
|
2998
|
+
if (this.resolvedScenariosById.has(resolvedScenario.id)) {
|
|
2999
|
+
throw new Error(`Multiple scenarios defined with the same id (${resolvedScenario.id})`);
|
|
3000
|
+
}
|
|
3001
|
+
this.resolvedScenariosById.set(resolvedScenario.id, resolvedScenario);
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
}
|
|
3005
|
+
getAll() {
|
|
3006
|
+
return this.resolvedScenarios;
|
|
3007
|
+
}
|
|
3008
|
+
getScenarioForId(id) {
|
|
3009
|
+
return this.resolvedScenariosById.get(id);
|
|
3010
|
+
}
|
|
3011
|
+
};
|
|
3012
|
+
function resolveScenariosFromSpec(modelInputsL, modelInputsR, scenarioSpec, genKey) {
|
|
3013
|
+
switch (scenarioSpec.kind) {
|
|
3014
|
+
case "scenario-matrix":
|
|
3015
|
+
return resolveScenarioMatrix(modelInputsL, modelInputsR, genKey);
|
|
3016
|
+
case "scenario-with-all-inputs": {
|
|
3017
|
+
const position = inputPosition2(scenarioSpec.position);
|
|
3018
|
+
return [
|
|
3019
|
+
resolveScenarioWithAllInputsAtPosition(
|
|
3020
|
+
genKey(),
|
|
3021
|
+
scenarioSpec.id,
|
|
3022
|
+
scenarioSpec.title,
|
|
3023
|
+
scenarioSpec.subtitle,
|
|
3024
|
+
position
|
|
3025
|
+
)
|
|
3026
|
+
];
|
|
3027
|
+
}
|
|
3028
|
+
case "scenario-with-inputs": {
|
|
3029
|
+
return [
|
|
3030
|
+
resolveScenarioForInputSpecs(
|
|
3031
|
+
modelInputsL,
|
|
3032
|
+
modelInputsR,
|
|
3033
|
+
genKey(),
|
|
3034
|
+
scenarioSpec.id,
|
|
3035
|
+
scenarioSpec.title,
|
|
3036
|
+
scenarioSpec.subtitle,
|
|
3037
|
+
scenarioSpec.inputs
|
|
3038
|
+
)
|
|
3039
|
+
];
|
|
3040
|
+
}
|
|
3041
|
+
default:
|
|
3042
|
+
(0, import_assert_never11.assertNever)(scenarioSpec);
|
|
3043
|
+
}
|
|
3044
|
+
}
|
|
3045
|
+
function resolveScenarioMatrix(modelInputsL, modelInputsR, genKey) {
|
|
3046
|
+
const resolvedScenarios = [];
|
|
3047
|
+
resolvedScenarios.push(
|
|
3048
|
+
resolveScenarioWithAllInputsAtPosition(genKey(), void 0, void 0, void 0, "at-default")
|
|
3049
|
+
);
|
|
3050
|
+
const inputIdAliases = /* @__PURE__ */ new Set();
|
|
3051
|
+
modelInputsL.getAllInputIdAliases().forEach((alias) => inputIdAliases.add(alias));
|
|
3052
|
+
modelInputsR.getAllInputIdAliases().forEach((alias) => inputIdAliases.add(alias));
|
|
3053
|
+
for (const inputIdAlias of inputIdAliases) {
|
|
3054
|
+
const inputAtMin = {
|
|
3055
|
+
kind: "input-at-position",
|
|
3056
|
+
inputName: inputIdAlias,
|
|
3057
|
+
position: "min"
|
|
3058
|
+
};
|
|
3059
|
+
const inputAtMax = {
|
|
3060
|
+
kind: "input-at-position",
|
|
3061
|
+
inputName: inputIdAlias,
|
|
3062
|
+
position: "max"
|
|
3063
|
+
};
|
|
3064
|
+
resolvedScenarios.push(
|
|
3065
|
+
resolveScenarioForInputSpecs(modelInputsL, modelInputsR, genKey(), void 0, void 0, void 0, [inputAtMin])
|
|
3066
|
+
);
|
|
3067
|
+
resolvedScenarios.push(
|
|
3068
|
+
resolveScenarioForInputSpecs(modelInputsL, modelInputsR, genKey(), void 0, void 0, void 0, [inputAtMax])
|
|
3069
|
+
);
|
|
3070
|
+
}
|
|
3071
|
+
return resolvedScenarios;
|
|
3072
|
+
}
|
|
3073
|
+
function resolveScenarioWithAllInputsAtPosition(key, id, title, subtitle, position) {
|
|
3074
|
+
const settings = {
|
|
3075
|
+
kind: "all-inputs-settings",
|
|
3076
|
+
position
|
|
3077
|
+
};
|
|
3078
|
+
const [specL, specR] = scenarioSpecsFromSettings(settings);
|
|
3079
|
+
return {
|
|
3080
|
+
kind: "scenario",
|
|
3081
|
+
key,
|
|
3082
|
+
id,
|
|
3083
|
+
title,
|
|
3084
|
+
subtitle,
|
|
3085
|
+
settings,
|
|
3086
|
+
specL,
|
|
3087
|
+
specR
|
|
3088
|
+
};
|
|
3089
|
+
}
|
|
3090
|
+
function resolveScenarioForInputSpecs(modelInputsL, modelInputsR, key, id, title, subtitle, inputSpecs) {
|
|
3091
|
+
const resolvedInputs = inputSpecs.map((inputSpec) => {
|
|
3092
|
+
switch (inputSpec.kind) {
|
|
3093
|
+
case "input-at-position":
|
|
3094
|
+
return resolveInputForName(modelInputsL, modelInputsR, inputSpec.inputName, inputSpec.position);
|
|
3095
|
+
case "input-at-value":
|
|
3096
|
+
return resolveInputForName(modelInputsL, modelInputsR, inputSpec.inputName, inputSpec.value);
|
|
3097
|
+
default:
|
|
3098
|
+
(0, import_assert_never11.assertNever)(inputSpec);
|
|
3099
|
+
}
|
|
3100
|
+
});
|
|
3101
|
+
const settings = {
|
|
3102
|
+
kind: "input-settings",
|
|
3103
|
+
inputs: resolvedInputs
|
|
3104
|
+
};
|
|
3105
|
+
const [specL, specR] = scenarioSpecsFromSettings(settings);
|
|
3106
|
+
return {
|
|
3107
|
+
kind: "scenario",
|
|
3108
|
+
key,
|
|
3109
|
+
id,
|
|
3110
|
+
title,
|
|
3111
|
+
subtitle,
|
|
3112
|
+
settings,
|
|
3113
|
+
specL,
|
|
3114
|
+
specR
|
|
3115
|
+
};
|
|
3116
|
+
}
|
|
3117
|
+
function resolveInputForName(modelInputsL, modelInputsR, inputName, at) {
|
|
3118
|
+
return {
|
|
3119
|
+
requestedName: inputName,
|
|
3120
|
+
stateL: resolveInputForNameInModel(modelInputsL, inputName, at),
|
|
3121
|
+
stateR: resolveInputForNameInModel(modelInputsR, inputName, at)
|
|
3122
|
+
};
|
|
3123
|
+
}
|
|
3124
|
+
function resolveInputForNameInModel(modelInputs, inputName, at) {
|
|
3125
|
+
const inputVar = modelInputs.getInputVarForName(inputName);
|
|
3126
|
+
if (inputVar) {
|
|
3127
|
+
return resolveInputVar(inputVar, at);
|
|
3128
|
+
} else {
|
|
3129
|
+
return {
|
|
3130
|
+
error: {
|
|
3131
|
+
kind: "unknown-input"
|
|
3132
|
+
}
|
|
3133
|
+
};
|
|
3134
|
+
}
|
|
3135
|
+
}
|
|
3136
|
+
function resolveInputVar(inputVar, at) {
|
|
3137
|
+
if (typeof at === "number") {
|
|
3138
|
+
const value = at;
|
|
3139
|
+
return resolveInputVarAtValue(inputVar, value);
|
|
3140
|
+
} else {
|
|
3141
|
+
const position = inputPosition2(at);
|
|
3142
|
+
return resolveInputVarAtPosition(inputVar, position);
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
3145
|
+
function resolveInputVarAtPosition(inputVar, position) {
|
|
3146
|
+
return {
|
|
3147
|
+
inputVar,
|
|
3148
|
+
position,
|
|
3149
|
+
value: inputValueAtPosition2(inputVar, position)
|
|
3150
|
+
};
|
|
3151
|
+
}
|
|
3152
|
+
function resolveInputVarAtValue(inputVar, value) {
|
|
3153
|
+
if (value >= inputVar.minValue && value <= inputVar.maxValue) {
|
|
3154
|
+
return {
|
|
3155
|
+
inputVar,
|
|
3156
|
+
value
|
|
3157
|
+
};
|
|
3158
|
+
} else {
|
|
3159
|
+
return {
|
|
3160
|
+
error: {
|
|
3161
|
+
kind: "invalid-value"
|
|
3162
|
+
}
|
|
3163
|
+
};
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
function inputPosition2(position) {
|
|
3167
|
+
switch (position) {
|
|
3168
|
+
case "default":
|
|
3169
|
+
return "at-default";
|
|
3170
|
+
case "min":
|
|
3171
|
+
return "at-minimum";
|
|
3172
|
+
case "max":
|
|
3173
|
+
return "at-maximum";
|
|
3174
|
+
default:
|
|
3175
|
+
return void 0;
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
function inputValueAtPosition2(inputVar, position) {
|
|
3179
|
+
switch (position) {
|
|
3180
|
+
case "at-default":
|
|
3181
|
+
return inputVar.defaultValue;
|
|
3182
|
+
case "at-minimum":
|
|
3183
|
+
return inputVar.minValue;
|
|
3184
|
+
case "at-maximum":
|
|
3185
|
+
return inputVar.maxValue;
|
|
3186
|
+
default:
|
|
3187
|
+
(0, import_assert_never11.assertNever)(position);
|
|
3188
|
+
}
|
|
3189
|
+
}
|
|
3190
|
+
var ResolvedScenarioGroups = class {
|
|
3191
|
+
constructor() {
|
|
3192
|
+
this.resolvedGroups = [];
|
|
3193
|
+
this.resolvedGroupsById = /* @__PURE__ */ new Map();
|
|
3194
|
+
}
|
|
3195
|
+
add(group) {
|
|
3196
|
+
this.resolvedGroups.push(group);
|
|
3197
|
+
if (group.id !== void 0) {
|
|
3198
|
+
if (this.resolvedGroupsById.has(group.id)) {
|
|
3199
|
+
throw new Error(`Multiple scenario groups defined with the same id (${group.id})`);
|
|
3200
|
+
}
|
|
3201
|
+
this.resolvedGroupsById.set(group.id, group);
|
|
3202
|
+
}
|
|
3203
|
+
}
|
|
3204
|
+
getAll() {
|
|
3205
|
+
return this.resolvedGroups;
|
|
3206
|
+
}
|
|
3207
|
+
getGroupForId(id) {
|
|
3208
|
+
return this.resolvedGroupsById.get(id);
|
|
3209
|
+
}
|
|
3210
|
+
};
|
|
3211
|
+
function resolveGraphsFromSpec(graphsSpec) {
|
|
3212
|
+
switch (graphsSpec.kind) {
|
|
3213
|
+
case "graphs-preset":
|
|
3214
|
+
return "all";
|
|
3215
|
+
case "graphs-array":
|
|
3216
|
+
return graphsSpec.graphIds;
|
|
3217
|
+
default:
|
|
3218
|
+
(0, import_assert_never11.assertNever)(graphsSpec);
|
|
3219
|
+
}
|
|
3220
|
+
}
|
|
3221
|
+
function resolveViewForScenarioId(resolvedScenarios, viewTitle, viewSubtitle, scenarioId, graphs) {
|
|
3222
|
+
const resolvedScenario = resolvedScenarios.getScenarioForId(scenarioId);
|
|
3223
|
+
if (resolvedScenario) {
|
|
3224
|
+
return resolveViewForScenario(viewTitle, viewSubtitle, resolvedScenario, graphs);
|
|
3225
|
+
} else {
|
|
3226
|
+
return unresolvedViewForScenarioId(viewTitle, viewSubtitle, scenarioId);
|
|
3227
|
+
}
|
|
3228
|
+
}
|
|
3229
|
+
function resolveViewForScenarioRefSpec(resolvedScenarios, refSpec, graphs) {
|
|
3230
|
+
const resolvedScenario = resolvedScenarios.getScenarioForId(refSpec.scenarioId);
|
|
3231
|
+
if (resolvedScenario) {
|
|
3232
|
+
return resolveViewForScenario(refSpec.title, refSpec.subtitle, resolvedScenario, graphs);
|
|
3233
|
+
} else {
|
|
3234
|
+
return unresolvedViewForScenarioId(void 0, void 0, refSpec.scenarioId);
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
function resolveViewForScenario(viewTitle, viewSubtitle, resolvedScenario, graphs) {
|
|
3238
|
+
if (viewTitle === void 0) {
|
|
3239
|
+
viewTitle = resolvedScenario.title;
|
|
3240
|
+
if (viewTitle === void 0) {
|
|
3241
|
+
viewTitle = "Untitled view";
|
|
3242
|
+
}
|
|
3243
|
+
if (viewSubtitle === void 0) {
|
|
3244
|
+
viewSubtitle = resolvedScenario.subtitle;
|
|
3245
|
+
}
|
|
3246
|
+
}
|
|
3247
|
+
return {
|
|
3248
|
+
kind: "view",
|
|
3249
|
+
title: viewTitle,
|
|
3250
|
+
subtitle: viewSubtitle,
|
|
3251
|
+
scenario: resolvedScenario,
|
|
3252
|
+
graphs
|
|
3253
|
+
};
|
|
3254
|
+
}
|
|
3255
|
+
function unresolvedViewForScenarioId(viewTitle, viewSubtitle, scenarioId) {
|
|
3256
|
+
return {
|
|
3257
|
+
kind: "unresolved-view",
|
|
3258
|
+
title: viewTitle,
|
|
3259
|
+
subtitle: viewSubtitle,
|
|
3260
|
+
scenarioId
|
|
3261
|
+
};
|
|
3262
|
+
}
|
|
3263
|
+
function unresolvedViewForScenarioGroupId(viewTitle, viewSubtitle, scenarioGroupId) {
|
|
3264
|
+
return {
|
|
3265
|
+
kind: "unresolved-view",
|
|
3266
|
+
title: viewTitle,
|
|
3267
|
+
subtitle: viewSubtitle,
|
|
3268
|
+
scenarioGroupId
|
|
3269
|
+
};
|
|
3270
|
+
}
|
|
3271
|
+
function resolveViewGroupFromSpec(resolvedScenarios, resolvedScenarioGroups, viewGroupSpec) {
|
|
3272
|
+
let views;
|
|
3273
|
+
switch (viewGroupSpec.kind) {
|
|
3274
|
+
case "view-group-with-views": {
|
|
3275
|
+
views = viewGroupSpec.views.map((viewSpec) => {
|
|
3276
|
+
const graphs = resolveGraphsFromSpec(viewSpec.graphs);
|
|
3277
|
+
return resolveViewForScenarioId(
|
|
3278
|
+
resolvedScenarios,
|
|
3279
|
+
viewSpec.title,
|
|
3280
|
+
viewSpec.subtitle,
|
|
3281
|
+
viewSpec.scenarioId,
|
|
3282
|
+
graphs
|
|
3283
|
+
);
|
|
3284
|
+
});
|
|
3285
|
+
break;
|
|
3286
|
+
}
|
|
3287
|
+
case "view-group-with-scenarios": {
|
|
3288
|
+
const graphs = resolveGraphsFromSpec(viewGroupSpec.graphs);
|
|
3289
|
+
views = [];
|
|
3290
|
+
for (const refSpec of viewGroupSpec.scenarios) {
|
|
3291
|
+
switch (refSpec.kind) {
|
|
3292
|
+
case "scenario-ref":
|
|
3293
|
+
views.push(resolveViewForScenarioRefSpec(resolvedScenarios, refSpec, graphs));
|
|
3294
|
+
break;
|
|
3295
|
+
case "scenario-group-ref": {
|
|
3296
|
+
const resolvedGroup = resolvedScenarioGroups.getGroupForId(refSpec.groupId);
|
|
3297
|
+
if (resolvedGroup) {
|
|
3298
|
+
for (const scenario of resolvedGroup.scenarios) {
|
|
3299
|
+
switch (scenario.kind) {
|
|
3300
|
+
case "unresolved-scenario-ref":
|
|
3301
|
+
views.push(unresolvedViewForScenarioId(void 0, void 0, scenario.scenarioId));
|
|
3302
|
+
break;
|
|
3303
|
+
case "scenario":
|
|
3304
|
+
views.push(resolveViewForScenario(void 0, void 0, scenario, graphs));
|
|
3305
|
+
break;
|
|
3306
|
+
default:
|
|
3307
|
+
(0, import_assert_never11.assertNever)(scenario);
|
|
3308
|
+
}
|
|
3309
|
+
}
|
|
3310
|
+
} else {
|
|
3311
|
+
views.push(unresolvedViewForScenarioGroupId(void 0, void 0, refSpec.groupId));
|
|
3312
|
+
}
|
|
3313
|
+
break;
|
|
3314
|
+
}
|
|
3315
|
+
default:
|
|
3316
|
+
(0, import_assert_never11.assertNever)(refSpec);
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
break;
|
|
3320
|
+
}
|
|
3321
|
+
default:
|
|
3322
|
+
(0, import_assert_never11.assertNever)(viewGroupSpec);
|
|
3323
|
+
}
|
|
3324
|
+
return {
|
|
3325
|
+
kind: "view-group",
|
|
3326
|
+
title: viewGroupSpec.title,
|
|
3327
|
+
views
|
|
3328
|
+
};
|
|
3329
|
+
}
|
|
3330
|
+
|
|
3331
|
+
// src/comparison/config/comparison-config.ts
|
|
3332
|
+
function resolveComparisonSpecsFromSources(modelInputsL, modelInputsR, specSources) {
|
|
3333
|
+
const combinedSpecs = {
|
|
3334
|
+
scenarios: [],
|
|
3335
|
+
scenarioGroups: [],
|
|
3336
|
+
viewGroups: []
|
|
3337
|
+
};
|
|
3338
|
+
for (const specSource of specSources) {
|
|
3339
|
+
let specs;
|
|
3340
|
+
if ("kind" in specSource) {
|
|
3341
|
+
const parseResult = parseComparisonSpecs(specSource);
|
|
3342
|
+
if (parseResult.isOk()) {
|
|
3343
|
+
specs = parseResult.value;
|
|
3344
|
+
} else {
|
|
3345
|
+
const filenamePart = specSource.filename ? ` in ${specSource.filename}` : "";
|
|
3346
|
+
console.error(`ERROR: Failed to parse comparison spec${filenamePart}, skipping`);
|
|
3347
|
+
continue;
|
|
3348
|
+
}
|
|
3349
|
+
} else {
|
|
3350
|
+
specs = specSource;
|
|
3351
|
+
}
|
|
3352
|
+
combinedSpecs.scenarios.push(...specs.scenarios);
|
|
3353
|
+
combinedSpecs.scenarioGroups.push(...specs.scenarioGroups);
|
|
3354
|
+
combinedSpecs.viewGroups.push(...specs.viewGroups);
|
|
3355
|
+
}
|
|
3356
|
+
return resolveComparisonSpecs(modelInputsL, modelInputsR, combinedSpecs);
|
|
3357
|
+
}
|
|
3358
|
+
|
|
3359
|
+
// src/comparison/config/comparison-datasets.ts
|
|
3360
|
+
function getComparisonDatasets(modelSpecL, modelSpecR, datasetOptions) {
|
|
3361
|
+
return new ComparisonDatasetsImpl(modelSpecL, modelSpecR, datasetOptions);
|
|
3362
|
+
}
|
|
3363
|
+
var ComparisonDatasetsImpl = class {
|
|
3364
|
+
constructor(modelSpecL, modelSpecR, datasetOptions) {
|
|
3365
|
+
this.datasetOptions = datasetOptions;
|
|
3366
|
+
const renamedDatasetKeys = datasetOptions == null ? void 0 : datasetOptions.renamedDatasetKeys;
|
|
3367
|
+
const invertedRenamedKeys = /* @__PURE__ */ new Map();
|
|
3368
|
+
renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.forEach((newKey, oldKey) => {
|
|
3369
|
+
invertedRenamedKeys.set(newKey, oldKey);
|
|
3370
|
+
});
|
|
3371
|
+
function leftKeyForRightKey(rightKey) {
|
|
3372
|
+
return invertedRenamedKeys.get(rightKey) || rightKey;
|
|
3373
|
+
}
|
|
3374
|
+
const allOutputVarKeysSet = /* @__PURE__ */ new Set();
|
|
3375
|
+
const modelOutputVarKeysSet = /* @__PURE__ */ new Set();
|
|
2247
3376
|
function addOutputVars(outputVars, handleRenames) {
|
|
2248
3377
|
outputVars.forEach((outputVar, key) => {
|
|
2249
3378
|
const remappedKey = handleRenames ? leftKeyForRightKey(key) : key;
|
|
@@ -2253,239 +3382,193 @@ var DatasetManager = class {
|
|
|
2253
3382
|
}
|
|
2254
3383
|
});
|
|
2255
3384
|
}
|
|
2256
|
-
addOutputVars(
|
|
2257
|
-
addOutputVars(
|
|
3385
|
+
addOutputVars(modelSpecL.outputVars, false);
|
|
3386
|
+
addOutputVars(modelSpecR.outputVars, true);
|
|
2258
3387
|
this.allOutputVarKeys = Array.from(allOutputVarKeysSet);
|
|
2259
3388
|
this.modelOutputVarKeys = Array.from(modelOutputVarKeysSet);
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
3389
|
+
this.allDatasets = /* @__PURE__ */ new Map();
|
|
3390
|
+
for (const datasetKeyL of this.allOutputVarKeys) {
|
|
3391
|
+
const datasetKeyR = (renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.get(datasetKeyL)) || datasetKeyL;
|
|
3392
|
+
const outputVarL = modelSpecL.outputVars.get(datasetKeyL);
|
|
3393
|
+
const outputVarR = modelSpecR.outputVars.get(datasetKeyR);
|
|
3394
|
+
this.allDatasets.set(datasetKeyL, {
|
|
3395
|
+
kind: "dataset",
|
|
3396
|
+
key: datasetKeyL,
|
|
3397
|
+
outputVarL,
|
|
3398
|
+
outputVarR
|
|
3399
|
+
});
|
|
2266
3400
|
}
|
|
2267
3401
|
}
|
|
2268
|
-
|
|
3402
|
+
getAllDatasets() {
|
|
3403
|
+
return this.allDatasets.values();
|
|
3404
|
+
}
|
|
3405
|
+
getDataset(datasetKey) {
|
|
3406
|
+
return this.allDatasets.get(datasetKey);
|
|
3407
|
+
}
|
|
3408
|
+
getDatasetKeysForScenario(scenario) {
|
|
2269
3409
|
var _a;
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
const datasetKeyL = datasetKey;
|
|
2273
|
-
const datasetKeyR = ((_a = this.renamedDatasetKeys) == null ? void 0 : _a.get(datasetKeyL)) || datasetKeyL;
|
|
2274
|
-
const outputVarL = modelSpecL.outputVars.get(datasetKeyL);
|
|
2275
|
-
const outputVarR = modelSpecR.outputVars.get(datasetKeyR);
|
|
2276
|
-
let varName;
|
|
2277
|
-
let newVarName;
|
|
2278
|
-
let sourceName;
|
|
2279
|
-
let newSourceName;
|
|
2280
|
-
if (outputVarL && outputVarR && outputVarL.varName != outputVarR.varName) {
|
|
2281
|
-
varName = outputVarL.varName;
|
|
2282
|
-
newVarName = outputVarR.varName;
|
|
2283
|
-
} else {
|
|
2284
|
-
const outputVar = outputVarR || outputVarL;
|
|
2285
|
-
varName = (outputVar == null ? void 0 : outputVar.varName) || "Unknown";
|
|
2286
|
-
}
|
|
2287
|
-
if (outputVarL && outputVarR && outputVarL.sourceName != outputVarR.sourceName) {
|
|
2288
|
-
sourceName = outputVarL.sourceName;
|
|
2289
|
-
newSourceName = outputVarR.sourceName;
|
|
3410
|
+
if (((_a = this.datasetOptions) == null ? void 0 : _a.datasetKeysForScenario) !== void 0) {
|
|
3411
|
+
return this.datasetOptions.datasetKeysForScenario(this.allOutputVarKeys, scenario);
|
|
2290
3412
|
} else {
|
|
2291
|
-
|
|
2292
|
-
|
|
3413
|
+
if (scenario.settings.kind === "all-inputs-settings" && scenario.settings.position === "at-default") {
|
|
3414
|
+
return this.allOutputVarKeys;
|
|
3415
|
+
} else {
|
|
3416
|
+
return this.modelOutputVarKeys;
|
|
3417
|
+
}
|
|
2293
3418
|
}
|
|
2294
|
-
return {
|
|
2295
|
-
varName,
|
|
2296
|
-
newVarName,
|
|
2297
|
-
sourceName,
|
|
2298
|
-
newSourceName,
|
|
2299
|
-
relatedItems: (outputVarR == null ? void 0 : outputVarR.relatedItems) || []
|
|
2300
|
-
};
|
|
2301
3419
|
}
|
|
2302
3420
|
};
|
|
2303
3421
|
|
|
2304
|
-
// src/config/
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
this.
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
this.groupInfo = /* @__PURE__ */ new Map();
|
|
2314
|
-
}
|
|
2315
|
-
getScenarios() {
|
|
2316
|
-
return [...this.scenarios.values()];
|
|
2317
|
-
}
|
|
2318
|
-
getScenario(scenarioKey) {
|
|
2319
|
-
return this.scenarios.get(scenarioKey);
|
|
2320
|
-
}
|
|
2321
|
-
getScenarioGroupInfo(groupKey) {
|
|
2322
|
-
return this.groupInfo.get(groupKey);
|
|
2323
|
-
}
|
|
2324
|
-
getScenarioInfo(scenario, groupKey) {
|
|
2325
|
-
if (scenario.key === "all_inputs_at_default") {
|
|
2326
|
-
const defaultInfo = this.defaultInfoForGroup.get(groupKey);
|
|
2327
|
-
if (defaultInfo) {
|
|
2328
|
-
return defaultInfo;
|
|
2329
|
-
}
|
|
2330
|
-
}
|
|
2331
|
-
return this.scenarioInfo.get(scenario.key);
|
|
2332
|
-
}
|
|
2333
|
-
setDefaultScenarioInfoForGroup(groupKey, scenarioInfo) {
|
|
2334
|
-
this.defaultInfoForGroup.set(groupKey, scenarioInfo);
|
|
2335
|
-
}
|
|
2336
|
-
addScenario(scenario, scenarioInfo, groupInfo) {
|
|
2337
|
-
this.scenarios.set(scenario.key, scenario);
|
|
2338
|
-
if (!scenarioInfo) {
|
|
2339
|
-
scenarioInfo = this.getInfoForScenario(scenario);
|
|
2340
|
-
}
|
|
2341
|
-
this.scenarioInfo.set(scenario.key, scenarioInfo);
|
|
2342
|
-
if (!groupInfo) {
|
|
2343
|
-
groupInfo = this.getGroupInfoForScenario(scenario);
|
|
2344
|
-
}
|
|
2345
|
-
this.groupInfo.set(scenario.groupKey, groupInfo);
|
|
2346
|
-
}
|
|
2347
|
-
addScenarioMatrix() {
|
|
2348
|
-
const inputVarIdsL = Array.from(this.bundleL.modelSpec.inputVars.keys());
|
|
2349
|
-
const inputVarIdsR = Array.from(this.bundleR.modelSpec.inputVars.keys());
|
|
2350
|
-
const inputVarIds = /* @__PURE__ */ new Set([...inputVarIdsL, ...inputVarIdsR]);
|
|
2351
|
-
this.addScenario(allInputsAtPositionScenario("at-default"));
|
|
2352
|
-
this.addScenario(allInputsAtPositionScenario("at-minimum"));
|
|
2353
|
-
this.addScenario(allInputsAtPositionScenario("at-maximum"));
|
|
2354
|
-
for (const inputVarId of inputVarIds) {
|
|
2355
|
-
this.addScenario(inputAtPositionScenario(inputVarId, inputVarId, "at-minimum"));
|
|
2356
|
-
this.addScenario(inputAtPositionScenario(inputVarId, inputVarId, "at-maximum"));
|
|
2357
|
-
}
|
|
2358
|
-
}
|
|
2359
|
-
getGroupInfoForScenario(scenario) {
|
|
2360
|
-
switch (scenario.kind) {
|
|
2361
|
-
case "all-inputs":
|
|
2362
|
-
return {
|
|
2363
|
-
title: "All Inputs",
|
|
2364
|
-
relatedItems: []
|
|
2365
|
-
};
|
|
2366
|
-
case "settings":
|
|
2367
|
-
if (scenario.settings.length === 1) {
|
|
2368
|
-
const inputVar = this.getInputVarForSetting(scenario.settings[0]);
|
|
2369
|
-
let relatedItems;
|
|
2370
|
-
let subtitle;
|
|
2371
|
-
if (inputVar == null ? void 0 : inputVar.relatedItem) {
|
|
2372
|
-
relatedItems = [inputVar.relatedItem];
|
|
2373
|
-
subtitle = inputVar.relatedItem.locationPath.join(' <span class="related-sep">></span> ');
|
|
2374
|
-
} else {
|
|
2375
|
-
relatedItems = [];
|
|
2376
|
-
subtitle = void 0;
|
|
2377
|
-
}
|
|
2378
|
-
return {
|
|
2379
|
-
title: (inputVar == null ? void 0 : inputVar.varName) || "Unknown Input",
|
|
2380
|
-
subtitle,
|
|
2381
|
-
relatedItems
|
|
2382
|
-
};
|
|
2383
|
-
} else {
|
|
2384
|
-
return {
|
|
2385
|
-
title: "Multiple Inputs",
|
|
2386
|
-
relatedItems: this.getRelatedItemsForSettings(scenario.settings)
|
|
2387
|
-
};
|
|
2388
|
-
}
|
|
2389
|
-
default:
|
|
2390
|
-
(0, import_assert_never8.assertNever)(scenario);
|
|
3422
|
+
// src/comparison/config/comparison-scenarios.ts
|
|
3423
|
+
function getComparisonScenarios(scenarios) {
|
|
3424
|
+
return new ComparisonScenariosImpl(scenarios);
|
|
3425
|
+
}
|
|
3426
|
+
var ComparisonScenariosImpl = class {
|
|
3427
|
+
constructor(scenarios) {
|
|
3428
|
+
this.scenarioDefs = /* @__PURE__ */ new Map();
|
|
3429
|
+
for (const scenario of scenarios) {
|
|
3430
|
+
this.scenarioDefs.set(scenario.key, scenario);
|
|
2391
3431
|
}
|
|
2392
3432
|
}
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
case "all-inputs":
|
|
2396
|
-
return this.getInfoForPositionSetting(void 0, scenario.position);
|
|
2397
|
-
case "settings":
|
|
2398
|
-
if (scenario.settings.length === 1 && scenario.settings[0].kind === "position") {
|
|
2399
|
-
const setting = scenario.settings[0];
|
|
2400
|
-
return this.getInfoForPositionSetting(setting.inputVarId, setting.position);
|
|
2401
|
-
} else {
|
|
2402
|
-
return {
|
|
2403
|
-
title: `PLACEHOLDER (scenario info not provided)`,
|
|
2404
|
-
position: 1
|
|
2405
|
-
};
|
|
2406
|
-
}
|
|
2407
|
-
default:
|
|
2408
|
-
(0, import_assert_never8.assertNever)(scenario);
|
|
2409
|
-
}
|
|
3433
|
+
getAllScenarios() {
|
|
3434
|
+
return this.scenarioDefs.values();
|
|
2410
3435
|
}
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
3436
|
+
getScenario(key) {
|
|
3437
|
+
return this.scenarioDefs.get(key);
|
|
3438
|
+
}
|
|
3439
|
+
};
|
|
3440
|
+
|
|
3441
|
+
// src/config/synchronized-model.ts
|
|
3442
|
+
function synchronizedBundleModel(sourceModel) {
|
|
3443
|
+
const promiseQueue = new PromiseQueue();
|
|
3444
|
+
return {
|
|
3445
|
+
modelSpec: sourceModel.modelSpec,
|
|
3446
|
+
getDatasetsForScenario: (scenarioSpec, datasetKeys) => {
|
|
3447
|
+
return promiseQueue.add(() => sourceModel.getDatasetsForScenario(scenarioSpec, datasetKeys));
|
|
3448
|
+
},
|
|
3449
|
+
getGraphDataForScenario: (scenarioSpec, graphId) => {
|
|
3450
|
+
return promiseQueue.add(() => sourceModel.getGraphDataForScenario(scenarioSpec, graphId));
|
|
3451
|
+
},
|
|
3452
|
+
getGraphLinksForScenario: sourceModel.getGraphLinksForScenario.bind(sourceModel)
|
|
3453
|
+
};
|
|
3454
|
+
}
|
|
3455
|
+
var PromiseQueue = class {
|
|
3456
|
+
constructor() {
|
|
3457
|
+
this.tasks = [];
|
|
3458
|
+
this.runningCount = 0;
|
|
3459
|
+
}
|
|
3460
|
+
add(f) {
|
|
3461
|
+
return new Promise((resolve, reject) => {
|
|
3462
|
+
const run = async () => {
|
|
3463
|
+
this.runningCount++;
|
|
3464
|
+
const promise = f();
|
|
3465
|
+
try {
|
|
3466
|
+
const result = await promise;
|
|
3467
|
+
resolve(result);
|
|
3468
|
+
} catch (e) {
|
|
3469
|
+
reject(e);
|
|
3470
|
+
} finally {
|
|
3471
|
+
this.runningCount--;
|
|
3472
|
+
this.runNext();
|
|
3473
|
+
}
|
|
3474
|
+
};
|
|
3475
|
+
if (this.runningCount < 1) {
|
|
3476
|
+
run();
|
|
2427
3477
|
} else {
|
|
2428
|
-
|
|
3478
|
+
this.tasks.push(run);
|
|
2429
3479
|
}
|
|
2430
|
-
}
|
|
2431
|
-
subtitle = void 0;
|
|
2432
|
-
}
|
|
2433
|
-
let position;
|
|
2434
|
-
switch (inputPosition2) {
|
|
2435
|
-
case "at-default":
|
|
2436
|
-
position = 0;
|
|
2437
|
-
break;
|
|
2438
|
-
case "at-minimum":
|
|
2439
|
-
position = 1;
|
|
2440
|
-
break;
|
|
2441
|
-
case "at-maximum":
|
|
2442
|
-
position = 2;
|
|
2443
|
-
break;
|
|
2444
|
-
default:
|
|
2445
|
-
(0, import_assert_never8.assertNever)(inputPosition2);
|
|
2446
|
-
}
|
|
2447
|
-
return {
|
|
2448
|
-
title,
|
|
2449
|
-
subtitle,
|
|
2450
|
-
position
|
|
2451
|
-
};
|
|
3480
|
+
});
|
|
2452
3481
|
}
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
relatedItems.push(inputVar.relatedItem);
|
|
3482
|
+
runNext() {
|
|
3483
|
+
if (this.tasks.length > 0) {
|
|
3484
|
+
const task = this.tasks.shift();
|
|
3485
|
+
if (task) {
|
|
3486
|
+
task();
|
|
2459
3487
|
}
|
|
2460
3488
|
}
|
|
2461
|
-
return relatedItems;
|
|
2462
|
-
}
|
|
2463
|
-
getInputVarForSetting(setting) {
|
|
2464
|
-
const inputVarId = setting.inputVarId;
|
|
2465
|
-
const inputVarL = this.bundleL.modelSpec.inputVars.get(inputVarId);
|
|
2466
|
-
const inputVarR = this.bundleR.modelSpec.inputVars.get(inputVarId);
|
|
2467
|
-
return inputVarR || inputVarL;
|
|
2468
3489
|
}
|
|
2469
3490
|
};
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
default:
|
|
2480
|
-
(0, import_assert_never8.assertNever)(position);
|
|
2481
|
-
}
|
|
3491
|
+
|
|
3492
|
+
// src/config/config.ts
|
|
3493
|
+
async function createConfig(options) {
|
|
3494
|
+
var _a;
|
|
3495
|
+
const origCurrentBundle = await loadSynchronized(options.current);
|
|
3496
|
+
let currentBundle;
|
|
3497
|
+
let comparisonConfig;
|
|
3498
|
+
if (options.comparison === void 0) {
|
|
3499
|
+
currentBundle = origCurrentBundle;
|
|
2482
3500
|
} else {
|
|
2483
|
-
|
|
3501
|
+
const baselineBundle = await loadSynchronized(options.comparison.baseline);
|
|
3502
|
+
const renamedDatasetKeys = (_a = options.comparison.datasets) == null ? void 0 : _a.renamedDatasetKeys;
|
|
3503
|
+
const invertedRenamedKeys = /* @__PURE__ */ new Map();
|
|
3504
|
+
renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.forEach((newKey, oldKey) => {
|
|
3505
|
+
invertedRenamedKeys.set(newKey, oldKey);
|
|
3506
|
+
});
|
|
3507
|
+
const rightKeyForLeftKey = (leftKey) => {
|
|
3508
|
+
return (renamedDatasetKeys == null ? void 0 : renamedDatasetKeys.get(leftKey)) || leftKey;
|
|
3509
|
+
};
|
|
3510
|
+
const leftKeyForRightKey = (rightKey) => {
|
|
3511
|
+
return invertedRenamedKeys.get(rightKey) || rightKey;
|
|
3512
|
+
};
|
|
3513
|
+
const origBundleModelR = origCurrentBundle.model;
|
|
3514
|
+
const adjBundleModelR = {
|
|
3515
|
+
modelSpec: origBundleModelR.modelSpec,
|
|
3516
|
+
getDatasetsForScenario: async (scenarioSpec, datasetKeys) => {
|
|
3517
|
+
const rightKeys = datasetKeys.map(rightKeyForLeftKey);
|
|
3518
|
+
const result = await origBundleModelR.getDatasetsForScenario(scenarioSpec, rightKeys);
|
|
3519
|
+
const mapWithRightKeys = result.datasetMap;
|
|
3520
|
+
const mapWithLeftKeys = /* @__PURE__ */ new Map();
|
|
3521
|
+
for (const [rightKey, dataset] of mapWithRightKeys.entries()) {
|
|
3522
|
+
const leftKey = leftKeyForRightKey(rightKey);
|
|
3523
|
+
mapWithLeftKeys.set(leftKey, dataset);
|
|
3524
|
+
}
|
|
3525
|
+
return {
|
|
3526
|
+
datasetMap: mapWithLeftKeys,
|
|
3527
|
+
modelRunTime: result.modelRunTime
|
|
3528
|
+
};
|
|
3529
|
+
},
|
|
3530
|
+
getGraphDataForScenario: origBundleModelR.getGraphDataForScenario.bind(origBundleModelR),
|
|
3531
|
+
getGraphLinksForScenario: origBundleModelR.getGraphLinksForScenario.bind(origBundleModelR)
|
|
3532
|
+
};
|
|
3533
|
+
currentBundle = {
|
|
3534
|
+
...origCurrentBundle,
|
|
3535
|
+
model: adjBundleModelR
|
|
3536
|
+
};
|
|
3537
|
+
const modelSpecL = baselineBundle.model.modelSpec;
|
|
3538
|
+
const modelSpecR = currentBundle.model.modelSpec;
|
|
3539
|
+
const modelInputsL = new ModelInputs(modelSpecL);
|
|
3540
|
+
const modelInputsR = new ModelInputs(modelSpecR);
|
|
3541
|
+
const comparisonDefs = resolveComparisonSpecsFromSources(modelInputsL, modelInputsR, options.comparison.specs);
|
|
3542
|
+
comparisonConfig = {
|
|
3543
|
+
bundleL: baselineBundle,
|
|
3544
|
+
bundleR: currentBundle,
|
|
3545
|
+
thresholds: options.comparison.thresholds,
|
|
3546
|
+
scenarios: getComparisonScenarios(comparisonDefs.scenarios),
|
|
3547
|
+
datasets: getComparisonDatasets(modelSpecL, modelSpecR, options.comparison.datasets),
|
|
3548
|
+
viewGroups: comparisonDefs.viewGroups
|
|
3549
|
+
};
|
|
2484
3550
|
}
|
|
3551
|
+
const checkConfig = {
|
|
3552
|
+
bundle: currentBundle,
|
|
3553
|
+
tests: options.check.tests
|
|
3554
|
+
};
|
|
3555
|
+
return {
|
|
3556
|
+
check: checkConfig,
|
|
3557
|
+
comparison: comparisonConfig
|
|
3558
|
+
};
|
|
3559
|
+
}
|
|
3560
|
+
async function loadSynchronized(sourceBundle) {
|
|
3561
|
+
const sourceModel = await sourceBundle.bundle.initModel();
|
|
3562
|
+
const synchronizedModel = synchronizedBundleModel(sourceModel);
|
|
3563
|
+
return {
|
|
3564
|
+
name: sourceBundle.name,
|
|
3565
|
+
version: sourceBundle.bundle.version,
|
|
3566
|
+
model: synchronizedModel
|
|
3567
|
+
};
|
|
2485
3568
|
}
|
|
2486
3569
|
|
|
2487
3570
|
// src/perf/perf-runner.ts
|
|
2488
|
-
var
|
|
3571
|
+
var import_assert_never12 = require("assert-never");
|
|
2489
3572
|
|
|
2490
3573
|
// src/perf/perf-stats.ts
|
|
2491
3574
|
var PerfStats = class {
|
|
@@ -2529,26 +3612,26 @@ var PerfRunner = class {
|
|
|
2529
3612
|
this.bundleModelL = bundleModelL;
|
|
2530
3613
|
this.bundleModelR = bundleModelR;
|
|
2531
3614
|
this.mode = mode;
|
|
2532
|
-
const
|
|
3615
|
+
const scenarioSpec = allInputsAtPositionSpec("at-default");
|
|
2533
3616
|
this.taskQueue = new TaskQueue({
|
|
2534
3617
|
process: async (request) => {
|
|
2535
3618
|
switch (request.kind) {
|
|
2536
3619
|
case "left": {
|
|
2537
|
-
const result = await bundleModelL.getDatasetsForScenario(
|
|
3620
|
+
const result = await bundleModelL.getDatasetsForScenario(scenarioSpec, []);
|
|
2538
3621
|
return {
|
|
2539
3622
|
runTimeL: result.modelRunTime
|
|
2540
3623
|
};
|
|
2541
3624
|
}
|
|
2542
3625
|
case "right": {
|
|
2543
|
-
const result = await bundleModelR.getDatasetsForScenario(
|
|
3626
|
+
const result = await bundleModelR.getDatasetsForScenario(scenarioSpec, []);
|
|
2544
3627
|
return {
|
|
2545
3628
|
runTimeR: result.modelRunTime
|
|
2546
3629
|
};
|
|
2547
3630
|
}
|
|
2548
3631
|
case "both": {
|
|
2549
3632
|
const [resultL, resultR] = await Promise.all([
|
|
2550
|
-
bundleModelL.getDatasetsForScenario(
|
|
2551
|
-
bundleModelR.getDatasetsForScenario(
|
|
3633
|
+
bundleModelL.getDatasetsForScenario(scenarioSpec, []),
|
|
3634
|
+
bundleModelR.getDatasetsForScenario(scenarioSpec, [])
|
|
2552
3635
|
]);
|
|
2553
3636
|
return {
|
|
2554
3637
|
runTimeL: resultL.modelRunTime,
|
|
@@ -2556,7 +3639,7 @@ var PerfRunner = class {
|
|
|
2556
3639
|
};
|
|
2557
3640
|
}
|
|
2558
3641
|
default:
|
|
2559
|
-
(0,
|
|
3642
|
+
(0, import_assert_never12.assertNever)(request.kind);
|
|
2560
3643
|
}
|
|
2561
3644
|
}
|
|
2562
3645
|
});
|
|
@@ -2604,46 +3687,126 @@ var PerfRunner = class {
|
|
|
2604
3687
|
}
|
|
2605
3688
|
};
|
|
2606
3689
|
|
|
2607
|
-
// src/suite/suite-runner.ts
|
|
2608
|
-
var import_assert_never10 = __toESM(require("assert-never"), 1);
|
|
2609
|
-
|
|
2610
3690
|
// src/data/data-planner.ts
|
|
2611
|
-
var
|
|
2612
|
-
constructor(
|
|
2613
|
-
this.
|
|
2614
|
-
this.
|
|
2615
|
-
this.
|
|
2616
|
-
this.
|
|
3691
|
+
var DataPlanner = class {
|
|
3692
|
+
constructor(batchSize) {
|
|
3693
|
+
this.batchSize = batchSize;
|
|
3694
|
+
this.taskSetsLR = /* @__PURE__ */ new Map();
|
|
3695
|
+
this.taskSetsL = /* @__PURE__ */ new Map();
|
|
3696
|
+
this.taskSetsR = /* @__PURE__ */ new Map();
|
|
3697
|
+
this.complete = false;
|
|
2617
3698
|
}
|
|
2618
|
-
|
|
2619
|
-
if (
|
|
2620
|
-
|
|
3699
|
+
addRequest(scenarioSpecL, scenarioSpecR, datasetKey, dataAction) {
|
|
3700
|
+
if (scenarioSpecL === void 0 && scenarioSpecR === void 0) {
|
|
3701
|
+
console.warn("WARNING: Both scenario specs are undefined for DataPlanner request, skipping");
|
|
3702
|
+
return;
|
|
3703
|
+
}
|
|
3704
|
+
let taskSetsMap;
|
|
3705
|
+
let uid;
|
|
3706
|
+
if (scenarioSpecL && scenarioSpecR) {
|
|
3707
|
+
taskSetsMap = this.taskSetsLR;
|
|
3708
|
+
uid = scenarioPairUid(scenarioSpecL, scenarioSpecR);
|
|
3709
|
+
} else if (scenarioSpecR) {
|
|
3710
|
+
taskSetsMap = this.taskSetsR;
|
|
3711
|
+
uid = scenarioSpecR.uid;
|
|
3712
|
+
} else {
|
|
3713
|
+
taskSetsMap = this.taskSetsL;
|
|
3714
|
+
uid = scenarioSpecL.uid;
|
|
2621
3715
|
}
|
|
2622
|
-
|
|
3716
|
+
let taskSet = taskSetsMap.get(uid);
|
|
3717
|
+
if (!taskSet) {
|
|
3718
|
+
taskSet = new DataTaskSet(scenarioSpecL, scenarioSpecR);
|
|
3719
|
+
taskSetsMap.set(uid, taskSet);
|
|
3720
|
+
}
|
|
3721
|
+
taskSet.addTask({
|
|
2623
3722
|
datasetKey,
|
|
2624
|
-
|
|
3723
|
+
dataAction
|
|
3724
|
+
});
|
|
3725
|
+
}
|
|
3726
|
+
buildPlan() {
|
|
3727
|
+
if (this.complete) {
|
|
3728
|
+
throw new Error("DataPlanner.buildPlan() can only be called once");
|
|
3729
|
+
}
|
|
3730
|
+
this.complete = true;
|
|
3731
|
+
const lKeyMappings = /* @__PURE__ */ new Map();
|
|
3732
|
+
const rKeyMappings = /* @__PURE__ */ new Map();
|
|
3733
|
+
for (const lrUid of this.taskSetsLR.keys()) {
|
|
3734
|
+
const [lUid, rUid] = lrUid.split("::");
|
|
3735
|
+
if (!lKeyMappings.has(lUid)) {
|
|
3736
|
+
lKeyMappings.set(lUid, lrUid);
|
|
3737
|
+
}
|
|
3738
|
+
if (!rKeyMappings.has(rUid)) {
|
|
3739
|
+
rKeyMappings.set(rUid, lrUid);
|
|
3740
|
+
}
|
|
3741
|
+
}
|
|
3742
|
+
function merge(taskSetsLR, taskSetsForSide, keyMappingsForSide) {
|
|
3743
|
+
for (const [keyForSide, taskSetForSide] of taskSetsForSide.entries()) {
|
|
3744
|
+
const lrKey = keyMappingsForSide.get(keyForSide);
|
|
3745
|
+
if (lrKey) {
|
|
3746
|
+
const taskSetLR = taskSetsLR.get(lrKey);
|
|
3747
|
+
taskSetLR.merge(taskSetForSide);
|
|
3748
|
+
taskSetsForSide.delete(keyForSide);
|
|
3749
|
+
}
|
|
3750
|
+
}
|
|
3751
|
+
}
|
|
3752
|
+
merge(this.taskSetsLR, this.taskSetsL, lKeyMappings);
|
|
3753
|
+
merge(this.taskSetsLR, this.taskSetsR, rKeyMappings);
|
|
3754
|
+
const requests = [];
|
|
3755
|
+
const batchSize = this.batchSize;
|
|
3756
|
+
function addRequests(taskSets) {
|
|
3757
|
+
for (const taskSet of taskSets) {
|
|
3758
|
+
requests.push(...taskSet.buildRequests(batchSize));
|
|
3759
|
+
}
|
|
3760
|
+
}
|
|
3761
|
+
addRequests(this.taskSetsLR.values());
|
|
3762
|
+
addRequests(this.taskSetsL.values());
|
|
3763
|
+
addRequests(this.taskSetsR.values());
|
|
3764
|
+
return {
|
|
3765
|
+
requests
|
|
2625
3766
|
};
|
|
3767
|
+
}
|
|
3768
|
+
};
|
|
3769
|
+
var DataTaskSet = class {
|
|
3770
|
+
constructor(scenarioSpecL, scenarioSpecR) {
|
|
3771
|
+
this.scenarioSpecL = scenarioSpecL;
|
|
3772
|
+
this.scenarioSpecR = scenarioSpecR;
|
|
3773
|
+
this.modelTasks = /* @__PURE__ */ new Map();
|
|
3774
|
+
this.modelImplTasks = /* @__PURE__ */ new Map();
|
|
3775
|
+
}
|
|
3776
|
+
addTask(dataTask) {
|
|
2626
3777
|
let taskMap;
|
|
2627
|
-
if (datasetKey.startsWith("ModelImpl")) {
|
|
3778
|
+
if (dataTask.datasetKey.startsWith("ModelImpl")) {
|
|
2628
3779
|
taskMap = this.modelImplTasks;
|
|
2629
3780
|
} else {
|
|
2630
3781
|
taskMap = this.modelTasks;
|
|
2631
3782
|
}
|
|
2632
|
-
let tasks = taskMap.get(datasetKey);
|
|
3783
|
+
let tasks = taskMap.get(dataTask.datasetKey);
|
|
2633
3784
|
if (!tasks) {
|
|
2634
3785
|
tasks = [];
|
|
2635
|
-
taskMap.set(datasetKey, tasks);
|
|
3786
|
+
taskMap.set(dataTask.datasetKey, tasks);
|
|
2636
3787
|
}
|
|
2637
3788
|
tasks.push(dataTask);
|
|
2638
3789
|
}
|
|
3790
|
+
merge(otherTaskSet) {
|
|
3791
|
+
for (const tasks of otherTaskSet.modelTasks.values()) {
|
|
3792
|
+
for (const task of tasks) {
|
|
3793
|
+
this.addTask(task);
|
|
3794
|
+
}
|
|
3795
|
+
}
|
|
3796
|
+
for (const tasks of otherTaskSet.modelImplTasks.values()) {
|
|
3797
|
+
for (const task of tasks) {
|
|
3798
|
+
this.addTask(task);
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
2639
3802
|
buildRequests(batchSize) {
|
|
2640
3803
|
const dataRequests = [];
|
|
2641
3804
|
if (this.modelTasks.size > 0) {
|
|
2642
3805
|
const dataTasks = [];
|
|
2643
3806
|
this.modelTasks.forEach((tasks) => dataTasks.push(...tasks));
|
|
2644
3807
|
dataRequests.push({
|
|
2645
|
-
|
|
2646
|
-
|
|
3808
|
+
scenarioSpecL: this.scenarioSpecL,
|
|
3809
|
+
scenarioSpecR: this.scenarioSpecR,
|
|
2647
3810
|
dataTasks
|
|
2648
3811
|
});
|
|
2649
3812
|
}
|
|
@@ -2656,8 +3819,8 @@ var ScenarioTaskSet = class {
|
|
|
2656
3819
|
dataTasks.push(...this.modelImplTasks.get(datasetKey));
|
|
2657
3820
|
}
|
|
2658
3821
|
dataRequests.push({
|
|
2659
|
-
|
|
2660
|
-
|
|
3822
|
+
scenarioSpecL: this.scenarioSpecL,
|
|
3823
|
+
scenarioSpecR: this.scenarioSpecR,
|
|
2661
3824
|
dataTasks
|
|
2662
3825
|
});
|
|
2663
3826
|
}
|
|
@@ -2665,29 +3828,11 @@ var ScenarioTaskSet = class {
|
|
|
2665
3828
|
return dataRequests;
|
|
2666
3829
|
}
|
|
2667
3830
|
};
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
addRequest(kind, scenario, datasetKey, dataFunc) {
|
|
2674
|
-
let scenarioTaskSet = this.scenarioTaskSets.get(scenario.key);
|
|
2675
|
-
if (!scenarioTaskSet) {
|
|
2676
|
-
scenarioTaskSet = new ScenarioTaskSet(scenario);
|
|
2677
|
-
this.scenarioTaskSets.set(scenario.key, scenarioTaskSet);
|
|
2678
|
-
}
|
|
2679
|
-
scenarioTaskSet.addTask(kind, datasetKey, dataFunc);
|
|
2680
|
-
}
|
|
2681
|
-
buildPlan() {
|
|
2682
|
-
const requests = [];
|
|
2683
|
-
for (const taskSet of this.scenarioTaskSets.values()) {
|
|
2684
|
-
requests.push(...taskSet.buildRequests(this.batchSize));
|
|
2685
|
-
}
|
|
2686
|
-
return {
|
|
2687
|
-
requests
|
|
2688
|
-
};
|
|
2689
|
-
}
|
|
2690
|
-
};
|
|
3831
|
+
function scenarioPairUid(scenarioSpecL, scenarioSpecR) {
|
|
3832
|
+
const uidL = (scenarioSpecL == null ? void 0 : scenarioSpecL.uid) || "";
|
|
3833
|
+
const uidR = (scenarioSpecR == null ? void 0 : scenarioSpecR.uid) || "";
|
|
3834
|
+
return `${uidL}::${uidR}`;
|
|
3835
|
+
}
|
|
2691
3836
|
|
|
2692
3837
|
// src/check/check-runner.ts
|
|
2693
3838
|
function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner, simplifyScenarios) {
|
|
@@ -2697,7 +3842,7 @@ function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner, simplify
|
|
|
2697
3842
|
const checkPlan = checkPlanner.buildPlan();
|
|
2698
3843
|
const refDatasets = /* @__PURE__ */ new Map();
|
|
2699
3844
|
for (const [dataRefKey, dataRef] of checkPlan.dataRefs.entries()) {
|
|
2700
|
-
refDataPlanner.addRequest(
|
|
3845
|
+
refDataPlanner.addRequest(void 0, dataRef.scenario.spec, dataRef.dataset.datasetKey, (datasets) => {
|
|
2701
3846
|
const dataset = datasets.datasetR;
|
|
2702
3847
|
if (dataset) {
|
|
2703
3848
|
refDatasets.set(dataRefKey, dataset);
|
|
@@ -2706,7 +3851,7 @@ function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner, simplify
|
|
|
2706
3851
|
}
|
|
2707
3852
|
const checkResults = /* @__PURE__ */ new Map();
|
|
2708
3853
|
for (const [checkKey, checkTask] of checkPlan.tasks.entries()) {
|
|
2709
|
-
dataPlanner.addRequest(
|
|
3854
|
+
dataPlanner.addRequest(void 0, checkTask.scenario.spec, checkTask.dataset.datasetKey, (datasets) => {
|
|
2710
3855
|
const dataset = datasets.datasetR;
|
|
2711
3856
|
const checkResult = runCheck(checkTask, dataset, refDatasets);
|
|
2712
3857
|
checkResults.set(checkKey, checkResult);
|
|
@@ -2737,7 +3882,7 @@ function runCheck(checkTask, dataset, refDatasets) {
|
|
|
2737
3882
|
name: dataRef.dataset.name
|
|
2738
3883
|
}
|
|
2739
3884
|
};
|
|
2740
|
-
} else if (dataRef.scenario.
|
|
3885
|
+
} else if (dataRef.scenario.spec === void 0) {
|
|
2741
3886
|
if (dataRef.scenario.error) {
|
|
2742
3887
|
return {
|
|
2743
3888
|
status: "error",
|
|
@@ -2774,16 +3919,15 @@ function runCheck(checkTask, dataset, refDatasets) {
|
|
|
2774
3919
|
return checkTask.action.run(dataset, opRefDatasets);
|
|
2775
3920
|
}
|
|
2776
3921
|
|
|
2777
|
-
// src/
|
|
2778
|
-
function
|
|
2779
|
-
const
|
|
2780
|
-
const
|
|
2781
|
-
|
|
2782
|
-
const datasetKeys = compareConfig.datasets.getDatasetKeysForScenario(scenario);
|
|
3922
|
+
// src/comparison/run/comparison-runner.ts
|
|
3923
|
+
function runComparisons(comparisonConfig, dataPlanner) {
|
|
3924
|
+
const testReports = [];
|
|
3925
|
+
for (const scenario of comparisonConfig.scenarios.getAllScenarios()) {
|
|
3926
|
+
const datasetKeys = comparisonConfig.datasets.getDatasetKeysForScenario(scenario);
|
|
2783
3927
|
for (const datasetKey of datasetKeys) {
|
|
2784
|
-
dataPlanner.addRequest(
|
|
3928
|
+
dataPlanner.addRequest(scenario.specL, scenario.specR, datasetKey, (datasets) => {
|
|
2785
3929
|
const diffReport = diffDatasets(datasets.datasetL, datasets.datasetR);
|
|
2786
|
-
|
|
3930
|
+
testReports.push({
|
|
2787
3931
|
scenarioKey: scenario.key,
|
|
2788
3932
|
datasetKey,
|
|
2789
3933
|
diffReport
|
|
@@ -2792,7 +3936,7 @@ function runCompare(compareConfig, dataPlanner, simplifyScenarios) {
|
|
|
2792
3936
|
}
|
|
2793
3937
|
}
|
|
2794
3938
|
return () => {
|
|
2795
|
-
return
|
|
3939
|
+
return testReports;
|
|
2796
3940
|
};
|
|
2797
3941
|
}
|
|
2798
3942
|
|
|
@@ -2830,9 +3974,9 @@ var SuiteRunner = class {
|
|
|
2830
3974
|
const checkSpec = checkSpecResult.value;
|
|
2831
3975
|
const simplifyScenarios = (options == null ? void 0 : options.simplifyScenarios) === true;
|
|
2832
3976
|
const buildCheckReport2 = runChecks(this.config.check, checkSpec, dataPlanner, refDataPlanner, simplifyScenarios);
|
|
2833
|
-
let
|
|
2834
|
-
if (this.config.
|
|
2835
|
-
|
|
3977
|
+
let buildComparisonTestReports;
|
|
3978
|
+
if (this.config.comparison) {
|
|
3979
|
+
buildComparisonTestReports = runComparisons(this.config.comparison, dataPlanner);
|
|
2836
3980
|
}
|
|
2837
3981
|
this.taskQueue.onIdle = (error) => {
|
|
2838
3982
|
var _a2, _b2, _c2, _d2;
|
|
@@ -2843,17 +3987,17 @@ var SuiteRunner = class {
|
|
|
2843
3987
|
(_b2 = (_a2 = this.callbacks).onError) == null ? void 0 : _b2.call(_a2, error);
|
|
2844
3988
|
} else {
|
|
2845
3989
|
const checkReport = buildCheckReport2();
|
|
2846
|
-
let
|
|
2847
|
-
if (this.config.
|
|
2848
|
-
|
|
2849
|
-
|
|
3990
|
+
let comparisonReport;
|
|
3991
|
+
if (this.config.comparison) {
|
|
3992
|
+
comparisonReport = {
|
|
3993
|
+
testReports: buildComparisonTestReports(),
|
|
2850
3994
|
perfReportL: this.perfStatsL.toReport(),
|
|
2851
3995
|
perfReportR: this.perfStatsR.toReport()
|
|
2852
3996
|
};
|
|
2853
3997
|
}
|
|
2854
3998
|
(_d2 = (_c2 = this.callbacks).onComplete) == null ? void 0 : _d2.call(_c2, {
|
|
2855
3999
|
checkReport,
|
|
2856
|
-
|
|
4000
|
+
comparisonReport
|
|
2857
4001
|
});
|
|
2858
4002
|
}
|
|
2859
4003
|
};
|
|
@@ -2862,10 +4006,10 @@ var SuiteRunner = class {
|
|
|
2862
4006
|
const dataRequests = [...refDataPlan.requests, ...dataPlan.requests];
|
|
2863
4007
|
const taskCount = dataRequests.length;
|
|
2864
4008
|
if (taskCount === 0) {
|
|
2865
|
-
let
|
|
2866
|
-
if (this.config.
|
|
2867
|
-
|
|
2868
|
-
|
|
4009
|
+
let comparisonReport;
|
|
4010
|
+
if (this.config.comparison) {
|
|
4011
|
+
comparisonReport = {
|
|
4012
|
+
testReports: [],
|
|
2869
4013
|
perfReportL: this.perfStatsL.toReport(),
|
|
2870
4014
|
perfReportR: this.perfStatsR.toReport()
|
|
2871
4015
|
};
|
|
@@ -2876,7 +4020,7 @@ var SuiteRunner = class {
|
|
|
2876
4020
|
checkReport: {
|
|
2877
4021
|
groups: []
|
|
2878
4022
|
},
|
|
2879
|
-
|
|
4023
|
+
comparisonReport
|
|
2880
4024
|
});
|
|
2881
4025
|
return;
|
|
2882
4026
|
}
|
|
@@ -2891,34 +4035,25 @@ var SuiteRunner = class {
|
|
|
2891
4035
|
}
|
|
2892
4036
|
}
|
|
2893
4037
|
async processRequest(request) {
|
|
4038
|
+
var _a, _b;
|
|
2894
4039
|
const datasetKeySet = /* @__PURE__ */ new Set();
|
|
2895
4040
|
for (const dataTask of request.dataTasks) {
|
|
2896
4041
|
datasetKeySet.add(dataTask.datasetKey);
|
|
2897
4042
|
}
|
|
2898
4043
|
const datasetKeys = [...datasetKeySet];
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
const bundleModel = this.config.check.bundle.model;
|
|
2905
|
-
datasetsResultR = await bundleModel.getDatasetsForScenario(scenario, datasetKeys);
|
|
2906
|
-
break;
|
|
2907
|
-
}
|
|
2908
|
-
case "compare": {
|
|
2909
|
-
const bundleModelL = this.config.compare.bundleL.model;
|
|
2910
|
-
const bundleModelR = this.config.compare.bundleR.model;
|
|
2911
|
-
const [resultL, resultR] = await Promise.all([
|
|
2912
|
-
bundleModelL.getDatasetsForScenario(scenario, datasetKeys),
|
|
2913
|
-
bundleModelR.getDatasetsForScenario(scenario, datasetKeys)
|
|
2914
|
-
]);
|
|
2915
|
-
datasetsResultL = resultL;
|
|
2916
|
-
datasetsResultR = resultR;
|
|
2917
|
-
break;
|
|
4044
|
+
async function getDatasets(bundleModel, scenarioSpec) {
|
|
4045
|
+
if (bundleModel && scenarioSpec) {
|
|
4046
|
+
return bundleModel.getDatasetsForScenario(scenarioSpec, datasetKeys);
|
|
4047
|
+
} else {
|
|
4048
|
+
return void 0;
|
|
2918
4049
|
}
|
|
2919
|
-
default:
|
|
2920
|
-
(0, import_assert_never10.default)(request.kind);
|
|
2921
4050
|
}
|
|
4051
|
+
const bundleModelL = (_a = this.config.comparison) == null ? void 0 : _a.bundleL.model;
|
|
4052
|
+
const bundleModelR = ((_b = this.config.comparison) == null ? void 0 : _b.bundleR.model) || this.config.check.bundle.model;
|
|
4053
|
+
const [datasetsResultL, datasetsResultR] = await Promise.all([
|
|
4054
|
+
getDatasets(bundleModelL, request.scenarioSpecL),
|
|
4055
|
+
getDatasets(bundleModelR, request.scenarioSpecR)
|
|
4056
|
+
]);
|
|
2922
4057
|
if (datasetsResultL == null ? void 0 : datasetsResultL.modelRunTime) {
|
|
2923
4058
|
this.perfStatsL.addRun(datasetsResultL == null ? void 0 : datasetsResultL.modelRunTime);
|
|
2924
4059
|
}
|
|
@@ -2930,7 +4065,7 @@ var SuiteRunner = class {
|
|
|
2930
4065
|
for (const dataTask of request.dataTasks) {
|
|
2931
4066
|
const datasetL = datasetMapL == null ? void 0 : datasetMapL.get(dataTask.datasetKey);
|
|
2932
4067
|
const datasetR = datasetMapR == null ? void 0 : datasetMapR.get(dataTask.datasetKey);
|
|
2933
|
-
dataTask.
|
|
4068
|
+
dataTask.dataAction({
|
|
2934
4069
|
datasetL,
|
|
2935
4070
|
datasetR
|
|
2936
4071
|
});
|
|
@@ -2945,44 +4080,35 @@ function runSuite(config, callbacks, options) {
|
|
|
2945
4080
|
};
|
|
2946
4081
|
}
|
|
2947
4082
|
|
|
2948
|
-
// src/suite/suite-
|
|
4083
|
+
// src/suite/suite-reporting.ts
|
|
2949
4084
|
function suiteSummaryFromReport(suiteReport) {
|
|
2950
4085
|
const checkSummary = checkSummaryFromReport(suiteReport.checkReport);
|
|
2951
|
-
let
|
|
2952
|
-
if (suiteReport.
|
|
2953
|
-
|
|
4086
|
+
let comparisonSummary;
|
|
4087
|
+
if (suiteReport.comparisonReport) {
|
|
4088
|
+
comparisonSummary = comparisonSummaryFromReport(suiteReport.comparisonReport);
|
|
2954
4089
|
}
|
|
2955
4090
|
return {
|
|
2956
4091
|
checkSummary,
|
|
2957
|
-
|
|
4092
|
+
comparisonSummary
|
|
2958
4093
|
};
|
|
2959
4094
|
}
|
|
2960
4095
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2961
4096
|
0 && (module.exports = {
|
|
2962
4097
|
CheckDataCoordinator,
|
|
2963
|
-
|
|
2964
|
-
DatasetManager,
|
|
4098
|
+
ComparisonDataCoordinator,
|
|
2965
4099
|
PerfRunner,
|
|
2966
4100
|
PerfStats,
|
|
2967
|
-
|
|
2968
|
-
allInputsAtPositionScenario,
|
|
4101
|
+
categorizeComparisonTestSummaries,
|
|
2969
4102
|
checkReportFromSummary,
|
|
2970
4103
|
checkSummaryFromReport,
|
|
2971
|
-
|
|
2972
|
-
compareSummaryFromReport,
|
|
4104
|
+
comparisonSummaryFromReport,
|
|
2973
4105
|
createConfig,
|
|
2974
4106
|
datasetMessage,
|
|
2975
4107
|
diffDatasets,
|
|
2976
4108
|
diffGraphs,
|
|
2977
|
-
inputAtPositionScenario,
|
|
2978
|
-
inputAtValueScenario,
|
|
2979
|
-
matrixScenarios,
|
|
2980
|
-
positionSetting,
|
|
2981
4109
|
predicateMessage,
|
|
2982
4110
|
runSuite,
|
|
2983
4111
|
scenarioMessage,
|
|
2984
|
-
|
|
2985
|
-
suiteSummaryFromReport,
|
|
2986
|
-
valueSetting
|
|
4112
|
+
suiteSummaryFromReport
|
|
2987
4113
|
});
|
|
2988
4114
|
//# sourceMappingURL=index.cjs.map
|