mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-10-06 14:06:32 -04:00
A patch is built in terms of where a line sits in the file's diff, which is what the patch explorer has to hand. The main view doesn't: a row of it resolves to a line of a file, and what index that line has depends on how much of the diff has been read and how a diff renderer chose to lay it out. So let the two meet at the patch builder's edge, in the identity of a change line — its number on the side it belongs to — leaving the main view to speak only of lines it can see. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
76 lines
2.8 KiB
Go
76 lines
2.8 KiB
Go
package patch
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// newTestPatchBuilder returns a patch builder started for a dummy commit, in which
|
|
// every file's diff is the given one.
|
|
func newTestPatchBuilder(diff string) *PatchBuilder {
|
|
patchBuilder := NewPatchBuilder(logrus.New().WithField("test", "test"),
|
|
func(from string, to string, reverse bool, filename string, previousPath string) (string, error) {
|
|
return diff, nil
|
|
})
|
|
patchBuilder.Start("from", "to", false, true)
|
|
return patchBuilder
|
|
}
|
|
|
|
// In simpleDiff the deletion "-orange" is line index 6 of the parsed diff (line 2 of
|
|
// the old file) and the addition "+grape" is index 7 (line 2 of the new file).
|
|
func TestPatchLineIndicesForLines(t *testing.T) {
|
|
patchBuilder := newTestPatchBuilder(simpleDiff)
|
|
|
|
indices, err := patchBuilder.PatchLineIndicesForLines("filename", "", []LineIdentity{
|
|
{LineNumber: 2, IsDeletion: true}, // -orange
|
|
{LineNumber: 2, IsDeletion: false}, // +grape
|
|
{LineNumber: 1, IsDeletion: false}, // " apple", a context line
|
|
})
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, []int{6, 7}, indices, "the context line names no change line")
|
|
}
|
|
|
|
// A renamed file's rename header makes its change lines sit further down the diff, and
|
|
// its old-file line numbers are of the file under its previous name.
|
|
func TestPatchLineIndicesForLinesOfARenamedFile(t *testing.T) {
|
|
patchBuilder := newTestPatchBuilder(renameWithModificationDiff)
|
|
|
|
indices, err := patchBuilder.PatchLineIndicesForLines("newname", "oldname", []LineIdentity{
|
|
{LineNumber: 2, IsDeletion: true}, // -orange
|
|
{LineNumber: 2, IsDeletion: false}, // +grape
|
|
})
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, []int{9, 10}, indices)
|
|
}
|
|
|
|
func TestIncludedLineIdentities(t *testing.T) {
|
|
patchBuilder := newTestPatchBuilder(simpleDiff)
|
|
|
|
// A file no part of the patch has nothing included.
|
|
assert.Empty(t, patchBuilder.IncludedLineIdentities("filename"))
|
|
|
|
// With only the deletion in, only its identity comes back.
|
|
assert.NoError(t, patchBuilder.AddFileLineRange("filename", "", []int{6}))
|
|
assert.Equal(t,
|
|
[]LineIdentity{{LineNumber: 2, IsDeletion: true}},
|
|
patchBuilder.IncludedLineIdentities("filename"))
|
|
|
|
// With the addition in as well, both do.
|
|
assert.NoError(t, patchBuilder.AddFileLineRange("filename", "", []int{7}))
|
|
assert.ElementsMatch(t,
|
|
[]LineIdentity{{LineNumber: 2, IsDeletion: true}, {LineNumber: 2, IsDeletion: false}},
|
|
patchBuilder.IncludedLineIdentities("filename"))
|
|
}
|
|
|
|
// A file taken into the patch whole has every one of its change lines in it.
|
|
func TestIncludedLineIdentitiesOfAWholeFile(t *testing.T) {
|
|
patchBuilder := newTestPatchBuilder(simpleDiff)
|
|
|
|
assert.NoError(t, patchBuilder.AddFileWhole("filename", ""))
|
|
assert.ElementsMatch(t,
|
|
[]LineIdentity{{LineNumber: 2, IsDeletion: true}, {LineNumber: 2, IsDeletion: false}},
|
|
patchBuilder.IncludedLineIdentities("filename"))
|
|
}
|