diff --git a/.changeset/law-credit-label.md b/.changeset/law-credit-label.md new file mode 100644 index 0000000..e330623 --- /dev/null +++ b/.changeset/law-credit-label.md @@ -0,0 +1,5 @@ +--- +'@tanstack/oracles': patch +--- + +The gap report's per-law table is now titled "First law to reject, by law". It says that each count credits only the first law that rejected a history, because a check returns its first violation and a later law on the same history is not checked. A law with no count is not shown to reject nothing. The section's next step tells the author to add a history that varies the input the law judges. diff --git a/packages/oracles/oracle-gaps/gap-report-classify-oracle.property.test.mjs b/packages/oracles/oracle-gaps/gap-report-classify-oracle.property.test.mjs index 821f915..80976b1 100644 --- a/packages/oracles/oracle-gaps/gap-report-classify-oracle.property.test.mjs +++ b/packages/oracles/oracle-gaps/gap-report-classify-oracle.property.test.mjs @@ -883,7 +883,7 @@ function model(h) { // sentence after its directive. const boundaryLine = `Add a boundary history with -0 and 0.` // The kills-by-law section's one next step for a law that rejects no mutant. -const killsDirective = `To find a law that rejects no mutant, add a history that varies the input the law judges, and run the check again.` +const killsDirective = `Each count credits only the first law that rejected a history: a later law on the same history is not checked. To test a law with no count, add a history that varies the input the law judges, and run the check again.` const exits = /equivalen|maintainer|approv|allowance|either|whether|\bor\b|\bif no\b|limit|accept|\?|\bsay\b/i const directives = { @@ -1295,7 +1295,9 @@ async function driver(h, observe) { streamed: printer ? [...report.gapsOf(results)].reverse().map((r) => printer.gapLine(r)) : undefined, - killsSection: summary.slice(summary.indexOf(`## Kills by law`)), + killsSection: summary.slice( + summary.indexOf(`## First law to reject, by law`), + ), // What results.json keeps of each mutant's change, after the printing. kept: results.map((r) => r.authored ? r.intent : [String(r.original), String(r.replacement)], diff --git a/packages/oracles/oracle-gaps/report.mjs b/packages/oracles/oracle-gaps/report.mjs index 6b023bf..d83b75b 100644 --- a/packages/oracles/oracle-gaps/report.mjs +++ b/packages/oracles/oracle-gaps/report.mjs @@ -172,7 +172,10 @@ const placeholders = { const legendOf = (kind) => directive[kind]({ ...placeholders, outcome: kind }) // What the author does about a law that rejects no mutant: one next step. -const killsDirective = `To find a law that rejects no mutant, add a history that varies the input the law judges, and run the check again.` +// The table credits each history's first rejecting law only: a check returns +// its first violation, so a later law on the same history is never judged. +// The count says which law rejected first, not which laws can reject. +const killsDirective = `Each count credits only the first law that rejected a history: a later law on the same history is not checked. To test a law with no count, add a history that varies the input the law judges, and run the check again.` export function gapsOf(results) { return results.filter( @@ -290,11 +293,11 @@ export function renderReport({ results, run, excluded }) { for (const law of result.laws ?? []) byLaw.set(law, (byLaw.get(law) ?? 0) + 1) lines.push( - `## Kills by law`, + `## First law to reject, by law`, ``, killsDirective, ``, - `| Law | Mutants it rejected |`, + `| Law | Mutants it rejected first |`, `|---|---|`, ...[...byLaw] .sort((a, b) => b[1] - a[1])