fix(review): group a triplet's findings title first, so arrival order never changes the rows
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
7175783ce5
commit
a5fcb5e8b4
6 changed files with 339 additions and 37 deletions
|
|
@ -637,3 +637,64 @@ test('armB — two different /code-review findings on one triplet stay two rows
|
|||
});
|
||||
assert.deepEqual(c.merged.map((f) => f.title).sort(), ['A lone CR does not split lines', 'EAGAIN on stdin']);
|
||||
});
|
||||
|
||||
// ---- ORD sibling: the workflow's inlined dedup does not depend on arrival order ----
|
||||
|
||||
test('[ORD] sibling: workflow — conformance B with /code-review A and B, in both engine orders, gives one row of A alone and one row of both B findings', async () => {
|
||||
const K = 'CODE_REVIEW_DEFECT';
|
||||
const engineA = F(K, 'MINOR', { title: 'A' });
|
||||
const engineB = F(K, 'MAJOR', { title: 'B' });
|
||||
for (const codeFindings of [[engineA, engineB], [engineB, engineA]]) {
|
||||
const name = codeFindings.map((f) => f.title).join(', ');
|
||||
const c = await floorCase({
|
||||
reviewerFindings: [F(K, 'MINOR', { title: 'B' })],
|
||||
codeFindings,
|
||||
returned: [],
|
||||
verdict: 'WARN',
|
||||
});
|
||||
const rows = c.merged.filter((m) => triplet(m) === triplet(F(K, 'MINOR')));
|
||||
assert.equal(rows.length, 2, `engine order ${name}: ${JSON.stringify(rows)}`);
|
||||
const got = rows
|
||||
.map((m) => ({ title: m.title, engine: m.engine ?? null, severity: m.severity }))
|
||||
.sort((x, y) => x.title.localeCompare(y.title));
|
||||
// A alone: the /code-review A finding survives with its own MINOR. Both B
|
||||
// findings: the conformance B finding survives (a reviewer over an engine)
|
||||
// at the MAJOR the /code-review B finding asserted.
|
||||
assert.deepEqual(got, [
|
||||
{ title: 'A', engine: 'code-review', severity: 'MINOR' },
|
||||
{ title: 'B', engine: null, severity: 'MAJOR' },
|
||||
], `engine order ${name}`);
|
||||
}
|
||||
});
|
||||
|
||||
test('[ORD] sibling: workflow — the title classes are placed in alphabetical order: conformance B with /code-review A, B and an untitled BLOCKER gives {A, untitled} BLOCKER kept as A and {B, B} MAJOR in all 6 engine orders', async () => {
|
||||
const K = 'CODE_REVIEW_DEFECT';
|
||||
const engineA = F(K, 'BLOCKER', { title: 'A' });
|
||||
const engineB = F(K, 'MINOR', { title: 'B' });
|
||||
const { title: _t, ...engineU } = F(K, 'BLOCKER');
|
||||
// The workflow reads the reviewer findings first, so class B always arrives
|
||||
// first: only the alphabetical order puts the untitled finding in A's row.
|
||||
// A and the untitled finding tie on every survivor rule, so the first in the
|
||||
// group's order (class A before the untitled findings) is kept.
|
||||
const engineOrders = [
|
||||
[engineA, engineB, engineU], [engineA, engineU, engineB], [engineB, engineA, engineU],
|
||||
[engineB, engineU, engineA], [engineU, engineA, engineB], [engineU, engineB, engineA],
|
||||
];
|
||||
for (const codeFindings of engineOrders) {
|
||||
const name = codeFindings.map((f) => f.title ?? 'U').join(', ');
|
||||
const c = await floorCase({
|
||||
reviewerFindings: [F(K, 'MAJOR', { title: 'B' })],
|
||||
codeFindings,
|
||||
returned: [],
|
||||
verdict: 'WARN',
|
||||
});
|
||||
const rows = c.merged.filter((m) => triplet(m) === triplet(F(K, 'MINOR')));
|
||||
const got = rows
|
||||
.map((m) => ({ title: m.title ?? null, engine: m.engine ?? null, severity: m.severity }))
|
||||
.sort((x, y) => String(x.title).localeCompare(String(y.title)));
|
||||
assert.deepEqual(got, [
|
||||
{ title: 'A', engine: 'code-review', severity: 'BLOCKER' },
|
||||
{ title: 'B', engine: null, severity: 'MAJOR' },
|
||||
], `engine order ${name}`);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue