Compare commits

...
2 changed files with 65 additions and 13 deletions

No files matched your search

@@ -110,3 +110,47 @@ describe("web resource comparison identity and optional size", () => {
}); });
}); });
}); });
it.each([
[[128, 256], [128], [false, true], "unknown"],
[[128], [256], [true, true], "unknown"],
[[128], [128], [true, true], "unknown"],
[[128], [128, 256], [false, true], "changed"],
[[], [128], [false, true], "changed"],
[[128], [], [true, true], "unknown"],
[[128], [null], [false, true], "unknown"],
] as const)(
"uses directional resource coverage for %j vs %j (limited=%j): %s",
(leftSizes, rightSizes, [leftLimited, rightLimited], status) => {
const before = capture(leftSizes.map((size) => resource(size)));
const after = capture(rightSizes.map((size) => resource(size)));
if (leftLimited) before.completeness.truncated_sections.push("resources");
if (rightLimited) after.completeness.truncated_sections.push("resources");
for (const [left, right] of [
[before, after],
[after, before],
] as const)
expect(compareResources(left, right)).toMatchObject({
status,
total_changes: status === "changed" ? 1 : 0,
changes:
status === "changed"
? [
{
identity: expect.stringMatching(/^resg_/u),
change:
left.resources.length === 0
? "added"
: right.resources.length === 0
? "removed"
: "modified",
},
]
: [],
reason:
status === "changed"
? null
: expect.stringContaining("Resource inventory"),
});
},
);
+21 -13
View File
@@ -213,9 +213,8 @@ const compareWebCaptureDimensions = (
resources: compareResources( resources: compareResources(
before.resources, before.resources,
after.resources, after.resources,
sectionsComplete(before, ["resources"]) && sectionsComplete(before, ["resources"]),
sectionsComplete(after, ["resources"]), sectionsComplete(after, ["resources"]),
"Resource inventory or content-size evidence was incomplete in at least one observation.",
), ),
network: networkDimension(before, after), network: networkDimension(before, after),
metadata: compareAggregate( metadata: compareAggregate(
@@ -235,9 +234,12 @@ const compareWebCaptureDimensions = (
const compareResources = ( const compareResources = (
before: WebPageInspection["resources"], before: WebPageInspection["resources"],
after: WebPageInspection["resources"], after: WebPageInspection["resources"],
complete: boolean, beforeComplete: boolean,
reason: string, afterComplete: boolean,
): Dimension => { ): Dimension => {
const reason =
"Resource inventory or content-size evidence was incomplete in at least one observation.";
const complete = beforeComplete && afterComplete;
const left = resourceGroups(before); const left = resourceGroups(before);
const right = resourceGroups(after); const right = resourceGroups(after);
const changes: Change[] = []; const changes: Change[] = [];
@@ -246,12 +248,14 @@ const compareResources = (
const leftSizes = left.get(identity); const leftSizes = left.get(identity);
const rightSizes = right.get(identity); const rightSizes = right.get(identity);
if (leftSizes === undefined || rightSizes === undefined) { if (leftSizes === undefined || rightSizes === undefined) {
if (!complete) unresolved = true; const absenceProven =
else leftSizes === undefined ? beforeComplete : afterComplete;
if (absenceProven)
changes.push({ changes.push({
identity, identity,
change: leftSizes === undefined ? "added" : "removed", change: leftSizes === undefined ? "added" : "removed",
}); });
else unresolved = true;
continue; continue;
} }
// Stable inventories deduplicate identical observations. A null size also // Stable inventories deduplicate identical observations. A null size also
@@ -261,7 +265,12 @@ const compareResources = (
unresolved = true; unresolved = true;
continue; continue;
} }
if (!sameResourceSizes(leftSizes, rightSizes)) // A partial set can omit any size variant. Only a complete peer can
// contradict a retained variant, including when the other side is partial.
if (
(beforeComplete && !resourceSizesContained(rightSizes, leftSizes)) ||
(afterComplete && !resourceSizesContained(leftSizes, rightSizes))
)
changes.push({ identity, change: "modified" }); changes.push({ identity, change: "modified" });
} }
if (changes.length > 0) if (changes.length > 0)
@@ -292,11 +301,10 @@ const resourceGroups = (
return groups; return groups;
}; };
const sameResourceSizes = ( const resourceSizesContained = (
left: ReadonlySet<number | null>, observed: ReadonlySet<number | null>,
right: ReadonlySet<number | null>, complete: ReadonlySet<number | null>,
): boolean => ): boolean => [...observed].every((size) => complete.has(size));
left.size === right.size && [...left].every((size) => right.has(size));
type BodyShapeSources = { type BodyShapeSources = {
readonly request: boolean; readonly request: boolean;