mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-05 23:02:10 +03:00
fix(ci): exclude check-test-masking.test.ts fixtures from self-referential tautology gate (#6634) (#6884)
* fix(ci): exclude check-test-masking.test.ts fixtures from self-referential tautology gate (#6634) * fix(ci): extend test-masking self-fixture exclusion to sibling gate regression files (#6634) The #6634 fix added isSelfTestFixtureFile()/scanBareTautologies() exclusions that only matched check-test-masking.test.ts exactly. Its own new regression file check-test-masking-selfref-6634.test.ts also embeds tautology-pattern literals as fixtures/documentation, so the absolute-floor scanBareTautologies gate self-tripped a HARD failure on the PR's own file. Generalize the exclusion to the whole check-test-masking* self-test family and lock it with two regression tests.
This commit is contained in:
committed by
GitHub
parent
993f280c4b
commit
ec1e79b8a7
1
changelog.d/fixes/6634-6634-testmasking-selfref.md
Normal file
1
changelog.d/fixes/6634-6634-testmasking-selfref.md
Normal file
@@ -0,0 +1 @@
|
||||
- fix(ci): exclude check-test-masking.test.ts's own tautology fixtures from the diff-based test-masking gate and recognize `✗` in validate-release-green's failure-line detector (#6634)
|
||||
@@ -319,6 +319,26 @@ export function partitionDeletedRenamed(nameStatusOutput) {
|
||||
* Os campos de skip e extTaut são opcionais (default 0) para compatibilidade
|
||||
* com chamadas legadas que só passam baseAsserts/headAsserts/baseTaut/headTaut.
|
||||
*/
|
||||
/**
|
||||
* (#6634) `check-test-masking.test.ts` legitimately embeds tautology-pattern string
|
||||
* literals (`assert.ok(true)`, `expect(true).toBe(true)`, `assert.equal(1,1)`) as
|
||||
* FIXTURES to exercise `countBareTautologies()`/`scanBareTautologies()` (#6404). The
|
||||
* diff-based tautology counters (`countTautologies()`/`countExtendedTautologies()`)
|
||||
* are dumb regex scans of raw source text with no awareness that a literal sits
|
||||
* inside a fixture string rather than real assertion code, so any new fixture line
|
||||
* self-trips a HARD "new tautology" flag on the gate's own regression-test file.
|
||||
* Mirrors the exclusion `scanBareTautologies()` already applies for the same reason.
|
||||
*
|
||||
* The exclusion covers the whole `check-test-masking*` gate self-test family — not
|
||||
* just `check-test-masking.test.ts` but sibling regression files such as
|
||||
* `check-test-masking-selfref-6634.test.ts`, which likewise embed tautology-pattern
|
||||
* literals as fixtures/documentation to prove this gate's own behavior.
|
||||
*/
|
||||
const SELF_TEST_FIXTURE_RE = /(^|\/)check-test-masking(-[\w-]+)?\.test\.tsx?$/;
|
||||
function isSelfTestFixtureFile(file) {
|
||||
return SELF_TEST_FIXTURE_RE.test(file);
|
||||
}
|
||||
|
||||
export function evaluateMasking(perFile, assertReductionAllowlist = new Set()) {
|
||||
const flags = [];
|
||||
for (const f of perFile) {
|
||||
@@ -326,6 +346,7 @@ export function evaluateMasking(perFile, assertReductionAllowlist = new Set()) {
|
||||
const headSkips = f.headSkips ?? 0;
|
||||
const baseExtTaut = f.baseExtTaut ?? 0;
|
||||
const headExtTaut = f.headExtTaut ?? 0;
|
||||
const isSelfTestFixture = isSelfTestFixtureFile(f.file);
|
||||
|
||||
// The net-assert-REDUCTION signal can be allowlisted per file when the reduction is a
|
||||
// verified-legitimate refactor/field-removal (config/quality/test-masking-allowlist.json).
|
||||
@@ -334,13 +355,13 @@ export function evaluateMasking(perFile, assertReductionAllowlist = new Set()) {
|
||||
flags.push(
|
||||
`${f.file}: asserts ${f.baseAsserts} → ${f.headAsserts} (REMOÇÃO de ${f.baseAsserts - f.headAsserts} — enfraquecimento?)`
|
||||
);
|
||||
if (f.headTaut > f.baseTaut)
|
||||
if (!isSelfTestFixture && f.headTaut > f.baseTaut)
|
||||
flags.push(`${f.file}: nova(s) ${f.headTaut - f.baseTaut} tautologia(s) assert.ok(true)`);
|
||||
if (headSkips > baseSkips)
|
||||
flags.push(
|
||||
`${f.file}: ${headSkips - baseSkips} novo(s) .skip/.todo/.only (asserts silenciados sem remoção)`
|
||||
);
|
||||
if (headExtTaut > baseExtTaut)
|
||||
if (!isSelfTestFixture && headExtTaut > baseExtTaut)
|
||||
flags.push(
|
||||
`${f.file}: nova(s) ${headExtTaut - baseExtTaut} tautologia(s) estendida(s) (expect(true).toBe(true) / assert.equal(1,1))`
|
||||
);
|
||||
@@ -374,7 +395,7 @@ export function scanBareTautologies(testFiles, readFile) {
|
||||
const read = readFile || ((f) => fs.readFileSync(f, "utf8"));
|
||||
const flags = [];
|
||||
for (const file of testFiles || []) {
|
||||
if (file.endsWith("check-test-masking.test.ts")) continue;
|
||||
if (isSelfTestFixtureFile(file)) continue;
|
||||
let src;
|
||||
try {
|
||||
src = read(file);
|
||||
|
||||
@@ -96,7 +96,9 @@ export function firstFailureLine(out) {
|
||||
.split("\n")
|
||||
.map((l) => l.trim())
|
||||
.filter(Boolean);
|
||||
const hit = lines.find((l) => /✖|not ok|AssertionError|error TS|FAIL|Error:|REGRESS/i.test(l));
|
||||
const hit = lines.find((l) =>
|
||||
/✖|✗|not ok|AssertionError|error TS|FAIL|Error:|REGRESS/i.test(l)
|
||||
);
|
||||
return (hit || lines[lines.length - 1] || "failed").slice(0, 200);
|
||||
}
|
||||
|
||||
|
||||
84
tests/unit/check-test-masking-selfref-6634.test.ts
Normal file
84
tests/unit/check-test-masking-selfref-6634.test.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Regression test for issue #6634 ("release/v3.8.47 branch not green — nightly
|
||||
* release-green found HARD failures"). The nightly's "Test-masking
|
||||
* (weakened-assert guard)" HARD failure was a SELF-REFERENTIAL false positive:
|
||||
* tests/unit/check-test-masking.test.ts legitimately embeds tautology-pattern
|
||||
* string literals (e.g. `expect(true).toBe(true);`, `assert.equal(1, 1);`) as
|
||||
* FIXTURES to exercise countBareTautologies()/scanBareTautologies() — the same
|
||||
* literal text that the diff-based subcheck (evaluateMasking(), fed by
|
||||
* countTautologies()/countExtendedTautologies()) treated as "new tautologies in
|
||||
* the file itself" because those counters are dumb regex scans of raw source
|
||||
* text, blind to "this is inside a fixture string, not real assertion code".
|
||||
*
|
||||
* scanBareTautologies() already special-cases this exact file
|
||||
* (`if (file.endsWith("check-test-masking.test.ts")) continue;` in
|
||||
* scripts/check/check-test-masking.mjs) for precisely this reason — this test
|
||||
* asserts evaluateMasking() now applies the same exclusion for its diff-based
|
||||
* tautology counters, using the real base(origin/main)/head(HEAD) diff of
|
||||
* tests/unit/check-test-masking.test.ts.
|
||||
*/
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { execFileSync } from "node:child_process";
|
||||
|
||||
import {
|
||||
countTautologies,
|
||||
countExtendedTautologies,
|
||||
evaluateMasking,
|
||||
} from "../../scripts/check/check-test-masking.mjs";
|
||||
|
||||
const FILE = "tests/unit/check-test-masking.test.ts";
|
||||
|
||||
function git(args: string[]): string {
|
||||
return execFileSync("git", args, { encoding: "utf8" });
|
||||
}
|
||||
|
||||
test("#6634: check-test-masking.test.ts's own tautology fixtures must not self-flag as weakening", () => {
|
||||
// origin/main predates the #6404 fixtures (countBareTautologies/scanBareTautologies
|
||||
// tests) that legitimately embed tautology-pattern literals as string fixtures.
|
||||
const baseSrc = git(["show", "origin/main:" + FILE]);
|
||||
const headSrc = git(["show", "HEAD:" + FILE]);
|
||||
|
||||
const perFile = [
|
||||
{
|
||||
file: FILE,
|
||||
baseAsserts: 0, // irrelevant to this assertion — only tautology counters matter
|
||||
headAsserts: 0,
|
||||
baseTaut: countTautologies(baseSrc),
|
||||
headTaut: countTautologies(headSrc),
|
||||
baseExtTaut: countExtendedTautologies(baseSrc),
|
||||
headExtTaut: countExtendedTautologies(headSrc),
|
||||
},
|
||||
];
|
||||
|
||||
const flags = evaluateMasking(perFile, new Set());
|
||||
|
||||
assert.deepEqual(
|
||||
flags,
|
||||
[],
|
||||
"check-test-masking.test.ts's own literal tautology fixtures (added for #6404) must be " +
|
||||
"excluded from the diff-based weakening check the same way scanBareTautologies() already " +
|
||||
"excludes this file from the absolute-floor scan — otherwise the gate's own regression " +
|
||||
"test permanently self-flags as a HARD release-green failure whenever new fixtures are added."
|
||||
);
|
||||
});
|
||||
|
||||
test("#6634: unrelated files still get flagged for genuinely new tautologies (guard is file-scoped, not global)", () => {
|
||||
const perFile = [
|
||||
{
|
||||
file: "tests/unit/some-other-file.test.ts",
|
||||
baseAsserts: 5,
|
||||
headAsserts: 5,
|
||||
baseTaut: 0,
|
||||
headTaut: 1,
|
||||
baseExtTaut: 0,
|
||||
headExtTaut: 1,
|
||||
},
|
||||
];
|
||||
|
||||
const flags = evaluateMasking(perFile, new Set());
|
||||
|
||||
assert.equal(flags.length, 2, "a non-fixture file must still trip both tautology signals");
|
||||
assert.match(flags[0], /nova\(s\) 1 tautologia\(s\) assert\.ok\(true\)/);
|
||||
assert.match(flags[1], /nova\(s\) 1 tautologia\(s\) estendida/);
|
||||
});
|
||||
@@ -330,6 +330,21 @@ test("scanBareTautologies: excludes check-test-masking.test.ts itself", () => {
|
||||
assert.deepEqual(scanBareTautologies(files, read), []);
|
||||
});
|
||||
|
||||
test("scanBareTautologies: excludes sibling gate self-test files (#6634 selfref regression)", () => {
|
||||
// The gate's own regression files (e.g. check-test-masking-selfref-6634.test.ts)
|
||||
// embed tautology-pattern literals as fixtures/documentation — the family-wide
|
||||
// exclusion must cover them too, not only check-test-masking.test.ts itself.
|
||||
const files = ["tests/unit/check-test-masking-selfref-6634.test.ts"];
|
||||
const read = () => `assert.equal(1, 1);`;
|
||||
assert.deepEqual(scanBareTautologies(files, read), []);
|
||||
});
|
||||
|
||||
test("scanBareTautologies: a non-family file with the pattern is still flagged (exclusion is scoped)", () => {
|
||||
const files = ["tests/unit/some-unrelated.test.ts"];
|
||||
const read = () => `assert.equal(1, 1);`;
|
||||
assert.equal(scanBareTautologies(files, read).length, 1);
|
||||
});
|
||||
|
||||
test("scanBareTautologies: skips unreadable files instead of throwing", () => {
|
||||
const files = ["tests/unit/does-not-exist.test.ts"];
|
||||
const read = () => {
|
||||
|
||||
Reference in New Issue
Block a user