mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 07:36:27 -04:00
Wait for the event loop to exit in integration tests
The test harness enqueued ErrQuit after a test finished, waited for the program to go idle, then slept a fixed second and declared "gocui should have already exited" if it hadn't. That fixed grace is fragile: under the race detector the shutdown legitimately takes longer than a second, so nearly every test failed with that message even though nothing was wrong. Wait for the main loop to actually return instead. gocui now closes a loopExited channel when MainLoop exits, and the harness blocks on it; the existing 40s watchdog still fails a test whose loop genuinely never quits. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
435e02efa8
commit
59ed1517bc
|
|
@ -148,6 +148,10 @@ type Gui struct {
|
|||
maxX, maxY int
|
||||
outputMode OutputMode
|
||||
stop chan struct{}
|
||||
// loopExited is closed when MainLoop returns, so callers (e.g. the
|
||||
// integration-test harness) can wait for the event loop to actually finish
|
||||
// rather than polling or sleeping a fixed interval.
|
||||
loopExited chan struct{}
|
||||
|
||||
// BgColor and FgColor allow to configure the background and foreground
|
||||
// colors of the GUI.
|
||||
|
|
@ -260,6 +264,7 @@ func NewGui(opts NewGuiOpts) (*Gui, error) {
|
|||
g.outputMode = opts.OutputMode
|
||||
|
||||
g.stop = make(chan struct{})
|
||||
g.loopExited = make(chan struct{})
|
||||
|
||||
g.gEvents = make(chan GocuiEvent, 20)
|
||||
g.userEvents = newUserEventQueue()
|
||||
|
|
@ -348,6 +353,11 @@ func (g *Gui) Close() {
|
|||
Screen.Fini()
|
||||
}
|
||||
|
||||
// LoopExited returns a channel that is closed once MainLoop has returned.
|
||||
func (g *Gui) LoopExited() <-chan struct{} {
|
||||
return g.loopExited
|
||||
}
|
||||
|
||||
// Size returns the terminal's size.
|
||||
func (g *Gui) Size() (x, y int) {
|
||||
return g.maxX, g.maxY
|
||||
|
|
@ -965,6 +975,8 @@ func (g *Gui) SetManagerFunc(manager func(*Gui) error) {
|
|||
// MainLoop runs the main loop until an error is returned. A successful
|
||||
// finish should return ErrQuit.
|
||||
func (g *Gui) MainLoop() error {
|
||||
defer close(g.loopExited)
|
||||
|
||||
g.uiThreadID.Store(goid.Get())
|
||||
|
||||
go func() {
|
||||
|
|
|
|||
|
|
@ -40,11 +40,8 @@ func (gui *Gui) handleTestMode() {
|
|||
return gocui.ErrQuit
|
||||
})
|
||||
|
||||
waitUntilIdle()
|
||||
|
||||
time.Sleep(time.Second * 1)
|
||||
|
||||
log.Fatal("gocui should have already exited")
|
||||
// Wait for the event loop to actually exit.
|
||||
<-gui.g.LoopExited()
|
||||
}()
|
||||
|
||||
if os.Getenv(components.WAIT_FOR_DEBUGGER_ENV_VAR) == "" {
|
||||
|
|
|
|||
Loading…
Reference in a new issue