diff --git a/pkg/gui/assert.go b/pkg/gui/assert.go index 43ecc26d8..253278220 100644 --- a/pkg/gui/assert.go +++ b/pkg/gui/assert.go @@ -2,8 +2,10 @@ package gui import ( "fmt" + "strings" "time" + guiTypes "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/integration/types" ) @@ -67,8 +69,23 @@ func (self *AssertImpl) CurrentBranchName(expectedViewName string) { }) } +func (self *AssertImpl) InListContext() { + self.assertWithRetries(func() (bool, string) { + currentContext := self.gui.currentContext() + _, ok := currentContext.(guiTypes.IListContext) + return ok, fmt.Sprintf("Expected current context to be a list context, but got %s", currentContext.GetKey()) + }) +} + +func (self *AssertImpl) SelectedLineContains(text string) { + self.assertWithRetries(func() (bool, string) { + line := self.gui.currentContext().GetView().SelectedLine() + return strings.Contains(line, text), fmt.Sprintf("Expected selected line to contain '%s', but got '%s'", text, line) + }) +} + func (self *AssertImpl) assertWithRetries(test func() (bool, string)) { - waitTimes := []int{0, 100, 200, 400, 800, 1600} + waitTimes := []int{0, 1, 5, 10, 200, 500, 1000} var message string for _, waitTime := range waitTimes { @@ -81,6 +98,10 @@ func (self *AssertImpl) assertWithRetries(test func() (bool, string)) { } } + self.Fail(message) +} + +func (self *AssertImpl) Fail(message string) { self.gui.g.Close() // need to give the gui time to close time.Sleep(time.Millisecond * 100) diff --git a/pkg/gui/input.go b/pkg/gui/input.go index c6424c077..111d0de8e 100644 --- a/pkg/gui/input.go +++ b/pkg/gui/input.go @@ -1,29 +1,45 @@ package gui import ( + "fmt" + "strings" "time" "github.com/gdamore/tcell/v2" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/gui/keybindings" + guiTypes "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/integration/types" ) type InputImpl struct { - g *gocui.Gui - keys config.KeybindingConfig + gui *Gui + keys config.KeybindingConfig + assert types.Assert + pushKeyDelay int +} + +func NewInputImpl(gui *Gui, keys config.KeybindingConfig, assert types.Assert, pushKeyDelay int) *InputImpl { + return &InputImpl{ + gui: gui, + keys: keys, + assert: assert, + pushKeyDelay: pushKeyDelay, + } } var _ types.Input = &InputImpl{} -func (self *InputImpl) PushKeys(keyStrs ...string) { +func (self *InputImpl) PressKeys(keyStrs ...string) { for _, keyStr := range keyStrs { - self.pushKey(keyStr) + self.pressKey(keyStr) } } -func (self *InputImpl) pushKey(keyStr string) { +func (self *InputImpl) pressKey(keyStr string) { + self.Wait(self.pushKeyDelay) + key := keybindings.GetKey(keyStr) var r rune @@ -36,58 +52,115 @@ func (self *InputImpl) pushKey(keyStr string) { tcellKey = tcell.Key(v) } - self.g.ReplayedEvents.Keys <- gocui.NewTcellKeyEventWrapper( + self.gui.g.ReplayedEvents.Keys <- gocui.NewTcellKeyEventWrapper( tcell.NewEventKey(tcellKey, r, tcell.ModNone), 0, ) } func (self *InputImpl) SwitchToStatusWindow() { - self.pushKey(self.keys.Universal.JumpToBlock[0]) + self.pressKey(self.keys.Universal.JumpToBlock[0]) } func (self *InputImpl) SwitchToFilesWindow() { - self.pushKey(self.keys.Universal.JumpToBlock[1]) + self.pressKey(self.keys.Universal.JumpToBlock[1]) } func (self *InputImpl) SwitchToBranchesWindow() { - self.pushKey(self.keys.Universal.JumpToBlock[2]) + self.pressKey(self.keys.Universal.JumpToBlock[2]) } func (self *InputImpl) SwitchToCommitsWindow() { - self.pushKey(self.keys.Universal.JumpToBlock[3]) + self.pressKey(self.keys.Universal.JumpToBlock[3]) } func (self *InputImpl) SwitchToStashWindow() { - self.pushKey(self.keys.Universal.JumpToBlock[4]) + self.pressKey(self.keys.Universal.JumpToBlock[4]) } func (self *InputImpl) Type(content string) { for _, char := range content { - self.pushKey(string(char)) + self.pressKey(string(char)) } } func (self *InputImpl) Confirm() { - self.pushKey(self.keys.Universal.Confirm) + self.pressKey(self.keys.Universal.Confirm) } func (self *InputImpl) Cancel() { - self.pushKey(self.keys.Universal.Return) + self.pressKey(self.keys.Universal.Return) } func (self *InputImpl) Select() { - self.pushKey(self.keys.Universal.Select) + self.pressKey(self.keys.Universal.Select) } func (self *InputImpl) NextItem() { - self.pushKey(self.keys.Universal.NextItem) + self.pressKey(self.keys.Universal.NextItem) } func (self *InputImpl) PreviousItem() { - self.pushKey(self.keys.Universal.PrevItem) + self.pressKey(self.keys.Universal.PrevItem) +} + +func (self *InputImpl) ContinueMerge() { + self.PressKeys(self.keys.Universal.CreateRebaseOptionsMenu) + self.assert.SelectedLineContains("continue") + self.Confirm() +} + +func (self *InputImpl) ContinueRebase() { + self.ContinueMerge() } func (self *InputImpl) Wait(milliseconds int) { time.Sleep(time.Duration(milliseconds) * time.Millisecond) } + +func (self *InputImpl) log(message string) { + self.gui.c.LogAction(message) +} + +// NOTE: this currently assumes that ViewBufferLines returns all the lines that can be accessed. +// If this changes in future, we'll need to update this code to first attempt to find the item +// in the current page and failing that, jump to the top of the view and iterate through all of it, +// looking for the item. +func (self *InputImpl) NavigateToListItemContainingText(text string) { + self.assert.InListContext() + + currentContext := self.gui.currentContext().(guiTypes.IListContext) + view := currentContext.GetView() + + // first we look for a duplicate on the current screen. We won't bother looking beyond that though. + matchCount := 0 + matchIndex := -1 + for i, line := range view.ViewBufferLines() { + if strings.Contains(line, text) { + matchCount++ + matchIndex = i + } + } + if matchCount > 1 { + self.assert.Fail(fmt.Sprintf("Found %d matches for %s, expected only a single match", matchCount, text)) + } + if matchCount == 1 { + selectedLineIdx := view.SelectedLineIdx() + if selectedLineIdx == matchIndex { + return + } + if selectedLineIdx < matchIndex { + for i := selectedLineIdx; i < matchIndex; i++ { + self.NextItem() + } + return + } else { + for i := selectedLineIdx; i > matchIndex; i-- { + self.PreviousItem() + } + return + } + } + + self.assert.Fail(fmt.Sprintf("Could not find item containing text: %s", text)) +} diff --git a/pkg/gui/test_mode.go b/pkg/gui/test_mode.go index 88e42e440..7f57a4be8 100644 --- a/pkg/gui/test_mode.go +++ b/pkg/gui/test_mode.go @@ -21,10 +21,15 @@ func (gui *Gui) handleTestMode() { go func() { time.Sleep(time.Millisecond * 100) + shell := &integration.ShellImpl{} + assert := &AssertImpl{gui: gui} + keys := gui.Config.GetUserConfig().Keybinding + input := NewInputImpl(gui, keys, assert, integration.KeyPressDelay()) + test.Run( - &integration.ShellImpl{}, - &InputImpl{g: gui.g, keys: gui.Config.GetUserConfig().Keybinding}, - &AssertImpl{gui: gui}, + shell, + input, + assert, gui.c.UserConfig.Keybinding, ) diff --git a/pkg/integration/env.go b/pkg/integration/env.go index 7cdc72267..0c0d0b196 100644 --- a/pkg/integration/env.go +++ b/pkg/integration/env.go @@ -2,6 +2,7 @@ package integration import ( "os" + "strconv" "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/integration/types" @@ -31,6 +32,21 @@ func PlayingIntegrationTest() bool { return IntegrationTestName() != "" } +// this is the delay in milliseconds between keypresses +// defaults to zero +func KeyPressDelay() int { + delayStr := os.Getenv("KEY_PRESS_DELAY") + if delayStr == "" { + return 0 + } + + delay, err := strconv.Atoi(delayStr) + if err != nil { + panic(err) + } + return delay +} + // OLD integration test format stuff func Replaying() bool { diff --git a/pkg/integration/integration_tests/branch/suggestions.go b/pkg/integration/integration_tests/branch/suggestions.go index ff37ec9be..47c360514 100644 --- a/pkg/integration/integration_tests/branch/suggestions.go +++ b/pkg/integration/integration_tests/branch/suggestions.go @@ -23,12 +23,12 @@ var Suggestions = types.NewTest(types.NewTestArgs{ Run: func(shell types.Shell, input types.Input, assert types.Assert, keys config.KeybindingConfig) { input.SwitchToBranchesWindow() - input.PushKeys(keys.Branches.CheckoutBranchByName) + input.PressKeys(keys.Branches.CheckoutBranchByName) assert.CurrentViewName("confirmation") input.Type("branch-to") - input.PushKeys(keys.Universal.TogglePanel) + input.PressKeys(keys.Universal.TogglePanel) assert.CurrentViewName("suggestions") // we expect the first suggestion to be the branch we want because it most diff --git a/pkg/integration/integration_tests/commit/commit.go b/pkg/integration/integration_tests/commit/commit.go index 777653bc0..f0af9462a 100644 --- a/pkg/integration/integration_tests/commit/commit.go +++ b/pkg/integration/integration_tests/commit/commit.go @@ -20,7 +20,7 @@ var Commit = types.NewTest(types.NewTestArgs{ input.Select() input.NextItem() input.Select() - input.PushKeys(keys.Files.CommitChanges) + input.PressKeys(keys.Files.CommitChanges) commitMessage := "my commit message" input.Type(commitMessage) diff --git a/pkg/integration/integration_tests/commit/new_branch.go b/pkg/integration/integration_tests/commit/new_branch.go index d70515280..218e95180 100644 --- a/pkg/integration/integration_tests/commit/new_branch.go +++ b/pkg/integration/integration_tests/commit/new_branch.go @@ -23,7 +23,7 @@ var NewBranch = types.NewTest(types.NewTestArgs{ assert.CurrentViewName("commits") input.NextItem() - input.PushKeys(keys.Universal.New) + input.PressKeys(keys.Universal.New) assert.CurrentViewName("confirmation") diff --git a/pkg/integration/integration_tests/interactive_rebase/one.go b/pkg/integration/integration_tests/interactive_rebase/one.go new file mode 100644 index 000000000..92780b24d --- /dev/null +++ b/pkg/integration/integration_tests/interactive_rebase/one.go @@ -0,0 +1,41 @@ +package interactive_rebase + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + "github.com/jesseduffield/lazygit/pkg/integration/types" +) + +var One = types.NewTest(types.NewTestArgs{ + Description: "Begins an interactive rebase, then fixups, drops, and squashes some commits", + ExtraCmdArgs: "", + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell types.Shell) { + shell. + CreateNCommits(5) // these will appears at commit 05, 04, 04, down to 01 + }, + Run: func(shell types.Shell, input types.Input, assert types.Assert, keys config.KeybindingConfig) { + input.SwitchToCommitsWindow() + assert.CurrentViewName("commits") + + input.NavigateToListItemContainingText("commit 02") + input.PressKeys(keys.Universal.Edit) + assert.SelectedLineContains("YOU ARE HERE") + + input.PreviousItem() + input.PressKeys(keys.Commits.MarkCommitAsFixup) + assert.SelectedLineContains("fixup") + + input.PreviousItem() + input.PressKeys(keys.Universal.Remove) + assert.SelectedLineContains("drop") + + input.PreviousItem() + input.PressKeys(keys.Commits.SquashDown) + assert.SelectedLineContains("squash") + + input.ContinueRebase() + + assert.CommitCount(2) + }, +}) diff --git a/pkg/integration/integration_tests/tests.go b/pkg/integration/integration_tests/tests.go index 1470ef178..752929698 100644 --- a/pkg/integration/integration_tests/tests.go +++ b/pkg/integration/integration_tests/tests.go @@ -3,6 +3,8 @@ package integration_tests import ( "github.com/jesseduffield/lazygit/pkg/integration/integration_tests/branch" "github.com/jesseduffield/lazygit/pkg/integration/integration_tests/commit" + "github.com/jesseduffield/lazygit/pkg/integration/integration_tests/interactive_rebase" + "github.com/jesseduffield/lazygit/pkg/integration/types" ) @@ -13,4 +15,5 @@ var Tests = []types.Test{ commit.Commit, commit.NewBranch, branch.Suggestions, + interactive_rebase.One, } diff --git a/pkg/integration/shell.go b/pkg/integration/shell.go index 69bccb66c..70da9c27b 100644 --- a/pkg/integration/shell.go +++ b/pkg/integration/shell.go @@ -40,6 +40,10 @@ func (s *ShellImpl) NewBranch(name string) types.Shell { return s.RunCommand("git checkout -b " + name) } +func (s *ShellImpl) GitAdd(path string) types.Shell { + return s.RunCommand(fmt.Sprintf("git add \"%s\"", path)) +} + func (s *ShellImpl) GitAddAll() types.Shell { return s.RunCommand("git add -A") } @@ -51,3 +55,21 @@ func (s *ShellImpl) Commit(message string) types.Shell { func (s *ShellImpl) EmptyCommit(message string) types.Shell { return s.RunCommand(fmt.Sprintf("git commit --allow-empty -m \"%s\"", message)) } + +func (s *ShellImpl) CreateFileAndAdd(fileName string, fileContents string) types.Shell { + return s. + CreateFile(fileName, fileContents). + GitAdd(fileName) +} + +func (s *ShellImpl) CreateNCommits(n int) types.Shell { + for i := 1; i <= n; i++ { + s.CreateFileAndAdd( + fmt.Sprintf("file%02d.txt", i), + fmt.Sprintf("file%02d content", i), + ). + Commit(fmt.Sprintf("commit %02d", i)) + } + + return s +} diff --git a/pkg/integration/types/types.go b/pkg/integration/types/types.go index 29b303f35..60fd4f353 100644 --- a/pkg/integration/types/types.go +++ b/pkg/integration/types/types.go @@ -31,9 +31,16 @@ type Shell interface { RunCommand(command string) Shell CreateFile(name string, content string) Shell NewBranch(branchName string) Shell + GitAdd(path string) Shell GitAddAll() Shell Commit(message string) Shell EmptyCommit(message string) Shell + // convenience method for creating a file and adding it + CreateFileAndAdd(fileName string, fileContents string) Shell + // creates commits 01, 02, 03, ..., n with a new file in each + // The reason for padding with zeroes is so that it's easier to do string + // matches on the commit messages when there are many of them + CreateNCommits(n int) Shell } // through this interface our test interacts with the lazygit gui @@ -41,7 +48,7 @@ type Shell interface { type Input interface { // key is something like 'w' or ''. It's best not to pass a direct value, // but instead to go through the default user config to get a more meaningful key name - PushKeys(keys ...string) + PressKeys(keys ...string) // for typing into a popup prompt Type(content string) // for when you want to allow lazygit to process something before continuing @@ -62,6 +69,15 @@ type Input interface { NextItem() // i.e. pressing up arrow PreviousItem() + // this will look for a list item in the current panel and if it finds it, it will + // enter the keypresses required to navigate to it. + // The test will fail if: + // - the user is not in a list item + // - no list item is found containing the given text + // - multiple list items are found containing the given text in the initial page of items + NavigateToListItemContainingText(text string) + ContinueRebase() + ContinueMerge() } // through this interface we assert on the state of the lazygit gui @@ -71,6 +87,10 @@ type Assert interface { HeadCommitMessage(string) CurrentViewName(expectedViewName string) CurrentBranchName(expectedBranchName string) + InListContext() + SelectedLineContains(text string) + // for when you just want to fail the test yourself + Fail(errorMessage string) } type TestImpl struct { diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/COMMIT_EDITMSG b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/COMMIT_EDITMSG new file mode 100644 index 000000000..9e0c89102 --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/COMMIT_EDITMSG @@ -0,0 +1,30 @@ +# This is a combination of 3 commits. +# This is the 1st commit message: + +commit 02 + +# The commit message #2 will be skipped: + +# commit 03 + +# This is the commit message #3: + +commit 05 + +# Please enter the commit message for your changes. Lines starting +# with '#' will be ignored, and an empty message aborts the commit. +# +# Date: Mon Aug 8 21:32:34 2022 +1000 +# +# interactive rebase in progress; onto a1a6f7b +# Last commands done (4 commands done): +# drop 84b1ae9 commit 04 +# squash aa2585a commit 05 +# No commands remaining. +# You are currently rebasing branch 'master' on 'a1a6f7b'. +# +# Changes to be committed: +# new file: file02.txt +# new file: file03.txt +# new file: file05.txt +# diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/FETCH_HEAD b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/FETCH_HEAD new file mode 100644 index 000000000..e69de29bb diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/HEAD b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/HEAD new file mode 100644 index 000000000..cb089cd89 --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/ORIG_HEAD b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/ORIG_HEAD new file mode 100644 index 000000000..42745976b --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/ORIG_HEAD @@ -0,0 +1 @@ +aa2585aff7d2278341ca816f187e623503d7c4fb diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/REBASE_HEAD b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/REBASE_HEAD new file mode 100644 index 000000000..42745976b --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/REBASE_HEAD @@ -0,0 +1 @@ +aa2585aff7d2278341ca816f187e623503d7c4fb diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/config b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/config new file mode 100644 index 000000000..8ae104545 --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/config @@ -0,0 +1,10 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + ignorecase = true + precomposeunicode = true +[user] + email = CI@example.com + name = CI diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/description b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/description new file mode 100644 index 000000000..498b267a8 --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/index b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/index new file mode 100644 index 000000000..ce7858b10 Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/index differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/info/exclude b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/info/exclude new file mode 100644 index 000000000..8e9f2071f --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/info/exclude @@ -0,0 +1,7 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ +.DS_Store diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/logs/HEAD b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/logs/HEAD new file mode 100644 index 000000000..0dda59a30 --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/logs/HEAD @@ -0,0 +1,10 @@ +0000000000000000000000000000000000000000 a1a6f7bda6aeaa08ec75f590845780fde90d901c CI 1659958354 +1000 commit (initial): commit 01 +a1a6f7bda6aeaa08ec75f590845780fde90d901c cb7e56856ecee89fa44c613e094fcf962fe18cf1 CI 1659958354 +1000 commit: commit 02 +cb7e56856ecee89fa44c613e094fcf962fe18cf1 6741ab4fe22a3d36b6c64397fc4295dbae1ba71d CI 1659958354 +1000 commit: commit 03 +6741ab4fe22a3d36b6c64397fc4295dbae1ba71d 84b1ae9d83049341897c9388afffdc9049c3317f CI 1659958354 +1000 commit: commit 04 +84b1ae9d83049341897c9388afffdc9049c3317f aa2585aff7d2278341ca816f187e623503d7c4fb CI 1659958354 +1000 commit: commit 05 +aa2585aff7d2278341ca816f187e623503d7c4fb a1a6f7bda6aeaa08ec75f590845780fde90d901c CI 1659958355 +1000 rebase (start): checkout a1a6f7bda6aeaa08ec75f590845780fde90d901c +a1a6f7bda6aeaa08ec75f590845780fde90d901c cb7e56856ecee89fa44c613e094fcf962fe18cf1 CI 1659958355 +1000 rebase: fast-forward +cb7e56856ecee89fa44c613e094fcf962fe18cf1 9c68b57ac7b652fbebc5e93a9a1b72014400c269 CI 1659958355 +1000 rebase (continue) (fixup): # This is a combination of 2 commits. +9c68b57ac7b652fbebc5e93a9a1b72014400c269 f4316f7a6df3fe5b7e8da1b2c8767ed1e825dc05 CI 1659958355 +1000 rebase (continue) (squash): commit 02 +f4316f7a6df3fe5b7e8da1b2c8767ed1e825dc05 f4316f7a6df3fe5b7e8da1b2c8767ed1e825dc05 CI 1659958355 +1000 rebase (continue) (finish): returning to refs/heads/master diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/logs/refs/heads/master b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/logs/refs/heads/master new file mode 100644 index 000000000..89309e282 --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/logs/refs/heads/master @@ -0,0 +1,6 @@ +0000000000000000000000000000000000000000 a1a6f7bda6aeaa08ec75f590845780fde90d901c CI 1659958354 +1000 commit (initial): commit 01 +a1a6f7bda6aeaa08ec75f590845780fde90d901c cb7e56856ecee89fa44c613e094fcf962fe18cf1 CI 1659958354 +1000 commit: commit 02 +cb7e56856ecee89fa44c613e094fcf962fe18cf1 6741ab4fe22a3d36b6c64397fc4295dbae1ba71d CI 1659958354 +1000 commit: commit 03 +6741ab4fe22a3d36b6c64397fc4295dbae1ba71d 84b1ae9d83049341897c9388afffdc9049c3317f CI 1659958354 +1000 commit: commit 04 +84b1ae9d83049341897c9388afffdc9049c3317f aa2585aff7d2278341ca816f187e623503d7c4fb CI 1659958354 +1000 commit: commit 05 +aa2585aff7d2278341ca816f187e623503d7c4fb f4316f7a6df3fe5b7e8da1b2c8767ed1e825dc05 CI 1659958355 +1000 rebase (continue) (finish): refs/heads/master onto a1a6f7bda6aeaa08ec75f590845780fde90d901c diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/06/47fe4b7302efbfb235b8f0681b592cc3389d36 b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/06/47fe4b7302efbfb235b8f0681b592cc3389d36 new file mode 100644 index 000000000..a8a2b586d Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/06/47fe4b7302efbfb235b8f0681b592cc3389d36 differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/35/da65f29bc0b48aa80bd3a02cff623cf4355fd3 b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/35/da65f29bc0b48aa80bd3a02cff623cf4355fd3 new file mode 100644 index 000000000..350af2800 Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/35/da65f29bc0b48aa80bd3a02cff623cf4355fd3 differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/3b/f868a389d0073e715e848f0ee33d71064539ca b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/3b/f868a389d0073e715e848f0ee33d71064539ca new file mode 100644 index 000000000..07b07e91f Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/3b/f868a389d0073e715e848f0ee33d71064539ca differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/47/d78ad7a27fc7fe483389512ebf7ea34c5514bc b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/47/d78ad7a27fc7fe483389512ebf7ea34c5514bc new file mode 100644 index 000000000..c562d38cc Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/47/d78ad7a27fc7fe483389512ebf7ea34c5514bc differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/55/3197193920043fb04f3e39e825916990955204 b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/55/3197193920043fb04f3e39e825916990955204 new file mode 100644 index 000000000..ac90c394a Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/55/3197193920043fb04f3e39e825916990955204 differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/67/41ab4fe22a3d36b6c64397fc4295dbae1ba71d b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/67/41ab4fe22a3d36b6c64397fc4295dbae1ba71d new file mode 100644 index 000000000..7aeda0bfd --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/67/41ab4fe22a3d36b6c64397fc4295dbae1ba71d @@ -0,0 +1,3 @@ +xM +0a9ɟ1 +֖ۅp,޺h< ĩH R䅽TEެ5oxuS@ҖQX}MmTea0ĩ.$Ր\tf6{ݧ:?O; \ No newline at end of file diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/84/b1ae9d83049341897c9388afffdc9049c3317f b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/84/b1ae9d83049341897c9388afffdc9049c3317f new file mode 100644 index 000000000..cd394caaf --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/84/b1ae9d83049341897c9388afffdc9049c3317f @@ -0,0 +1,3 @@ +xM +0@a9I2?m@DcL +֖ۅp,fU[LLsE&K#dnݪ:@A35Qd)BV(&Y-dBuevNe/SnT?σ'u; \ No newline at end of file diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/9c/68b57ac7b652fbebc5e93a9a1b72014400c269 b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/9c/68b57ac7b652fbebc5e93a9a1b72014400c269 new file mode 100644 index 000000000..c97722a50 --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/9c/68b57ac7b652fbebc5e93a9a1b72014400c269 @@ -0,0 +1,2 @@ +xJ0=)zIڴȲfb6mi"F ^9}3 {(;3p ڌ9;%á2%Yv^ +> SOLAmtz0<[(L<_o|tkkiuETt}袁)fCP..T@}z,~Yeb+H38*mq1{65X؊Oz d \ No newline at end of file diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/a0/2c4b36b68df7081152282cf1aabcab7b24e69b b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/a0/2c4b36b68df7081152282cf1aabcab7b24e69b new file mode 100644 index 000000000..85866acd8 Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/a0/2c4b36b68df7081152282cf1aabcab7b24e69b differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/a1/a6f7bda6aeaa08ec75f590845780fde90d901c b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/a1/a6f7bda6aeaa08ec75f590845780fde90d901c new file mode 100644 index 000000000..540590758 Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/a1/a6f7bda6aeaa08ec75f590845780fde90d901c differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/aa/2585aff7d2278341ca816f187e623503d7c4fb b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/aa/2585aff7d2278341ca816f187e623503d7c4fb new file mode 100644 index 000000000..9a3b44f36 --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/aa/2585aff7d2278341ca816f187e623503d7c4fb @@ -0,0 +1,4 @@ +xA +1 a=E4m@Dh3) + +.<ۏGwUpLJ9׊$BT!*lyWKB=$˜ҘEx B&}|vOnSO@̔=s z|);= \ No newline at end of file diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/c2/55cf4ef7fd5661a9d68b717243a978e42b05ac b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/c2/55cf4ef7fd5661a9d68b717243a978e42b05ac new file mode 100644 index 000000000..6ac1f71b1 Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/c2/55cf4ef7fd5661a9d68b717243a978e42b05ac differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/cb/7e56856ecee89fa44c613e094fcf962fe18cf1 b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/cb/7e56856ecee89fa44c613e094fcf962fe18cf1 new file mode 100644 index 000000000..0145803af Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/cb/7e56856ecee89fa44c613e094fcf962fe18cf1 differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/e2/1978e5aaff3752bdeeb635c1667ec59c5bbde1 b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/e2/1978e5aaff3752bdeeb635c1667ec59c5bbde1 new file mode 100644 index 000000000..37f59fe0f Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/e2/1978e5aaff3752bdeeb635c1667ec59c5bbde1 differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/e6/db1f58c2bb5ead41049a8ef3910360eead21e2 b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/e6/db1f58c2bb5ead41049a8ef3910360eead21e2 new file mode 100644 index 000000000..8bcfafeb6 Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/e6/db1f58c2bb5ead41049a8ef3910360eead21e2 differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/e9/380a3c752e4b7c7e754fc402ce52302795a95a b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/e9/380a3c752e4b7c7e754fc402ce52302795a95a new file mode 100644 index 000000000..a75ffaf35 Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/e9/380a3c752e4b7c7e754fc402ce52302795a95a differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/f2/c01a881661486f147e47f5be82914c5d0c0030 b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/f2/c01a881661486f147e47f5be82914c5d0c0030 new file mode 100644 index 000000000..7e30b2e35 Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/f2/c01a881661486f147e47f5be82914c5d0c0030 differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/f4/316f7a6df3fe5b7e8da1b2c8767ed1e825dc05 b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/f4/316f7a6df3fe5b7e8da1b2c8767ed1e825dc05 new file mode 100644 index 000000000..b48b3e823 Binary files /dev/null and b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/objects/f4/316f7a6df3fe5b7e8da1b2c8767ed1e825dc05 differ diff --git a/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/refs/heads/master b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/refs/heads/master new file mode 100644 index 000000000..4190292c7 --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/.git_keep/refs/heads/master @@ -0,0 +1 @@ +f4316f7a6df3fe5b7e8da1b2c8767ed1e825dc05 diff --git a/test/integration_new/interactive_rebase/one/expected/repo/file01.txt b/test/integration_new/interactive_rebase/one/expected/repo/file01.txt new file mode 100644 index 000000000..47d78ad7a --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/file01.txt @@ -0,0 +1 @@ +file01 content \ No newline at end of file diff --git a/test/integration_new/interactive_rebase/one/expected/repo/file02.txt b/test/integration_new/interactive_rebase/one/expected/repo/file02.txt new file mode 100644 index 000000000..0647fe4b7 --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/file02.txt @@ -0,0 +1 @@ +file02 content \ No newline at end of file diff --git a/test/integration_new/interactive_rebase/one/expected/repo/file03.txt b/test/integration_new/interactive_rebase/one/expected/repo/file03.txt new file mode 100644 index 000000000..3bf868a38 --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/file03.txt @@ -0,0 +1 @@ +file03 content \ No newline at end of file diff --git a/test/integration_new/interactive_rebase/one/expected/repo/file05.txt b/test/integration_new/interactive_rebase/one/expected/repo/file05.txt new file mode 100644 index 000000000..c255cf4ef --- /dev/null +++ b/test/integration_new/interactive_rebase/one/expected/repo/file05.txt @@ -0,0 +1 @@ +file05 content \ No newline at end of file diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go index 8ec290176..95c7ef4b1 100644 --- a/vendor/github.com/jesseduffield/gocui/view.go +++ b/vendor/github.com/jesseduffield/gocui/view.go @@ -465,6 +465,14 @@ func (v *View) Cursor() (x, y int) { return v.cx, v.cy } +func (v *View) CursorX() int { + return v.cx +} + +func (v *View) CursorY() int { + return v.cy +} + // SetOrigin sets the origin position of the view's internal buffer, // so the buffer starts to be printed from this point, which means that // it is linked with the origin point of view. It can be used to @@ -1235,6 +1243,13 @@ func (v *View) SelectedLineIdx() int { return seletedLineIdx } +// expected to only be used in tests +func (v *View) SelectedLine() string { + line := v.lines[v.SelectedLineIdx()] + str := lineType(line).String() + return strings.Replace(str, "\x00", " ", -1) +} + func (v *View) SelectedPoint() (int, int) { cx, cy := v.Cursor() ox, oy := v.Origin()