1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-03-05 15:15:49 +02:00

add popup handler for easier testing

This commit is contained in:
Jesse Duffield 2021-12-06 21:08:36 +11:00
parent 1996eddd91
commit 18283ad41b
6 changed files with 134 additions and 51 deletions

View File

@ -1,5 +1,3 @@
// lots of this has been directly ported from one of the example files, will brush up later
package gui package gui
import ( import (
@ -7,7 +5,6 @@ import (
"strings" "strings"
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/theme" "github.com/jesseduffield/lazygit/pkg/theme"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
@ -44,30 +41,15 @@ type promptOpts struct {
} }
func (gui *Gui) ask(opts askOpts) error { func (gui *Gui) ask(opts askOpts) error {
return gui.createPopupPanel(createPopupPanelOpts{ return gui.PopupHandler.Ask(opts)
title: opts.title,
prompt: opts.prompt,
handleConfirm: opts.handleConfirm,
handleClose: opts.handleClose,
handlersManageFocus: opts.handlersManageFocus,
})
} }
func (gui *Gui) prompt(opts promptOpts) error { func (gui *Gui) prompt(opts promptOpts) error {
return gui.createPopupPanel(createPopupPanelOpts{ return gui.PopupHandler.Prompt(opts)
title: opts.title,
prompt: opts.initialContent,
editable: true,
handleConfirmPrompt: opts.handleConfirm,
findSuggestionsFunc: opts.findSuggestionsFunc,
})
} }
func (gui *Gui) createLoaderPanel(prompt string) error { func (gui *Gui) createLoaderPanel(prompt string) error {
return gui.createPopupPanel(createPopupPanelOpts{ return gui.PopupHandler.Loader(prompt)
prompt: prompt,
hasLoader: true,
})
} }
func (gui *Gui) wrappedConfirmationFunction(handlersManageFocus bool, function func() error) func() error { func (gui *Gui) wrappedConfirmationFunction(handlersManageFocus bool, function func() error) func() error {
@ -339,15 +321,7 @@ func (gui *Gui) wrappedHandler(f func() error) func(g *gocui.Gui, v *gocui.View)
} }
func (gui *Gui) createErrorPanel(message string) error { func (gui *Gui) createErrorPanel(message string) error {
coloredMessage := style.FgRed.Sprint(strings.TrimSpace(message)) return gui.PopupHandler.Error(message)
if err := gui.refreshSidePanels(refreshOptions{mode: ASYNC}); err != nil {
return err
}
return gui.ask(askOpts{
title: gui.Tr.Error,
prompt: coloredMessage,
})
} }
func (gui *Gui) surfaceError(err error) error { func (gui *Gui) surfaceError(err error) error {

View File

@ -8,7 +8,7 @@ import (
) )
func TestCanDeactivatePopupContextsWithoutViews(t *testing.T) { func TestCanDeactivatePopupContextsWithoutViews(t *testing.T) {
contexts := []func(gui *Gui) Context { contexts := []func(gui *Gui) Context{
func(gui *Gui) Context { return gui.State.Contexts.Credentials }, func(gui *Gui) Context { return gui.State.Contexts.Credentials },
func(gui *Gui) Context { return gui.State.Contexts.Confirmation }, func(gui *Gui) Context { return gui.State.Contexts.Confirmation },
func(gui *Gui) Context { return gui.State.Contexts.CommitMessage }, func(gui *Gui) Context { return gui.State.Contexts.CommitMessage },
@ -20,7 +20,7 @@ func TestCanDeactivatePopupContextsWithoutViews(t *testing.T) {
context := c(gui) context := c(gui)
gui.g = &gocui.Gui{} gui.g = &gocui.Gui{}
gui.deactivateContext(context) _ = gui.deactivateContext(context)
// This really only checks a prerequisit, not the effect of deactivateContext // This really only checks a prerequisit, not the effect of deactivateContext
view, _ := gui.g.View(context.GetViewName()) view, _ := gui.g.View(context.GetViewName())
@ -32,7 +32,7 @@ func TestCanDeactivateCommitFilesContextsWithoutViews(t *testing.T) {
gui := NewDummyGui() gui := NewDummyGui()
gui.g = &gocui.Gui{} gui.g = &gocui.Gui{}
gui.deactivateContext(gui.State.Contexts.CommitFiles) _ = gui.deactivateContext(gui.State.Contexts.CommitFiles)
// This really only checks a prerequisite, not the effect of deactivateContext // This really only checks a prerequisite, not the effect of deactivateContext
view, _ := gui.g.View(gui.State.Contexts.CommitFiles.GetViewName()) view, _ := gui.g.View(gui.State.Contexts.CommitFiles.GetViewName())

View File

@ -28,7 +28,7 @@ func setupGuiForTest(gui *Gui) {
gui.Views.Main, _ = gui.prepareView("main") gui.Views.Main, _ = gui.prepareView("main")
gui.Views.Secondary, _ = gui.prepareView("secondary") gui.Views.Secondary, _ = gui.prepareView("secondary")
gui.GitCommand.PatchManager = &patch.PatchManager{} gui.GitCommand.PatchManager = &patch.PatchManager{}
gui.refreshLineByLinePanel(diffForTest, "", false, 11) _, _ = gui.refreshLineByLinePanel(diffForTest, "", false, 11)
} }
func TestIncreasesContextInDiffViewByOneInContextWithDiff(t *testing.T) { func TestIncreasesContextInDiffViewByOneInContextWithDiff(t *testing.T) {
@ -47,9 +47,9 @@ func TestIncreasesContextInDiffViewByOneInContextWithDiff(t *testing.T) {
context := c(gui) context := c(gui)
setupGuiForTest(gui) setupGuiForTest(gui)
gui.Config.GetUserConfig().Git.DiffContextSize = 1 gui.Config.GetUserConfig().Git.DiffContextSize = 1
gui.pushContextDirect(context) _ = gui.pushContextDirect(context)
gui.IncreaseContextInDiffView() _ = gui.IncreaseContextInDiffView()
assert.Equal(t, 2, gui.Config.GetUserConfig().Git.DiffContextSize, string(context.GetKey())) assert.Equal(t, 2, gui.Config.GetUserConfig().Git.DiffContextSize, string(context.GetKey()))
} }
@ -73,9 +73,9 @@ func TestDoesntIncreaseContextInDiffViewInContextWithoutDiff(t *testing.T) {
context := c(gui) context := c(gui)
setupGuiForTest(gui) setupGuiForTest(gui)
gui.Config.GetUserConfig().Git.DiffContextSize = 1 gui.Config.GetUserConfig().Git.DiffContextSize = 1
gui.pushContextDirect(context) _ = gui.pushContextDirect(context)
gui.IncreaseContextInDiffView() _ = gui.IncreaseContextInDiffView()
assert.Equal(t, 1, gui.Config.GetUserConfig().Git.DiffContextSize, string(context.GetKey())) assert.Equal(t, 1, gui.Config.GetUserConfig().Git.DiffContextSize, string(context.GetKey()))
} }
@ -97,9 +97,9 @@ func TestDecreasesContextInDiffViewByOneInContextWithDiff(t *testing.T) {
context := c(gui) context := c(gui)
setupGuiForTest(gui) setupGuiForTest(gui)
gui.Config.GetUserConfig().Git.DiffContextSize = 2 gui.Config.GetUserConfig().Git.DiffContextSize = 2
gui.pushContextDirect(context) _ = gui.pushContextDirect(context)
gui.DecreaseContextInDiffView() _ = gui.DecreaseContextInDiffView()
assert.Equal(t, 1, gui.Config.GetUserConfig().Git.DiffContextSize, string(context.GetKey())) assert.Equal(t, 1, gui.Config.GetUserConfig().Git.DiffContextSize, string(context.GetKey()))
} }
@ -123,9 +123,9 @@ func TestDoesntDecreaseContextInDiffViewInContextWithoutDiff(t *testing.T) {
context := c(gui) context := c(gui)
setupGuiForTest(gui) setupGuiForTest(gui)
gui.Config.GetUserConfig().Git.DiffContextSize = 2 gui.Config.GetUserConfig().Git.DiffContextSize = 2
gui.pushContextDirect(context) _ = gui.pushContextDirect(context)
gui.DecreaseContextInDiffView() _ = gui.DecreaseContextInDiffView()
assert.Equal(t, 2, gui.Config.GetUserConfig().Git.DiffContextSize, string(context.GetKey())) assert.Equal(t, 2, gui.Config.GetUserConfig().Git.DiffContextSize, string(context.GetKey()))
} }
@ -135,11 +135,21 @@ func TestDoesntIncreaseContextInDiffViewInContextWhenInPatchBuildingMode(t *test
gui := NewDummyGui() gui := NewDummyGui()
setupGuiForTest(gui) setupGuiForTest(gui)
gui.Config.GetUserConfig().Git.DiffContextSize = 2 gui.Config.GetUserConfig().Git.DiffContextSize = 2
gui.pushContextDirect(gui.State.Contexts.CommitFiles) _ = gui.pushContextDirect(gui.State.Contexts.CommitFiles)
gui.GitCommand.PatchManager.Start("from", "to", false, false) gui.GitCommand.PatchManager.Start("from", "to", false, false)
gui.IncreaseContextInDiffView() errorCount := 0
gui.PopupHandler = &TestPopupHandler{
onError: func(message string) error {
assert.Equal(t, gui.Tr.CantChangeContextSizeError, message)
errorCount += 1
return nil
},
}
_ = gui.IncreaseContextInDiffView()
assert.Equal(t, 1, errorCount)
assert.Equal(t, 2, gui.Config.GetUserConfig().Git.DiffContextSize) assert.Equal(t, 2, gui.Config.GetUserConfig().Git.DiffContextSize)
} }
@ -147,10 +157,19 @@ func TestDoesntDecreaseContextInDiffViewInContextWhenInPatchBuildingMode(t *test
gui := NewDummyGui() gui := NewDummyGui()
setupGuiForTest(gui) setupGuiForTest(gui)
gui.Config.GetUserConfig().Git.DiffContextSize = 2 gui.Config.GetUserConfig().Git.DiffContextSize = 2
gui.pushContextDirect(gui.State.Contexts.CommitFiles) _ = gui.pushContextDirect(gui.State.Contexts.CommitFiles)
gui.GitCommand.PatchManager.Start("from", "to", false, false) gui.GitCommand.PatchManager.Start("from", "to", false, false)
gui.DecreaseContextInDiffView() errorCount := 0
gui.PopupHandler = &TestPopupHandler{
onError: func(message string) error {
assert.Equal(t, gui.Tr.CantChangeContextSizeError, message)
errorCount += 1
return nil
},
}
_ = gui.DecreaseContextInDiffView()
assert.Equal(t, 2, gui.Config.GetUserConfig().Git.DiffContextSize) assert.Equal(t, 2, gui.Config.GetUserConfig().Git.DiffContextSize)
} }
@ -160,7 +179,7 @@ func TestDecreasesContextInDiffViewNoFurtherThanOne(t *testing.T) {
setupGuiForTest(gui) setupGuiForTest(gui)
gui.Config.GetUserConfig().Git.DiffContextSize = 1 gui.Config.GetUserConfig().Git.DiffContextSize = 1
gui.DecreaseContextInDiffView() _ = gui.DecreaseContextInDiffView()
assert.Equal(t, 1, gui.Config.GetUserConfig().Git.DiffContextSize) assert.Equal(t, 1, gui.Config.GetUserConfig().Git.DiffContextSize)
} }

View File

@ -12,12 +12,12 @@ import (
// NewDummyGui creates a new dummy GUI for testing // NewDummyGui creates a new dummy GUI for testing
func NewDummyUpdater() *updates.Updater { func NewDummyUpdater() *updates.Updater {
newAppConfig := config.NewDummyAppConfig() newAppConfig := config.NewDummyAppConfig()
DummyUpdater, _ := updates.NewUpdater(utils.NewDummyLog(), newAppConfig, oscommands.NewDummyOSCommand(), i18n.NewTranslationSet(utils.NewDummyLog(), newAppConfig.GetUserConfig().Gui.Language)) dummyUpdater, _ := updates.NewUpdater(utils.NewDummyLog(), newAppConfig, oscommands.NewDummyOSCommand(), i18n.NewTranslationSet(utils.NewDummyLog(), newAppConfig.GetUserConfig().Gui.Language))
return DummyUpdater return dummyUpdater
} }
func NewDummyGui() *Gui { func NewDummyGui() *Gui {
newAppConfig := config.NewDummyAppConfig() newAppConfig := config.NewDummyAppConfig()
DummyGui, _ := NewGui(utils.NewDummyLog(), commands.NewDummyGitCommand(), oscommands.NewDummyOSCommand(), i18n.NewTranslationSet(utils.NewDummyLog(), newAppConfig.GetUserConfig().Gui.Language), newAppConfig, NewDummyUpdater(), "", false) dummyGui, _ := NewGui(utils.NewDummyLog(), commands.NewDummyGitCommand(), oscommands.NewDummyOSCommand(), i18n.NewTranslationSet(utils.NewDummyLog(), newAppConfig.GetUserConfig().Gui.Language), newAppConfig, NewDummyUpdater(), "", false)
return DummyGui return dummyGui
} }

View File

@ -121,6 +121,8 @@ type Gui struct {
ShowExtrasWindow bool ShowExtrasWindow bool
suggestionsAsyncHandler *tasks.AsyncHandler suggestionsAsyncHandler *tasks.AsyncHandler
PopupHandler PopupHandler
} }
type listPanelState struct { type listPanelState struct {
@ -455,6 +457,7 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *oscom
onRunCommand := gui.GetOnRunCommand() onRunCommand := gui.GetOnRunCommand()
oSCommand.SetOnRunCommand(onRunCommand) oSCommand.SetOnRunCommand(onRunCommand)
gui.OnRunCommand = onRunCommand gui.OnRunCommand = onRunCommand
gui.PopupHandler = &RealPopupHandler{gui: gui}
authors.SetCustomAuthors(gui.Config.GetUserConfig().Gui.AuthorColors) authors.SetCustomAuthors(gui.Config.GetUserConfig().Gui.AuthorColors)

87
pkg/gui/popup_handler.go Normal file
View File

@ -0,0 +1,87 @@
package gui
import (
"strings"
"github.com/jesseduffield/lazygit/pkg/gui/style"
)
type PopupHandler interface {
Error(message string) error
Ask(opts askOpts) error
Prompt(opts promptOpts) error
Loader(message string) error
}
type RealPopupHandler struct {
gui *Gui
}
func (self *RealPopupHandler) Error(message string) error {
gui := self.gui
coloredMessage := style.FgRed.Sprint(strings.TrimSpace(message))
if err := gui.refreshSidePanels(refreshOptions{mode: ASYNC}); err != nil {
return err
}
return self.Ask(askOpts{
title: gui.Tr.Error,
prompt: coloredMessage,
})
}
func (self *RealPopupHandler) Ask(opts askOpts) error {
gui := self.gui
return gui.createPopupPanel(createPopupPanelOpts{
title: opts.title,
prompt: opts.prompt,
handleConfirm: opts.handleConfirm,
handleClose: opts.handleClose,
handlersManageFocus: opts.handlersManageFocus,
})
}
func (self *RealPopupHandler) Prompt(opts promptOpts) error {
gui := self.gui
return gui.createPopupPanel(createPopupPanelOpts{
title: opts.title,
prompt: opts.initialContent,
editable: true,
handleConfirmPrompt: opts.handleConfirm,
findSuggestionsFunc: opts.findSuggestionsFunc,
})
}
func (self *RealPopupHandler) Loader(message string) error {
gui := self.gui
return gui.createPopupPanel(createPopupPanelOpts{
prompt: message,
hasLoader: true,
})
}
type TestPopupHandler struct {
onError func(message string) error
onAsk func(opts askOpts) error
onPrompt func(opts promptOpts) error
}
func (self *TestPopupHandler) Error(message string) error {
return self.onError(message)
}
func (self *TestPopupHandler) Ask(opts askOpts) error {
return self.onAsk(opts)
}
func (self *TestPopupHandler) Prompt(opts promptOpts) error {
return self.onPrompt(opts)
}
func (self *TestPopupHandler) Loader(message string) error {
return nil
}