sub2api/backend/internal/pkg/windsurf/lspool_log_test.go

61 lines
1.5 KiB
Go

package windsurf
import (
"bytes"
"log/slog"
"strings"
"sync"
"testing"
"time"
)
// TestScanLSOutputEmitsLines checks that scanLSOutput forwards each non-empty
// line (with \r stripped) to slog and exits on EOF without leaking goroutines.
func TestScanLSOutputEmitsLines(t *testing.T) {
prev := slog.Default()
defer slog.SetDefault(prev)
var buf bytes.Buffer
var mu sync.Mutex
slog.SetDefault(slog.New(slog.NewTextHandler(&lockedWriter{b: &buf, mu: &mu}, &slog.HandlerOptions{Level: slog.LevelDebug})))
input := "line one\r\nline two\n\nline three\n"
done := make(chan struct{})
go func() {
scanLSOutput(strings.NewReader(input), "test-key", 4242, "stdout")
close(done)
}()
select {
case <-done:
case <-time.After(2 * time.Second):
t.Fatal("scanLSOutput did not return within 2s after EOF")
}
mu.Lock()
out := buf.String()
mu.Unlock()
for _, want := range []string{"line one", "line two", "line three", "test-key", "stdout", "pid=4242"} {
if !strings.Contains(out, want) {
t.Errorf("expected log output to contain %q, got:\n%s", want, out)
}
}
if strings.Count(out, "windsurf_ls_output") != 3 {
t.Errorf("expected 3 log entries (empty line skipped), got:\n%s", out)
}
}
// lockedWriter serializes slog handler writes so the test can read the buffer
// safely from the test goroutine.
type lockedWriter struct {
b *bytes.Buffer
mu *sync.Mutex
}
func (w *lockedWriter) Write(p []byte) (int, error) {
w.mu.Lock()
defer w.mu.Unlock()
return w.b.Write(p)
}