Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ad3e80b

Browse files
committedOct 17, 2024·
fix goroutine leaks and close channels in window tests
1 parent a54c66a commit ad3e80b

File tree

2 files changed

+116
-87
lines changed

2 files changed

+116
-87
lines changed
 

‎window/manager_test.go

+83-45
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,15 @@ func TestManagerOpenEmpty(t *testing.T) {
3333
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
3434
wm.Init(eventCh, redrawCh)
3535
go func() {
36-
<-redrawCh
36+
defer close(eventCh)
37+
defer close(redrawCh)
38+
ev := <-eventCh
39+
if ev.Type != event.Error {
40+
t.Errorf("event type should be %d but got: %d", event.Error, ev.Type)
41+
}
42+
if expected := "no file name"; ev.Error.Error() != expected {
43+
t.Errorf("err should be %q but got: %v", expected, ev.Error)
44+
}
3745
}()
3846
wm.SetSize(110, 20)
3947
if err := wm.Open(""); err != nil {
@@ -62,21 +70,18 @@ func TestManagerOpenEmpty(t *testing.T) {
6270
if err != nil {
6371
t.Errorf("err should be nil but got: %v", err)
6472
}
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-
}
73+
wm.Emit(event.Event{Type: event.Write})
7374
wm.Close()
7475
}
7576

7677
func TestManagerOpenStates(t *testing.T) {
7778
wm := NewManager()
7879
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
7980
wm.Init(eventCh, redrawCh)
81+
go func() {
82+
defer close(eventCh)
83+
defer close(redrawCh)
84+
}()
8085
wm.SetSize(110, 20)
8186
str := "Hello, world! こんにちは、世界!"
8287
f, err := createTemp(t.TempDir(), str)
@@ -117,11 +122,13 @@ func TestManagerOpenNonExistsWrite(t *testing.T) {
117122
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
118123
wm.Init(eventCh, redrawCh)
119124
go func() {
120-
for {
121-
select {
122-
case <-eventCh:
123-
case <-redrawCh:
124-
}
125+
defer close(eventCh)
126+
defer close(redrawCh)
127+
for range 16 {
128+
<-redrawCh
129+
}
130+
if ev := <-eventCh; ev.Type != event.QuitAll {
131+
t.Errorf("event type should be %d but got: %d", event.QuitAll, ev.Type)
125132
}
126133
}()
127134
wm.SetSize(110, 20)
@@ -175,6 +182,10 @@ func TestManagerOpenExpandBacktick(t *testing.T) {
175182
wm := NewManager()
176183
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
177184
wm.Init(eventCh, redrawCh)
185+
go func() {
186+
defer close(eventCh)
187+
defer close(redrawCh)
188+
}()
178189
wm.SetSize(110, 20)
179190
cmd, name := "`which ls`", "ls"
180191
if runtime.GOOS == "windows" {
@@ -210,6 +221,10 @@ func TestEditorOpenExpandHomedir(t *testing.T) {
210221
wm := NewManager()
211222
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
212223
wm.Init(eventCh, redrawCh)
224+
go func() {
225+
defer close(eventCh)
226+
defer close(redrawCh)
227+
}()
213228
wm.SetSize(110, 20)
214229
str := "Hello, world!"
215230
f, err := createTemp(t.TempDir(), str)
@@ -248,19 +263,43 @@ func TestManagerOpenChdirWrite(t *testing.T) {
248263
wm := NewManager()
249264
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
250265
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)
260266
f, err := createTemp(t.TempDir(), "Hello")
261267
if err != nil {
262268
t.Fatalf("err should be nil but got: %v", err)
263269
}
270+
go func() {
271+
defer close(eventCh)
272+
defer close(redrawCh)
273+
ev := <-eventCh
274+
dir, err := filepath.EvalSymlinks(filepath.Dir(f.Name()))
275+
if err != nil {
276+
t.Fatal(err)
277+
}
278+
if ev.Type != event.Info {
279+
t.Errorf("event type should be %d but got: %d", event.Info, ev.Type)
280+
}
281+
if expected := dir; ev.Error.Error() != expected {
282+
t.Errorf("err should be %q but got: %v", expected, ev.Error)
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 := filepath.Dir(dir); ev.Error.Error() != expected {
289+
t.Errorf("err should be %q but got: %v", expected, ev.Error)
290+
}
291+
for range 11 {
292+
<-redrawCh
293+
}
294+
ev = <-eventCh
295+
if ev.Type != event.Info {
296+
t.Errorf("event type should be %d but got: %d", event.Info, ev.Type)
297+
}
298+
if expected := "13 (0xd) bytes written"; !strings.HasSuffix(ev.Error.Error(), expected) {
299+
t.Errorf("err should be %q but got: %v", expected, ev.Error)
300+
}
301+
}()
302+
wm.SetSize(110, 20)
264303
wm.Emit(event.Event{Type: event.Chdir, Arg: filepath.Dir(f.Name())})
265304
if err := wm.Open(filepath.Base(f.Name())); err != nil {
266305
t.Fatalf("err should be nil but got: %v", err)
@@ -292,12 +331,8 @@ func TestManagerOpenDirectory(t *testing.T) {
292331
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
293332
wm.Init(eventCh, redrawCh)
294333
go func() {
295-
for {
296-
select {
297-
case <-eventCh:
298-
case <-redrawCh:
299-
}
300-
}
334+
defer close(eventCh)
335+
defer close(redrawCh)
301336
}()
302337
wm.SetSize(110, 20)
303338
dir := t.TempDir()
@@ -315,6 +350,10 @@ func TestManagerRead(t *testing.T) {
315350
wm := NewManager()
316351
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
317352
wm.Init(eventCh, redrawCh)
353+
go func() {
354+
defer close(eventCh)
355+
defer close(redrawCh)
356+
}()
318357
wm.SetSize(110, 20)
319358
r := strings.NewReader("Hello, world!")
320359
if err := wm.Read(r); err != nil {
@@ -348,11 +387,10 @@ func TestManagerOnly(t *testing.T) {
348387
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
349388
wm.Init(eventCh, redrawCh)
350389
go func() {
351-
for {
352-
select {
353-
case <-eventCh:
354-
case <-redrawCh:
355-
}
390+
defer close(eventCh)
391+
defer close(redrawCh)
392+
for range 4 {
393+
<-eventCh
356394
}
357395
}()
358396
wm.SetSize(110, 20)
@@ -387,11 +425,10 @@ func TestManagerAlternative(t *testing.T) {
387425
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
388426
wm.Init(eventCh, redrawCh)
389427
go func() {
390-
for {
391-
select {
392-
case <-eventCh:
393-
case <-redrawCh:
394-
}
428+
defer close(eventCh)
429+
defer close(redrawCh)
430+
for range 9 {
431+
<-eventCh
395432
}
396433
}()
397434
wm.SetSize(110, 20)
@@ -483,11 +520,10 @@ func TestManagerWincmd(t *testing.T) {
483520
eventCh, redrawCh := make(chan event.Event), make(chan struct{})
484521
wm.Init(eventCh, redrawCh)
485522
go func() {
486-
for {
487-
select {
488-
case <-eventCh:
489-
case <-redrawCh:
490-
}
523+
defer close(eventCh)
524+
defer close(redrawCh)
525+
for range 17 {
526+
<-eventCh
491527
}
492528
}()
493529
wm.SetSize(110, 20)
@@ -556,6 +592,9 @@ func TestManagerCopyCutPaste(t *testing.T) {
556592
}
557593
_, _, _, _ = wm.State()
558594
go func() {
595+
defer close(eventCh)
596+
defer close(redrawCh)
597+
defer close(waitCh)
559598
<-redrawCh
560599
<-redrawCh
561600
<-redrawCh
@@ -620,7 +659,6 @@ func TestManagerCopyCutPaste(t *testing.T) {
620659
if expected := "Hefoobarfoobarfoobarlrld!"; !strings.HasPrefix(string(ws.Bytes), expected) {
621660
t.Errorf("Bytes should start with %q but got %q", expected, string(ws.Bytes))
622661
}
623-
close(waitCh)
624662
}()
625663
wm.Emit(event.Event{Type: event.CursorNext, Mode: mode.Normal, Count: 3})
626664
wm.Emit(event.Event{Type: event.StartVisual})

‎window/window_test.go

+33-42
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
func TestWindowState(t *testing.T) {
1515
r := strings.NewReader("Hello, world!")
1616
width, height := 16, 10
17-
window, err := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
17+
window, err := newWindow(r, "test", "test", nil, nil)
1818
if err != nil {
1919
t.Fatal(err)
2020
}
@@ -70,7 +70,7 @@ func TestWindowState(t *testing.T) {
7070
func TestWindowEmptyState(t *testing.T) {
7171
r := strings.NewReader("")
7272
width, height := 16, 10
73-
window, err := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
73+
window, err := newWindow(r, "test", "test", nil, nil)
7474
if err != nil {
7575
t.Fatal(err)
7676
}
@@ -136,7 +136,7 @@ func TestWindowEmptyState(t *testing.T) {
136136
func TestWindowCursorMotions(t *testing.T) {
137137
r := strings.NewReader(strings.Repeat("Hello, world!", 100))
138138
width, height := 16, 10
139-
window, err := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
139+
window, err := newWindow(r, "test", "test", nil, nil)
140140
if err != nil {
141141
t.Fatal(err)
142142
}
@@ -437,7 +437,7 @@ func TestWindowCursorMotions(t *testing.T) {
437437
func TestWindowScreenMotions(t *testing.T) {
438438
r := strings.NewReader(strings.Repeat("Hello, world!", 100))
439439
width, height := 16, 10
440-
window, err := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
440+
window, err := newWindow(r, "test", "test", nil, nil)
441441
if err != nil {
442442
t.Fatal(err)
443443
}
@@ -619,13 +619,7 @@ func TestWindowScreenMotions(t *testing.T) {
619619
func TestWindowDeleteBytes(t *testing.T) {
620620
r := strings.NewReader("Hello, world!")
621621
width, height := 16, 10
622-
eventCh := make(chan event.Event)
623-
go func() {
624-
for {
625-
<-eventCh
626-
}
627-
}()
628-
window, _ := newWindow(r, "test", "test", eventCh, make(chan struct{}))
622+
window, _ := newWindow(r, "test", "test", nil, nil)
629623
window.setSize(width, height)
630624

631625
window.cursorNext(mode.Normal, 7)
@@ -687,13 +681,7 @@ func TestWindowDeleteBytes(t *testing.T) {
687681
func TestWindowDeletePrevBytes(t *testing.T) {
688682
r := strings.NewReader("Hello, world!")
689683
width, height := 16, 10
690-
eventCh := make(chan event.Event)
691-
go func() {
692-
for {
693-
<-eventCh
694-
}
695-
}()
696-
window, _ := newWindow(r, "test", "test", eventCh, make(chan struct{}))
684+
window, _ := newWindow(r, "test", "test", nil, nil)
697685
window.setSize(width, height)
698686

699687
window.cursorNext(mode.Normal, 5)
@@ -728,7 +716,7 @@ func TestWindowDeletePrevBytes(t *testing.T) {
728716
func TestWindowIncrementDecrement(t *testing.T) {
729717
r := strings.NewReader("Hello, world!")
730718
width, height := 16, 10
731-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
719+
window, _ := newWindow(r, "test", "test", nil, nil)
732720
window.setSize(width, height)
733721

734722
window.increment(0)
@@ -778,7 +766,7 @@ func TestWindowIncrementDecrement(t *testing.T) {
778766
func TestWindowIncrementDecrementEmpty(t *testing.T) {
779767
r := strings.NewReader("")
780768
width, height := 16, 10
781-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
769+
window, _ := newWindow(r, "test", "test", nil, nil)
782770
window.setSize(width, height)
783771

784772
s, _ := window.state(width, height)
@@ -801,7 +789,7 @@ func TestWindowIncrementDecrementEmpty(t *testing.T) {
801789
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
802790
}
803791

804-
window, _ = newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
792+
window, _ = newWindow(r, "test", "test", nil, nil)
805793
window.setSize(width, height)
806794

807795
window.decrement(0)
@@ -820,7 +808,7 @@ func TestWindowIncrementDecrementEmpty(t *testing.T) {
820808
func TestWindowInsertByte(t *testing.T) {
821809
r := strings.NewReader("Hello, world!")
822810
width, height := 16, 1
823-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
811+
window, _ := newWindow(r, "test", "test", nil, nil)
824812
window.setSize(width, height)
825813

826814
window.cursorNext(mode.Normal, 7)
@@ -879,7 +867,7 @@ func TestWindowInsertByte(t *testing.T) {
879867
func TestWindowInsertEmpty(t *testing.T) {
880868
r := strings.NewReader("")
881869
width, height := 16, 10
882-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
870+
window, _ := newWindow(r, "test", "test", nil, nil)
883871
window.setSize(width, height)
884872

885873
window.startInsert()
@@ -915,7 +903,7 @@ func TestWindowInsertEmpty(t *testing.T) {
915903
func TestWindowInsertHead(t *testing.T) {
916904
r := strings.NewReader(strings.Repeat("Hello, world!", 2))
917905
width, height := 16, 10
918-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
906+
window, _ := newWindow(r, "test", "test", nil, nil)
919907
window.setSize(width, height)
920908

921909
window.pageEnd()
@@ -948,7 +936,7 @@ func TestWindowInsertHead(t *testing.T) {
948936
func TestWindowInsertHeadEmpty(t *testing.T) {
949937
r := strings.NewReader("")
950938
width, height := 16, 10
951-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
939+
window, _ := newWindow(r, "test", "test", nil, nil)
952940
window.setSize(width, height)
953941

954942
window.startInsertHead()
@@ -984,7 +972,7 @@ func TestWindowInsertHeadEmpty(t *testing.T) {
984972
func TestWindowAppend(t *testing.T) {
985973
r := strings.NewReader("Hello, world!")
986974
width, height := 16, 10
987-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
975+
window, _ := newWindow(r, "test", "test", nil, nil)
988976
window.setSize(width, height)
989977

990978
window.cursorNext(mode.Normal, 7)
@@ -1028,7 +1016,7 @@ func TestWindowAppend(t *testing.T) {
10281016
func TestWindowAppendEmpty(t *testing.T) {
10291017
r := strings.NewReader("")
10301018
width, height := 16, 10
1031-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
1019+
window, _ := newWindow(r, "test", "test", nil, nil)
10321020
window.setSize(width, height)
10331021

10341022
window.startAppend()
@@ -1075,7 +1063,7 @@ func TestWindowAppendEmpty(t *testing.T) {
10751063
func TestWindowReplaceByte(t *testing.T) {
10761064
r := strings.NewReader("Hello, world!")
10771065
width, height := 16, 10
1078-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
1066+
window, _ := newWindow(r, "test", "test", nil, nil)
10791067
window.setSize(width, height)
10801068

10811069
window.cursorNext(mode.Normal, 7)
@@ -1102,7 +1090,7 @@ func TestWindowReplaceByte(t *testing.T) {
11021090
func TestWindowReplaceByteEmpty(t *testing.T) {
11031091
r := strings.NewReader("")
11041092
width, height := 16, 10
1105-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
1093+
window, _ := newWindow(r, "test", "test", nil, nil)
11061094
window.setSize(width, height)
11071095

11081096
window.startReplaceByte()
@@ -1128,7 +1116,7 @@ func TestWindowReplaceByteEmpty(t *testing.T) {
11281116
func TestWindowReplace(t *testing.T) {
11291117
r := strings.NewReader("Hello, world!")
11301118
width, height := 16, 10
1131-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
1119+
window, _ := newWindow(r, "test", "test", nil, nil)
11321120
window.setSize(width, height)
11331121

11341122
window.cursorNext(mode.Normal, 10)
@@ -1175,7 +1163,7 @@ func TestWindowReplace(t *testing.T) {
11751163
func TestWindowReplaceEmpty(t *testing.T) {
11761164
r := strings.NewReader("")
11771165
width, height := 16, 10
1178-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
1166+
window, _ := newWindow(r, "test", "test", nil, nil)
11791167
window.setSize(width, height)
11801168

11811169
window.startReplace()
@@ -1204,7 +1192,7 @@ func TestWindowReplaceEmpty(t *testing.T) {
12041192
func TestWindowInsertByte2(t *testing.T) {
12051193
r := strings.NewReader("")
12061194
width, height := 16, 10
1207-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
1195+
window, _ := newWindow(r, "test", "test", nil, nil)
12081196
window.setSize(width, height)
12091197

12101198
window.startInsert()
@@ -1234,7 +1222,7 @@ func TestWindowInsertByte2(t *testing.T) {
12341222
func TestWindowBackspace(t *testing.T) {
12351223
r := strings.NewReader("Hello, world!")
12361224
width, height := 16, 10
1237-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
1225+
window, _ := newWindow(r, "test", "test", nil, nil)
12381226
window.setSize(width, height)
12391227

12401228
window.cursorNext(mode.Normal, 5)
@@ -1258,7 +1246,7 @@ func TestWindowBackspace(t *testing.T) {
12581246
func TestWindowBackspacePending(t *testing.T) {
12591247
r := strings.NewReader("Hello, world!")
12601248
width, height := 16, 10
1261-
window, _ := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
1249+
window, _ := newWindow(r, "test", "test", nil, nil)
12621250
window.setSize(width, height)
12631251

12641252
window.cursorNext(mode.Normal, 5)
@@ -1288,11 +1276,12 @@ func TestWindowBackspacePending(t *testing.T) {
12881276
func TestWindowEventRune(t *testing.T) {
12891277
width, height := 16, 10
12901278
redrawCh := make(chan struct{})
1291-
window, _ := newWindow(strings.NewReader(""), "test", "test", make(chan event.Event), redrawCh)
1279+
window, _ := newWindow(strings.NewReader(""), "test", "test", nil, redrawCh)
12921280
window.setSize(width, height)
12931281

12941282
str := "48723fffab"
12951283
go func() {
1284+
defer close(redrawCh)
12961285
window.emit(event.Event{Type: event.StartInsert})
12971286
for _, r := range str {
12981287
window.emit(event.Event{Type: event.Rune, Rune: r, Mode: mode.Insert})
@@ -1306,16 +1295,18 @@ func TestWindowEventRune(t *testing.T) {
13061295
if expected := "\x48\x72\x3f\xff\xab\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
13071296
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
13081297
}
1298+
<-redrawCh
13091299
}
13101300

13111301
func TestWindowEventRuneText(t *testing.T) {
13121302
width, height := 16, 10
13131303
redrawCh := make(chan struct{})
1314-
window, _ := newWindow(strings.NewReader(""), "test", "test", make(chan event.Event), redrawCh)
1304+
window, _ := newWindow(strings.NewReader(""), "test", "test", nil, redrawCh)
13151305
window.setSize(width, height)
13161306

13171307
str := "Hello, World!\nこんにちは、世界!\n鰰は魚の一種"
13181308
go func() {
1309+
defer close(redrawCh)
13191310
window.emit(event.Event{Type: event.SwitchFocus})
13201311
window.emit(event.Event{Type: event.StartInsert})
13211312
for _, r := range str {
@@ -1331,25 +1322,24 @@ func TestWindowEventRuneText(t *testing.T) {
13311322
if expected := str + "\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
13321323
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
13331324
}
1325+
<-redrawCh
13341326
}
13351327

13361328
func TestWindowEventUndoRedo(t *testing.T) {
13371329
width, height := 16, 10
13381330
redrawCh := make(chan struct{})
1339-
window, _ := newWindow(strings.NewReader("Hello, world!"), "test", "test", make(chan event.Event), redrawCh)
1331+
window, _ := newWindow(strings.NewReader("Hello, world!"), "test", "test", nil, redrawCh)
13401332
window.setSize(width, height)
13411333
waitCh := make(chan struct{})
1342-
defer func() {
1343-
close(waitCh)
1344-
close(redrawCh)
1345-
}()
13461334

13471335
waitRedraw := func(count int) {
13481336
for range count {
13491337
<-redrawCh
13501338
}
13511339
}
13521340
go func() {
1341+
defer close(redrawCh)
1342+
defer close(waitCh)
13531343
window.emit(event.Event{Type: event.Undo})
13541344
window.emit(event.Event{Type: event.SwitchFocus})
13551345
window.emit(event.Event{Type: event.StartAppend, Mode: mode.Insert})
@@ -1439,11 +1429,12 @@ func TestWindowEventUndoRedo(t *testing.T) {
14391429
if expected := int64(4); s.Cursor != expected {
14401430
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
14411431
}
1432+
<-redrawCh
14421433
}
14431434

14441435
func TestWindowWriteTo(t *testing.T) {
14451436
r := strings.NewReader("Hello, world!")
1446-
window, err := newWindow(r, "test", "test", make(chan event.Event), make(chan struct{}))
1437+
window, err := newWindow(r, "test", "test", nil, nil)
14471438
if err != nil {
14481439
t.Fatal(err)
14491440
}

0 commit comments

Comments
 (0)
Please sign in to comment.