@sdeverywhere/check-core 0.1.13 → 0.1.14
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 +208 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -4
- package/dist/index.d.ts +19 -4
- package/dist/index.js +208 -89
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/schema/check.schema.json +49 -0
package/dist/index.cjs
CHANGED
|
@@ -545,7 +545,7 @@ function predicateReport(predicatePlan, checkKey, result) {
|
|
|
545
545
|
opValue = `${sym} ${predOp}`;
|
|
546
546
|
} else {
|
|
547
547
|
const dataRef = (_a = predicatePlan.dataRefs) == null ? void 0 : _a.get(op);
|
|
548
|
-
if (!dataRef) {
|
|
548
|
+
if (!dataRef || dataRef.refs.length === 0) {
|
|
549
549
|
return;
|
|
550
550
|
}
|
|
551
551
|
const opDataRef = {
|
|
@@ -553,8 +553,9 @@ function predicateReport(predicatePlan, checkKey, result) {
|
|
|
553
553
|
dataRef
|
|
554
554
|
};
|
|
555
555
|
opRef = opDataRef;
|
|
556
|
-
|
|
557
|
-
|
|
556
|
+
const refDatasetNames = dataRef.refs.map((ref) => `'${ref.dataset.name}'`);
|
|
557
|
+
opValue = `${sym} ${refDatasetNames.join(" + ")}`;
|
|
558
|
+
const refScenarioSpec = (_b = dataRef.refs[0].scenario) == null ? void 0 : _b.spec;
|
|
558
559
|
if (!refScenarioSpec) {
|
|
559
560
|
return;
|
|
560
561
|
}
|
|
@@ -1111,6 +1112,12 @@ var check_schema_default = {
|
|
|
1111
1112
|
type: "number"
|
|
1112
1113
|
},
|
|
1113
1114
|
predicate_ref_data: {
|
|
1115
|
+
oneOf: [
|
|
1116
|
+
{ $ref: "#/$defs/predicate_ref_data_single_dataset" },
|
|
1117
|
+
{ $ref: "#/$defs/predicate_ref_data_multiple_datasets" }
|
|
1118
|
+
]
|
|
1119
|
+
},
|
|
1120
|
+
predicate_ref_data_single_dataset: {
|
|
1114
1121
|
type: "object",
|
|
1115
1122
|
additionalProperties: false,
|
|
1116
1123
|
properties: {
|
|
@@ -1119,6 +1126,27 @@ var check_schema_default = {
|
|
|
1119
1126
|
},
|
|
1120
1127
|
required: ["dataset"]
|
|
1121
1128
|
},
|
|
1129
|
+
predicate_ref_data_multiple_datasets: {
|
|
1130
|
+
type: "object",
|
|
1131
|
+
additionalProperties: false,
|
|
1132
|
+
properties: {
|
|
1133
|
+
op: { $ref: "#/$defs/predicate_ref_data_datasets_op" },
|
|
1134
|
+
datasets: {
|
|
1135
|
+
type: "array",
|
|
1136
|
+
items: { $ref: "#/$defs/predicate_ref_data_datasets_item" },
|
|
1137
|
+
minItems: 1
|
|
1138
|
+
},
|
|
1139
|
+
scenario: { $ref: "#/$defs/predicate_ref_data_scenario" }
|
|
1140
|
+
},
|
|
1141
|
+
required: ["op", "datasets"]
|
|
1142
|
+
},
|
|
1143
|
+
predicate_ref_data_datasets_op: {
|
|
1144
|
+
type: "string",
|
|
1145
|
+
enum: ["sum"]
|
|
1146
|
+
},
|
|
1147
|
+
predicate_ref_data_datasets_item: {
|
|
1148
|
+
oneOf: [{ type: "string" }, { $ref: "#/$defs/dataset_name" }]
|
|
1149
|
+
},
|
|
1122
1150
|
predicate_ref_data_dataset: {
|
|
1123
1151
|
oneOf: [{ $ref: "#/$defs/dataset_name" }, { $ref: "#/$defs/predicate_ref_data_dataset_special" }]
|
|
1124
1152
|
},
|
|
@@ -1971,6 +1999,17 @@ var CheckPlanner = class {
|
|
|
1971
1999
|
* this will add a reference to the scenario/dataset pair so that the data can
|
|
1972
2000
|
* be fetched in a later stage.
|
|
1973
2001
|
*
|
|
2002
|
+
* A predicate can also reference multiple datasets that are combined into a
|
|
2003
|
+
* single dataset, for example:
|
|
2004
|
+
* ```
|
|
2005
|
+
* approx:
|
|
2006
|
+
* op: sum
|
|
2007
|
+
* datasets:
|
|
2008
|
+
* - 'X'
|
|
2009
|
+
* - 'Y'
|
|
2010
|
+
* ```
|
|
2011
|
+
* in which case one reference is added for each of the datasets.
|
|
2012
|
+
*
|
|
1974
2013
|
* @param predicateSpec The predicate spec.
|
|
1975
2014
|
* @param checkScenario The scenario in which the dataset is being checked.
|
|
1976
2015
|
* @param checkDataset The dataset that is being checked.
|
|
@@ -1982,25 +2021,22 @@ var CheckPlanner = class {
|
|
|
1982
2021
|
if (predOp === void 0 || typeof predOp === "number") {
|
|
1983
2022
|
return;
|
|
1984
2023
|
}
|
|
1985
|
-
|
|
1986
|
-
if (
|
|
2024
|
+
const refDatasets = [];
|
|
2025
|
+
if (predOp.datasets !== void 0) {
|
|
2026
|
+
for (const datasetSpec of predOp.datasets) {
|
|
2027
|
+
const refDatasetSpec = typeof datasetSpec === "string" ? { name: datasetSpec } : { name: datasetSpec.name, source: datasetSpec.source };
|
|
2028
|
+
refDatasets.push(this.resolveRefDataset(refDatasetSpec));
|
|
2029
|
+
}
|
|
2030
|
+
} else if (typeof predOp.dataset === "string") {
|
|
1987
2031
|
switch (predOp.dataset) {
|
|
1988
2032
|
case "inherit":
|
|
1989
|
-
|
|
2033
|
+
refDatasets.push(checkDataset);
|
|
1990
2034
|
break;
|
|
1991
2035
|
default:
|
|
1992
2036
|
(0, import_assert_never5.default)(predOp.dataset);
|
|
1993
2037
|
}
|
|
1994
2038
|
} else {
|
|
1995
|
-
|
|
1996
|
-
const matchedRefDatasets = expandDatasets(this.modelSpec, refDatasetSpec);
|
|
1997
|
-
if (matchedRefDatasets.length === 1) {
|
|
1998
|
-
refDataset = matchedRefDatasets[0];
|
|
1999
|
-
} else {
|
|
2000
|
-
refDataset = {
|
|
2001
|
-
name: predOp.dataset.name
|
|
2002
|
-
};
|
|
2003
|
-
}
|
|
2039
|
+
refDatasets.push(this.resolveRefDataset({ name: predOp.dataset.name }));
|
|
2004
2040
|
}
|
|
2005
2041
|
let refScenario;
|
|
2006
2042
|
if (typeof predOp.scenario === "string") {
|
|
@@ -2023,22 +2059,28 @@ var CheckPlanner = class {
|
|
|
2023
2059
|
};
|
|
2024
2060
|
}
|
|
2025
2061
|
}
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2062
|
+
const refs = refDatasets.map((refDataset) => {
|
|
2063
|
+
let dataRefKey;
|
|
2064
|
+
if (refScenario.spec && refDataset.datasetKey) {
|
|
2065
|
+
dataRefKey = `${refScenario.spec.uid}::${refDataset.datasetKey}`;
|
|
2066
|
+
}
|
|
2067
|
+
const ref = {
|
|
2068
|
+
key: dataRefKey,
|
|
2069
|
+
dataset: refDataset,
|
|
2070
|
+
scenario: refScenario
|
|
2071
|
+
};
|
|
2072
|
+
if (dataRefKey) {
|
|
2073
|
+
this.dataRefs.set(dataRefKey, ref);
|
|
2074
|
+
}
|
|
2075
|
+
return ref;
|
|
2076
|
+
});
|
|
2038
2077
|
if (dataRefs === void 0) {
|
|
2039
2078
|
dataRefs = /* @__PURE__ */ new Map();
|
|
2040
2079
|
}
|
|
2041
|
-
dataRefs.set(op,
|
|
2080
|
+
dataRefs.set(op, {
|
|
2081
|
+
op: predOp.op,
|
|
2082
|
+
refs
|
|
2083
|
+
});
|
|
2042
2084
|
};
|
|
2043
2085
|
addDataRef("gt");
|
|
2044
2086
|
addDataRef("gte");
|
|
@@ -2048,6 +2090,23 @@ var CheckPlanner = class {
|
|
|
2048
2090
|
addDataRef("approx");
|
|
2049
2091
|
return dataRefs;
|
|
2050
2092
|
}
|
|
2093
|
+
/**
|
|
2094
|
+
* Resolve the dataset that matches the given spec. If the spec does not expand
|
|
2095
|
+
* to exactly one dataset, this will return a `CheckDataset` with an undefined
|
|
2096
|
+
* `datasetKey` so that the error can be reported later.
|
|
2097
|
+
*
|
|
2098
|
+
* @param refDatasetSpec The spec for the referenced dataset.
|
|
2099
|
+
*/
|
|
2100
|
+
resolveRefDataset(refDatasetSpec) {
|
|
2101
|
+
const matchedRefDatasets = expandDatasets(this.modelSpec, refDatasetSpec);
|
|
2102
|
+
if (matchedRefDatasets.length === 1) {
|
|
2103
|
+
return matchedRefDatasets[0];
|
|
2104
|
+
} else {
|
|
2105
|
+
return {
|
|
2106
|
+
name: refDatasetSpec.name
|
|
2107
|
+
};
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2051
2110
|
};
|
|
2052
2111
|
|
|
2053
2112
|
// src/check/check-summary.ts
|
|
@@ -5397,14 +5456,15 @@ function scenarioPairUid(scenarioSpecL, scenarioSpecR, constantsL, constantsR, l
|
|
|
5397
5456
|
}
|
|
5398
5457
|
|
|
5399
5458
|
// src/check/check-runner.ts
|
|
5459
|
+
var import_assert_never13 = __toESM(require("assert-never"), 1);
|
|
5400
5460
|
function runChecks(checkConfig, checkSpec, dataPlanner, refDataPlanner, skipChecks) {
|
|
5401
5461
|
const modelSpec = checkConfig.bundle.modelSpec;
|
|
5402
5462
|
const checkPlanner = new CheckPlanner(modelSpec);
|
|
5403
5463
|
checkPlanner.addAllChecks(checkSpec, skipChecks);
|
|
5404
5464
|
const checkPlan = checkPlanner.buildPlan();
|
|
5405
5465
|
const refDatasets = /* @__PURE__ */ new Map();
|
|
5406
|
-
for (const [dataRefKey,
|
|
5407
|
-
refDataPlanner.addRequest(void 0,
|
|
5466
|
+
for (const [dataRefKey, ref] of checkPlan.dataRefs.entries()) {
|
|
5467
|
+
refDataPlanner.addRequest(void 0, ref.scenario.spec, ref.dataset.datasetKey, (datasets) => {
|
|
5408
5468
|
const dataset = datasets.datasetR;
|
|
5409
5469
|
if (dataset) {
|
|
5410
5470
|
refDatasets.set(dataRefKey, dataset);
|
|
@@ -5438,52 +5498,91 @@ function runCheck(checkTask, dataset, refDatasets) {
|
|
|
5438
5498
|
if (checkTask.dataRefs) {
|
|
5439
5499
|
opRefDatasets = /* @__PURE__ */ new Map();
|
|
5440
5500
|
for (const [op, dataRef] of checkTask.dataRefs.entries()) {
|
|
5441
|
-
const
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
errorInfo: {
|
|
5447
|
-
kind: "unknown-dataset",
|
|
5448
|
-
name: dataRef.dataset.name
|
|
5449
|
-
}
|
|
5450
|
-
};
|
|
5451
|
-
} else if (dataRef.scenario.spec === void 0) {
|
|
5452
|
-
if (dataRef.scenario.error) {
|
|
5453
|
-
return {
|
|
5454
|
-
status: "error",
|
|
5455
|
-
errorInfo: {
|
|
5456
|
-
kind: dataRef.scenario.error.kind,
|
|
5457
|
-
name: dataRef.scenario.error.name
|
|
5458
|
-
}
|
|
5459
|
-
};
|
|
5460
|
-
} else {
|
|
5461
|
-
let inputName;
|
|
5462
|
-
if (dataRef.scenario.inputDescs.length > 0) {
|
|
5463
|
-
inputName = dataRef.scenario.inputDescs[0].name;
|
|
5464
|
-
} else {
|
|
5465
|
-
inputName = "unknown";
|
|
5466
|
-
}
|
|
5467
|
-
return {
|
|
5468
|
-
status: "error",
|
|
5469
|
-
errorInfo: {
|
|
5470
|
-
kind: "unknown-input",
|
|
5471
|
-
name: inputName
|
|
5472
|
-
}
|
|
5473
|
-
};
|
|
5474
|
-
}
|
|
5475
|
-
} else {
|
|
5476
|
-
return {
|
|
5477
|
-
status: "error",
|
|
5478
|
-
message: "unresolved data reference"
|
|
5479
|
-
};
|
|
5501
|
+
const resolvedDatasets = [];
|
|
5502
|
+
for (const ref of dataRef.refs) {
|
|
5503
|
+
const refDataset = refDatasets == null ? void 0 : refDatasets.get(ref.key);
|
|
5504
|
+
if (refDataset === void 0) {
|
|
5505
|
+
return errorResultForRefDataset(ref);
|
|
5480
5506
|
}
|
|
5507
|
+
resolvedDatasets.push(refDataset);
|
|
5481
5508
|
}
|
|
5482
|
-
opRefDatasets.set(op,
|
|
5509
|
+
opRefDatasets.set(op, combineRefDatasets(dataRef, resolvedDatasets));
|
|
5483
5510
|
}
|
|
5484
5511
|
}
|
|
5485
5512
|
return checkTask.action.run(dataset, opRefDatasets);
|
|
5486
5513
|
}
|
|
5514
|
+
function errorResultForRefDataset(ref) {
|
|
5515
|
+
if (ref.dataset.datasetKey === void 0) {
|
|
5516
|
+
return {
|
|
5517
|
+
status: "error",
|
|
5518
|
+
errorInfo: {
|
|
5519
|
+
kind: "unknown-dataset",
|
|
5520
|
+
name: ref.dataset.name
|
|
5521
|
+
}
|
|
5522
|
+
};
|
|
5523
|
+
} else if (ref.scenario.spec === void 0) {
|
|
5524
|
+
if (ref.scenario.error) {
|
|
5525
|
+
return {
|
|
5526
|
+
status: "error",
|
|
5527
|
+
errorInfo: {
|
|
5528
|
+
kind: ref.scenario.error.kind,
|
|
5529
|
+
name: ref.scenario.error.name
|
|
5530
|
+
}
|
|
5531
|
+
};
|
|
5532
|
+
} else {
|
|
5533
|
+
let inputName;
|
|
5534
|
+
if (ref.scenario.inputDescs.length > 0) {
|
|
5535
|
+
inputName = ref.scenario.inputDescs[0].name;
|
|
5536
|
+
} else {
|
|
5537
|
+
inputName = "unknown";
|
|
5538
|
+
}
|
|
5539
|
+
return {
|
|
5540
|
+
status: "error",
|
|
5541
|
+
errorInfo: {
|
|
5542
|
+
kind: "unknown-input",
|
|
5543
|
+
name: inputName
|
|
5544
|
+
}
|
|
5545
|
+
};
|
|
5546
|
+
}
|
|
5547
|
+
} else {
|
|
5548
|
+
return {
|
|
5549
|
+
status: "error",
|
|
5550
|
+
message: "unresolved data reference"
|
|
5551
|
+
};
|
|
5552
|
+
}
|
|
5553
|
+
}
|
|
5554
|
+
function combineRefDatasets(dataRef, datasets) {
|
|
5555
|
+
if (dataRef.op === void 0) {
|
|
5556
|
+
return datasets[0];
|
|
5557
|
+
}
|
|
5558
|
+
switch (dataRef.op) {
|
|
5559
|
+
case "sum":
|
|
5560
|
+
return sumDatasets(datasets);
|
|
5561
|
+
default:
|
|
5562
|
+
(0, import_assert_never13.default)(dataRef.op);
|
|
5563
|
+
}
|
|
5564
|
+
}
|
|
5565
|
+
function sumDatasets(datasets) {
|
|
5566
|
+
const firstDataset = datasets[0];
|
|
5567
|
+
const otherDatasets = datasets.slice(1);
|
|
5568
|
+
const summed = /* @__PURE__ */ new Map();
|
|
5569
|
+
for (const [time, value] of firstDataset) {
|
|
5570
|
+
let sum = value;
|
|
5571
|
+
let complete = true;
|
|
5572
|
+
for (const otherDataset of otherDatasets) {
|
|
5573
|
+
const otherValue = otherDataset.get(time);
|
|
5574
|
+
if (otherValue === void 0) {
|
|
5575
|
+
complete = false;
|
|
5576
|
+
break;
|
|
5577
|
+
}
|
|
5578
|
+
sum += otherValue;
|
|
5579
|
+
}
|
|
5580
|
+
if (complete) {
|
|
5581
|
+
summed.set(time, sum);
|
|
5582
|
+
}
|
|
5583
|
+
}
|
|
5584
|
+
return summed;
|
|
5585
|
+
}
|
|
5487
5586
|
|
|
5488
5587
|
// src/comparison/run/comparison-runner.ts
|
|
5489
5588
|
function runComparisons(comparisonConfig, dataPlanner, skipScenarios) {
|
|
@@ -5619,8 +5718,9 @@ var SuiteRunner = class {
|
|
|
5619
5718
|
}
|
|
5620
5719
|
const refDataPlan = refDataPlanner.buildPlan();
|
|
5621
5720
|
const dataPlan = dataPlanner.buildPlan();
|
|
5622
|
-
const
|
|
5623
|
-
const
|
|
5721
|
+
const refDataRequests = refDataPlan.requests;
|
|
5722
|
+
const dataRequests = dataPlan.requests;
|
|
5723
|
+
const taskCount = refDataRequests.length + dataRequests.length;
|
|
5624
5724
|
if (taskCount === 0) {
|
|
5625
5725
|
const checkReport = buildCheckReport2();
|
|
5626
5726
|
let comparisonReport;
|
|
@@ -5658,23 +5758,42 @@ var SuiteRunner = class {
|
|
|
5658
5758
|
};
|
|
5659
5759
|
let tasksCompleted = 0;
|
|
5660
5760
|
let dataTaskId = 1;
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
this
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5761
|
+
const scheduleRequests = (requests, onGroupComplete) => {
|
|
5762
|
+
let groupTasksCompleted = 0;
|
|
5763
|
+
for (const dataRequest of requests) {
|
|
5764
|
+
const task = {
|
|
5765
|
+
key: `suite-runner-${dataTaskId++}`,
|
|
5766
|
+
kind: "suite-runner",
|
|
5767
|
+
process: (bundleModels) => __async(this, null, function* () {
|
|
5768
|
+
var _a2, _b2;
|
|
5769
|
+
this.pendingTaskKeys.delete(task.key);
|
|
5770
|
+
yield this.processRequest(dataRequest, bundleModels);
|
|
5771
|
+
tasksCompleted++;
|
|
5772
|
+
(_b2 = (_a2 = this.callbacks).onProgress) == null ? void 0 : _b2.call(_a2, tasksCompleted / taskCount);
|
|
5773
|
+
groupTasksCompleted++;
|
|
5774
|
+
if (groupTasksCompleted === requests.length) {
|
|
5775
|
+
onGroupComplete();
|
|
5776
|
+
}
|
|
5777
|
+
})
|
|
5778
|
+
};
|
|
5779
|
+
this.taskQueue.addTask(task);
|
|
5780
|
+
this.pendingTaskKeys.add(task.key);
|
|
5781
|
+
}
|
|
5782
|
+
};
|
|
5783
|
+
const scheduleDataRequests = () => {
|
|
5784
|
+
if (this.stopped) {
|
|
5785
|
+
return;
|
|
5786
|
+
}
|
|
5787
|
+
if (dataRequests.length > 0) {
|
|
5788
|
+
scheduleRequests(dataRequests, buildReport);
|
|
5789
|
+
} else {
|
|
5790
|
+
buildReport();
|
|
5791
|
+
}
|
|
5792
|
+
};
|
|
5793
|
+
if (refDataRequests.length > 0) {
|
|
5794
|
+
scheduleRequests(refDataRequests, scheduleDataRequests);
|
|
5795
|
+
} else {
|
|
5796
|
+
scheduleDataRequests();
|
|
5678
5797
|
}
|
|
5679
5798
|
}
|
|
5680
5799
|
processRequest(request, bundleModels) {
|