1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-04-23 12:18:51 +02:00
This commit is contained in:
Jesse Duffield 2022-12-27 15:56:02 +11:00
parent 09e80e5f2a
commit c5c9f5bb94
8 changed files with 84 additions and 51 deletions

View File

@ -7,7 +7,7 @@ type AlertAsserter struct {
hasCheckedContent bool hasCheckedContent bool
} }
func (self *AlertAsserter) getViewAsserter() *Views { func (self *AlertAsserter) getViewAsserter() *View {
return self.assert.Views().ByName("confirmation") return self.assert.Views().ByName("confirmation")
} }

View File

@ -7,7 +7,8 @@ import (
// through this struct we assert on the state of the lazygit gui // through this struct we assert on the state of the lazygit gui
type Assert struct { type Assert struct {
gui integrationTypes.GuiDriver input *Input
gui integrationTypes.GuiDriver
*assertionHelper *assertionHelper
} }
@ -16,8 +17,8 @@ func NewAssert(gui integrationTypes.GuiDriver) *Assert {
} }
// for making assertions on lazygit views // for making assertions on lazygit views
func (self *Assert) Views() *ViewAsserterGetter { func (self *Assert) Views() *Views {
return &ViewAsserterGetter{assert: self} return &Views{assert: self, input: self.input}
} }
// for making assertions on the lazygit model // for making assertions on the lazygit model

View File

@ -5,7 +5,7 @@ type CommitMessagePanelAsserter struct {
input *Input input *Input
} }
func (self *CommitMessagePanelAsserter) getViewAsserter() *Views { func (self *CommitMessagePanelAsserter) getViewAsserter() *View {
return self.assert.Views().ByName("commitMessage") return self.assert.Views().ByName("commitMessage")
} }

View File

@ -7,7 +7,7 @@ type ConfirmationAsserter struct {
hasCheckedContent bool hasCheckedContent bool
} }
func (self *ConfirmationAsserter) getViewAsserter() *Views { func (self *ConfirmationAsserter) getViewAsserter() *View {
return self.assert.Views().ByName("confirmation") return self.assert.Views().ByName("confirmation")
} }

View File

@ -18,11 +18,10 @@ type Input struct {
pushKeyDelay int pushKeyDelay int
} }
func NewInput(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, assert *Assert, pushKeyDelay int) *Input { func NewInput(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, pushKeyDelay int) *Input {
return &Input{ return &Input{
gui: gui, gui: gui,
keys: keys, keys: keys,
assert: assert,
pushKeyDelay: pushKeyDelay, pushKeyDelay: pushKeyDelay,
assertionHelper: assert.assertionHelper, assertionHelper: assert.assertionHelper,
} }
@ -53,14 +52,14 @@ func (self *Input) SwitchToStatusView() {
self.assert.Views().Current().Name("status") self.assert.Views().Current().Name("status")
} }
func (self *Input) SwitchToFilesWindow() { func (self *Input) switchToFilesWindow() {
self.press(self.keys.Universal.JumpToBlock[1]) self.press(self.keys.Universal.JumpToBlock[1])
self.currentWindowName("files") self.currentWindowName("files")
} }
// switch to files window and assert that the files view is on top // switch to files window and assert that the files view is on top
func (self *Input) SwitchToFilesView() { func (self *Input) SwitchToFilesView() {
self.SwitchToFilesWindow() self.switchToFilesWindow()
self.assert.Views().Current().Name("files") self.assert.Views().Current().Name("files")
} }

View File

@ -6,7 +6,7 @@ type MenuAsserter struct {
hasCheckedTitle bool hasCheckedTitle bool
} }
func (self *MenuAsserter) getViewAsserter() *Views { func (self *MenuAsserter) getViewAsserter() *View {
return self.assert.Views().ByName("menu") return self.assert.Views().ByName("menu")
} }

View File

@ -6,7 +6,7 @@ type PromptAsserter struct {
hasCheckedTitle bool hasCheckedTitle bool
} }
func (self *PromptAsserter) getViewAsserter() *Views { func (self *PromptAsserter) getViewAsserter() *View {
return self.assert.Views().ByName("confirmation") return self.assert.Views().ByName("confirmation")
} }

