1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-12-02 09:21:40 +02:00

Merge pull request #2335 from jesseduffield/alas-more-test-refactoring

This commit is contained in:
Jesse Duffield 2022-12-28 11:30:51 +11:00 committed by GitHub
commit 0a8731eecf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 179 additions and 179 deletions

View File

@ -1,18 +1,18 @@
package components
type AlertAsserter struct {
type AlertDriver struct {
t *TestDriver
hasCheckedTitle bool
hasCheckedContent bool
}
func (self *AlertAsserter) getViewAsserter() *View {
func (self *AlertDriver) getViewDriver() *ViewDriver {
return self.t.Views().Confirmation()
}
// asserts that the alert view has the expected title
func (self *AlertAsserter) Title(expected *matcher) *AlertAsserter {
self.getViewAsserter().Title(expected)
func (self *AlertDriver) Title(expected *matcher) *AlertDriver {
self.getViewDriver().Title(expected)
self.hasCheckedTitle = true
@ -20,27 +20,27 @@ func (self *AlertAsserter) Title(expected *matcher) *AlertAsserter {
}
// asserts that the alert view has the expected content
func (self *AlertAsserter) Content(expected *matcher) *AlertAsserter {
self.getViewAsserter().Content(expected)
func (self *AlertDriver) Content(expected *matcher) *AlertDriver {
self.getViewDriver().Content(expected)
self.hasCheckedContent = true
return self
}
func (self *AlertAsserter) Confirm() {
func (self *AlertDriver) Confirm() {
self.checkNecessaryChecksCompleted()
self.getViewAsserter().PressEnter()
self.getViewDriver().PressEnter()
}
func (self *AlertAsserter) Cancel() {
func (self *AlertDriver) Cancel() {
self.checkNecessaryChecksCompleted()
self.getViewAsserter().PressEscape()
self.getViewDriver().PressEscape()
}
func (self *AlertAsserter) checkNecessaryChecksCompleted() {
func (self *AlertDriver) checkNecessaryChecksCompleted() {
if !self.hasCheckedContent || !self.hasCheckedTitle {
self.t.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().")
}

View File

@ -1,40 +0,0 @@
package components
type CommitMessagePanelAsserter struct {
t *TestDriver
}
func (self *CommitMessagePanelAsserter) getViewAsserter() *View {
return self.t.Views().CommitMessage()
}
// asserts on the text initially present in the prompt
func (self *CommitMessagePanelAsserter) InitialText(expected *matcher) *CommitMessagePanelAsserter {
self.getViewAsserter().Content(expected)
return self
}
func (self *CommitMessagePanelAsserter) Type(value string) *CommitMessagePanelAsserter {
self.t.typeContent(value)
return self
}
func (self *CommitMessagePanelAsserter) AddNewline() *CommitMessagePanelAsserter {
self.t.press(self.t.keys.Universal.AppendNewline)
return self
}
func (self *CommitMessagePanelAsserter) Clear() *CommitMessagePanelAsserter {
panic("Clear method not yet implemented!")
}
func (self *CommitMessagePanelAsserter) Confirm() {
self.getViewAsserter().PressEnter()
}
func (self *CommitMessagePanelAsserter) Cancel() {
self.getViewAsserter().PressEscape()
}

View File

@ -0,0 +1,40 @@
package components
type CommitMessagePanelDriver struct {
t *TestDriver
}
func (self *CommitMessagePanelDriver) getViewDriver() *ViewDriver {
return self.t.Views().CommitMessage()
}
// asserts on the text initially present in the prompt
func (self *CommitMessagePanelDriver) InitialText(expected *matcher) *CommitMessagePanelDriver {
self.getViewDriver().Content(expected)
return self
}
func (self *CommitMessagePanelDriver) Type(value string) *CommitMessagePanelDriver {
self.t.typeContent(value)
return self
}
func (self *CommitMessagePanelDriver) AddNewline() *CommitMessagePanelDriver {
self.t.press(self.t.keys.Universal.AppendNewline)
return self
}
func (self *CommitMessagePanelDriver) Clear() *CommitMessagePanelDriver {
panic("Clear method not yet implemented!")
}
func (self *CommitMessagePanelDriver) Confirm() {
self.getViewDriver().PressEnter()
}
func (self *CommitMessagePanelDriver) Cancel() {
self.getViewDriver().PressEscape()
}

View File

@ -1,18 +1,18 @@
package components
type ConfirmationAsserter struct {
type ConfirmationDriver struct {
t *TestDriver
hasCheckedTitle bool
hasCheckedContent bool
}
func (self *ConfirmationAsserter) getViewAsserter() *View {
func (self *ConfirmationDriver) getViewDriver() *ViewDriver {
return self.t.Views().Confirmation()
}
// asserts that the confirmation view has the expected title
func (self *ConfirmationAsserter) Title(expected *matcher) *ConfirmationAsserter {
self.getViewAsserter().Title(expected)
func (self *ConfirmationDriver) Title(expected *matcher) *ConfirmationDriver {
self.getViewDriver().Title(expected)
self.hasCheckedTitle = true
@ -20,27 +20,27 @@ func (self *ConfirmationAsserter) Title(expected *matcher) *ConfirmationAsserter
}
// asserts that the confirmation view has the expected content
func (self *ConfirmationAsserter) Content(expected *matcher) *ConfirmationAsserter {
self.getViewAsserter().Content(expected)
func (self *ConfirmationDriver) Content(expected *matcher) *ConfirmationDriver {
self.getViewDriver().Content(expected)
self.hasCheckedContent = true
return self
}
func (self *ConfirmationAsserter) Confirm() {
func (self *ConfirmationDriver) Confirm() {
self.checkNecessaryChecksCompleted()
self.getViewAsserter().PressEnter()
self.getViewDriver().PressEnter()
}
func (self *ConfirmationAsserter) Cancel() {
func (self *ConfirmationDriver) Cancel() {
self.checkNecessaryChecksCompleted()
self.getViewAsserter().PressEscape()
self.getViewDriver().PressEscape()
}
func (self *ConfirmationAsserter) checkNecessaryChecksCompleted() {
func (self *ConfirmationDriver) checkNecessaryChecksCompleted() {
if !self.hasCheckedContent || !self.hasCheckedTitle {
self.t.Fail("You must both check the content and title of a confirmation popup by calling Title()/Content() before calling Confirm()/Cancel().")
}

View File

@ -1,43 +0,0 @@
package components
type MenuAsserter struct {
t *TestDriver
hasCheckedTitle bool
}
func (self *MenuAsserter) getViewAsserter() *View {
return self.t.Views().Menu()
}
// asserts that the popup has the expected title
func (self *MenuAsserter) Title(expected *matcher) *MenuAsserter {
self.getViewAsserter().Title(expected)
self.hasCheckedTitle = true
return self
}
func (self *MenuAsserter) Confirm() {
self.checkNecessaryChecksCompleted()
self.getViewAsserter().PressEnter()
}
func (self *MenuAsserter) Cancel() {
self.checkNecessaryChecksCompleted()
self.getViewAsserter().PressEscape()
}
func (self *MenuAsserter) Select(option *matcher) *MenuAsserter {
self.getViewAsserter().NavigateToListItem(option)
return self
}
func (self *MenuAsserter) checkNecessaryChecksCompleted() {
if !self.hasCheckedTitle {
self.t.Fail("You must check the title of a menu popup by calling Title() before calling Confirm()/Cancel().")
}
}

View File

@ -0,0 +1,43 @@
package components
type MenuDriver struct {
t *TestDriver
hasCheckedTitle bool
}
func (self *MenuDriver) getViewDriver() *ViewDriver {
return self.t.Views().Menu()
}
// asserts that the popup has the expected title
func (self *MenuDriver) Title(expected *matcher) *MenuDriver {
self.getViewDriver().Title(expected)
self.hasCheckedTitle = true
return self
}
func (self *MenuDriver) Confirm() {
self.checkNecessaryChecksCompleted()
self.getViewDriver().PressEnter()
}
func (self *MenuDriver) Cancel() {
self.checkNecessaryChecksCompleted()
self.getViewDriver().PressEscape()
}
func (self *MenuDriver) Select(option *matcher) *MenuDriver {
self.getViewDriver().NavigateToListItem(option)
return self
}
func (self *MenuDriver) checkNecessaryChecksCompleted() {
if !self.hasCheckedTitle {
self.t.Fail("You must check the title of a menu popup by calling Title() before calling Confirm()/Cancel().")
}
}

View File

@ -4,10 +4,10 @@ type Popup struct {
t *TestDriver
}
func (self *Popup) Confirmation() *ConfirmationAsserter {
func (self *Popup) Confirmation() *ConfirmationDriver {
self.inConfirm()
return &ConfirmationAsserter{t: self.t}
return &ConfirmationDriver{t: self.t}
}
func (self *Popup) inConfirm() {
@ -17,10 +17,10 @@ func (self *Popup) inConfirm() {
})
}
func (self *Popup) Prompt() *PromptAsserter {
func (self *Popup) Prompt() *PromptDriver {
self.inPrompt()
return &PromptAsserter{t: self.t}
return &PromptDriver{t: self.t}
}
func (self *Popup) inPrompt() {
@ -30,10 +30,10 @@ func (self *Popup) inPrompt() {
})
}
func (self *Popup) Alert() *AlertAsserter {
func (self *Popup) Alert() *AlertDriver {
self.inAlert()
return &AlertAsserter{t: self.t}
return &AlertDriver{t: self.t}
}
func (self *Popup) inAlert() {
@ -44,10 +44,10 @@ func (self *Popup) inAlert() {
})
}
func (self *Popup) Menu() *MenuAsserter {
func (self *Popup) Menu() *MenuDriver {
self.inMenu()
return &MenuAsserter{t: self.t}
return &MenuDriver{t: self.t}
}
func (self *Popup) inMenu() {
@ -56,10 +56,10 @@ func (self *Popup) inMenu() {
})
}
func (self *Popup) CommitMessagePanel() *CommitMessagePanelAsserter {
func (self *Popup) CommitMessagePanel() *CommitMessagePanelDriver {
self.inCommitMessagePanel()
return &CommitMessagePanelAsserter{t: self.t}
return &CommitMessagePanelDriver{t: self.t}
}
func (self *Popup) inCommitMessagePanel() {

View File

@ -1,17 +1,17 @@
package components
type PromptAsserter struct {
type PromptDriver struct {
t *TestDriver
hasCheckedTitle bool
}
func (self *PromptAsserter) getViewAsserter() *View {
func (self *PromptDriver) getViewDriver() *ViewDriver {
return self.t.Views().Confirmation()
}
// asserts that the popup has the expected title
func (self *PromptAsserter) Title(expected *matcher) *PromptAsserter {
self.getViewAsserter().Title(expected)
func (self *PromptDriver) Title(expected *matcher) *PromptDriver {
self.getViewDriver().Title(expected)
self.hasCheckedTitle = true
@ -19,53 +19,53 @@ func (self *PromptAsserter) Title(expected *matcher) *PromptAsserter {
}
// asserts on the text initially present in the prompt
func (self *PromptAsserter) InitialText(expected *matcher) *PromptAsserter {
self.getViewAsserter().Content(expected)
func (self *PromptDriver) InitialText(expected *matcher) *PromptDriver {
self.getViewDriver().Content(expected)
return self
}
func (self *PromptAsserter) Type(value string) *PromptAsserter {
func (self *PromptDriver) Type(value string) *PromptDriver {
self.t.typeContent(value)
return self
}
func (self *PromptAsserter) Clear() *PromptAsserter {
func (self *PromptDriver) Clear() *PromptDriver {
panic("Clear method not yet implemented!")
}
func (self *PromptAsserter) Confirm() {
func (self *PromptDriver) Confirm() {
self.checkNecessaryChecksCompleted()
self.getViewAsserter().PressEnter()
self.getViewDriver().PressEnter()
}
func (self *PromptAsserter) Cancel() {
func (self *PromptDriver) Cancel() {
self.checkNecessaryChecksCompleted()
self.getViewAsserter().PressEscape()
self.getViewDriver().PressEscape()
}
func (self *PromptAsserter) checkNecessaryChecksCompleted() {
func (self *PromptDriver) checkNecessaryChecksCompleted() {
if !self.hasCheckedTitle {
self.t.Fail("You must check the title of a prompt popup by calling Title() before calling Confirm()/Cancel().")
}
}
func (self *PromptAsserter) SuggestionLines(matchers ...*matcher) *PromptAsserter {
func (self *PromptDriver) SuggestionLines(matchers ...*matcher) *PromptDriver {
self.t.Views().Suggestions().Lines(matchers...)
return self
}
func (self *PromptAsserter) SuggestionTopLines(matchers ...*matcher) *PromptAsserter {
func (self *PromptDriver) SuggestionTopLines(matchers ...*matcher) *PromptDriver {
self.t.Views().Suggestions().TopLines(matchers...)
return self
}
func (self *PromptAsserter) ConfirmFirstSuggestion() {
func (self *PromptDriver) ConfirmFirstSuggestion() {
self.t.press(self.t.keys.Universal.TogglePanel)
self.t.Views().Suggestions().
IsFocused().
@ -73,7 +73,7 @@ func (self *PromptAsserter) ConfirmFirstSuggestion() {
PressEnter()
}
func (self *PromptAsserter) ConfirmSuggestion(matcher *matcher) {
func (self *PromptDriver) ConfirmSuggestion(matcher *matcher) {
self.t.press(self.t.keys.Universal.TogglePanel)
self.t.Views().Suggestions().
IsFocused().

View File

@ -7,7 +7,7 @@ import (
"github.com/jesseduffield/gocui"
)
type View struct {
type ViewDriver struct {
// context is prepended to any error messages e.g. 'context: "current view"'
context string
getView func() *gocui.View
@ -15,7 +15,7 @@ type View struct {
}
// asserts that the view has the expected title
func (self *View) Title(expected *matcher) *View {
func (self *ViewDriver) Title(expected *matcher) *ViewDriver {
self.t.assertWithRetries(func() (bool, string) {
actual := self.getView().Title
return expected.context(fmt.Sprintf("%s title", self.context)).test(actual)
@ -28,7 +28,7 @@ func (self *View) Title(expected *matcher) *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
// assert on the first couple of commits.
func (self *View) TopLines(matchers ...*matcher) *View {
func (self *ViewDriver) TopLines(matchers ...*matcher) *ViewDriver {
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()")
}
@ -43,13 +43,13 @@ 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 {
func (self *ViewDriver) Lines(matchers ...*matcher) *ViewDriver {
self.LineCount(len(matchers))
return self.assertLines(matchers...)
}
func (self *View) assertLines(matchers ...*matcher) *View {
func (self *ViewDriver) assertLines(matchers ...*matcher) *ViewDriver {
view := self.getView()
for i, matcher := range matchers {
@ -73,7 +73,7 @@ func (self *View) assertLines(matchers ...*matcher) *View {
}
// asserts on the content of the view i.e. the stuff within the view's frame.
func (self *View) Content(matcher *matcher) *View {
func (self *ViewDriver) Content(matcher *matcher) *ViewDriver {
self.t.matchString(matcher, fmt.Sprintf("%s: Unexpected content.", self.context),
func() string {
return self.getView().Buffer()
@ -84,7 +84,7 @@ func (self *View) Content(matcher *matcher) *View {
}
// asserts on the selected line of the view
func (self *View) SelectedLine(matcher *matcher) *View {
func (self *ViewDriver) SelectedLine(matcher *matcher) *ViewDriver {
self.t.matchString(matcher, fmt.Sprintf("%s: Unexpected selected line.", self.context),
func() string {
return self.getView().SelectedLine()
@ -95,7 +95,7 @@ func (self *View) SelectedLine(matcher *matcher) *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 *View) SelectedLineIdx(expected int) *View {
func (self *ViewDriver) SelectedLineIdx(expected int) *ViewDriver {
self.t.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)
@ -105,7 +105,7 @@ func (self *View) SelectedLineIdx(expected int) *View {
}
// focus the view (assumes the view is a side-view that can be focused via a keybinding)
func (self *View) Focus() *View {
func (self *ViewDriver) Focus() *ViewDriver {
// 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).
@ -135,7 +135,7 @@ func (self *View) Focus() *View {
}
// asserts that the view is focused
func (self *View) IsFocused() *View {
func (self *ViewDriver) IsFocused() *ViewDriver {
self.t.assertWithRetries(func() (bool, string) {
expected := self.getView().Name()
actual := self.t.gui.CurrentContext().GetView().Name()
@ -145,7 +145,7 @@ func (self *View) IsFocused() *View {
return self
}
func (self *View) Press(keyStr string) *View {
func (self *ViewDriver) Press(keyStr string) *ViewDriver {
self.IsFocused()
self.t.press(keyStr)
@ -154,31 +154,31 @@ func (self *View) Press(keyStr string) *View {
}
// i.e. pressing down arrow
func (self *View) SelectNextItem() *View {
func (self *ViewDriver) SelectNextItem() *ViewDriver {
return self.Press(self.t.keys.Universal.NextItem)
}
// i.e. pressing up arrow
func (self *View) SelectPreviousItem() *View {
func (self *ViewDriver) SelectPreviousItem() *ViewDriver {
return self.Press(self.t.keys.Universal.PrevItem)
}
// i.e. pressing space
func (self *View) PressPrimaryAction() *View {
func (self *ViewDriver) PressPrimaryAction() *ViewDriver {
return self.Press(self.t.keys.Universal.Select)
}
// i.e. pressing space
func (self *View) PressEnter() *View {
func (self *ViewDriver) PressEnter() *ViewDriver {
return self.Press(self.t.keys.Universal.Confirm)
}
// i.e. pressing escape
func (self *View) PressEscape() *View {
func (self *ViewDriver) PressEscape() *ViewDriver {
return self.Press(self.t.keys.Universal.Return)
}
func (self *View) NavigateToListItem(matcher *matcher) *View {
func (self *ViewDriver) NavigateToListItem(matcher *matcher) *ViewDriver {
self.IsFocused()
self.t.navigateToListItem(matcher)
@ -187,7 +187,7 @@ func (self *View) NavigateToListItem(matcher *matcher) *View {
}
// returns true if the view is a list view and it contains no items
func (self *View) IsEmpty() *View {
func (self *ViewDriver) IsEmpty() *ViewDriver {
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)
@ -196,7 +196,7 @@ func (self *View) IsEmpty() *View {
return self
}
func (self *View) LineCount(expectedCount int) *View {
func (self *ViewDriver) LineCount(expectedCount int) *ViewDriver {
if expectedCount == 0 {
return self.IsEmpty()
}
@ -223,7 +223,7 @@ func (self *View) LineCount(expectedCount int) *View {
// 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 {
func (self *ViewDriver) Tap(f func()) *ViewDriver {
f()
return self

View File

@ -12,110 +12,110 @@ type Views struct {
// not exporting this because I want the test to always be explicit about what
// view it's dealing with.
func (self *Views) current() *View {
return &View{
func (self *Views) current() *ViewDriver {
return &ViewDriver{
context: "current view",
getView: func() *gocui.View { return self.t.gui.CurrentContext().GetView() },
t: self.t,
}
}
func (self *Views) Main() *View {
return &View{
func (self *Views) Main() *ViewDriver {
return &ViewDriver{
context: "main view",
getView: func() *gocui.View { return self.t.gui.MainView() },
t: self.t,
}
}
func (self *Views) Secondary() *View {
return &View{
func (self *Views) Secondary() *ViewDriver {
return &ViewDriver{
context: "secondary view",
getView: func() *gocui.View { return self.t.gui.SecondaryView() },
t: self.t,
}
}
func (self *Views) byName(viewName string) *View {
return &View{
func (self *Views) byName(viewName string) *ViewDriver {
return &ViewDriver{
context: fmt.Sprintf("%s view", viewName),
getView: func() *gocui.View { return self.t.gui.View(viewName) },
t: self.t,
}
}
func (self *Views) Commits() *View {
func (self *Views) Commits() *ViewDriver {
return self.byName("commits")
}
func (self *Views) Files() *View {
func (self *Views) Files() *ViewDriver {
return self.byName("files")
}
func (self *Views) Status() *View {
func (self *Views) Status() *ViewDriver {
return self.byName("status")
}
func (self *Views) Submodules() *View {
func (self *Views) Submodules() *ViewDriver {
return self.byName("submodules")
}
func (self *Views) Information() *View {
func (self *Views) Information() *ViewDriver {
return self.byName("information")
}
func (self *Views) Branches() *View {
func (self *Views) Branches() *ViewDriver {
return self.byName("localBranches")
}
func (self *Views) RemoteBranches() *View {
func (self *Views) RemoteBranches() *ViewDriver {
return self.byName("remoteBranches")
}
func (self *Views) Tags() *View {
func (self *Views) Tags() *ViewDriver {
return self.byName("tags")
}
func (self *Views) ReflogCommits() *View {
func (self *Views) ReflogCommits() *ViewDriver {
return self.byName("reflogCommits")
}
func (self *Views) SubCommits() *View {
func (self *Views) SubCommits() *ViewDriver {
return self.byName("subCommits")
}
func (self *Views) CommitFiles() *View {
func (self *Views) CommitFiles() *ViewDriver {
return self.byName("commitFiles")
}
func (self *Views) Stash() *View {
func (self *Views) Stash() *ViewDriver {
return self.byName("stash")
}
func (self *Views) Staging() *View {
func (self *Views) Staging() *ViewDriver {
return self.byName("staging")
}
func (self *Views) StagingSecondary() *View {
func (self *Views) StagingSecondary() *ViewDriver {
return self.byName("stagingSecondary")
}
func (self *Views) Menu() *View {
func (self *Views) Menu() *ViewDriver {
return self.byName("menu")
}
func (self *Views) Confirmation() *View {
func (self *Views) Confirmation() *ViewDriver {
return self.byName("confirmation")
}
func (self *Views) CommitMessage() *View {
func (self *Views) CommitMessage() *ViewDriver {
return self.byName("commitMessage")
}
func (self *Views) Suggestions() *View {
func (self *Views) Suggestions() *ViewDriver {
return self.byName("suggestions")
}
func (self *Views) MergeConflicts() *View {
func (self *Views) MergeConflicts() *ViewDriver {
return self.byName("mergeConflicts")
}