diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2023-02-23 22:29:40 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2023-02-23 22:29:40 +1100 |
commit | c63fed20743478848a3bfe6642c58edf1058603d (patch) | |
tree | 47986567beb96b0f2764eb8d399a3ae2c6121640 /pkg/integration | |
parent | 1b52a0d83fc08f47d22fd4af38b6b278dc40bb5b (diff) |
migrate staging tests
Diffstat (limited to 'pkg/integration')
-rw-r--r-- | pkg/integration/components/actions.go | 7 | ||||
-rw-r--r-- | pkg/integration/components/commit_message_panel_driver.go | 16 | ||||
-rw-r--r-- | pkg/integration/components/test_driver.go | 7 | ||||
-rw-r--r-- | pkg/integration/tests/file/remember_commit_message_after_fail.go | 62 | ||||
-rw-r--r-- | pkg/integration/tests/staging/diff_context_change.go | 80 | ||||
-rw-r--r-- | pkg/integration/tests/staging/discard_all_changes.go | 54 | ||||
-rw-r--r-- | pkg/integration/tests/staging/stage_hunks.go | 91 | ||||
-rw-r--r-- | pkg/integration/tests/staging/stage_lines.go | 108 | ||||
-rw-r--r-- | pkg/integration/tests/staging/stage_ranges.go | 75 | ||||
-rw-r--r-- | pkg/integration/tests/tests_gen.go | 7 | ||||
-rw-r--r-- | pkg/integration/tests/ui/double_popup.go | 34 |
11 files changed, 540 insertions, 1 deletions
diff --git a/pkg/integration/components/actions.go b/pkg/integration/components/actions.go index c599f3697..50564233a 100644 --- a/pkg/integration/components/actions.go +++ b/pkg/integration/components/actions.go @@ -31,3 +31,10 @@ func (self *Actions) ContinueOnConflictsResolved() { Content(Contains("all merge conflicts resolved. Continue?")). Confirm() } + +func (self *Actions) ConfirmDiscardLines() { + self.t.ExpectPopup().Confirmation(). + Title(Equals("Unstage lines")). + Content(Contains("Are you sure you want to delete the selected lines")). + Confirm() +} diff --git a/pkg/integration/components/commit_message_panel_driver.go b/pkg/integration/components/commit_message_panel_driver.go index a70688e73..b44a6c1dc 100644 --- a/pkg/integration/components/commit_message_panel_driver.go +++ b/pkg/integration/components/commit_message_panel_driver.go @@ -28,7 +28,21 @@ func (self *CommitMessagePanelDriver) AddNewline() *CommitMessagePanelDriver { } func (self *CommitMessagePanelDriver) Clear() *CommitMessagePanelDriver { - panic("Clear method not yet implemented!") + // clearing multiple times in case there's multiple lines + // (the clear button only clears a single line at a time) + maxAttempts := 100 + for i := 0; i < maxAttempts+1; i++ { + if self.getViewDriver().getView().Buffer() == "" { + break + } + + self.t.press(ClearKey) + if i == maxAttempts { + panic("failed to clear commit message panel") + } + } + + return self } func (self *CommitMessagePanelDriver) Confirm() { diff --git a/pkg/integration/components/test_driver.go b/pkg/integration/components/test_driver.go index e52cc8915..43618f23c 100644 --- a/pkg/integration/components/test_driver.go +++ b/pkg/integration/components/test_driver.go @@ -37,6 +37,13 @@ func (self *TestDriver) press(keyStr string) { self.gui.PressKey(keyStr) } +// Should only be used in specific cases where you're doing something weird! +// E.g. invoking a global keybinding from within a popup. +// You probably shouldn't use this function, and should instead go through a view like t.Views().Commit().Focus().Press(...) +func (self *TestDriver) GlobalPress(keyStr string) { + self.press(keyStr) +} + func (self *TestDriver) typeContent(content string) { for _, char := range content { self.press(string(char)) diff --git a/pkg/integration/tests/file/remember_commit_message_after_fail.go b/pkg/integration/tests/file/remember_commit_message_after_fail.go new file mode 100644 index 000000000..bb9b341b1 --- /dev/null +++ b/pkg/integration/tests/file/remember_commit_message_after_fail.go @@ -0,0 +1,62 @@ +package file + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var preCommitHook = `#!/bin/bash + +if [[ -f bad ]]; then + exit 1 +fi +` + +var RememberCommitMessageAfterFail = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Verify that the commit message is remembered after a failed attempt at committing", + ExtraCmdArgs: "", + Skip: false, + SetupConfig: func(config *config.AppConfig) { + }, + SetupRepo: func(shell *Shell) { + shell.CreateFile(".git/hooks/pre-commit", preCommitHook) + shell.RunCommand("chmod +x .git/hooks/pre-commit") + + shell.CreateFileAndAdd("one", "one") + + // the presence of this file will cause the pre-commit hook to fail + shell.CreateFile("bad", "bad") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Files(). + IsFocused(). + Lines( + Contains("bad"), + Contains("one"), + ). + Press(keys.Files.CommitChanges). + Tap(func() { + t.ExpectPopup().CommitMessagePanel().Type("my message").Confirm() + + t.ExpectPopup().Alert().Title(Equals("Error")).Content(Contains("Git command failed")).Confirm() + }). + Press(keys.Universal.Remove). // remove file that triggers pre-commit hook to fail + Tap(func() { + t.ExpectPopup().Menu().Title(Equals("bad")).Select(Contains("discard all changes")).Confirm() + }). + Lines( + Contains("one"), + ). + Press(keys.Files.CommitChanges). + Tap(func() { + t.ExpectPopup().CommitMessagePanel(). + InitialText(Equals("my message")). // it remembered the commit message + Confirm() + + t.Views().Commits(). + Lines( + Contains("my message"), + ) + }) + }, +}) diff --git a/pkg/integration/tests/staging/diff_context_change.go b/pkg/integration/tests/staging/diff_context_change.go new file mode 100644 index 000000000..8ddf3d37f --- /dev/null +++ b/pkg/integration/tests/staging/diff_context_change.go @@ -0,0 +1,80 @@ +package staging + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var DiffContextChange = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Change the number of diff context lines while in the staging panel", + ExtraCmdArgs: "", + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + // need to be working with a few lines so that git perceives it as two separate hunks + shell.CreateFileAndAdd("file1", "1a\n2a\n3a\n4a\n5a\n6a\n7a\n8a\n9a\n10a\n11a\n12a\n13a\n14a\n15a") + shell.Commit("one") + + shell.UpdateFile("file1", "1a\n2a\n3b\n4a\n5a\n6a\n7a\n8a\n9a\n10a\n11a\n12a\n13b\n14a\n15a") + + // hunk looks like: + // diff --git a/file1 b/file1 + // index 3653080..a6388b6 100644 + // --- a/file1 + // +++ b/file1 + // @@ -1,6 +1,6 @@ + // 1a + // 2a + // -3a + // +3b + // 4a + // 5a + // 6a + // @@ -10,6 +10,6 @@ + // 10a + // 11a + // 12a + // -13a + // +13b + // 14a + // 15a + // \ No newline at end of file + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Files(). + IsFocused(). + Lines( + Contains("file1").IsSelected(), + ). + PressEnter() + + t.Views().Staging(). + IsFocused(). + Content(Contains("@@ -1,6 +1,6 @@").DoesNotContain(" 7a")). + SelectedLine(Contains("-3a")). + Press(keys.Universal.IncreaseContextInDiffView). + // still on the same line + SelectedLine(Contains("-3a")). + // '7a' is now visible + Content(Contains("@@ -1,7 +1,7 @@").Contains(" 7a")). + Press(keys.Universal.DecreaseContextInDiffView). + SelectedLine(Contains("-3a")). + Content(Contains("@@ -1,6 +1,6 @@").DoesNotContain(" 7a")). + Press(keys.Universal.DecreaseContextInDiffView). + SelectedLine(Contains("-3a")). + Content(Contains("@@ -1,5 +1,5 @@").DoesNotContain(" 6a")). + Press(keys.Universal.DecreaseContextInDiffView). + // arguably we should still be on -3a, but at the moment the logic puts us on on +3b + SelectedLine(Contains("+3b")). + Content(Contains("@@ -2,3 +2,3 @@").DoesNotContain(" 5a")). + PressPrimaryAction(). + Content(DoesNotContain("+3b")). + Press(keys.Universal.TogglePanel) + + t.Views().StagingSecondary(). + IsFocused(). + Content(Contains("@@ -3,2 +3,3 @@\n 3a\n+3b\n 4a")). + Press(keys.Universal.IncreaseContextInDiffView). + Content(Contains("@@ -2,4 +2,5 @@\n 2a\n 3a\n+3b\n 4a\n 5a")) + }, +}) diff --git a/pkg/integration/tests/staging/discard_all_changes.go b/pkg/integration/tests/staging/discard_all_changes.go new file mode 100644 index 000000000..7d27e7ec2 --- /dev/null +++ b/pkg/integration/tests/staging/discard_all_changes.go @@ -0,0 +1,54 @@ +package staging + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var DiscardAllChanges = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Discard all changes of a file in the staging panel, then assert we land in the staging panel of the next file", + ExtraCmdArgs: "", + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.CreateFileAndAdd("file1", "one\ntwo\n") + shell.CreateFileAndAdd("file2", "1\n2\n") + shell.Commit("one") + + shell.UpdateFile("file1", "one\ntwo\nthree\nfour\n") + shell.UpdateFile("file2", "1\n2\n3\n4\n") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Files(). + IsFocused(). + Lines( + Contains("file1").IsSelected(), + Contains("file2"), + ). + PressEnter() + + t.Views().Staging(). + IsFocused(). + SelectedLine(Contains("+three")). + // discard the line + Press(keys.Universal.Remove). + Tap(func() { + t.Actions().ConfirmDiscardLines() + }). + SelectedLine(Contains("+four")). + // discard the other line + Press(keys.Universal.Remove). + Tap(func() { + t.Actions().ConfirmDiscardLines() + + // because there are no more changes in file1 we switch to file2 + t.Views().Files(). + Lines( + Contains("file2").IsSelected(), + ) + }). + // assert we are still in the staging panel, but now looking at the changes of the other file + IsFocused(). + SelectedLine(Contains("+3")) + }, +}) diff --git a/pkg/integration/tests/staging/stage_hunks.go b/pkg/integration/tests/staging/stage_hunks.go new file mode 100644 index 000000000..b79819108 --- /dev/null +++ b/pkg/integration/tests/staging/stage_hunks.go @@ -0,0 +1,91 @@ +package staging + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var StageHunks = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Stage and unstage various hunks of a file in the staging panel", + ExtraCmdArgs: "", + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + // need to be working with a few lines so that git perceives it as two separate hunks + shell.CreateFileAndAdd("file1", "1a\n2a\n3a\n4a\n5a\n6a\n7a\n8a\n9a\n10a\n11a\n12a\n13a\n14a\n15a") + shell.Commit("one") + + shell.UpdateFile("file1", "1a\n2a\n3b\n4a\n5a\n6a\n7a\n8a\n9a\n10a\n11a\n12a\n13b\n14a\n15a") + + // hunk looks like: + // diff --git a/file1 b/file1 + // index 3653080..a6388b6 100644 + // --- a/file1 + // +++ b/file1 + // @@ -1,6 +1,6 @@ + // 1a + // 2a + // -3a + // +3b + // 4a + // 5a + // 6a + // @@ -10,6 +10,6 @@ + // 10a + // 11a + // 12a + // -13a + // +13b + // 14a + // 15a + // \ No newline at end of file + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Files(). + IsFocused(). + Lines( + Contains("file1").IsSelected(), + ). + PressEnter() + + t.Views().Staging(). + IsFocused(). + SelectedLine(Contains("-3a")). + Press(keys.Universal.NextBlock). + SelectedLine(Contains("-13a")). + Press(keys.Main.ToggleSelectHunk). + // when in hunk mode, pressing up/down moves us up/down by a hunk + SelectPreviousItem(). + SelectedLine(Contains("-3a")). + SelectNextItem(). + SelectedLine(Contains("-13a")). + // stage the second hunk + PressPrimaryAction(). + Content(Contains("-3a\n+3b")). + Tap(func() { + t.Views().StagingSecondary(). + Content(Contains("-13a\n+13b")) + }). + Press(keys.Universal.TogglePanel) + + t.Views().StagingSecondary(). + IsFocused(). + SelectedLine(Contains("-13a")). + // after toggling panel, we're back to only having selected a single line + PressPrimaryAction(). + SelectedLine(Contains("+13b")). + PressPrimaryAction(). + IsEmpty() + + t.Views().Staging(). + IsFocused(). + SelectedLine(Contains("-3a")). + Press(keys.Main.ToggleSelectHunk). + Press(keys.Universal.Remove). + Tap(func() { + t.Actions().ConfirmDiscardLines() + }). + SelectedLine(Contains("-13a")). + Content(DoesNotContain("-3a").DoesNotContain("+3b")) + }, +}) diff --git a/pkg/integration/tests/staging/stage_lines.go b/pkg/integration/tests/staging/stage_lines.go new file mode 100644 index 000000000..f1777fb36 --- /dev/null +++ b/pkg/integration/tests/staging/stage_lines.go @@ -0,0 +1,108 @@ +package staging + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var StageLines = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Stage and unstage various lines of a file in the staging panel", + ExtraCmdArgs: "", + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.CreateFileAndAdd("file1", "one\ntwo\n") + shell.Commit("one") + + shell.UpdateFile("file1", "one\ntwo\nthree\nfour\n") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Files(). + IsFocused(). + Lines( + Contains("file1").IsSelected(), + ). + PressEnter() + + t.Views().Staging(). + IsFocused(). + SelectedLine(Contains("+three")). + // stage 'three' + PressPrimaryAction(). + // 'three' moves over to the staging secondary panel + Content(DoesNotContain("+three")). + Tap(func() { + t.Views().StagingSecondary(). + Content(Contains("+three")) + }). + SelectedLine(Contains("+four")). + // stage 'four' + PressPrimaryAction(). + // nothing left in our staging panel + IsEmpty() + + // because we've staged everything we get moved to the staging secondary panel + // do the same thing as above, moving the lines back to the staging panel + t.Views().StagingSecondary(). + IsFocused(). + Content(Contains("+three\n+four")). + SelectedLine(Contains("+three")). + PressPrimaryAction(). + Content(DoesNotContain("+three")). + Tap(func() { + t.Views().Staging(). + Content(Contains("+three")) + }). + SelectedLine(Contains("+four")). + // pressing 'remove' has the same effect as pressing space when in the staging secondary panel + Press(keys.Universal.Remove). + IsEmpty() + + // stage one line and then manually toggle to the staging secondary panel + t.Views().Staging(). + IsFocused(). + Content(Contains("+three\n+four")). + SelectedLine(Contains("+three")). + PressPrimaryAction(). + Content(DoesNotContain("+three")). + Tap(func() { + t.Views().StagingSecondary(). + Content(Contains("+three")) + }). + Press(keys.Universal.TogglePanel) + + // manually toggle back to the staging panel + t.Views().StagingSecondary(). + IsFocused(). + Press(keys.Universal.TogglePanel) + + t.Views().Staging(). + SelectedLine(Contains("+four")). + // discard the line + Press(keys.Universal.Remove). + Tap(func() { + t.ExpectPopup().Confirmation(). + Title(Equals("Unstage lines")). + Content(Contains("Are you sure you want to delete the selected lines")). + Confirm() + }). + IsEmpty() + + t.Views().StagingSecondary(). + IsFocused(). + Content(Contains("+three\n")). + // return to file + PressEscape() + + t.Views().Files(). + IsFocused(). + Lines( + Contains("M file1").IsSelected(), + ). + PressEnter() + + // because we only have a staged change we'll land in the staging secondary panel + t.Views().StagingSecondary(). + IsFocused() + }, +}) diff --git a/pkg/integration/tests/staging/stage_ranges.go b/pkg/integration/tests/staging/stage_ranges.go new file mode 100644 index 000000000..cd6d8021f --- /dev/null +++ b/pkg/integration/tests/staging/stage_ranges.go @@ -0,0 +1,75 @@ +package staging + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var StageRanges = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Stage and unstage various ranges of a file in the staging panel", + ExtraCmdArgs: "", + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.CreateFileAndAdd("file1", "one\ntwo\n") + shell.Commit("one") + + shell.UpdateFile("file1", "one\ntwo\nthree\nfour\nfive\nsix\n") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Files(). + IsFocused(). + Lines( + Contains("file1").IsSelected(), + ). + PressEnter() + + t.Views().Staging(). + IsFocused(). + SelectedLine(Contains("+three")). + Press(keys.Main.ToggleDragSelect). + SelectNextItem(). + SelectedLine(Contains("+four")). + SelectNextItem(). + SelectedLine(Contains("+five")). + // stage the three lines we've just selected + PressPrimaryAction(). + Content(Contains(" five\n+six")). + Tap(func() { + t.Views().StagingSecondary(). + Content(Contains("+three\n+four\n+five")) + }). + Press(keys.Universal.TogglePanel) + + t.Views().StagingSecondary(). + IsFocused(). + SelectedLine(Contains("+three")). + Press(keys.Main.ToggleDragSelect). + SelectNextItem(). + SelectedLine(Contains("+four")). + SelectNextItem(). + SelectedLine(Contains("+five")). + // unstage the three selected lines + PressPrimaryAction(). + // nothing left in our staging secondary panel + IsEmpty(). + Tap(func() { + t.Views().Staging(). + Content(Contains("+three\n+four\n+five\n+six")) + }) + + t.Views().Staging(). + IsFocused(). + // coincidentally we land at '+four' here. Maybe we should instead land + // at '+three'? given it's at the start of the hunk? + SelectedLine(Contains("+four")). + Press(keys.Main.ToggleDragSelect). + SelectNextItem(). + SelectedLine(Contains("+five")). + Press(keys.Universal.Remove). + Tap(func() { + t.Actions().ConfirmDiscardLines() + }). + Content(Contains("+three\n+six")) + }, +}) diff --git a/pkg/integration/tests/tests_gen.go b/pkg/integration/tests/tests_gen.go index c99870d43..6814ae631 100644 --- a/pkg/integration/tests/tests_gen.go +++ b/pkg/integration/tests/tests_gen.go @@ -73,6 +73,7 @@ var tests = []*components.IntegrationTest{ file.DiscardChanges, file.DiscardStagedChanges, file.Gitignore, + file.RememberCommitMessageAfterFail, filter_by_path.CliArg, filter_by_path.SelectFile, filter_by_path.TypeFile, @@ -98,7 +99,12 @@ var tests = []*components.IntegrationTest{ reflog.CherryPick, reflog.Patch, reflog.Reset, + staging.DiffContextChange, + staging.DiscardAllChanges, staging.Search, + staging.StageHunks, + staging.StageLines, + staging.StageRanges, stash.Apply, stash.ApplyPatch, stash.CreateBranch, @@ -139,6 +145,7 @@ var tests = []*components.IntegrationTest{ tag.CrudAnnotated, tag.CrudLightweight, tag.Reset, + ui.DoublePopup, ui.SwitchTabFromMenu, undo.UndoCheckoutAndDrop, undo.UndoDrop, diff --git a/pkg/integration/tests/ui/double_popup.go b/pkg/integration/tests/ui/double_popup.go new file mode 100644 index 000000000..85ba4309e --- /dev/null +++ b/pkg/integration/tests/ui/double_popup.go @@ -0,0 +1,34 @@ +package ui + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var DoublePopup = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Open a popup from within another popup and assert you can escape back to the side panels", + ExtraCmdArgs: "", + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.EmptyCommit("one") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). + Focus(). + // arbitrarily bringing up a popup + PressPrimaryAction() + + t.ExpectPopup().Alert(). + Title(Contains("Error")). + Content(Contains("You have already checked out this branch")) + + t.GlobalPress(keys.Universal.OpenRecentRepos) + + t.ExpectPopup().Menu().Title(Contains("recent repositories")).Cancel() + + t.Views().Branches().IsFocused() + + t.Views().Files().Focus() + }, +}) |