View File

@ -7,15 +7,57 @@ import (
) )
type Views struct { type Views struct {
assert *Assert
input *Input
}
func (self *Views) Current() *View {
return &View{
context: "current view",
getView: func() *gocui.View { return self.assert.gui.CurrentContext().GetView() },
assert: self.assert,
input: self.input,
}
}
func (self *Views) Main() *View {
return &View{
context: "main view",
getView: func() *gocui.View { return self.assert.gui.MainView() },
assert: self.assert,
input: self.input,
}
}
func (self *Views) Secondary() *View {
return &View{
context: "secondary view",
getView: func() *gocui.View { return self.assert.gui.SecondaryView() },
assert: self.assert,
input: self.input,
}
}
func (self *Views) ByName(viewName string) *View {
return &View{
context: fmt.Sprintf("%s view", viewName),
getView: func() *gocui.View { return self.assert.gui.View(viewName) },
assert: self.assert,
input: self.input,
}
}
type View struct {
// context is prepended to any error messages e.g. 'context: "current view"' // context is prepended to any error messages e.g. 'context: "current view"'
context string context string
getView func() *gocui.View getView func() *gocui.View
assert *Assert assert *Assert
input *Input
} }
// asserts that the view has the expected name. This is typically used in tandem with the CurrentView method i.e.; // 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. // assert.CurrentView().Name("commits") to assert that the current view is the commits view.
func (self *Views) Name(expected string) *Views { func (self *View) Name(expected string) *View {
self.assert.assertWithRetries(func() (bool, string) { self.assert.assertWithRetries(func() (bool, string) {
actual := self.getView().Name() actual := self.getView().Name()
return actual == expected, fmt.Sprintf("%s: Expected view name to be '%s', but got '%s'", self.context, expected, actual) return actual == expected, fmt.Sprintf("%s: Expected view name to be '%s', but got '%s'", self.context, expected, actual)
@ -25,7 +67,7 @@ func (self *Views) Name(expected string) *Views {
} }
// asserts that the view has the expected title // asserts that the view has the expected title
func (self *Views) Title(expected *matcher) *Views { func (self *View) Title(expected *matcher) *View {
self.assert.assertWithRetries(func() (bool, string) { self.assert.assertWithRetries(func() (bool, string) {
actual := self.getView().Title actual := self.getView().Title
return expected.context(fmt.Sprintf("%s title", self.context)).test(actual) return expected.context(fmt.Sprintf("%s title", self.context)).test(actual)
@ -38,7 +80,7 @@ func (self *Views) Title(expected *matcher) *Views {
// are passed, we only check the first three lines of the view. // 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 // This method is convenient when you have a list of commits but you only want to
// assert on the first couple of commits. // assert on the first couple of commits.
func (self *Views) TopLines(matchers ...*matcher) *Views { func (self *View) TopLines(matchers ...*matcher) *View {
self.assert.assertWithRetries(func() (bool, string) { self.assert.assertWithRetries(func() (bool, string) {
lines := self.getView().BufferLines() 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 len(lines) >= len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected at least %d, got %d", len(matchers), len(lines))
@ -49,7 +91,7 @@ func (self *Views) TopLines(matchers ...*matcher) *Views {
// asserts that the view has lines matching the given matchers. One matcher must be passed for each line. // 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. // If you only care about the top n lines, use the TopLines method instead.
func (self *Views) Lines(matchers ...*matcher) *Views { func (self *View) Lines(matchers ...*matcher) *View {
self.assert.assertWithRetries(func() (bool, string) { self.assert.assertWithRetries(func() (bool, string) {
lines := self.getView().BufferLines() 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 len(lines) == len(matchers), fmt.Sprintf("unexpected number of lines in view. Expected %d, got %d", len(matchers), len(lines))
@ -58,7 +100,7 @@ func (self *Views) Lines(matchers ...*matcher) *Views {
return self.assertLines(matchers...) return self.assertLines(matchers...)
} }
func (self *Views) assertLines(matchers ...*matcher) *Views { func (self *View) assertLines(matchers ...*matcher) *View {
view := self.getView() view := self.getView()
for i, matcher := range matchers { for i, matcher := range matchers {
@ -82,7 +124,7 @@ func (self *Views) assertLines(matchers ...*matcher) *Views {
} }
// asserts on the content of the view i.e. the stuff within the view's frame. // asserts on the content of the view i.e. the stuff within the view's frame.
func (self *Views) Content(matcher *matcher) *Views { func (self *View) Content(matcher *matcher) *View {
self.assert.matchString(matcher, fmt.Sprintf("%s: Unexpected content.", self.context), self.assert.matchString(matcher, fmt.Sprintf("%s: Unexpected content.", self.context),
func() string { func() string {
return self.getView().Buffer() return self.getView().Buffer()
@ -93,7 +135,7 @@ func (self *Views) Content(matcher *matcher) *Views {
} }
// asserts on the selected line of the view // asserts on the selected line of the view
func (self *Views) SelectedLine(matcher *matcher) *Views { func (self *View) SelectedLine(matcher *matcher) *View {
self.assert.matchString(matcher, fmt.Sprintf("%s: Unexpected selected line.", self.context), self.assert.matchString(matcher, fmt.Sprintf("%s: Unexpected selected line.", self.context),
func() string { func() string {
return self.getView().SelectedLine() return self.getView().SelectedLine()
@ -104,7 +146,7 @@ func (self *Views) SelectedLine(matcher *matcher) *Views {
} }
// asserts on the index of the selected line. 0 is the first index, representing the line at the top of the view. // asserts on the index of the selected line. 0 is the first index, representing the line at the top of the view.
func (self *Views) SelectedLineIdx(expected int) *Views { func (self *View) SelectedLineIdx(expected int) *View {
self.assert.assertWithRetries(func() (bool, string) { self.assert.assertWithRetries(func() (bool, string) {
actual := self.getView().SelectedLineIdx() actual := self.getView().SelectedLineIdx()
return expected == actual, fmt.Sprintf("%s: Expected selected line index to be %d, got %d", self.context, expected, actual) return expected == actual, fmt.Sprintf("%s: Expected selected line index to be %d, got %d", self.context, expected, actual)
@ -113,38 +155,29 @@ func (self *Views) SelectedLineIdx(expected int) *Views {
return self return self
} }
type ViewAsserterGetter struct { // func (self *View) Focus() *View {
assert *Assert // // we can easily change focus by switching to the view's window, but this assumes that the desired view
} // // is at the top of that window. So for now we'll switch to the window then assert that the desired
// // view is on top (i.e. that it's the current view).
// whitelistedViewNames := []string{"status", "files", "localBranches", "commits", "stash"}
func (self *ViewAsserterGetter) Current() *Views { // viewName := self.getView().Name()
return &Views{
context: "current view",
getView: func() *gocui.View { return self.assert.gui.CurrentContext().GetView() },
assert: self.assert,
}
}
func (self *ViewAsserterGetter) Main() *Views { // if !lo.Contains(whitelistedViewNames, self.getView().Name()) {
return &Views{ // self.assert.fail(fmt.Sprintf("Cannot focus view %s: Focus() method not implemented", viewName))
context: "main view", // }
getView: func() *gocui.View { return self.assert.gui.MainView() },
assert: self.assert,
}
}
func (self *ViewAsserterGetter) Secondary() *Views { // windowIndexMap := map[string]int{
return &Views{ // "status": 0,
context: "secondary view", // "files": 1,
getView: func() *gocui.View { return self.assert.gui.SecondaryView() }, // "localBranches": 2,
assert: self.assert, // "commits": 3,
} // "stash": 4,
} // }
func (self *ViewAsserterGetter) ByName(viewName string) *Views { // self.input.switchToFilesWindow()
return &Views{ // self.press(self.keys.Universal.JumpToBlock[1])
context: fmt.Sprintf("%s view", viewName), // self.assert.Views().Current().Name(viewName)
getView: func() *gocui.View { return self.assert.gui.View(viewName) },
assert: self.assert, // return self
} // }
}