Make it possible to handle toasts in integration tests

Use it in two selected tests to demonstrate what it looks like.
This commit is contained in:
Stefan Haller 2024-01-12 08:12:39 +01:00
parent 37590a495c
commit 9fa43394fe
13 changed files with 49 additions and 8 deletions

View file

@ -23,6 +23,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/env" "github.com/jesseduffield/lazygit/pkg/env"
"github.com/jesseduffield/lazygit/pkg/gui" "github.com/jesseduffield/lazygit/pkg/gui"
"github.com/jesseduffield/lazygit/pkg/i18n" "github.com/jesseduffield/lazygit/pkg/i18n"
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
"github.com/jesseduffield/lazygit/pkg/logs" "github.com/jesseduffield/lazygit/pkg/logs"
"github.com/jesseduffield/lazygit/pkg/updates" "github.com/jesseduffield/lazygit/pkg/updates"
) )
@ -42,7 +43,7 @@ func Run(
common *common.Common, common *common.Common,
startArgs appTypes.StartArgs, startArgs appTypes.StartArgs,
) { ) {
app, err := NewApp(config, common) app, err := NewApp(config, startArgs.IntegrationTest, common)
if err == nil { if err == nil {
err = app.Run(startArgs) err = app.Run(startArgs)
@ -94,7 +95,7 @@ func newLogger(cfg config.AppConfigurer) *logrus.Entry {
} }
// NewApp bootstrap a new application // NewApp bootstrap a new application
func NewApp(config config.AppConfigurer, common *common.Common) (*App, error) { func NewApp(config config.AppConfigurer, test integrationTypes.IntegrationTest, common *common.Common) (*App, error) {
app := &App{ app := &App{
closers: []io.Closer{}, closers: []io.Closer{},
Config: config, Config: config,
@ -128,7 +129,7 @@ func NewApp(config config.AppConfigurer, common *common.Common) (*App, error) {
showRecentRepos = true showRecentRepos = true
} }
app.Gui, err = gui.NewGui(common, config, gitVersion, updater, showRecentRepos, dirName) app.Gui, err = gui.NewGui(common, config, gitVersion, updater, showRecentRepos, dirName, test)
if err != nil { if err != nil {
return app, err return app, err
} }

View file

@ -61,7 +61,7 @@ func generateAtDir(cheatsheetDir string) {
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
mApp, _ := app.NewApp(mConfig, common) mApp, _ := app.NewApp(mConfig, nil, common)
path := cheatsheetDir + "/Keybindings_" + lang + ".md" path := cheatsheetDir + "/Keybindings_" + lang + ".md"
file, err := os.Create(path) file, err := os.Create(path)
if err != nil { if err != nil {

View file

@ -17,6 +17,6 @@ func NewDummyUpdater() *updates.Updater {
func NewDummyGui() *Gui { func NewDummyGui() *Gui {
newAppConfig := config.NewDummyAppConfig() newAppConfig := config.NewDummyAppConfig()
dummyGui, _ := NewGui(utils.NewDummyCommon(), newAppConfig, &git_commands.GitVersion{}, NewDummyUpdater(), false, "") dummyGui, _ := NewGui(utils.NewDummyCommon(), newAppConfig, &git_commands.GitVersion{}, NewDummyUpdater(), false, "", nil)
return dummyGui return dummyGui
} }

View file

@ -467,6 +467,7 @@ func NewGui(
updater *updates.Updater, updater *updates.Updater,
showRecentRepos bool, showRecentRepos bool,
initialDir string, initialDir string,
test integrationTypes.IntegrationTest,
) (*Gui, error) { ) (*Gui, error) {
gui := &Gui{ gui := &Gui{
Common: cmn, Common: cmn,

View file

@ -20,6 +20,7 @@ import (
type GuiDriver struct { type GuiDriver struct {
gui *Gui gui *Gui
isIdleChan chan struct{} isIdleChan chan struct{}
toastChan chan string
} }
var _ integrationTypes.GuiDriver = &GuiDriver{} var _ integrationTypes.GuiDriver = &GuiDriver{}
@ -133,3 +134,12 @@ func (self *GuiDriver) SetCaptionPrefix(prefix string) {
self.gui.setCaptionPrefix(prefix) self.gui.setCaptionPrefix(prefix)
self.waitTillIdle() self.waitTillIdle()
} }
func (self *GuiDriver) NextToast() *string {
select {
case t := <-self.toastChan:
return &t
default:
return nil
}
}

View file

@ -66,6 +66,10 @@ func (self *PopupHandler) Toast(message string) {
self.toastFn(message) self.toastFn(message)
} }
func (self *PopupHandler) SetToastFunc(f func(string)) {
self.toastFn = f
}
func (self *PopupHandler) WithWaitingStatus(message string, f func(gocui.Task) error) error { func (self *PopupHandler) WithWaitingStatus(message string, f func(gocui.Task) error) error {
self.withWaitingStatusFn(message, f) self.withWaitingStatusFn(message, f)
return nil return nil

View file

@ -6,6 +6,7 @@ import (
"time" "time"
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/popup"
"github.com/jesseduffield/lazygit/pkg/integration/components" "github.com/jesseduffield/lazygit/pkg/integration/components"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
) )
@ -32,7 +33,11 @@ func (gui *Gui) handleTestMode() {
go func() { go func() {
waitUntilIdle() waitUntilIdle()
test.Run(&GuiDriver{gui: gui, isIdleChan: isIdleChan}) toastChan := make(chan string, 100)
gui.PopupHandler.(*popup.PopupHandler).SetToastFunc(
func(message string) { toastChan <- message })
test.Run(&GuiDriver{gui: gui, isIdleChan: isIdleChan, toastChan: toastChan})
gui.g.Update(func(*gocui.Gui) error { gui.g.Update(func(*gocui.Gui) error {
return gocui.ErrQuit return gocui.ErrQuit

View file

@ -144,6 +144,7 @@ type IPopupHandler interface {
WithWaitingStatusSync(message string, f func() error) error WithWaitingStatusSync(message string, f func() error) error
Menu(opts CreateMenuOptions) error Menu(opts CreateMenuOptions) error
Toast(message string) Toast(message string)
SetToastFunc(func(string))
GetPromptInput() string GetPromptInput() string
} }

View file

@ -102,8 +102,19 @@ func (self *TestDriver) ExpectPopup() *Popup {
return &Popup{t: self} return &Popup{t: self}
} }
func (self *TestDriver) ExpectToast(matcher *TextMatcher) { func (self *TestDriver) ExpectToast(matcher *TextMatcher) *TestDriver {
self.Views().AppStatus().Content(matcher) t := self.gui.NextToast()
if t == nil {
self.gui.Fail("Expected toast, but didn't get one")
} else {
self.matchString(matcher, "Unexpected toast message",
func() string {
return *t
},
)
}
return self
} }
func (self *TestDriver) ExpectClipboard(matcher *TextMatcher) { func (self *TestDriver) ExpectClipboard(matcher *TextMatcher) {

View file

@ -78,6 +78,10 @@ func (self *fakeGuiDriver) SetCaption(string) {
func (self *fakeGuiDriver) SetCaptionPrefix(string) { func (self *fakeGuiDriver) SetCaptionPrefix(string) {
} }
func (self *fakeGuiDriver) NextToast() *string {
return nil
}
func TestManualFailure(t *testing.T) { func TestManualFailure(t *testing.T) {
test := NewIntegrationTest(NewIntegrationTestArgs{ test := NewIntegrationTest(NewIntegrationTestArgs{
Description: unitTestDescription, Description: unitTestDescription,

View file

@ -65,6 +65,7 @@ var CrudAnnotated = NewIntegrationTest(NewIntegrationTestArgs{
Title(Equals("Delete tag 'new-tag'?")). Title(Equals("Delete tag 'new-tag'?")).
Content(Equals("Are you sure you want to delete the remote tag 'new-tag' from 'origin'?")). Content(Equals("Are you sure you want to delete the remote tag 'new-tag' from 'origin'?")).
Confirm() Confirm()
t.ExpectToast(Equals("Remote tag deleted"))
}). }).
Lines( Lines(
MatchesRegexp(`new-tag.*message`).IsSelected(), MatchesRegexp(`new-tag.*message`).IsSelected(),

View file

@ -70,6 +70,7 @@ var CrudLightweight = NewIntegrationTest(NewIntegrationTestArgs{
Title(Equals("Delete tag 'new-tag'?")). Title(Equals("Delete tag 'new-tag'?")).
Content(Equals("Are you sure you want to delete the remote tag 'new-tag' from 'origin'?")). Content(Equals("Are you sure you want to delete the remote tag 'new-tag' from 'origin'?")).
Confirm() Confirm()
t.ExpectToast(Equals("Remote tag deleted"))
}). }).
Lines( Lines(
MatchesRegexp(`new-tag.*initial commit`).IsSelected(), MatchesRegexp(`new-tag.*initial commit`).IsSelected(),

View file

@ -43,4 +43,6 @@ type GuiDriver interface {
View(viewName string) *gocui.View View(viewName string) *gocui.View
SetCaption(caption string) SetCaption(caption string)
SetCaptionPrefix(prefix string) SetCaptionPrefix(prefix string)
// Pop the next toast that was displayed; returns nil if there was none
NextToast() *string
} }