59 lines
1.7 KiB
TypeScript
59 lines
1.7 KiB
TypeScript
import type { FidelityVector } from "@siax/c0py-types";
|
|
|
|
export interface FidelityPolicy {
|
|
minimum: Partial<Record<keyof FidelityVector, number | boolean>>;
|
|
requireZeroRuntimeErrors?: boolean;
|
|
requireProductionBuild?: boolean;
|
|
}
|
|
|
|
export interface FidelityGateResult {
|
|
passed: boolean;
|
|
failures: string[];
|
|
}
|
|
|
|
export const defaultClonePolicy: FidelityPolicy = {
|
|
minimum: {
|
|
routeCoverage: 1,
|
|
interactionCoverage: 1,
|
|
workflowCoverage: 1,
|
|
networkContractParity: 1,
|
|
responsiveCoverage: 1,
|
|
assets: 1,
|
|
accessibilityPass: true,
|
|
},
|
|
requireZeroRuntimeErrors: true,
|
|
requireProductionBuild: true,
|
|
};
|
|
|
|
export function evaluateFidelity(
|
|
vector: FidelityVector,
|
|
policy: FidelityPolicy = defaultClonePolicy,
|
|
): FidelityGateResult {
|
|
const failures: string[] = [];
|
|
|
|
for (const [dimension, requirement] of Object.entries(policy.minimum) as Array<
|
|
[keyof FidelityVector, number | boolean]
|
|
>) {
|
|
const actual = vector[dimension];
|
|
|
|
if (typeof requirement === "boolean") {
|
|
if (actual !== requirement) failures.push(`${dimension}: expected ${requirement}, got ${String(actual)}`);
|
|
continue;
|
|
}
|
|
|
|
if (typeof actual !== "number" || actual < requirement) {
|
|
failures.push(`${dimension}: expected >= ${requirement}, got ${String(actual)}`);
|
|
}
|
|
}
|
|
|
|
if (policy.requireZeroRuntimeErrors && vector.runtimeErrorCount !== 0) {
|
|
failures.push(`runtimeErrorCount: expected 0, got ${String(vector.runtimeErrorCount)}`);
|
|
}
|
|
|
|
if (policy.requireProductionBuild && vector.productionBuildPass !== true) {
|
|
failures.push(`productionBuildPass: expected true, got ${String(vector.productionBuildPass)}`);
|
|
}
|
|
|
|
return { passed: failures.length === 0, failures };
|
|
}
|