Files
orca/config/scripts/check-changed-code-quality.test.mjs
T
Neil 6faaf3af74 fix(lint): match moved code by ordered near-match, not strict contiguity (#16385)
A diagnostic's span often reaches past the block a split moved — most commonly
to a hook dependency array, which legitimately grows when closure variables
become props. Requiring every line of the span to match contiguously reported
the moved body as new.

The block must still start at the same line in the base and appear in order,
and >=90% of it must be present. Genuinely new code shares neither the anchor
nor the ordering.
2026-08-24 23:17:04 -07:00

107 lines
3.9 KiB
JavaScript

import { describe, expect, it } from 'vitest'
import {
OXLINT_SCANS,
diagnosticTouchesAddedLines,
isMovedCode,
overlapsAddedLines,
parseAddedLineRanges
} from './check-changed-code-quality.mjs'
describe('changed-code quality line matching', () => {
it('parses added and replaced hunk ranges while ignoring deletions', () => {
const ranges = parseAddedLineRanges(
['@@ -10,2 +10,3 @@', '@@ -20 +21 @@', '@@ -40,4 +42,0 @@', '@@ -50 +48,2 @@'].join('\n')
)
expect(ranges).toEqual([
{ start: 10, end: 12 },
{ start: 21, end: 21 },
{ start: 48, end: 49 }
])
})
it('matches diagnostics that overlap any added line', () => {
const ranges = [
{ start: 5, end: 7 },
{ start: 12, end: 12 }
]
expect(overlapsAddedLines(3, 5, ranges)).toBe(true)
expect(overlapsAddedLines(8, 11, ranges)).toBe(false)
expect(overlapsAddedLines(12, 14, ranges)).toBe(true)
})
it('normalizes absolute diagnostic paths before matching', () => {
const root = process.cwd()
const file = 'config/scripts/check-changed-code-quality.test.mjs'
const diagnostic = {
filename: `${root}/${file}`,
labels: [{ span: { line: 24 } }]
}
expect(
diagnosticTouchesAddedLines(diagnostic, new Map([[file, [{ start: 24, end: 24 }]]]), root)
).toBe(true)
})
// Why: pinning --config disables nested-config discovery, so root rules that
// mobile/.oxlintrc.json turns off would fail the gate on mobile files.
it('lets the untyped scan discover nested configs instead of pinning the root config', () => {
const scan = OXLINT_SCANS.find((candidate) => candidate.label === 'code quality')
expect(scan.args).not.toContain('--config')
expect(scan.args).not.toContain('--disable-nested-config')
})
})
describe('moved-code exemption', () => {
it('treats a verbatim contiguous block from the base as moved', () => {
const base = [['const a = 1', 'items.map((item, index) => (', 'key={index}', '))']]
expect(isMovedCode(['items.map((item, index) => (', 'key={index}', '))'], base)).toBe(true)
})
it('ignores indentation and whitespace changes from the move', () => {
const base = [[' items.map((item, index) => (', ' key={index}']]
expect(isMovedCode(['items.map((item, index) => (', 'key={index}'], base)).toBe(true)
})
it('does not exempt a genuinely new violation', () => {
const base = [['const a = 1', 'const b = 2']]
expect(isMovedCode(['rows.map((row, i) => <td key={i} />)'], base)).toBe(false)
})
it('does not exempt a block that is only partly present in the base', () => {
const base = [['doThing()', 'unrelated()']]
expect(isMovedCode(['doThing()', 'newlyAddedSideEffect()'], base)).toBe(false)
})
it('tolerates a few lines appended inside the moved block', () => {
// A split commonly grows a hook dependency array when closure variables
// become props; the moved body around it is still moved.
const body = Array.from({ length: 20 }, (_, i) => `line${i}()`)
const base = [body]
const moved = [...body.slice(0, 19), 'newDep,', body[19]]
expect(isMovedCode(moved, base)).toBe(true)
})
it('does not exempt when the anchor line is absent from the base', () => {
const base = [['doThing()', 'filler()', 'other()']]
expect(isMovedCode(['brandNewCall()', 'doThing()', 'other()'], base)).toBe(false)
})
it('does not exempt when most of the block is absent from the base', () => {
const base = [['keep0()', 'keep1()', 'unrelated()']]
const mostlyNew = ['keep0()', ...Array.from({ length: 18 }, (_, i) => `fresh${i}()`)]
expect(isMovedCode(mostlyNew, base)).toBe(false)
})
it('ignores blank lines when matching', () => {
const base = [['a()', 'b()']]
expect(isMovedCode(['a()', '', 'b()'], base)).toBe(true)
})
it('never exempts an empty highlight', () => {
expect(isMovedCode(['', ' '], [['a()']])).toBe(false)
})
})