Skip to content

Commit e56e838

Browse files
committed
fix goroutine leaks and close channels in window tests
1 parent a54c66a commit e56e838

File tree

2 files changed

+121
-105
lines changed

2 files changed

+121
-105
lines changed

window/manager_test.go

Lines changed: 88 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,19 @@ func createTemp(dir, contents string) (*os.File, error) {
3030

3131
func TestManagerOpenEmpty(t *testing.T) {
3232
wm := NewManager()
33-
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
33+
eventCh, redrawCh, waitCh := make(chan event.Event), make(chan struct{}), make(chan struct{})
3434
wm.Init(eventCh, redrawCh)
3535
go func() {
36-
<-redrawCh
36+
defer close(eventCh)
37+
defer close(redrawCh)
38+
defer close(waitCh)
39+
ev := <-eventCh
40+
if ev.Type != event.Error {
41+
t.Errorf("event type should be %d but got: %d", event.Error, ev.Type)
42+
}
43+
if expected := "no file name"; ev.Error.Error() != expected {
44+
t.Errorf("err should be %q but got: %v", expected, ev.Error)
45+
}
3746
}()
3847
wm.SetSize(110, 20)
3948
if err := wm.Open(""); err != nil {
@@ -62,21 +71,14 @@ func TestManagerOpenEmpty(t *testing.T) {
6271
if err != nil {
6372
t.Errorf("err should be nil but got: %v", err)
6473
}
65-
go wm.Emit(event.Event{Type: event.Write})
66-
ev := <-eventCh
67-
if ev.Type != event.Error {
68-
t.Errorf("event type should be %d but got: %d", event.Error, ev.Type)
69-
}
70-
if expected := "no file name"; ev.Error.Error() != expected {
71-
t.Errorf("err should be %q but got: %v", expected, ev.Error)
72-
}
74+
wm.Emit(event.Event{Type: event.Write})
75+
<-waitCh
7376
wm.Close()
7477
}
7578

7679
func TestManagerOpenStates(t *testing.T) {
7780
wm := NewManager()
78-
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
79-
wm.Init(eventCh, redrawCh)
81+
wm.Init(nil, nil)
8082
wm.SetSize(110, 20)
8183
str := "Hello, world! こんにちは、世界!"
8284
f, err := createTemp(t.TempDir(), str)
@@ -114,14 +116,17 @@ func TestManagerOpenStates(t *testing.T) {
114116

115117
func TestManagerOpenNonExistsWrite(t *testing.T) {
116118
wm := NewManager()
117-
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
119+
eventCh, redrawCh, waitCh := make(chan event.Event), make(chan struct{}), make(chan struct{})
118120
wm.Init(eventCh, redrawCh)
119121
go func() {
120-
for {
121-
select {
122-
case <-eventCh:
123-
case <-redrawCh:
124-
}
122+
defer close(eventCh)
123+
defer close(redrawCh)
124+
defer close(waitCh)
125+
for range 16 {
126+
<-redrawCh
127+
}
128+
if ev := <-eventCh; ev.Type != event.QuitAll {
129+
t.Errorf("event type should be %d but got: %d", event.QuitAll, ev.Type)
125130
}
126131
}()
127132
wm.SetSize(110, 20)
@@ -168,13 +173,13 @@ func TestManagerOpenNonExistsWrite(t *testing.T) {
168173
if string(bs) != str {
169174
t.Errorf("file contents should be %q but got %q", str, string(bs))
170175
}
176+
<-waitCh
171177
wm.Close()
172178
}
173179

174180
func TestManagerOpenExpandBacktick(t *testing.T) {
175181
wm := NewManager()
176-
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
177-
wm.Init(eventCh, redrawCh)
182+
wm.Init(nil, nil)
178183
wm.SetSize(110, 20)
179184
cmd, name := "`which ls`", "ls"
180185
if runtime.GOOS == "windows" {
@@ -208,8 +213,7 @@ func TestEditorOpenExpandHomedir(t *testing.T) {
208213
t.Skip("skip on Windows")
209214
}
210215
wm := NewManager()
211-
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
212-
wm.Init(eventCh, redrawCh)
216+
wm.Init(nil, nil)
213217
wm.SetSize(110, 20)
214218
str := "Hello, world!"
215219
f, err := createTemp(t.TempDir(), str)
@@ -246,21 +250,46 @@ func TestManagerOpenChdirWrite(t *testing.T) {
246250
t.Skip("skip on Windows")
247251
}
248252
wm := NewManager()
249-
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
253+
eventCh, redrawCh, waitCh := make(chan event.Event), make(chan struct{}), make(chan struct{})
250254
wm.Init(eventCh, redrawCh)
251-
go func() {
252-
for {
253-
select {
254-
case <-eventCh:
255-
case <-redrawCh:
256-
}
257-
}
258-
}()
259-
wm.SetSize(110, 20)
260255
f, err := createTemp(t.TempDir(), "Hello")
261256
if err != nil {
262257
t.Fatalf("err should be nil but got: %v", err)
263258
}
259+
go func() {
260+
defer close(eventCh)
261+
defer close(redrawCh)
262+
defer close(waitCh)
263+
ev := <-eventCh
264+
if ev.Type != event.Info {
265+
t.Errorf("event type should be %d but got: %d", event.Info, ev.Type)
266+
}
267+
dir, err := filepath.EvalSymlinks(filepath.Dir(f.Name()))
268+
if err != nil {
269+
t.Errorf("err should be nil but got: %v", err)
270+
}
271+
if expected := dir; ev.Error.Error() != expected {
272+
t.Errorf("err should be %q but got: %v", expected, ev.Error)
273+
}
274+
ev = <-eventCh
275+
if ev.Type != event.Info {
276+
t.Errorf("event type should be %d but got: %d", event.Info, ev.Type)
277+
}
278+
if expected := filepath.Dir(dir); ev.Error.Error() != expected {
279+
t.Errorf("err should be %q but got: %v", expected, ev.Error)
280+
}
281+
for range 11 {
282+
<-redrawCh
283+
}
284+
ev = <-eventCh
285+
if ev.Type != event.Info {
286+
t.Errorf("event type should be %d but got: %d", event.Info, ev.Type)
287+
}
288+
if expected := "13 (0xd) bytes written"; !strings.HasSuffix(ev.Error.Error(), expected) {
289+
t.Errorf("err should be %q but got: %v", expected, ev.Error)
290+
}
291+
}()
292+
wm.SetSize(110, 20)
264293
wm.Emit(event.Event{Type: event.Chdir, Arg: filepath.Dir(f.Name())})
265294
if err := wm.Open(filepath.Base(f.Name())); err != nil {
266295
t.Fatalf("err should be nil but got: %v", err)
@@ -284,21 +313,13 @@ func TestManagerOpenChdirWrite(t *testing.T) {
284313
if expected := "Hello, world!"; string(bs) != expected {
285314
t.Errorf("file contents should be %q but got %q", expected, string(bs))
286315
}
316+
<-waitCh
287317
wm.Close()
288318
}
289319

290320
func TestManagerOpenDirectory(t *testing.T) {
291321
wm := NewManager()
292-
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
293-
wm.Init(eventCh, redrawCh)
294-
go func() {
295-
for {
296-
select {
297-
case <-eventCh:
298-
case <-redrawCh:
299-
}
300-
}
301-
}()
322+
wm.Init(nil, nil)
302323
wm.SetSize(110, 20)
303324
dir := t.TempDir()
304325
if err := wm.Open(dir); err != nil {
@@ -313,8 +334,7 @@ func TestManagerOpenDirectory(t *testing.T) {
313334

314335
func TestManagerRead(t *testing.T) {
315336
wm := NewManager()
316-
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
317-
wm.Init(eventCh, redrawCh)
337+
wm.Init(nil, nil)
318338
wm.SetSize(110, 20)
319339
r := strings.NewReader("Hello, world!")
320340
if err := wm.Read(r); err != nil {
@@ -345,14 +365,14 @@ func TestManagerRead(t *testing.T) {
345365

346366
func TestManagerOnly(t *testing.T) {
347367
wm := NewManager()
348-
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
368+
eventCh, redrawCh, waitCh := make(chan event.Event), make(chan struct{}), make(chan struct{})
349369
wm.Init(eventCh, redrawCh)
350370
go func() {
351-
for {
352-
select {
353-
case <-eventCh:
354-
case <-redrawCh:
355-
}
371+
defer close(eventCh)
372+
defer close(redrawCh)
373+
defer close(waitCh)
374+
for range 4 {
375+
<-eventCh
356376
}
357377
}()
358378
wm.SetSize(110, 20)
@@ -379,19 +399,20 @@ func TestManagerOnly(t *testing.T) {
379399
t.Errorf("layout should be %#v but got %#v", expected, got)
380400
}
381401

402+
<-waitCh
382403
wm.Close()
383404
}
384405

385406
func TestManagerAlternative(t *testing.T) {
386407
wm := NewManager()
387-
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
408+
eventCh, redrawCh, waitCh := make(chan event.Event), make(chan struct{}), make(chan struct{})
388409
wm.Init(eventCh, redrawCh)
389410
go func() {
390-
for {
391-
select {
392-
case <-eventCh:
393-
case <-redrawCh:
394-
}
411+
defer close(eventCh)
412+
defer close(redrawCh)
413+
defer close(waitCh)
414+
for range 9 {
415+
<-eventCh
395416
}
396417
}()
397418
wm.SetSize(110, 20)
@@ -475,19 +496,20 @@ func TestManagerAlternative(t *testing.T) {
475496
t.Errorf("windowIndex should be %d but got %d", expected, windowIndex)
476497
}
477498

499+
<-waitCh
478500
wm.Close()
479501
}
480502

481503
func TestManagerWincmd(t *testing.T) {
482504
wm := NewManager()
483-
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
505+
eventCh, redrawCh, waitCh := make(chan event.Event), make(chan struct{}), make(chan struct{})
484506
wm.Init(eventCh, redrawCh)
485507
go func() {
486-
for {
487-
select {
488-
case <-eventCh:
489-
case <-redrawCh:
490-
}
508+
defer close(eventCh)
509+
defer close(redrawCh)
510+
defer close(waitCh)
511+
for range 17 {
512+
<-eventCh
491513
}
492514
}()
493515
wm.SetSize(110, 20)
@@ -538,6 +560,7 @@ func TestManagerWincmd(t *testing.T) {
538560
t.Errorf("layout should be %#v but got %#v", expected, got)
539561
}
540562

563+
<-waitCh
541564
wm.Close()
542565
}
543566

@@ -556,6 +579,9 @@ func TestManagerCopyCutPaste(t *testing.T) {
556579
}
557580
_, _, _, _ = wm.State()
558581
go func() {
582+
defer close(eventCh)
583+
defer close(redrawCh)
584+
defer close(waitCh)
559585
<-redrawCh
560586
<-redrawCh
561587
<-redrawCh
@@ -620,7 +646,6 @@ func TestManagerCopyCutPaste(t *testing.T) {
620646
if expected := "Hefoobarfoobarfoobarlrld!"; !strings.HasPrefix(string(ws.Bytes), expected) {
621647
t.Errorf("Bytes should start with %q but got %q", expected, string(ws.Bytes))
622648
}
623-
close(waitCh)
624649
}()
625650
wm.Emit(event.Event{Type: event.CursorNext, Mode: mode.Normal, Count: 3})
626651
wm.Emit(event.Event{Type: event.StartVisual})

0 commit comments

Comments
 (0)