mirror of
https://github.com/jesseduffield/lazygit.git
synced 2024-12-02 09:21:40 +02:00
Merge pull request #2330 from jesseduffield/yet-more-test-migrations
This commit is contained in:
commit
cd418ec929
@ -39,8 +39,12 @@ The run step has four arguments passed in:
|
||||
|
||||
### Tips
|
||||
|
||||
#### Handle most setup in the `shell` part of the test
|
||||
|
||||
Try to do as much setup work as possible in your setup step. For example, if all you're testing is that the user is able to resolve merge conflicts, create the merge conflicts in the setup step. On the other hand, if you're testing to see that lazygit can warn the user about merge conflicts after an attempted merge, it's fine to wait until the run step to actually create the conflicts. If the run step is focused on the thing you're trying to test, the test will run faster and its intent will be clearer.
|
||||
|
||||
#### Assert after input
|
||||
|
||||
Use assertions to ensure that lazygit has processed all your keybindings so far. Each time you press a key, something should happen on the screen, so you should assert that that thing has happened. This means we won't get into trouble from keys being entered two quickly because at each stage we ensure the key has been processed. This also makes tests more readable because they help explain what we expect to be happening on-screen. For example:
|
||||
|
||||
```go
|
||||
@ -48,6 +52,10 @@ input.Press(keys.Files.CommitChanges)
|
||||
assert.InCommitMessagePanel()
|
||||
```
|
||||
|
||||
Note that there are some `input` methods that have assertions baked in, such as the `SwitchToView` methods.
|
||||
|
||||
#### Create helper functions for (very) frequently used test logic
|
||||
|
||||
If you find yourself doing something frequently in a test, consider making it a method in one of the helper arguments. For example, instead of calling `input.PressKey(keys.Universal.Confirm)` in 100 places, it's better to have a method `input.Confirm()`. This is not to say that everything should be made into a method on the input struct: just things that are particularly common in tests.
|
||||
|
||||
Also, given how often we need to select a menu item or type into a prompt panel, there are some helper functions for that. For example:
|
||||
|
@ -3,10 +3,9 @@ package components
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||
)
|
||||
@ -21,46 +20,6 @@ func NewAssert(gui integrationTypes.GuiDriver) *Assert {
|
||||
return &Assert{gui: gui}
|
||||
}
|
||||
|
||||
func Contains(target string) *matcher {
|
||||
return NewMatcher(
|
||||
fmt.Sprintf("contains '%s'", target),
|
||||
func(value string) (bool, string) {
|
||||
return strings.Contains(value, target), fmt.Sprintf("Expected '%s' to be found in '%s'", target, value)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func NotContains(target string) *matcher {
|
||||
return NewMatcher(
|
||||
fmt.Sprintf("does not contain '%s'", target),
|
||||
func(value string) (bool, string) {
|
||||
return !strings.Contains(value, target), fmt.Sprintf("Expected '%s' to NOT be found in '%s'", target, value)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func MatchesRegexp(target string) *matcher {
|
||||
return NewMatcher(
|
||||
fmt.Sprintf("matches regular expression '%s'", target),
|
||||
func(value string) (bool, string) {
|
||||
matched, err := regexp.MatchString(target, value)
|
||||
if err != nil {
|
||||
return false, fmt.Sprintf("Unexpected error parsing regular expression '%s': %s", target, err.Error())
|
||||
}
|
||||
return matched, fmt.Sprintf("Expected '%s' to match regular expression '%s'", value, target)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func Equals(target string) *matcher {
|
||||
return NewMatcher(
|
||||
fmt.Sprintf("equals '%s'", target),
|
||||
func(value string) (bool, string) {
|
||||
return target == value, fmt.Sprintf("Expected '%s' to equal '%s'", value, target)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (self *Assert) WorkingTreeFileCount(expectedCount int) {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
actualCount := len(self.gui.Model().Files)
|
||||
@ -114,13 +73,6 @@ func (self *Assert) HeadCommitMessage(matcher *matcher) {
|
||||
)
|
||||
}
|
||||
|
||||
func (self *Assert) CurrentViewName(expectedViewName string) {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
actual := self.gui.CurrentContext().GetView().Name()
|
||||
return actual == expectedViewName, fmt.Sprintf("Expected current view name to be '%s', but got '%s'", expectedViewName, actual)
|
||||
})
|
||||
}
|
||||
|
||||
func (self *Assert) CurrentWindowName(expectedWindowName string) {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
actual := self.gui.CurrentContext().GetView().Name()
|
||||
@ -143,14 +95,6 @@ func (self *Assert) InListContext() {
|
||||
})
|
||||
}
|
||||
|
||||
func (self *Assert) SelectedLine(matcher *matcher) {
|
||||
self.matchString(matcher, "Unexpected selected line.",
|
||||
func() string {
|
||||
return self.gui.CurrentContext().GetView().SelectedLine()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (self *Assert) InPrompt() {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
currentView := self.gui.CurrentContext().GetView()
|
||||
@ -193,46 +137,6 @@ func (self *Assert) NotInPopup() {
|
||||
})
|
||||
}
|
||||
|
||||
func (self *Assert) CurrentViewTitle(matcher *matcher) {
|
||||
self.matchString(matcher, "Unexpected current view title.",
|
||||
func() string {
|
||||
return self.gui.CurrentContext().GetView().Title
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (self *Assert) ViewContent(viewName string, matcher *matcher) {
|
||||
self.matchString(matcher, fmt.Sprintf("Unexpected content in view '%s'.", viewName),
|
||||
func() string {
|
||||
return self.gui.View(viewName).Buffer()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (self *Assert) CurrentViewContent(matcher *matcher) {
|
||||
self.matchString(matcher, "Unexpected content in current view.",
|
||||
func() string {
|
||||
return self.gui.CurrentContext().GetView().Buffer()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (self *Assert) MainViewContent(matcher *matcher) {
|
||||
self.matchString(matcher, "Unexpected main view content.",
|
||||
func() string {
|
||||
return self.gui.MainView().Buffer()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (self *Assert) SecondaryViewContent(matcher *matcher) {
|
||||
self.matchString(matcher, "Unexpected secondary view title.",
|
||||
func() string {
|
||||
return self.gui.SecondaryView().Buffer()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (self *Assert) matchString(matcher *matcher, context string, getValue func() string) {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
value := getValue()
|
||||
@ -277,3 +181,35 @@ func (self *Assert) FileSystemPathNotPresent(path string) {
|
||||
return os.IsNotExist(err), fmt.Sprintf("Expected path '%s' to not exist, but it does", path)
|
||||
})
|
||||
}
|
||||
|
||||
func (self *Assert) CurrentView() *ViewAsserter {
|
||||
return &ViewAsserter{
|
||||
context: "current view",
|
||||
getView: func() *gocui.View { return self.gui.CurrentContext().GetView() },
|
||||
assert: self,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Assert) View(viewName string) *ViewAsserter {
|
||||
return &ViewAsserter{
|
||||
context: fmt.Sprintf("%s view", viewName),
|
||||
getView: func() *gocui.View { return self.gui.View(viewName) },
|
||||
assert: self,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Assert) MainView() *ViewAsserter {
|
||||
return &ViewAsserter{
|
||||
context: "main view",
|
||||
getView: func() *gocui.View { return self.gui.MainView() },
|
||||
assert: self,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Assert) SecondaryView() *ViewAsserter {
|
||||
return &ViewAsserter{
|
||||
context: "secondary view",
|
||||
getView: func() *gocui.View { return self.gui.SecondaryView() },
|
||||
assert: self,
|
||||
}
|
||||
}
|
||||
|
@ -45,26 +45,56 @@ func (self *Input) SwitchToStatusWindow() {
|
||||
self.assert.CurrentWindowName("status")
|
||||
}
|
||||
|
||||
// switch to status window and assert that the status view is on top
|
||||
func (self *Input) SwitchToStatusView() {
|
||||
self.SwitchToStatusWindow()
|
||||
self.assert.CurrentView().Name("status")
|
||||
}
|
||||
|
||||
func (self *Input) SwitchToFilesWindow() {
|
||||
self.press(self.keys.Universal.JumpToBlock[1])
|
||||
self.assert.CurrentWindowName("files")
|
||||
}
|
||||
|
||||
// switch to files window and assert that the files view is on top
|
||||
func (self *Input) SwitchToFilesView() {
|
||||
self.SwitchToFilesWindow()
|
||||
self.assert.CurrentView().Name("files")
|
||||
}
|
||||
|
||||
func (self *Input) SwitchToBranchesWindow() {
|
||||
self.press(self.keys.Universal.JumpToBlock[2])
|
||||
self.assert.CurrentWindowName("localBranches")
|
||||
}
|
||||
|
||||
// switch to branches window and assert that the branches view is on top
|
||||
func (self *Input) SwitchToBranchesView() {
|
||||
self.SwitchToBranchesWindow()
|
||||
self.assert.CurrentView().Name("localBranches")
|
||||
}
|
||||
|
||||
func (self *Input) SwitchToCommitsWindow() {
|
||||
self.press(self.keys.Universal.JumpToBlock[3])
|
||||
self.assert.CurrentWindowName("commits")
|
||||
}
|
||||
|
||||
// switch to commits window and assert that the commits view is on top
|
||||
func (self *Input) SwitchToCommitsView() {
|
||||
self.SwitchToCommitsWindow()
|
||||
self.assert.CurrentView().Name("commits")
|
||||
}
|
||||
|
||||
func (self *Input) SwitchToStashWindow() {
|
||||
self.press(self.keys.Universal.JumpToBlock[4])
|
||||
self.assert.CurrentWindowName("stash")
|
||||
}
|
||||
|
||||
// switch to stash window and assert that the stash view is on top
|
||||
func (self *Input) SwitchToStashView() {
|
||||
self.SwitchToStashWindow()
|
||||
self.assert.CurrentView().Name("stash")
|
||||
}
|
||||
|
||||
func (self *Input) Type(content string) {
|
||||
for _, char := range content {
|
||||
self.press(string(char))
|
||||
@ -103,7 +133,7 @@ func (self *Input) PreviousItem() {
|
||||
|
||||
func (self *Input) ContinueMerge() {
|
||||
self.Press(self.keys.Universal.CreateRebaseOptionsMenu)
|
||||
self.assert.SelectedLine(Contains("continue"))
|
||||
self.assert.CurrentView().SelectedLine(Contains("continue"))
|
||||
self.Confirm()
|
||||
}
|
||||
|
||||
@ -147,8 +177,9 @@ func (self *Input) NavigateToListItem(matcher *matcher) {
|
||||
self.assert.assertWithRetries(func() (bool, string) {
|
||||
matchIndex = -1
|
||||
var matches []string
|
||||
lines := view.ViewBufferLines()
|
||||
// first we look for a duplicate on the current screen. We won't bother looking beyond that though.
|
||||
for i, line := range view.ViewBufferLines() {
|
||||
for i, line := range lines {
|
||||
ok, _ := matcher.test(line)
|
||||
if ok {
|
||||
matches = append(matches, line)
|
||||
@ -156,9 +187,9 @@ func (self *Input) NavigateToListItem(matcher *matcher) {
|
||||
}
|
||||
}
|
||||
if len(matches) > 1 {
|
||||
return false, fmt.Sprintf("Found %d matches for `%s`, expected only a single match. Lines:\n%s", len(matches), matcher.name, strings.Join(matches, "\n"))
|
||||
return false, fmt.Sprintf("Found %d matches for `%s`, expected only a single match. Matching lines:\n%s", len(matches), matcher.name(), strings.Join(matches, "\n"))
|
||||
} else if len(matches) == 0 {
|
||||
return false, fmt.Sprintf("Could not find item matching: %s", matcher.name)
|
||||
return false, fmt.Sprintf("Could not find item matching: %s. Lines:\n%s", matcher.name(), strings.Join(lines, "\n"))
|
||||
} else {
|
||||
return true, ""
|
||||
}
|
||||
@ -166,41 +197,41 @@ func (self *Input) NavigateToListItem(matcher *matcher) {
|
||||
|
||||
selectedLineIdx := view.SelectedLineIdx()
|
||||
if selectedLineIdx == matchIndex {
|
||||
self.assert.SelectedLine(matcher)
|
||||
self.assert.CurrentView().SelectedLine(matcher)
|
||||
return
|
||||
}
|
||||
if selectedLineIdx < matchIndex {
|
||||
for i := selectedLineIdx; i < matchIndex; i++ {
|
||||
self.NextItem()
|
||||
}
|
||||
self.assert.SelectedLine(matcher)
|
||||
self.assert.CurrentView().SelectedLine(matcher)
|
||||
return
|
||||
} else {
|
||||
for i := selectedLineIdx; i > matchIndex; i-- {
|
||||
self.PreviousItem()
|
||||
}
|
||||
self.assert.SelectedLine(matcher)
|
||||
self.assert.CurrentView().SelectedLine(matcher)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Input) AcceptConfirmation(title *matcher, content *matcher) {
|
||||
self.assert.InConfirm()
|
||||
self.assert.CurrentViewTitle(title)
|
||||
self.assert.CurrentViewContent(content)
|
||||
self.assert.CurrentView().Title(title)
|
||||
self.assert.CurrentView().Content(content)
|
||||
self.Confirm()
|
||||
}
|
||||
|
||||
func (self *Input) DenyConfirmation(title *matcher, content *matcher) {
|
||||
self.assert.InConfirm()
|
||||
self.assert.CurrentViewTitle(title)
|
||||
self.assert.CurrentViewContent(content)
|
||||
self.assert.CurrentView().Title(title)
|
||||
self.assert.CurrentView().Content(content)
|
||||
self.Cancel()
|
||||
}
|
||||
|
||||
func (self *Input) Prompt(title *matcher, textToType string) {
|
||||
self.assert.InPrompt()
|
||||
self.assert.CurrentViewTitle(title)
|
||||
self.assert.CurrentView().Title(title)
|
||||
self.Type(textToType)
|
||||
self.Confirm()
|
||||
}
|
||||
@ -209,24 +240,24 @@ func (self *Input) Prompt(title *matcher, textToType string) {
|
||||
// item to match the given matcher, then confirm that item.
|
||||
func (self *Input) Typeahead(title *matcher, textToType string, expectedFirstOption *matcher) {
|
||||
self.assert.InPrompt()
|
||||
self.assert.CurrentViewTitle(title)
|
||||
self.assert.CurrentView().Title(title)
|
||||
self.Type(textToType)
|
||||
self.Press(self.keys.Universal.TogglePanel)
|
||||
self.assert.CurrentViewName("suggestions")
|
||||
self.assert.SelectedLine(expectedFirstOption)
|
||||
self.assert.CurrentView().Name("suggestions")
|
||||
self.assert.CurrentView().SelectedLine(expectedFirstOption)
|
||||
self.Confirm()
|
||||
}
|
||||
|
||||
func (self *Input) Menu(title *matcher, optionToSelect *matcher) {
|
||||
self.assert.InMenu()
|
||||
self.assert.CurrentViewTitle(title)
|
||||
self.assert.CurrentView().Title(title)
|
||||
self.NavigateToListItem(optionToSelect)
|
||||
self.Confirm()
|
||||
}
|
||||
|
||||
func (self *Input) Alert(title *matcher, content *matcher) {
|
||||
self.assert.InListContext()
|
||||
self.assert.CurrentViewTitle(title)
|
||||
self.assert.CurrentViewContent(content)
|
||||
self.assert.CurrentView().Title(title)
|
||||
self.assert.CurrentView().Content(content)
|
||||
self.Confirm()
|
||||
}
|
||||
|
@ -1,35 +1,156 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
// for making assertions on string values
|
||||
type matcher struct {
|
||||
rules []matcherRule
|
||||
|
||||
// this is printed when there's an error so that it's clear what the context of the assertion is
|
||||
prefix string
|
||||
}
|
||||
|
||||
type matcherRule struct {
|
||||
// e.g. "contains 'foo'"
|
||||
name string
|
||||
// returns a bool that says whether the test passed and if it returns false, it
|
||||
// also returns a string of the error message
|
||||
testFn func(string) (bool, string)
|
||||
// this is printed when there's an error so that it's clear what the context of the assertion is
|
||||
prefix string
|
||||
}
|
||||
|
||||
func NewMatcher(name string, testFn func(string) (bool, string)) *matcher {
|
||||
return &matcher{name: name, testFn: testFn}
|
||||
rules := []matcherRule{{name: name, testFn: testFn}}
|
||||
return &matcher{rules: rules}
|
||||
}
|
||||
|
||||
func (self *matcher) name() string {
|
||||
if len(self.rules) == 0 {
|
||||
return "anything"
|
||||
}
|
||||
|
||||
return strings.Join(
|
||||
lo.Map(self.rules, func(rule matcherRule, _ int) string { return rule.name }),
|
||||
", ",
|
||||
)
|
||||
}
|
||||
|
||||
func (self *matcher) test(value string) (bool, string) {
|
||||
ok, message := self.testFn(value)
|
||||
if ok {
|
||||
return true, ""
|
||||
for _, rule := range self.rules {
|
||||
ok, message := rule.testFn(value)
|
||||
if ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if self.prefix != "" {
|
||||
return false, self.prefix + " " + message
|
||||
}
|
||||
|
||||
return false, message
|
||||
}
|
||||
|
||||
if self.prefix != "" {
|
||||
return false, self.prefix + " " + message
|
||||
}
|
||||
|
||||
return false, message
|
||||
return true, ""
|
||||
}
|
||||
|
||||
func (self *matcher) Contains(target string) *matcher {
|
||||
return self.appendRule(matcherRule{
|
||||
name: fmt.Sprintf("contains '%s'", target),
|
||||
testFn: func(value string) (bool, string) {
|
||||
return strings.Contains(value, target), fmt.Sprintf("Expected '%s' to be found in '%s'", target, value)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (self *matcher) DoesNotContain(target string) *matcher {
|
||||
return self.appendRule(matcherRule{
|
||||
name: fmt.Sprintf("does not contain '%s'", target),
|
||||
testFn: func(value string) (bool, string) {
|
||||
return !strings.Contains(value, target), fmt.Sprintf("Expected '%s' to NOT be found in '%s'", target, value)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (self *matcher) MatchesRegexp(target string) *matcher {
|
||||
return self.appendRule(matcherRule{
|
||||
name: fmt.Sprintf("matches regular expression '%s'", target),
|
||||
testFn: func(value string) (bool, string) {
|
||||
matched, err := regexp.MatchString(target, value)
|
||||
if err != nil {
|
||||
return false, fmt.Sprintf("Unexpected error parsing regular expression '%s': %s", target, err.Error())
|
||||
}
|
||||
return matched, fmt.Sprintf("Expected '%s' to match regular expression '%s'", value, target)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (self *matcher) Equals(target string) *matcher {
|
||||
return self.appendRule(matcherRule{
|
||||
name: fmt.Sprintf("equals '%s'", target),
|
||||
testFn: func(value string) (bool, string) {
|
||||
return target == value, fmt.Sprintf("Expected '%s' to equal '%s'", value, target)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const IS_SELECTED_RULE_NAME = "is selected"
|
||||
|
||||
// special rule that is only to be used in the TopLines and Lines methods, as a way of
|
||||
// asserting that a given line is selected.
|
||||
func (self *matcher) IsSelected() *matcher {
|
||||
return self.appendRule(matcherRule{
|
||||
name: IS_SELECTED_RULE_NAME,
|
||||
testFn: func(value string) (bool, string) {
|
||||
panic("Special IsSelected matcher is not supposed to have its testFn method called. This rule should only be used within the .Lines() and .TopLines() method on a ViewAsserter.")
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (self *matcher) appendRule(rule matcherRule) *matcher {
|
||||
self.rules = append(self.rules, rule)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
// adds context so that if the matcher test(s) fails, we understand what we were trying to test.
|
||||
// E.g. prefix: "Unexpected content in view 'files'."
|
||||
func (self *matcher) context(prefix string) *matcher {
|
||||
self.prefix = prefix
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
// if the matcher has an `IsSelected` rule, it returns true, along with the matcher after that rule has been removed
|
||||
func (self *matcher) checkIsSelected() (bool, *matcher) {
|
||||
check := lo.ContainsBy(self.rules, func(rule matcherRule) bool { return rule.name == IS_SELECTED_RULE_NAME })
|
||||
|
||||
self.rules = lo.Filter(self.rules, func(rule matcherRule, _ int) bool { return rule.name != IS_SELECTED_RULE_NAME })
|
||||
|
||||
return check, self
|
||||
}
|
||||
|
||||
// this matcher has no rules meaning it always passes the test. Use this
|
||||
// when you don't care what value you're dealing with.
|
||||
func Anything() *matcher {
|
||||
return &matcher{}
|
||||
}
|
||||
|
||||
func Contains(target string) *matcher {
|
||||
return Anything().Contains(target)
|
||||
}
|
||||
|
||||
func DoesNotContain(target string) *matcher {
|
||||
return Anything().DoesNotContain(target)
|
||||
}
|
||||
|
||||
func MatchesRegexp(target string) *matcher {
|
||||
return Anything().MatchesRegexp(target)
|
||||
}
|
||||
|
||||
func Equals(target string) *matcher {
|
||||
return Anything().Equals(target)
|
||||
}
|
||||
|
114
pkg/integration/components/view_asserter.go
Normal file
114
pkg/integration/components/view_asserter.go
Normal file
@ -0,0 +1,114 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
)
|
||||
|
||||
type ViewAsserter struct {
|
||||
// context is prepended to any error messages e.g. 'context: "current view"'
|
||||
context string
|
||||
getView func() *gocui.View
|
||||
assert *Assert
|
||||
}
|
||||
|
||||
// asserts that the view has the expected name. This is typically used in tandem with the CurrentView method i.e.;
|
||||
// assert.CurrentView().Name("commits") to assert that the current view is the commits view.
|
||||
func (self *ViewAsserter) Name(expected string) *ViewAsserter {
|
||||
self.assert.assertWithRetries(func() (bool, string) {
|
||||
actual := self.getView().Name()
|
||||
return actual == expected, fmt.Sprintf("%s: Expected view name to be '%s', but got '%s'", self.context, expected, actual)
|
||||
})
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
// asserts that the view has the expected title
|
||||
func (self *ViewAsserter) Title(expected *matcher) *ViewAsserter {
|
||||
self.assert.assertWithRetries(func() (bool, string) {
|
||||
actual := self.getView().Title
|
||||
return expected.context(fmt.Sprintf("%s title", self.context)).test(actual)
|
||||
})
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
// asserts that the view has lines matching the given matchers. So if three matchers
|
||||
// are passed, we only check the first three lines of the view.
|
||||
// This method is convenient when you have a list of commits but you only want to
|
||||
// assert on the first couple of commits.
|
||||
func (self *ViewAsserter) TopLines(matchers ...*matcher) *ViewAsserter {
|
||||
self.assert.assertWithRetries(func() (bool, string) {
|
||||
lines := self.getView().BufferLines()
|
||||
return len(lines) >= len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected at least %d, got %d", len(matchers), len(lines))
|
||||
})
|
||||
|
||||
return self.assertLines(matchers...)
|
||||
}
|
||||
|
||||
// asserts that the view has lines matching the given matchers. One matcher must be passed for each line.
|
||||
// If you only care about the top n lines, use the TopLines method instead.
|
||||
func (self *ViewAsserter) Lines(matchers ...*matcher) *ViewAsserter {
|
||||
self.assert.assertWithRetries(func() (bool, string) {
|
||||
lines := self.getView().BufferLines()
|
||||
return len(lines) == len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", len(matchers), len(lines))
|
||||
})
|
||||
|
||||
return self.assertLines(matchers...)
|
||||
}
|
||||
|
||||
func (self *ViewAsserter) assertLines(matchers ...*matcher) *ViewAsserter {
|
||||
view := self.getView()
|
||||
|
||||
for i, matcher := range matchers {
|
||||
checkIsSelected, matcher := matcher.checkIsSelected()
|
||||
|
||||
self.assert.matchString(matcher, fmt.Sprintf("Unexpected content in view '%s'.", view.Name()),
|
||||
func() string {
|
||||
return view.BufferLines()[i]
|
||||
},
|
||||
)
|
||||
|
||||
if checkIsSelected {
|
||||
self.assert.assertWithRetries(func() (bool, string) {
|
||||
lineIdx := view.SelectedLineIdx()
|
||||
return lineIdx == i, fmt.Sprintf("Unexpected selected line index in view '%s'. Expected %d, got %d", view.Name(), i, lineIdx)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
// asserts on the content of the view i.e. the stuff within the view's frame.
|
||||
func (self *ViewAsserter) Content(matcher *matcher) *ViewAsserter {
|
||||
self.assert.matchString(matcher, fmt.Sprintf("%s: Unexpected content.", self.context),
|
||||
func() string {
|
||||
return self.getView().Buffer()
|
||||
},
|
||||
)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
// asserts on the selected line of the view
|
||||
func (self *ViewAsserter) SelectedLine(matcher *matcher) *ViewAsserter {
|
||||
self.assert.matchString(matcher, fmt.Sprintf("%s: Unexpected selected line.", self.context),
|
||||
func() string {
|
||||
return self.getView().SelectedLine()
|
||||
},
|
||||
)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
// asserts on the index of the selected line. 0 is the first index, representing the line at the top of the view.
|
||||
func (self *ViewAsserter) SelectedLineIdx(expected int) *ViewAsserter {
|
||||
self.assert.assertWithRetries(func() (bool, string) {
|
||||
actual := self.getView().SelectedLineIdx()
|
||||
return expected == actual, fmt.Sprintf("%s: Expected selected line index to be %d, got %d", self.context, expected, actual)
|
||||
})
|
||||
|
||||
return self
|
||||
}
|
@ -32,41 +32,39 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
|
||||
assert.AtLeastOneCommit()
|
||||
|
||||
input.SwitchToCommitsWindow()
|
||||
input.SwitchToCommitsView()
|
||||
|
||||
assert.SelectedLine(Contains("commit 10"))
|
||||
assert.CurrentView().SelectedLine(Contains("commit 10"))
|
||||
|
||||
input.NavigateToListItem(Contains("commit 09"))
|
||||
|
||||
markCommitAsBad()
|
||||
|
||||
assert.ViewContent("information", Contains("bisecting"))
|
||||
assert.View("information").Content(Contains("bisecting"))
|
||||
|
||||
assert.CurrentViewName("commits")
|
||||
assert.SelectedLine(Contains("<-- bad"))
|
||||
assert.CurrentView().Name("commits").SelectedLine(Contains("<-- bad"))
|
||||
|
||||
input.NavigateToListItem(Contains("commit 02"))
|
||||
|
||||
markCommitAsGood()
|
||||
|
||||
// lazygit will land us in the commit between our good and bad commits.
|
||||
assert.CurrentViewName("commits")
|
||||
assert.SelectedLine(Contains("commit 05"))
|
||||
assert.SelectedLine(Contains("<-- current"))
|
||||
assert.CurrentView().
|
||||
Name("commits").
|
||||
SelectedLine(Contains("commit 05").Contains("<-- current"))
|
||||
|
||||
markCommitAsBad()
|
||||
|
||||
assert.CurrentViewName("commits")
|
||||
assert.SelectedLine(Contains("commit 04"))
|
||||
assert.SelectedLine(Contains("<-- current"))
|
||||
assert.CurrentView().
|
||||
Name("commits").
|
||||
SelectedLine(Contains("commit 04").Contains("<-- current"))
|
||||
|
||||
markCommitAsGood()
|
||||
|
||||
// commit 5 is the culprit because we marked 4 as good and 5 as bad.
|
||||
input.Alert(Equals("Bisect complete"), MatchesRegexp("(?s)commit 05.*Do you want to reset"))
|
||||
|
||||
assert.CurrentViewName("commits")
|
||||
assert.CurrentViewContent(Contains("commit 04"))
|
||||
assert.ViewContent("information", NotContains("bisecting"))
|
||||
assert.CurrentView().Name("commits").Content(Contains("commit 04"))
|
||||
assert.View("information").Content(DoesNotContain("bisecting"))
|
||||
},
|
||||
})
|
||||
|
@ -24,29 +24,31 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
assert *Assert,
|
||||
keys config.KeybindingConfig,
|
||||
) {
|
||||
assert.ViewContent("information", Contains("bisecting"))
|
||||
assert.View("information").Content(Contains("bisecting"))
|
||||
|
||||
assert.AtLeastOneCommit()
|
||||
|
||||
input.SwitchToCommitsWindow()
|
||||
input.SwitchToCommitsView()
|
||||
|
||||
assert.SelectedLine(Contains("<-- bad"))
|
||||
assert.SelectedLine(Contains("commit 08"))
|
||||
assert.CurrentView().TopLines(
|
||||
MatchesRegexp(`<-- bad.*commit 08`),
|
||||
MatchesRegexp(`<-- current.*commit 07`),
|
||||
MatchesRegexp(`\?.*commit 06`),
|
||||
MatchesRegexp(`<-- good.*commit 05`),
|
||||
)
|
||||
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("<-- current"))
|
||||
assert.SelectedLine(Contains("commit 07"))
|
||||
|
||||
input.Press(keys.Commits.ViewBisectOptions)
|
||||
input.Menu(Equals("Bisect"), MatchesRegexp(`mark .* as good`))
|
||||
|
||||
input.Alert(Equals("Bisect complete"), MatchesRegexp(`(?s)commit 08.*Do you want to reset`))
|
||||
|
||||
assert.ViewContent("information", NotContains("bisecting"))
|
||||
assert.View("information").Content(DoesNotContain("bisecting"))
|
||||
|
||||
// back in master branch which just had the one commit
|
||||
assert.CurrentViewName("commits")
|
||||
assert.CommitCount(1)
|
||||
assert.SelectedLine(Contains("only commit on master"))
|
||||
assert.CurrentView().Name("commits").Lines(
|
||||
Contains("only commit on master"),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
@ -18,19 +18,26 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
EmptyCommit("blah")
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToBranchesWindow()
|
||||
assert.CurrentViewName("localBranches")
|
||||
input.SwitchToBranchesView()
|
||||
|
||||
assert.SelectedLine(Contains("master"))
|
||||
assert.CurrentView().Lines(
|
||||
Contains("master"),
|
||||
Contains("@"),
|
||||
)
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("@"))
|
||||
|
||||
input.Press(keys.Branches.CheckoutBranchByName)
|
||||
|
||||
input.Prompt(Equals("Branch name:"), "new-branch")
|
||||
|
||||
input.Alert(Equals("Branch not found"), Equals("Branch not found. Create a new branch named new-branch?"))
|
||||
|
||||
assert.CurrentViewName("localBranches")
|
||||
assert.SelectedLine(Contains("new-branch"))
|
||||
assert.CurrentView().Name("localBranches").
|
||||
Lines(
|
||||
MatchesRegexp(`\*.*new-branch`),
|
||||
Contains("master"),
|
||||
Contains("@"),
|
||||
).
|
||||
SelectedLine(Contains("new-branch"))
|
||||
},
|
||||
})
|
||||
|
@ -17,21 +17,26 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
NewBranch("branch-two")
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToBranchesWindow()
|
||||
assert.CurrentViewName("localBranches")
|
||||
input.SwitchToBranchesView()
|
||||
|
||||
assert.CurrentView().Lines(
|
||||
MatchesRegexp(`\*.*branch-two`),
|
||||
MatchesRegexp(`branch-one`),
|
||||
MatchesRegexp(`master`),
|
||||
)
|
||||
|
||||
assert.SelectedLine(Contains("branch-two"))
|
||||
input.Press(keys.Universal.Remove)
|
||||
input.Alert(Equals("Error"), Contains("You cannot delete the checked out branch!"))
|
||||
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("branch-one"))
|
||||
|
||||
input.Press(keys.Universal.Remove)
|
||||
input.AcceptConfirmation(Equals("Delete Branch"), Contains("Are you sure you want to delete the branch 'branch-one'?"))
|
||||
|
||||
assert.CurrentViewName("localBranches")
|
||||
assert.SelectedLine(Contains("master"))
|
||||
assert.CurrentViewContent(NotContains("branch-one"))
|
||||
assert.CurrentView().Name("localBranches").
|
||||
Lines(
|
||||
MatchesRegexp(`\*.*branch-two`),
|
||||
MatchesRegexp(`master`).IsSelected(),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
@ -15,35 +15,44 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
shared.MergeConflictsSetup(shell)
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToBranchesWindow()
|
||||
assert.CurrentViewName("localBranches")
|
||||
input.SwitchToBranchesView()
|
||||
|
||||
assert.View("localBranches").Lines(
|
||||
Contains("first-change-branch"),
|
||||
Contains("second-change-branch"),
|
||||
Contains("original-branch"),
|
||||
)
|
||||
|
||||
assert.View("commits").TopLines(
|
||||
Contains("first change"),
|
||||
Contains("original"),
|
||||
)
|
||||
|
||||
assert.SelectedLine(Contains("first-change-branch"))
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("second-change-branch"))
|
||||
input.Press(keys.Branches.RebaseBranch)
|
||||
|
||||
input.AcceptConfirmation(Equals("Rebasing"), Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?"))
|
||||
|
||||
input.AcceptConfirmation(Equals("Auto-merge failed"), Contains("Conflicts!"))
|
||||
|
||||
assert.CurrentViewName("files")
|
||||
assert.SelectedLine(Contains("file"))
|
||||
assert.CurrentView().Name("files").SelectedLine(Contains("file"))
|
||||
|
||||
// not using Confirm() convenience method because I suspect we might change this
|
||||
// keybinding to something more bespoke
|
||||
input.Press(keys.Universal.Confirm)
|
||||
|
||||
assert.CurrentViewName("mergeConflicts")
|
||||
assert.CurrentView().Name("mergeConflicts")
|
||||
input.PrimaryAction()
|
||||
|
||||
assert.ViewContent("information", Contains("rebasing"))
|
||||
assert.View("information").Content(Contains("rebasing"))
|
||||
|
||||
input.AcceptConfirmation(Equals("continue"), Contains("all merge conflicts resolved. Continue?"))
|
||||
|
||||
assert.ViewContent("information", NotContains("rebasing"))
|
||||
assert.View("information").Content(DoesNotContain("rebasing"))
|
||||
|
||||
// this proves we actually have integrated the changes from second-change-branch
|
||||
assert.ViewContent("commits", Contains("second-change-branch unrelated change"))
|
||||
assert.View("commits").TopLines(
|
||||
Contains("second-change-branch unrelated change"),
|
||||
Contains("second change"),
|
||||
Contains("original"),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
@ -18,48 +18,74 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
shell.EmptyCommit("to keep")
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToBranchesWindow()
|
||||
assert.CurrentViewName("localBranches")
|
||||
input.SwitchToBranchesView()
|
||||
|
||||
assert.CurrentView().Lines(
|
||||
Contains("first-change-branch"),
|
||||
Contains("second-change-branch"),
|
||||
Contains("original-branch"),
|
||||
)
|
||||
|
||||
assert.View("commits").TopLines(
|
||||
Contains("to keep").IsSelected(),
|
||||
Contains("to remove"),
|
||||
Contains("first change"),
|
||||
Contains("original"),
|
||||
)
|
||||
|
||||
assert.SelectedLine(Contains("first-change-branch"))
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("second-change-branch"))
|
||||
input.Press(keys.Branches.RebaseBranch)
|
||||
|
||||
input.AcceptConfirmation(Equals("Rebasing"), Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?"))
|
||||
|
||||
assert.ViewContent("information", Contains("rebasing"))
|
||||
assert.View("information").Content(Contains("rebasing"))
|
||||
|
||||
input.AcceptConfirmation(Equals("Auto-merge failed"), Contains("Conflicts!"))
|
||||
|
||||
assert.CurrentViewName("files")
|
||||
assert.SelectedLine(Contains("file"))
|
||||
assert.CurrentView().
|
||||
Name("files").
|
||||
SelectedLine(MatchesRegexp("UU.*file"))
|
||||
|
||||
input.SwitchToCommitsView()
|
||||
assert.CurrentView().
|
||||
TopLines(
|
||||
MatchesRegexp(`pick.*to keep`).IsSelected(),
|
||||
MatchesRegexp(`pick.*to remove`),
|
||||
MatchesRegexp("YOU ARE HERE.*second-change-branch unrelated change"),
|
||||
MatchesRegexp("second change"),
|
||||
MatchesRegexp("original"),
|
||||
)
|
||||
|
||||
input.SwitchToCommitsWindow()
|
||||
assert.SelectedLine(Contains("pick")) // this means it's a rebasing commit
|
||||
input.NextItem()
|
||||
input.Press(keys.Universal.Remove)
|
||||
// this is the commit name
|
||||
assert.SelectedLine(Contains("to remove"))
|
||||
// the commit has been marked to drop once we continue the rebase.
|
||||
assert.SelectedLine(Contains("drop"))
|
||||
|
||||
input.SwitchToFilesWindow()
|
||||
assert.CurrentView().
|
||||
TopLines(
|
||||
MatchesRegexp(`pick.*to keep`),
|
||||
MatchesRegexp(`drop.*to remove`).IsSelected(),
|
||||
MatchesRegexp("YOU ARE HERE.*second-change-branch unrelated change"),
|
||||
MatchesRegexp("second change"),
|
||||
MatchesRegexp("original"),
|
||||
)
|
||||
|
||||
input.SwitchToFilesView()
|
||||
|
||||
// not using Confirm() convenience method because I suspect we might change this
|
||||
// keybinding to something more bespoke
|
||||
input.Press(keys.Universal.Confirm)
|
||||
|
||||
assert.CurrentViewName("mergeConflicts")
|
||||
assert.CurrentView().Name("mergeConflicts")
|
||||
input.PrimaryAction()
|
||||
|
||||
input.AcceptConfirmation(Equals("continue"), Contains("all merge conflicts resolved. Continue?"))
|
||||
|
||||
assert.ViewContent("information", NotContains("rebasing"))
|
||||
assert.View("information").Content(DoesNotContain("rebasing"))
|
||||
|
||||
// this proves we actually have integrated the changes from second-change-branch
|
||||
assert.ViewContent("commits", Contains("second-change-branch unrelated change"))
|
||||
assert.ViewContent("commits", Contains("to keep"))
|
||||
assert.ViewContent("commits", NotContains("to remove"))
|
||||
assert.View("commits").TopLines(
|
||||
Contains("to keep"),
|
||||
Contains("second-change-branch unrelated change").IsSelected(),
|
||||
Contains("second change"),
|
||||
Contains("original"),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
@ -21,26 +21,31 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
shell.EmptyCommit("current-branch commit")
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToBranchesWindow()
|
||||
assert.CurrentViewName("localBranches")
|
||||
assert.View("commits").Lines(
|
||||
Contains("current-branch commit"),
|
||||
Contains("root commit"),
|
||||
)
|
||||
|
||||
assert.SelectedLine(Contains("current-branch"))
|
||||
input.SwitchToBranchesView()
|
||||
|
||||
assert.CurrentView().Lines(
|
||||
Contains("current-branch"),
|
||||
Contains("other-branch"),
|
||||
)
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("other-branch"))
|
||||
|
||||
input.Press(keys.Commits.ViewResetOptions)
|
||||
|
||||
input.Menu(Contains("reset to other-branch"), Contains("hard reset"))
|
||||
|
||||
// ensure that we've returned from the menu before continuing
|
||||
assert.CurrentViewName("localBranches")
|
||||
assert.CurrentView().Name("localBranches")
|
||||
|
||||
// assert that we now have the expected commits in the commit panel
|
||||
input.SwitchToCommitsWindow()
|
||||
assert.CurrentViewName("commits")
|
||||
assert.CommitCount(2)
|
||||
assert.SelectedLine(Contains("other-branch commit"))
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("root commit"))
|
||||
input.SwitchToCommitsView()
|
||||
assert.CurrentView().Lines(
|
||||
Contains("other-branch commit"),
|
||||
Contains("root commit"),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
@ -21,8 +21,7 @@ var Suggestions = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
NewBranch("other-new-branch-3")
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToBranchesWindow()
|
||||
assert.CurrentViewName("localBranches")
|
||||
input.SwitchToBranchesView()
|
||||
|
||||
input.Press(keys.Branches.CheckoutBranchByName)
|
||||
|
||||
|
@ -24,41 +24,52 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Checkout("first-branch")
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToBranchesWindow()
|
||||
assert.CurrentViewName("localBranches")
|
||||
input.SwitchToBranchesView()
|
||||
|
||||
assert.CurrentView().Lines(
|
||||
Contains("first-branch"),
|
||||
Contains("second-branch"),
|
||||
Contains("master"),
|
||||
)
|
||||
|
||||
assert.SelectedLine(Contains("first-branch"))
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("second-branch"))
|
||||
|
||||
input.Enter()
|
||||
|
||||
assert.CurrentViewName("subCommits")
|
||||
assert.SelectedLine(Contains("four"))
|
||||
input.Press(keys.Commits.CherryPickCopy)
|
||||
assert.ViewContent("information", Contains("1 commit copied"))
|
||||
assert.CurrentView().Name("subCommits").Lines(
|
||||
Contains("four"),
|
||||
Contains("three"),
|
||||
Contains("base"),
|
||||
)
|
||||
|
||||
// copy commits 'four' and 'three'
|
||||
input.Press(keys.Commits.CherryPickCopy)
|
||||
assert.View("information").Content(Contains("1 commit copied"))
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("three"))
|
||||
input.Press(keys.Commits.CherryPickCopy)
|
||||
assert.ViewContent("information", Contains("2 commits copied"))
|
||||
assert.View("information").Content(Contains("2 commits copied"))
|
||||
|
||||
input.SwitchToCommitsWindow()
|
||||
assert.CurrentViewName("commits")
|
||||
input.SwitchToCommitsView()
|
||||
|
||||
assert.CurrentView().Lines(
|
||||
Contains("two"),
|
||||
Contains("one"),
|
||||
Contains("base"),
|
||||
)
|
||||
|
||||
assert.SelectedLine(Contains("two"))
|
||||
input.Press(keys.Commits.PasteCommits)
|
||||
input.Alert(Equals("Cherry-Pick"), Contains("Are you sure you want to cherry-pick the copied commits onto this branch?"))
|
||||
|
||||
assert.CurrentViewName("commits")
|
||||
assert.SelectedLine(Contains("four"))
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("three"))
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("two"))
|
||||
assert.CurrentView().Name("commits").Lines(
|
||||
Contains("four"),
|
||||
Contains("three"),
|
||||
Contains("two"),
|
||||
Contains("one"),
|
||||
Contains("base"),
|
||||
)
|
||||
|
||||
assert.ViewContent("information", Contains("2 commits copied"))
|
||||
assert.View("information").Content(Contains("2 commits copied"))
|
||||
input.Press(keys.Universal.Return)
|
||||
assert.ViewContent("information", NotContains("commits copied"))
|
||||
assert.View("information").Content(DoesNotContain("commits copied"))
|
||||
},
|
||||
})
|
||||
|
@ -15,67 +15,74 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
shared.MergeConflictsSetup(shell)
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToBranchesWindow()
|
||||
assert.CurrentViewName("localBranches")
|
||||
input.SwitchToBranchesView()
|
||||
assert.CurrentView().Lines(
|
||||
Contains("first-change-branch"),
|
||||
Contains("second-change-branch"),
|
||||
Contains("original-branch"),
|
||||
)
|
||||
|
||||
assert.SelectedLine(Contains("first-change-branch"))
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("second-change-branch"))
|
||||
|
||||
input.Enter()
|
||||
|
||||
assert.CurrentViewName("subCommits")
|
||||
assert.SelectedLine(Contains("second-change-branch unrelated change"))
|
||||
assert.CurrentView().Name("subCommits").TopLines(
|
||||
Contains("second-change-branch unrelated change"),
|
||||
Contains("second change"),
|
||||
)
|
||||
|
||||
input.Press(keys.Commits.CherryPickCopy)
|
||||
assert.ViewContent("information", Contains("1 commit copied"))
|
||||
assert.View("information").Content(Contains("1 commit copied"))
|
||||
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("second change"))
|
||||
input.Press(keys.Commits.CherryPickCopy)
|
||||
assert.ViewContent("information", Contains("2 commits copied"))
|
||||
assert.View("information").Content(Contains("2 commits copied"))
|
||||
|
||||
input.SwitchToCommitsWindow()
|
||||
assert.CurrentViewName("commits")
|
||||
input.SwitchToCommitsView()
|
||||
|
||||
assert.CurrentView().TopLines(
|
||||
Contains("first change"),
|
||||
)
|
||||
|
||||
assert.SelectedLine(Contains("first change"))
|
||||
input.Press(keys.Commits.PasteCommits)
|
||||
input.Alert(Equals("Cherry-Pick"), Contains("Are you sure you want to cherry-pick the copied commits onto this branch?"))
|
||||
|
||||
input.AcceptConfirmation(Equals("Auto-merge failed"), Contains("Conflicts!"))
|
||||
|
||||
assert.CurrentViewName("files")
|
||||
assert.SelectedLine(Contains("file"))
|
||||
assert.CurrentView().Name("files")
|
||||
assert.CurrentView().SelectedLine(Contains("file"))
|
||||
|
||||
// not using Confirm() convenience method because I suspect we might change this
|
||||
// keybinding to something more bespoke
|
||||
input.Press(keys.Universal.Confirm)
|
||||
|
||||
assert.CurrentViewName("mergeConflicts")
|
||||
assert.CurrentView().Name("mergeConflicts")
|
||||
// picking 'Second change'
|
||||
input.NextItem()
|
||||
input.PrimaryAction()
|
||||
|
||||
input.AcceptConfirmation(Equals("continue"), Contains("all merge conflicts resolved. Continue?"))
|
||||
|
||||
assert.CurrentViewName("files")
|
||||
assert.CurrentView().Name("files")
|
||||
assert.WorkingTreeFileCount(0)
|
||||
|
||||
input.SwitchToCommitsWindow()
|
||||
assert.CurrentViewName("commits")
|
||||
input.SwitchToCommitsView()
|
||||
|
||||
assert.SelectedLine(Contains("second-change-branch unrelated change"))
|
||||
assert.CurrentView().TopLines(
|
||||
Contains("second-change-branch unrelated change"),
|
||||
Contains("second change"),
|
||||
Contains("first change"),
|
||||
)
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("second change"))
|
||||
// because we picked 'Second change' when resolving the conflict,
|
||||
// we now see this commit as having replaced First Change with Second Change,
|
||||
// as opposed to replacing 'Original' with 'Second change'
|
||||
assert.MainViewContent(Contains("-First Change"))
|
||||
assert.MainViewContent(Contains("+Second Change"))
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Contains("first change"))
|
||||
assert.MainView().
|
||||
Content(Contains("-First Change")).
|
||||
Content(Contains("+Second Change"))
|
||||
|
||||
assert.ViewContent("information", Contains("2 commits copied"))
|
||||
assert.View("information").Content(Contains("2 commits copied"))
|
||||
input.Press(keys.Universal.Return)
|
||||
assert.ViewContent("information", NotContains("commits copied"))
|
||||
assert.View("information").Content(DoesNotContain("commits copied"))
|
||||
},
|
||||
})
|
||||
|
@ -29,7 +29,7 @@ var CommitMultiline = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
assert.CommitCount(1)
|
||||
assert.HeadCommitMessage(Equals("first line"))
|
||||
|
||||
input.SwitchToCommitsWindow()
|
||||
assert.MainViewContent(MatchesRegexp("first line\n\\s*\n\\s*third line"))
|
||||
input.SwitchToCommitsView()
|
||||
assert.MainView().Content(MatchesRegexp("first line\n\\s*\n\\s*third line"))
|
||||
},
|
||||
})
|
||||
|
@ -19,8 +19,12 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
assert.CommitCount(3)
|
||||
|
||||
input.SwitchToCommitsWindow()
|
||||
assert.CurrentViewName("commits")
|
||||
input.SwitchToCommitsView()
|
||||
assert.CurrentView().Lines(
|
||||
Contains("commit 3"),
|
||||
Contains("commit 2"),
|
||||
Contains("commit 1"),
|
||||
)
|
||||
input.NextItem()
|
||||
|
||||
input.Press(keys.Universal.New)
|
||||
@ -28,8 +32,11 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
branchName := "my-branch-name"
|
||||
input.Prompt(Contains("New Branch Name"), branchName)
|
||||
|
||||
assert.CommitCount(2)
|
||||
assert.HeadCommitMessage(Contains("commit 2"))
|
||||
assert.CurrentBranchName(branchName)
|
||||
|
||||
assert.View("commits").Lines(
|
||||
Contains("commit 2"),
|
||||
Contains("commit 1"),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
@ -18,15 +18,22 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
assert.CommitCount(1)
|
||||
|
||||
input.SwitchToCommitsWindow()
|
||||
input.SwitchToCommitsView()
|
||||
|
||||
assert.CurrentView().Lines(
|
||||
Contains("first commit"),
|
||||
)
|
||||
|
||||
input.Press(keys.Commits.RevertCommit)
|
||||
input.AcceptConfirmation(Equals("Revert commit"), MatchesRegexp(`Are you sure you want to revert \w+?`))
|
||||
|
||||
assert.CommitCount(2)
|
||||
assert.HeadCommitMessage(Contains("Revert \"first commit\""))
|
||||
input.PreviousItem()
|
||||
assert.MainViewContent(Contains("-myfile content"))
|
||||
assert.CurrentView().Name("commits").
|
||||
Lines(
|
||||
Contains("Revert \"first commit\"").IsSelected(),
|
||||
Contains("first commit"),
|
||||
)
|
||||
|
||||
assert.MainView().Content(Contains("-myfile content"))
|
||||
assert.FileSystemPathNotPresent("myfile")
|
||||
},
|
||||
})
|
||||
|
@ -18,26 +18,26 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
assert.CommitCount(0)
|
||||
|
||||
assert.CurrentViewName("files")
|
||||
assert.SelectedLine(Contains("myfile"))
|
||||
assert.CurrentView().Name("files")
|
||||
assert.CurrentView().SelectedLine(Contains("myfile"))
|
||||
// stage the file
|
||||
input.PrimaryAction()
|
||||
input.Enter()
|
||||
assert.CurrentViewName("stagingSecondary")
|
||||
assert.CurrentView().Name("stagingSecondary")
|
||||
// we start with both lines having been staged
|
||||
assert.ViewContent("stagingSecondary", Contains("+myfile content"))
|
||||
assert.ViewContent("stagingSecondary", Contains("+with a second line"))
|
||||
assert.ViewContent("staging", NotContains("+myfile content"))
|
||||
assert.ViewContent("staging", NotContains("+with a second line"))
|
||||
assert.View("stagingSecondary").Content(Contains("+myfile content"))
|
||||
assert.View("stagingSecondary").Content(Contains("+with a second line"))
|
||||
assert.View("staging").Content(DoesNotContain("+myfile content"))
|
||||
assert.View("staging").Content(DoesNotContain("+with a second line"))
|
||||
|
||||
// unstage the selected line
|
||||
input.PrimaryAction()
|
||||
|
||||
// the line should have been moved to the main view
|
||||
assert.ViewContent("stagingSecondary", NotContains("+myfile content"))
|
||||
assert.ViewContent("stagingSecondary", Contains("+with a second line"))
|
||||
assert.ViewContent("staging", Contains("+myfile content"))
|
||||
assert.ViewContent("staging", NotContains("+with a second line"))
|
||||
assert.View("stagingSecondary").Content(DoesNotContain("+myfile content"))
|
||||
assert.View("stagingSecondary").Content(Contains("+with a second line"))
|
||||
assert.View("staging").Content(Contains("+myfile content"))
|
||||
assert.View("staging").Content(DoesNotContain("+with a second line"))
|
||||
|
||||
input.Press(keys.Files.CommitChanges)
|
||||
commitMessage := "my commit message"
|
||||
|
@ -19,36 +19,36 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
assert.CommitCount(0)
|
||||
|
||||
// stage the file
|
||||
assert.CurrentViewName("files")
|
||||
assert.SelectedLine(Contains("myfile"))
|
||||
assert.CurrentView().Name("files")
|
||||
assert.CurrentView().SelectedLine(Contains("myfile"))
|
||||
input.PrimaryAction()
|
||||
input.Enter()
|
||||
assert.CurrentViewName("stagingSecondary")
|
||||
assert.CurrentView().Name("stagingSecondary")
|
||||
// we start with both lines having been staged
|
||||
assert.ViewContent("stagingSecondary", Contains("+myfile content"))
|
||||
assert.ViewContent("stagingSecondary", Contains("+with a second line"))
|
||||
assert.ViewContent("staging", NotContains("+myfile content"))
|
||||
assert.ViewContent("staging", NotContains("+with a second line"))
|
||||
assert.View("stagingSecondary").Content(
|
||||
Contains("+myfile content").Contains("+with a second line"),
|
||||
)
|
||||
assert.View("staging").Content(
|
||||
DoesNotContain("+myfile content").DoesNotContain("+with a second line"),
|
||||
)
|
||||
|
||||
// unstage the selected line
|
||||
input.PrimaryAction()
|
||||
|
||||
// the line should have been moved to the main view
|
||||
assert.ViewContent("stagingSecondary", NotContains("+myfile content"))
|
||||
assert.ViewContent("stagingSecondary", Contains("+with a second line"))
|
||||
assert.ViewContent("staging", Contains("+myfile content"))
|
||||
assert.ViewContent("staging", NotContains("+with a second line"))
|
||||
assert.View("stagingSecondary").Content(DoesNotContain("+myfile content").Contains("+with a second line"))
|
||||
assert.View("staging").Content(Contains("+myfile content").DoesNotContain("+with a second line"))
|
||||
|
||||
input.Press(keys.Files.CommitChangesWithoutHook)
|
||||
assert.InCommitMessagePanel()
|
||||
assert.CurrentViewContent(Contains("WIP"))
|
||||
assert.CurrentView().Content(Contains("WIP"))
|
||||
commitMessage := ": my commit message"
|
||||
input.Type(commitMessage)
|
||||
input.Confirm()
|
||||
|
||||
assert.CommitCount(1)
|
||||
assert.HeadCommitMessage(Equals("WIP" + commitMessage))
|
||||
assert.CurrentViewName("stagingSecondary")
|
||||
assert.CurrentView().Name("stagingSecondary")
|
||||
|
||||
// TODO: assert that the staging panel has been refreshed (it currently does not get correctly refreshed)
|
||||
},
|
||||
|
@ -20,15 +20,14 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
assert.CommitCount(0)
|
||||
|
||||
assert.CurrentViewName("files")
|
||||
assert.SelectedLine(Contains("myfile"))
|
||||
assert.CurrentView().Name("files").SelectedLine(Contains("myfile"))
|
||||
input.Enter()
|
||||
assert.CurrentViewName("staging")
|
||||
assert.ViewContent("stagingSecondary", NotContains("+myfile content"))
|
||||
assert.CurrentView().Name("staging")
|
||||
assert.View("stagingSecondary").Content(DoesNotContain("+myfile content"))
|
||||
// stage the first line
|
||||
input.PrimaryAction()
|
||||
assert.ViewContent("staging", NotContains("+myfile content"))
|
||||
assert.ViewContent("stagingSecondary", Contains("+myfile content"))
|
||||
assert.View("staging").Content(DoesNotContain("+myfile content"))
|
||||
assert.View("stagingSecondary").Content(Contains("+myfile content"))
|
||||
|
||||
input.Press(keys.Files.CommitChanges)
|
||||
assert.InCommitMessagePanel()
|
||||
|
@ -21,6 +21,7 @@ var RemoteNamedStar = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
assert *Assert,
|
||||
keys config.KeybindingConfig,
|
||||
) {
|
||||
// here we're just asserting that we haven't panicked upon starting lazygit
|
||||
assert.AtLeastOneCommit()
|
||||
},
|
||||
})
|
||||
|
@ -30,7 +30,9 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
assert.WorkingTreeFileCount(0)
|
||||
|
||||
input.Press("a")
|
||||
assert.WorkingTreeFileCount(1)
|
||||
assert.SelectedLine(Contains("myfile"))
|
||||
|
||||
assert.View("files").Lines(
|
||||
Contains("myfile"),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
@ -72,7 +72,7 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
input.AcceptConfirmation(Equals("Are you sure?"), Equals("Are you REALLY sure you want to make this file? Up to you buddy."))
|
||||
|
||||
assert.WorkingTreeFileCount(1)
|
||||
assert.SelectedLine(Contains("my file"))
|
||||
assert.MainViewContent(Contains(`"BAR"`))
|
||||
assert.CurrentView().SelectedLine(Contains("my file"))
|
||||
assert.MainView().Content(Contains(`"BAR"`))
|
||||
},
|
||||
})
|
||||
|
@ -49,7 +49,7 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
keys config.KeybindingConfig,
|
||||
) {
|
||||
assert.WorkingTreeFileCount(0)
|
||||
input.SwitchToBranchesWindow()
|
||||
input.SwitchToBranchesView()
|
||||
|
||||
input.Press("a")
|
||||
|
||||
@ -57,10 +57,10 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
|
||||
input.Prompt(Equals("Description"), " my branch")
|
||||
|
||||
input.SwitchToFilesWindow()
|
||||
input.SwitchToFilesView()
|
||||
|
||||
assert.WorkingTreeFileCount(1)
|
||||
assert.SelectedLine(Contains("output.txt"))
|
||||
assert.MainViewContent(Contains("bar Branch: #feature/foo my branch feature/foo"))
|
||||
assert.CurrentView().SelectedLine(Contains("output.txt"))
|
||||
assert.MainView().Content(Contains("bar Branch: #feature/foo my branch feature/foo"))
|
||||
},
|
||||
})
|
||||
|
@ -50,13 +50,14 @@ var MenuFromCommandsOutput = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
assert.CurrentBranchName("feature/bar")
|
||||
|
||||
assert.WorkingTreeFileCount(0)
|
||||
input.SwitchToBranchesWindow()
|
||||
input.SwitchToBranchesView()
|
||||
|
||||
input.Press("a")
|
||||
|
||||
assert.InPrompt()
|
||||
assert.CurrentViewTitle(Equals("Which git command do you want to run?"))
|
||||
assert.SelectedLine(Equals("branch"))
|
||||
assert.CurrentView().
|
||||
Title(Equals("Which git command do you want to run?")).
|
||||
SelectedLine(Equals("branch"))
|
||||
input.Confirm()
|
||||
|
||||
input.Menu(Equals("Branch:"), Equals("master"))
|
||||
|
@ -70,7 +70,7 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
input.AcceptConfirmation(Equals("Are you sure?"), Equals("Are you REALLY sure you want to make this file? Up to you buddy."))
|
||||
|
||||
assert.WorkingTreeFileCount(1)
|
||||
assert.SelectedLine(Contains("myfile"))
|
||||
assert.MainViewContent(Contains("BAR"))
|
||||
assert.CurrentView().SelectedLine(Contains("myfile"))
|
||||
assert.MainView().Content(Contains("BAR"))
|
||||
},
|
||||
})
|
||||
|
@ -22,36 +22,37 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
shell.Checkout("branch-a")
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToBranchesWindow()
|
||||
assert.CurrentViewName("localBranches")
|
||||
input.SwitchToBranchesView()
|
||||
|
||||
assert.SelectedLine(Contains("branch-a"))
|
||||
assert.CurrentView().TopLines(
|
||||
Contains("branch-a"),
|
||||
Contains("branch-b"),
|
||||
)
|
||||
input.Press(keys.Universal.DiffingMenu)
|
||||
input.Menu(Equals("Diffing"), Contains(`diff branch-a`))
|
||||
|
||||
assert.CurrentViewName("localBranches")
|
||||
assert.CurrentView().Name("localBranches")
|
||||
|
||||
assert.ViewContent("information", Contains("showing output for: git diff branch-a branch-a"))
|
||||
assert.View("information").Content(Contains("showing output for: git diff branch-a branch-a"))
|
||||
input.NextItem()
|
||||
assert.ViewContent("information", Contains("showing output for: git diff branch-a branch-b"))
|
||||
assert.MainViewContent(Contains("+second line"))
|
||||
assert.View("information").Content(Contains("showing output for: git diff branch-a branch-b"))
|
||||
assert.MainView().Content(Contains("+second line"))
|
||||
|
||||
input.Enter()
|
||||
assert.CurrentViewName("subCommits")
|
||||
assert.MainViewContent(Contains("+second line"))
|
||||
assert.SelectedLine(Contains("update"))
|
||||
assert.CurrentView().Name("subCommits")
|
||||
assert.MainView().Content(Contains("+second line"))
|
||||
assert.CurrentView().SelectedLine(Contains("update"))
|
||||
input.Enter()
|
||||
assert.CurrentViewName("commitFiles")
|
||||
assert.SelectedLine(Contains("file1"))
|
||||
assert.MainViewContent(Contains("+second line"))
|
||||
assert.CurrentView().Name("commitFiles").SelectedLine(Contains("file1"))
|
||||
assert.MainView().Content(Contains("+second line"))
|
||||
|
||||
input.Press(keys.Universal.Return)
|
||||
input.Press(keys.Universal.Return)
|
||||
assert.CurrentViewName("localBranches")
|
||||
assert.CurrentView().Name("localBranches")
|
||||
|
||||
input.Press(keys.Universal.DiffingMenu)
|
||||
input.Menu(Equals("Diffing"), Contains("reverse diff direction"))
|
||||
assert.ViewContent("information", Contains("showing output for: git diff branch-a branch-b -R"))
|
||||
assert.MainViewContent(Contains("-second line"))
|
||||
assert.View("information").Content(Contains("showing output for: git diff branch-a branch-b -R"))
|
||||
assert.MainView().Content(Contains("-second line"))
|
||||
},
|
||||
})
|
||||
|
@ -22,29 +22,31 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
shell.Checkout("branch-a")
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToBranchesWindow()
|
||||
assert.CurrentViewName("localBranches")
|
||||
input.SwitchToBranchesView()
|
||||
assert.CurrentView().Lines(
|
||||
Contains("branch-a"),
|
||||
Contains("branch-b"),
|
||||
)
|
||||
|
||||
assert.SelectedLine(Contains("branch-a"))
|
||||
input.Press(keys.Universal.DiffingMenu)
|
||||
|
||||
input.Menu(Equals("Diffing"), Equals("diff branch-a"))
|
||||
|
||||
assert.CurrentViewName("localBranches")
|
||||
assert.CurrentView().Name("localBranches")
|
||||
|
||||
assert.ViewContent("information", Contains("showing output for: git diff branch-a branch-a"))
|
||||
assert.View("information").Content(Contains("showing output for: git diff branch-a branch-a"))
|
||||
input.NextItem()
|
||||
assert.ViewContent("information", Contains("showing output for: git diff branch-a branch-b"))
|
||||
assert.MainViewContent(Contains("+second line"))
|
||||
assert.View("information").Content(Contains("showing output for: git diff branch-a branch-b"))
|
||||
assert.MainView().Content(Contains("+second line"))
|
||||
|
||||
input.Enter()
|
||||
assert.CurrentViewName("subCommits")
|
||||
assert.MainViewContent(Contains("+second line"))
|
||||
assert.SelectedLine(Contains("update"))
|
||||
assert.CurrentView().Name("subCommits")
|
||||
assert.MainView().Content(Contains("+second line"))
|
||||
assert.CurrentView().SelectedLine(Contains("update"))
|
||||
input.Enter()
|
||||
assert.CurrentViewName("commitFiles")
|
||||
assert.SelectedLine(Contains("file1"))
|
||||
assert.MainViewContent(Contains("+second line"))
|
||||
assert.CurrentView().Name("commitFiles")
|
||||
assert.CurrentView().SelectedLine(Contains("file1"))
|
||||
assert.MainView().Content(Contains("+second line"))
|
||||
|
||||
// add the file to the patch
|
||||
input.PrimaryAction()
|
||||
@ -52,15 +54,15 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
input.Press(keys.Universal.DiffingMenu)
|
||||
input.Menu(Equals("Diffing"), Contains("exit diff mode"))
|
||||
|
||||
assert.ViewContent("information", NotContains("building patch"))
|
||||
assert.View("information").Content(DoesNotContain("building patch"))
|
||||
|
||||
input.Press(keys.Universal.CreatePatchOptionsMenu)
|
||||
// adding the regex '$' here to distinguish the menu item from the 'apply patch in reverse' item
|
||||
input.Menu(Equals("Patch Options"), MatchesRegexp("apply patch$"))
|
||||
|
||||
input.SwitchToFilesWindow()
|
||||
input.SwitchToFilesView()
|
||||
|
||||
assert.SelectedLine(Contains("file1"))
|
||||
assert.MainViewContent(Contains("+second line"))
|
||||
assert.CurrentView().SelectedLine(Contains("file1"))
|
||||
assert.MainView().Content(Contains("+second line"))
|
||||
},
|
||||
})
|
||||
|
@ -19,35 +19,36 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
shell.Commit("third commit")
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToCommitsWindow()
|
||||
assert.CurrentViewName("commits")
|
||||
input.SwitchToCommitsView()
|
||||
|
||||
assert.SelectedLine(Contains("third commit"))
|
||||
assert.CurrentView().Lines(
|
||||
Contains("third commit"),
|
||||
Contains("second commit"),
|
||||
Contains("first commit"),
|
||||
)
|
||||
|
||||
input.Press(keys.Universal.DiffingMenu)
|
||||
input.Menu(Equals("Diffing"), MatchesRegexp(`diff \w+`))
|
||||
|
||||
assert.NotInPopup()
|
||||
|
||||
assert.ViewContent("information", Contains("showing output for: git diff"))
|
||||
assert.View("information").Content(Contains("showing output for: git diff"))
|
||||
|
||||
input.NextItem()
|
||||
input.NextItem()
|
||||
assert.CurrentView().SelectedLine(Contains("first commit"))
|
||||
|
||||
assert.SelectedLine(Contains("first commit"))
|
||||
|
||||
assert.MainViewContent(Contains("-second line\n-third line"))
|
||||
assert.MainView().Content(Contains("-second line\n-third line"))
|
||||
|
||||
input.Press(keys.Universal.DiffingMenu)
|
||||
input.Menu(Equals("Diffing"), Contains("reverse diff direction"))
|
||||
assert.NotInPopup()
|
||||
|
||||
assert.MainViewContent(Contains("+second line\n+third line"))
|
||||
assert.MainView().Content(Contains("+second line\n+third line"))
|
||||
|
||||
input.Enter()
|
||||
|
||||
assert.CurrentViewName("commitFiles")
|
||||
assert.SelectedLine(Contains("file1"))
|
||||
assert.MainViewContent(Contains("+second line\n+third line"))
|
||||
assert.CurrentView().Name("commitFiles").SelectedLine(Contains("file1"))
|
||||
assert.MainView().Content(Contains("+second line\n+third line"))
|
||||
},
|
||||
})
|
||||
|
@ -24,9 +24,10 @@ var DirWithUntrackedFile = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
assert.CommitCount(1)
|
||||
|
||||
assert.MainViewContent(NotContains("error: Could not access"))
|
||||
// we show baz because it's a modified file but we don't show bar because it's untracked
|
||||
// (though it would be cool if we could show that too)
|
||||
assert.MainViewContent(Contains("baz"))
|
||||
assert.MainView().
|
||||
Content(DoesNotContain("error: Could not access")).
|
||||
// we show baz because it's a modified file but we don't show bar because it's untracked
|
||||
// (though it would be cool if we could show that too)
|
||||
Content(Contains("baz"))
|
||||
},
|
||||
})
|
||||
|
@ -82,7 +82,7 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
|
||||
discardOneByOne := func(files []statusFile) {
|
||||
for _, file := range files {
|
||||
assert.SelectedLine(Contains(file.status + " " + file.label))
|
||||
assert.CurrentView().SelectedLine(Contains(file.status + " " + file.label))
|
||||
input.Press(keys.Universal.Remove)
|
||||
input.Menu(Equals(file.menuTitle), Contains("discard all changes"))
|
||||
}
|
||||
@ -98,10 +98,7 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
{status: "DU", label: "deleted-us.txt", menuTitle: "deleted-us.txt"},
|
||||
})
|
||||
|
||||
assert.InConfirm()
|
||||
assert.CurrentViewTitle(Contains("continue"))
|
||||
assert.CurrentViewContent(Contains("all merge conflicts resolved. Continue?"))
|
||||
input.Press(keys.Universal.Return)
|
||||
input.DenyConfirmation(Equals("continue"), Contains("all merge conflicts resolved. Continue?"))
|
||||
|
||||
discardOneByOne([]statusFile{
|
||||
{status: "MD", label: "change-delete.txt", menuTitle: "change-delete.txt"},
|
||||
|
@ -30,8 +30,7 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
assert.CommitCount(3)
|
||||
|
||||
input.SwitchToCommitsWindow()
|
||||
assert.CurrentViewName("commits")
|
||||
input.SwitchToCommitsView()
|
||||
|
||||
mergeCommitMessage := "Merge branch 'feature-branch' into development-branch"
|
||||
assert.HeadCommitMessage(Contains(mergeCommitMessage))
|
||||
@ -44,7 +43,8 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
assert.HeadCommitMessage(Contains(mergeCommitMessage))
|
||||
|
||||
// assuring the post-merge file shows up in the merge commit.
|
||||
assert.MainViewContent(Contains(postMergeFilename))
|
||||
assert.MainViewContent(Contains("++" + postMergeFileContent))
|
||||
assert.MainView().
|
||||
Content(Contains(postMergeFilename)).
|
||||
Content(Contains("++" + postMergeFileContent))
|
||||
},
|
||||
})
|
||||
|
@ -15,27 +15,62 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
CreateNCommits(5) // these will appears at commit 05, 04, 04, down to 01
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToCommitsWindow()
|
||||
assert.CurrentViewName("commits")
|
||||
input.SwitchToCommitsView()
|
||||
assert.CurrentView().Lines(
|
||||
Contains("commit 05"),
|
||||
Contains("commit 04"),
|
||||
Contains("commit 03"),
|
||||
Contains("commit 02"),
|
||||
Contains("commit 01"),
|
||||
)
|
||||
|
||||
input.NavigateToListItem(Contains("commit 02"))
|
||||
input.Press(keys.Universal.Edit)
|
||||
assert.SelectedLine(Contains("YOU ARE HERE"))
|
||||
|
||||
assert.CurrentView().Lines(
|
||||
MatchesRegexp("pick.*commit 05"),
|
||||
MatchesRegexp("pick.*commit 04"),
|
||||
MatchesRegexp("pick.*commit 03"),
|
||||
MatchesRegexp("YOU ARE HERE.*commit 02"),
|
||||
Contains("commit 01"),
|
||||
)
|
||||
|
||||
input.PreviousItem()
|
||||
input.Press(keys.Commits.MarkCommitAsFixup)
|
||||
assert.SelectedLine(Contains("fixup"))
|
||||
assert.CurrentView().Lines(
|
||||
MatchesRegexp("pick.*commit 05"),
|
||||
MatchesRegexp("pick.*commit 04"),
|
||||
MatchesRegexp("fixup.*commit 03"),
|
||||
MatchesRegexp("YOU ARE HERE.*commit 02"),
|
||||
Contains("commit 01"),
|
||||
)
|
||||
|
||||
input.PreviousItem()
|
||||
input.Press(keys.Universal.Remove)
|
||||
assert.SelectedLine(Contains("drop"))
|
||||
assert.CurrentView().Lines(
|
||||
MatchesRegexp("pick.*commit 05"),
|
||||
MatchesRegexp("drop.*commit 04"),
|
||||
MatchesRegexp("fixup.*commit 03"),
|
||||
MatchesRegexp("YOU ARE HERE.*commit 02"),
|
||||
Contains("commit 01"),
|
||||
)
|
||||
|
||||
input.PreviousItem()
|
||||
input.Press(keys.Commits.SquashDown)
|
||||
assert.SelectedLine(Contains("squash"))
|
||||
|
||||
assert.CurrentView().Lines(
|
||||
MatchesRegexp("squash.*commit 05"),
|
||||
MatchesRegexp("drop.*commit 04"),
|
||||
MatchesRegexp("fixup.*commit 03"),
|
||||
MatchesRegexp("YOU ARE HERE.*commit 02"),
|
||||
Contains("commit 01"),
|
||||
)
|
||||
|
||||
input.ContinueRebase()
|
||||
|
||||
assert.CommitCount(2)
|
||||
assert.CurrentView().Lines(
|
||||
Contains("commit 02"),
|
||||
Contains("commit 01"),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
@ -19,16 +19,17 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
StashWithMessage("bar")
|
||||
},
|
||||
Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) {
|
||||
input.SwitchToStashWindow()
|
||||
assert.CurrentViewName("stash")
|
||||
input.SwitchToStashView()
|
||||
|
||||
assert.SelectedLine(Equals("On master: bar"))
|
||||
assert.CurrentView().Lines(
|
||||
Equals("On master: bar"),
|
||||
Equals("On master: foo"),
|
||||
)
|
||||
input.NextItem()
|
||||
assert.SelectedLine(Equals("On master: foo"))
|
||||
input.Press(keys.Stash.RenameStash)
|
||||
|
||||
input.Prompt(Equals("Rename stash: stash@{1}"), " baz")
|
||||
|
||||
assert.SelectedLine(Equals("On master: foo baz"))
|
||||
assert.CurrentView().SelectedLine(Equals("On master: foo baz"))
|
||||
},
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user