kittenipc/kitcom/internal/tsgo/lsp/lsproto/baseproto_test.go
2025-10-15 10:12:44 +03:00

152 lines
3.1 KiB
Go

package lsproto_test
import (
"bytes"
"errors"
"testing"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/lsp/lsproto"
"gotest.tools/v3/assert"
)
func TestBaseReader(t *testing.T) {
t.Parallel()
tests := []struct {
name string
input []byte
value []byte
err string
}{
{
name: "empty",
input: []byte("Content-Length: 0\r\n\r\n"),
err: "lsp: no content length",
},
{
name: "early end",
input: []byte("oops"),
err: "EOF",
},
{
name: "negative length",
input: []byte("Content-Length: -1\r\n\r\n"),
err: "lsp: invalid content length: negative value -1",
},
{
name: "invalid content",
input: []byte("Content-Length: 1\r\n\r\n{"),
value: []byte("{"),
},
{
name: "valid content",
input: []byte("Content-Length: 2\r\n\r\n{}"),
value: []byte("{}"),
},
{
name: "extra header values",
input: []byte("Content-Length: 2\r\nExtra: 1\r\n\r\n{}"),
value: []byte("{}"),
},
{
name: "too long content length",
input: []byte("Content-Length: 100\r\n\r\n{}"),
err: "lsp: read content: unexpected EOF",
},
{
name: "missing content length",
input: []byte("Content-Length: \r\n\r\n{}"),
err: "lsp: invalid content length: parse error: strconv.ParseInt: parsing \"\": invalid syntax",
},
{
name: "invalid header",
input: []byte("Nope\r\n\r\n{}"),
err: "lsp: invalid header: \"Nope\\r\\n\"",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
r := lsproto.NewBaseReader(bytes.NewReader(tt.input))
out, err := r.Read()
if tt.err != "" {
assert.Error(t, err, tt.err)
}
assert.DeepEqual(t, out, tt.value)
})
}
}
func TestBaseReaderMultipleReads(t *testing.T) {
t.Parallel()
data := []byte(
"Content-Length: 4\r\n\r\n1234" +
"Content-Length: 2\r\n\r\n{}",
)
r := lsproto.NewBaseReader(bytes.NewReader(data))
v1, err := r.Read()
assert.NilError(t, err)
assert.DeepEqual(t, v1, []byte("1234"))
v2, err := r.Read()
assert.NilError(t, err)
assert.DeepEqual(t, v2, []byte("{}"))
_, err = r.Read()
assert.Error(t, err, "EOF")
}
type errorReader struct{}
func (*errorReader) Read([]byte) (int, error) {
return 0, errors.New("test error")
}
func TestBaseWriter(t *testing.T) {
t.Parallel()
tests := []struct {
name string
value []byte
input []byte
}{
{
name: "empty",
value: []byte("{}"),
input: []byte("Content-Length: 2\r\n\r\n{}"),
},
{
name: "bigger object",
value: []byte("{\"key\":\"value\"}"),
input: []byte("Content-Length: 15\r\n\r\n{\"key\":\"value\"}"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
var b bytes.Buffer
w := lsproto.NewBaseWriter(&b)
err := w.Write(tt.value)
assert.NilError(t, err)
assert.DeepEqual(t, b.Bytes(), tt.input)
})
}
}
func TestBaseWriterWriteError(t *testing.T) {
t.Parallel()
w := lsproto.NewBaseWriter(&errorWriter{})
err := w.Write([]byte("{}"))
assert.Error(t, err, "test error")
}
type errorWriter struct{}
func (*errorWriter) Write([]byte) (int, error) {
return 0, errors.New("test error")
}