diff --git a/nvim/nvim_test.go b/nvim/nvim_test.go index 3cdc3d2b..043b3c63 100644 --- a/nvim/nvim_test.go +++ b/nvim/nvim_test.go @@ -1,11 +1,13 @@ package nvim import ( + "bytes" "errors" "fmt" "log" "reflect" "strings" + "sync/atomic" "testing" "time" ) @@ -379,6 +381,115 @@ func TestAPI(t *testing.T) { t.Errorf("HLByID(id, true)\n got %+v,\nwant %+v", hl, gui) } }) + + t.Run("buf_attach", func(t *testing.T) { + buffer, err := v.CurrentBuffer() + if err != nil { + t.Fatal(err) + } + + // clear curret buffer text + if err := v.SetBufferLines(buffer, 0, -1, true, bytes.Fields(nil)); err != nil { + t.Fatal(err) + } + + type ChangedtickEvent struct { + Buffer Buffer + Changetick int64 + } + type BufLinesEvent struct { + Buffer Buffer + Changetick int64 + FirstLine int64 + LastLine int64 + LineData string + IsMultipart bool + } + + changedtickChan := make(chan *ChangedtickEvent) + v.RegisterHandler("nvim_buf_changedtick_event", func(changedtickEvent ...interface{}) { + ev := &ChangedtickEvent{ + Buffer: changedtickEvent[0].(Buffer), + Changetick: changedtickEvent[1].(int64), + } + changedtickChan <- ev + }) + + bufLinesChan := make(chan *BufLinesEvent) + v.RegisterHandler("nvim_buf_lines_event", func(bufLinesEvent ...interface{}) { + ev := &BufLinesEvent{ + Buffer: bufLinesEvent[0].(Buffer), + Changetick: bufLinesEvent[1].(int64), + FirstLine: bufLinesEvent[2].(int64), + LastLine: bufLinesEvent[3].(int64), + LineData: fmt.Sprint(bufLinesEvent[4]), + IsMultipart: bufLinesEvent[5].(bool), + } + bufLinesChan <- ev + }) + + ok, err := v.AttachBuffer(buffer, false, make(map[string]interface{})) + if err != nil { + t.Fatal(err) + } + if !ok { + t.Fatal(errors.New("could not attach buffer")) + } + + changedtickExpected := &ChangedtickEvent{ + Buffer: 1, + Changetick: 4, + } + bufLinesEventExpected := &BufLinesEvent{ + Buffer: 1, + Changetick: 5, + FirstLine: 0, + LastLine: 1, + LineData: "[test]", + IsMultipart: false, + } + + var numEvent int64 // add and load should be atomically + errc := make(chan error) + done := make(chan struct{}) + go func() { + for { + select { + default: + if atomic.LoadInt64(&numEvent) == 2 { // end buf_attach test when handle 2 event + done <- struct{}{} + return + } + case changedtick := <-changedtickChan: + if !reflect.DeepEqual(changedtick, changedtickExpected) { + errc <- fmt.Errorf("changedtick = %+v, want %+v", changedtick, changedtickExpected) + } + atomic.AddInt64(&numEvent, 1) + case bufLines := <-bufLinesChan: + if expected := bufLinesEventExpected; !reflect.DeepEqual(bufLines, expected) { + errc <- fmt.Errorf("bufLines = %+v, want %+v", bufLines, expected) + } + atomic.AddInt64(&numEvent, 1) + } + } + }() + + go func() { + <-done + close(errc) + }() + + test := []byte("test") + if err := v.SetBufferLines(buffer, 0, -1, true, bytes.Fields(test)); err != nil { + t.Fatal(err) + } + + for err := range errc { + if err != nil { + t.Fatal(err) + } + } + }) } func TestDial(t *testing.T) {