mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 14:00:37 +00:00
Compare every on/off combination of requested Cargo features over the Boolean-lattice edges, in Gray-code build order, with a matrix index of configs, edge comparisons and provenance. Single runs record explicit feature sets as schemaVersion 2 with resolved defaults and build environments. Edge comparisons stay diagnostic; edges clean apart from the intended toggle are marked controlled. Validate with 68 focused tests, CLI fault checks, dry runs, and container smoke matrices for branch-b pan cases. AI-assisted-by: muse-spark-1.3-contributor-free
241 lines
7.0 KiB
JavaScript
241 lines
7.0 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { compareRuns, formatComparison } from "../compare.js";
|
|
import { tagExpectedFeatureDiff } from "../compare.js";
|
|
|
|
function run(value = 10) {
|
|
return {
|
|
schemaVersion: 2,
|
|
status: "complete",
|
|
metadata: {
|
|
git: { sha: "before", dirty: false },
|
|
build: {
|
|
mode: "release",
|
|
featurePolicy: "manifest-defaults",
|
|
features: [],
|
|
defaultFeatures: ["default"],
|
|
target: "frontend",
|
|
env: { BUILD_MODE: "release" },
|
|
ambientEnv: { CARGO_HOME: "/home/penpot/.cargo" },
|
|
},
|
|
environment: { chromium: "123", headless: true },
|
|
configuration: { viewport: { width: 1920, height: 1080 }, dpr: 2 },
|
|
},
|
|
cases: [
|
|
{
|
|
id: "rects/default/load",
|
|
scenarioId: "rects",
|
|
scenarioVersion: 1,
|
|
sceneSeed: 123,
|
|
params: { count: 1000 },
|
|
initialView: { x: 0, y: 0, zoom: 1 },
|
|
interaction: null,
|
|
group: "fresh-module-context",
|
|
preparation: "fresh",
|
|
environment: { webgl: { renderer: "GPU" } },
|
|
status: "complete",
|
|
attempts: Array.from({ length: 10 }, (_, index) => ({
|
|
index,
|
|
warmup: false,
|
|
status: "ok",
|
|
metrics: { render: value },
|
|
invalidMetrics: {},
|
|
})),
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
test("offline comparison allows intentional source and build changes", () => {
|
|
const candidate = run(12);
|
|
candidate.metadata.git.sha = "after";
|
|
candidate.metadata.build.revision = "candidate";
|
|
const result = compareRuns(run(), candidate);
|
|
const metric = result.cases[0].metrics.render;
|
|
assert.equal(result.compatible, true);
|
|
assert.equal(metric.absoluteChange, 2);
|
|
assert.equal(metric.relativeChangePercent, 20);
|
|
assert.deepEqual(metric.absoluteInterval, { low: 2, high: 2 });
|
|
assert.deepEqual(result, compareRuns(run(), candidate));
|
|
});
|
|
|
|
for (const [name, change] of [
|
|
[
|
|
"profiling features",
|
|
(r) => {
|
|
r.metadata.build.features = ["profile"];
|
|
},
|
|
],
|
|
[
|
|
"build mode",
|
|
(r) => {
|
|
r.metadata.build.mode = "debug";
|
|
},
|
|
],
|
|
[
|
|
"DPR",
|
|
(r) => {
|
|
r.metadata.configuration.dpr = 1;
|
|
},
|
|
],
|
|
[
|
|
"browser",
|
|
(r) => {
|
|
r.metadata.environment.chromium = "124";
|
|
},
|
|
],
|
|
[
|
|
"GPU",
|
|
(r) => {
|
|
r.cases[0].environment.webgl.renderer = "software";
|
|
},
|
|
],
|
|
[
|
|
"seed",
|
|
(r) => {
|
|
r.cases[0].sceneSeed = 456;
|
|
},
|
|
],
|
|
[
|
|
"version",
|
|
(r) => {
|
|
r.cases[0].scenarioVersion = 2;
|
|
},
|
|
],
|
|
[
|
|
"workload",
|
|
(r) => {
|
|
r.cases[0].params.count = 2000;
|
|
},
|
|
],
|
|
[
|
|
"preparation",
|
|
(r) => {
|
|
r.cases[0].preparation = "warm";
|
|
},
|
|
],
|
|
[
|
|
"case set",
|
|
(r) => {
|
|
r.cases[0].id = "different";
|
|
},
|
|
],
|
|
]) {
|
|
test(`comparison refuses incompatible ${name} unless diagnostic override is explicit`, () => {
|
|
const candidate = run();
|
|
change(candidate);
|
|
assert.throws(() => compareRuns(run(), candidate), {
|
|
name: "CompatibilityError",
|
|
});
|
|
const result = compareRuns(run(), candidate, { diagnostic: true });
|
|
assert.equal(result.compatible, false);
|
|
assert.ok(result.mismatches.length > 0);
|
|
assert.match(result.warnings.join(" "), /incompatible/i);
|
|
});
|
|
}
|
|
|
|
test("object key order is immaterial to compatibility", () => {
|
|
const candidate = run();
|
|
candidate.metadata.configuration.viewport = { height: 1080, width: 1920 };
|
|
assert.equal(compareRuns(run(), candidate).compatible, true);
|
|
});
|
|
|
|
test("relative change is unsupported when baseline is zero", () => {
|
|
const metric = compareRuns(run(0), run(1)).cases[0].metrics.render;
|
|
assert.equal(metric.relativeChangePercent, null);
|
|
assert.equal(metric.relativeIntervalPercent, null);
|
|
assert.match(metric.suppressed.relativeChangePercent, /zero/);
|
|
});
|
|
|
|
test("failed attempts never enter comparison observations", () => {
|
|
const candidate = run(12);
|
|
candidate.cases[0].attempts[0].status = "failed";
|
|
const metric = compareRuns(run(), candidate).cases[0].metrics.render;
|
|
assert.equal(metric.candidate.n, 9);
|
|
assert.equal(metric.candidate.invalid, 1);
|
|
assert.equal(metric.absoluteInterval, null);
|
|
});
|
|
|
|
test("comparisons warn when a run failed even if available metrics are compatible", () => {
|
|
const candidate = run(12);
|
|
candidate.status = "failed";
|
|
candidate.cases[0].status = "failed";
|
|
const result = compareRuns(run(), candidate);
|
|
assert.equal(result.compatible, true);
|
|
assert.equal(result.runs.candidate.status, "failed");
|
|
assert.match(formatComparison(result), /candidate run is failed/i);
|
|
});
|
|
|
|
test("offline comparison rejects malformed results without diagnostic bypass", () => {
|
|
const missingEnvironment = run();
|
|
delete missingEnvironment.metadata.environment;
|
|
const duplicateCase = run();
|
|
duplicateCase.cases.push(structuredClone(duplicateCase.cases[0]));
|
|
const invalidMetric = run();
|
|
invalidMetric.cases[0].attempts[0].metrics.render = "12";
|
|
for (const invalid of [
|
|
null,
|
|
{},
|
|
{ schemaVersion: 1 },
|
|
{ schemaVersion: 3 },
|
|
missingEnvironment,
|
|
duplicateCase,
|
|
invalidMetric,
|
|
]) {
|
|
assert.throws(
|
|
() => compareRuns(invalid, run(), { diagnostic: true }),
|
|
/Invalid benchmark result/,
|
|
);
|
|
}
|
|
});
|
|
|
|
test("text comparisons display changes, intervals and incompatibilities", () => {
|
|
const candidate = run(12);
|
|
candidate.metadata.configuration.dpr = 1;
|
|
const report = formatComparison(
|
|
compareRuns(run(), candidate, { diagnostic: true }),
|
|
);
|
|
assert.match(report, /DIAGNOSTIC ONLY/);
|
|
assert.match(report, /MISMATCH metadata.configuration.dpr: 2 -> 1/);
|
|
assert.match(report, /change 2\.000 \(20\.000%\)/);
|
|
assert.match(report, /change interval: \[2\.000, 2\.000\]/);
|
|
});
|
|
|
|
for (const [name, change] of [
|
|
["default features", (r) => (r.metadata.build.defaultFeatures = [])],
|
|
["build env", (r) => (r.metadata.build.env.BUILD_MODE = "debug")],
|
|
["ambient env", (r) => (r.metadata.build.ambientEnv.CARGO_HOME = "/other")],
|
|
]) {
|
|
test(`comparison refuses changed ${name} unless diagnostic override is explicit`, () => {
|
|
const candidate = run();
|
|
change(candidate);
|
|
assert.throws(() => compareRuns(run(), candidate), {
|
|
name: "CompatibilityError",
|
|
});
|
|
const result = compareRuns(run(), candidate, { diagnostic: true });
|
|
assert.equal(result.compatible, false);
|
|
assert.ok(result.mismatches.length > 0);
|
|
});
|
|
}
|
|
|
|
test("ab edge tags the expected feature mismatch without suppressing it", () => {
|
|
const candidate = run();
|
|
candidate.metadata.build.features = ["branch-b"];
|
|
candidate.metadata.build.featurePolicy = "explicit";
|
|
assert.throws(() => compareRuns(run(), candidate), {
|
|
name: "CompatibilityError",
|
|
});
|
|
const compared = compareRuns(run(), candidate, { diagnostic: true });
|
|
assert.equal(compared.compatible, false);
|
|
tagExpectedFeatureDiff(compared, "branch-b");
|
|
const tagged = compared.mismatches.filter((entry) => entry.expected);
|
|
assert.equal(tagged.length, 1);
|
|
assert.deepEqual(tagged[0], {
|
|
path: "metadata.build.features",
|
|
baseline: [],
|
|
candidate: ["branch-b"],
|
|
expected: true,
|
|
toggledFeature: "branch-b",
|
|
});
|
|
});
|