mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-07-30 03:23:08 +03:00
remove dependency on model
This commit is contained in:
28
pkg/integration/components/git.go
Normal file
28
pkg/integration/components/git.go
Normal file
@ -0,0 +1,28 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Git struct {
|
||||
*assertionHelper
|
||||
shell *Shell
|
||||
}
|
||||
|
||||
func (self *Git) CurrentBranchName(expectedName string) *Git {
|
||||
return self.assert("git rev-parse --abbrev-ref HEAD", expectedName)
|
||||
}
|
||||
|
||||
func (self *Git) assert(cmdStr string, expected string) *Git {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
output, err := self.shell.runCommandWithOutput(cmdStr)
|
||||
if err != nil {
|
||||
return false, fmt.Sprintf("Unexpected error running command: `%s`. Error: %s", cmdStr, err.Error())
|
||||
}
|
||||
actual := strings.TrimSpace(output)
|
||||
return actual == expected, fmt.Sprintf("Expected current branch name to be '%s', but got '%s'", expected, actual)
|
||||
})
|
||||
|
||||
return self
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||
)
|
||||
|
||||
type Model struct {
|
||||
*assertionHelper
|
||||
gui integrationTypes.GuiDriver
|
||||
}
|
||||
|
||||
func (self *Model) WorkingTreeFileCount(expectedCount int) *Model {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
actualCount := len(self.gui.Model().Files)
|
||||
|
||||
return actualCount == expectedCount, fmt.Sprintf(
|
||||
"Expected %d changed working tree files, but got %d",
|
||||
expectedCount, actualCount,
|
||||
)
|
||||
})
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *Model) CommitCount(expectedCount int) *Model {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
actualCount := len(self.gui.Model().Commits)
|
||||
|
||||
return actualCount == expectedCount, fmt.Sprintf(
|
||||
"Expected %d commits present, but got %d",
|
||||
expectedCount, actualCount,
|
||||
)
|
||||
})
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *Model) StashCount(expectedCount int) *Model {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
actualCount := len(self.gui.Model().StashEntries)
|
||||
|
||||
return actualCount == expectedCount, fmt.Sprintf(
|
||||
"Expected %d stash entries, but got %d",
|
||||
expectedCount, actualCount,
|
||||
)
|
||||
})
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *Model) AtLeastOneCommit() *Model {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
actualCount := len(self.gui.Model().Commits)
|
||||
|
||||
return actualCount > 0, "Expected at least one commit present"
|
||||
})
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *Model) HeadCommitMessage(matcher *matcher) *Model {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
return len(self.gui.Model().Commits) > 0, "Expected at least one commit to be present"
|
||||
})
|
||||
|
||||
self.matchString(matcher, "Unexpected commit message.",
|
||||
func() string {
|
||||
return self.gui.Model().Commits[0].Name
|
||||
},
|
||||
)
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *Model) CurrentBranchName(expectedViewName string) *Model {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
actual := self.gui.CheckedOutRef().Name
|
||||
return actual == expectedViewName, fmt.Sprintf("Expected current branch name to be '%s', but got '%s'", expectedViewName, actual)
|
||||
})
|
||||
|
||||
return self
|
||||
}
|
@ -38,6 +38,17 @@ func (self *Shell) RunCommand(cmdStr string) *Shell {
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *Shell) runCommandWithOutput(cmdStr string) (string, error) {
|
||||
args := str.ToArgv(cmdStr)
|
||||
cmd := secureexec.Command(args[0], args[1:]...)
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Dir = self.dir
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
|
||||
return string(output), err
|
||||
}
|
||||
|
||||
func (self *Shell) RunShellCommand(cmdStr string) *Shell {
|
||||
cmd := secureexec.Command("sh", "-c", cmdStr)
|
||||
cmd.Env = os.Environ()
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/env"
|
||||
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
@ -89,9 +90,12 @@ func (self *IntegrationTest) SetupRepo(shell *Shell) {
|
||||
self.setupRepo(shell)
|
||||
}
|
||||
|
||||
// I want access to all contexts, the model, the ability to press a key, the ability to log,
|
||||
func (self *IntegrationTest) Run(gui integrationTypes.GuiDriver) {
|
||||
shell := NewShell("/tmp/lazygit-test", func(errorMsg string) { gui.Fail(errorMsg) })
|
||||
// we pass the --pass arg to lazygit when running an integration test, and that
|
||||
// ends up stored in the following env var
|
||||
repoPath := env.GetGitWorkTreeEnv()
|
||||
|
||||
shell := NewShell(repoPath, func(errorMsg string) { gui.Fail(errorMsg) })
|
||||
keys := gui.Keys()
|
||||
testDriver := NewTestDriver(gui, shell, keys, KeyPressDelay())
|
||||
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type TestDriver struct {
|
||||
@ -220,9 +219,9 @@ func (self *TestDriver) Views() *Views {
|
||||
return &Views{t: self}
|
||||
}
|
||||
|
||||
// for making assertions on the lazygit model
|
||||
func (self *TestDriver) Model() *Model {
|
||||
return &Model{assertionHelper: self.assertionHelper, gui: self.gui}
|
||||
// for making assertions through git itself
|
||||
func (self *TestDriver) Git() *Git {
|
||||
return &Git{assertionHelper: self.assertionHelper, shell: self.shell}
|
||||
}
|
||||
|
||||
// for making assertions on the file system
|
||||
@ -235,10 +234,3 @@ func (self *TestDriver) FileSystem() *FileSystem {
|
||||
func (self *TestDriver) Fail(message string) {
|
||||
self.assertionHelper.fail(message)
|
||||
}
|
||||
|
||||
func (self *TestDriver) NotInPopup() {
|
||||
self.assertWithRetries(func() (bool, string) {
|
||||
viewName := self.gui.CurrentContext().GetView().Name()
|
||||
return !lo.Contains([]string{"menu", "confirmation", "commitMessage"}, viewName), fmt.Sprintf("Unexpected popup view present: %s view", viewName)
|
||||
})
|
||||
}
|
||||
|
@ -30,10 +30,6 @@ func (self *fakeGuiDriver) CurrentContext() types.Context {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *fakeGuiDriver) Model() *types.Model {
|
||||
return &types.Model{Commits: []*models.Commit{}}
|
||||
}
|
||||
|
||||
func (self *fakeGuiDriver) Fail(message string) {
|
||||
self.failureMessage = message
|
||||
}
|
||||
@ -66,7 +62,6 @@ func TestAssertionFailure(t *testing.T) {
|
||||
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||
t.press("a")
|
||||
t.press("b")
|
||||
t.Model().CommitCount(2)
|
||||
},
|
||||
})
|
||||
driver := &fakeGuiDriver{}
|
||||
@ -93,7 +88,6 @@ func TestSuccess(t *testing.T) {
|
||||
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||
t.press("a")
|
||||
t.press("b")
|
||||
t.Model().CommitCount(0)
|
||||
},
|
||||
})
|
||||
driver := &fakeGuiDriver{}
|
||||
|
@ -2,6 +2,7 @@ package components
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
)
|
||||
@ -28,6 +29,10 @@ func (self *View) Title(expected *matcher) *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 *View) TopLines(matchers ...*matcher) *View {
|
||||
if len(matchers) < 1 {
|
||||
self.t.fail("TopLines method requires at least one matcher. If you are trying to assert that there are no lines, use .IsEmpty()")
|
||||
}
|
||||
|
||||
self.t.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))
|
||||
@ -39,10 +44,7 @@ func (self *View) TopLines(matchers ...*matcher) *View {
|
||||
// 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 *View) Lines(matchers ...*matcher) *View {
|
||||
self.t.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))
|
||||
})
|
||||
self.LineCount(len(matchers))
|
||||
|
||||
return self.assertLines(matchers...)
|
||||
}
|
||||
@ -184,6 +186,41 @@ func (self *View) NavigateToListItem(matcher *matcher) *View {
|
||||
return self
|
||||
}
|
||||
|
||||
// returns true if the view is a list view and it contains no items
|
||||
func (self *View) IsEmpty() *View {
|
||||
self.t.assertWithRetries(func() (bool, string) {
|
||||
actual := strings.TrimSpace(self.getView().Buffer())
|
||||
return actual == "", fmt.Sprintf("%s: Unexpected content in view: expected no content. Content: %s", self.context, actual)
|
||||
})
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *View) LineCount(expectedCount int) *View {
|
||||
if expectedCount == 0 {
|
||||
return self.IsEmpty()
|
||||
}
|
||||
|
||||
self.t.assertWithRetries(func() (bool, string) {
|
||||
lines := self.getView().BufferLines()
|
||||
return len(lines) == expectedCount, fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", expectedCount, len(lines))
|
||||
})
|
||||
|
||||
self.t.assertWithRetries(func() (bool, string) {
|
||||
lines := self.getView().BufferLines()
|
||||
|
||||
// if the view has a single blank line (often the case) we want to treat that as having no lines
|
||||
if len(lines) == 1 && expectedCount == 1 {
|
||||
actual := strings.TrimSpace(self.getView().Buffer())
|
||||
return actual == "", fmt.Sprintf("unexpected number of lines in view. Expected %d, got 0", expectedCount)
|
||||
}
|
||||
|
||||
return len(lines) == expectedCount, fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", expectedCount, len(lines))
|
||||
})
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
// for when you want to make some assertion unrelated to the current view
|
||||
// without breaking the method chain
|
||||
func (self *View) Tap(f func()) *View {
|
||||
|
Reference in New Issue
Block a user