Skip to content

Commit a391caf

Browse files
fix(tooling): scope an expectation to every fixture its group reaches
A source-scoped entry matched a group as soon as one of its fixtures matched, so the same repro found somewhere the entry does not name was suppressed with it. Covers findingGroups' classification in the unit suite, which reached none of it.
1 parent eab6e58 commit a391caf

2 files changed

Lines changed: 101 additions & 2 deletions

File tree

‎test/unitCases/CompareToolsHarness.unittest.js‎

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const {
88
compress,
99
exists,
1010
filterFrom,
11+
findingGroups,
1112
formatCost,
1213
installPackages,
1314
kb,
@@ -545,4 +546,100 @@ describe("compare-tools-harness", () => {
545546
expect(wanted("csso")).toBe(false);
546547
});
547548
});
549+
550+
describe("findingGroups", () => {
551+
/**
552+
* @param {string} relation what the finding is about
553+
* @param {string} repro the lines reproducing it
554+
* @returns {import("../../tooling/compare-tools-harness").Report} the finding
555+
*/
556+
const finding = (relation, repro) => ({ relation, what: "bytes", repro });
557+
558+
/**
559+
* @param {ReturnType<typeof findingGroups>} groups the collector
560+
* @returns {{ text: string, count: number }} what it wrote and counted
561+
*/
562+
const written = (groups) => {
563+
let text = "";
564+
const count = groups.write((line) => {
565+
text += line;
566+
});
567+
return { text, count };
568+
};
569+
570+
it("names a finding no entry expects, and counts it", () => {
571+
const groups = findingGroups();
572+
groups.add(finding("idempotence", " a -> b"), "default", "one.html");
573+
const { text, count } = written(groups);
574+
expect(count).toBe(1);
575+
expect(text).toContain("idempotence — bytes");
576+
expect(text).toContain("one.html");
577+
});
578+
579+
it("gathers one repro found in several sources into one finding", () => {
580+
const groups = findingGroups();
581+
groups.add(finding("idempotence", " a -> b"), "default", "one.html");
582+
groups.add(finding("idempotence", " a -> b"), "aggressive", "two.html");
583+
const { text, count } = written(groups);
584+
expect(count).toBe(1);
585+
expect(text).toContain("2 sources, from one.html");
586+
expect(text).toContain("[default, aggressive]");
587+
});
588+
589+
it("counts an expected finding apart, and says why it is owed nothing", () => {
590+
const groups = findingGroups([
591+
{ relation: "idempotence", contains: "a ->", why: "the spec says so" }
592+
]);
593+
groups.add(finding("idempotence", " a -> b"), "default", "one.html");
594+
const { text, count } = written(groups);
595+
expect(count).toBe(0);
596+
expect(text).toContain("expected, and why — 1 of 1");
597+
expect(text).toContain("the spec says so");
598+
});
599+
600+
it("expects nothing on a relation or a repro the entry does not name", () => {
601+
const groups = findingGroups([
602+
{ relation: "idempotence", contains: "a ->", why: "…" }
603+
]);
604+
groups.add(finding("respelling", " a -> b"), "default", "one.html");
605+
groups.add(finding("idempotence", " c -> d"), "default", "two.html");
606+
expect(written(groups).count).toBe(3);
607+
});
608+
609+
it("reports an entry that matched nothing as stale", () => {
610+
const groups = findingGroups([
611+
{ relation: "idempotence", contains: "gone", why: "…" }
612+
]);
613+
const { text, count } = written(groups);
614+
expect(count).toBe(1);
615+
expect(text).toContain("stale — 1 expectation(s) matched nothing");
616+
expect(text).toContain("idempotence: gone");
617+
});
618+
619+
it("lets a source-scoped entry cover the fixture it names", () => {
620+
const groups = findingGroups([
621+
{
622+
relation: "idempotence",
623+
contains: "a ->",
624+
source: "one",
625+
why: "that fixture writes it"
626+
}
627+
]);
628+
groups.add(finding("idempotence", " a -> b"), "default", "one.html");
629+
expect(written(groups).count).toBe(0);
630+
});
631+
632+
it("leaves a group unexpected where it reaches a fixture the entry omits", () => {
633+
const groups = findingGroups([
634+
{ relation: "idempotence", contains: "a ->", source: "one", why: "…" }
635+
]);
636+
groups.add(finding("idempotence", " a -> b"), "default", "one.html");
637+
groups.add(finding("idempotence", " a -> b"), "default", "other.html");
638+
const { text, count } = written(groups);
639+
// The finding itself, and the entry that then covers nothing.
640+
expect(count).toBe(2);
641+
expect(text).toContain("idempotence — bytes");
642+
expect(text).toContain("stale — 1 expectation(s) matched nothing");
643+
});
644+
});
548645
});

‎tooling/compare-tools-harness.js‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -587,10 +587,12 @@ const _covers = (expected, report, sources) => {
587587
if (expected.relation !== report.relation) return false;
588588
if (!report.repro.includes(expected.contains)) return false;
589589
if (expected.source === undefined) return true;
590+
// Every fixture the group reaches, not any one of them: the same repro found
591+
// somewhere the entry does not name is a divergence it says nothing about.
590592
for (const source of sources) {
591-
if (source.includes(expected.source)) return true;
593+
if (!source.includes(expected.source)) return false;
592594
}
593-
return false;
595+
return true;
594596
};
595597

596598
/**

0 commit comments

Comments
 (0)