Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion src/tools/FileEditTool/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { describe, expect, test } from 'bun:test'
import { findWhitespaceAgnosticMatch, adjustNewStringIndentation } from './utils.js'
import {
findWhitespaceAgnosticMatch,
adjustNewStringIndentation,
getSnippetForTwoFileDiff,
} from './utils.js'

describe('findWhitespaceAgnosticMatch', () => {
test('returns exact match for simple string', () => {
Expand Down Expand Up @@ -180,3 +184,29 @@ describe('adjustNewStringIndentation', () => {
expect(adjustNewStringIndentation(oldString, fileMatch, newString)).toBeNull()
})
})

describe('getSnippetForTwoFileDiff truncation notice', () => {
test('reports the exact number of dropped lines when cutting at a line boundary', () => {
// A full-replacement diff of an empty file with a large file yields a single
// hunk whose line-numbered snippet far exceeds DIFF_SNIPPET_MAX_BYTES (8192),
// forcing truncation at a line boundary.
const bigFile =
Array.from({ length: 800 }, (_, i) => `line ${i + 1} content here`).join(
'\n',
) + '\n'
const snippet = getSnippetForTwoFileDiff('', bigFile)

const match = snippet.match(/\.\.\. \[(\d+) lines truncated\] \.\.\./)
expect(match).not.toBeNull()
const reportedTruncated = Number(match![1])

// The snippet body before the marker holds the kept lines. Together with the
// reported truncated count they must sum to the total lines the untruncated
// snippet would have shown — here, the 800 added lines. Before the fix the
// boundary newline was double-counted and this reported 801.
const keptBody = snippet.slice(0, snippet.indexOf('\n\n... ['))
const keptLines = keptBody.split('\n').length

expect(keptLines + reportedTruncated).toBe(800)
})
})
19 changes: 16 additions & 3 deletions src/tools/FileEditTool/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,9 +399,22 @@ export function getSnippetForTwoFileDiff(
// Truncate at the last line boundary that fits within the cap.
// Marker format matches BashTool/utils.ts.
const cutoff = full.lastIndexOf('\n', DIFF_SNIPPET_MAX_BYTES)
const kept =
cutoff > 0 ? full.slice(0, cutoff) : full.slice(0, DIFF_SNIPPET_MAX_BYTES)
const remaining = countCharInString(full, '\n', kept.length) + 1
let kept: string
let remaining: number
if (cutoff > 0) {
kept = full.slice(0, cutoff)
// `full[cutoff]` is the newline that terminates the last kept line, so
// counting newlines from `cutoff` onward counts that boundary newline plus
// every later one — exactly the number of dropped lines. No `+1`: the
// boundary newline is not itself a dropped line, it stands in for the
// missing trailing newline of the final dropped line.
remaining = countCharInString(full, '\n', cutoff)
} else {
kept = full.slice(0, DIFF_SNIPPET_MAX_BYTES)
// Mid-line cut (no newline within the cap): the partial tail line and every
// following line are dropped, so add 1 for that partial line.
remaining = countCharInString(full, '\n', kept.length) + 1
}
return `${kept}\n\n... [${remaining} lines truncated] ...`
}

Expand Down