Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 17 additions & 26 deletions internal/error_accumulator_test.go
Original file line number Diff line number Diff line change
@@ -1,41 +1,32 @@
package openai_test

import (
"bytes"
"errors"
"testing"

utils "github.com/sashabaranov/go-openai/internal"
"github.com/sashabaranov/go-openai/internal/test"
openai "github.com/sashabaranov/go-openai/internal"
"github.com/sashabaranov/go-openai/internal/test/checks"
)

func TestErrorAccumulatorBytes(t *testing.T) {
accumulator := &utils.DefaultErrorAccumulator{
Buffer: &bytes.Buffer{},
func TestDefaultErrorAccumulator_WriteMultiple(t *testing.T) {
ea, ok := openai.NewErrorAccumulator().(*openai.DefaultErrorAccumulator)
if !ok {
t.Fatal("type assertion to *DefaultErrorAccumulator failed")
}
checks.NoError(t, ea.Write([]byte("{\"error\": \"test1\"}")))
checks.NoError(t, ea.Write([]byte("{\"error\": \"test2\"}")))

errBytes := accumulator.Bytes()
if len(errBytes) != 0 {
t.Fatalf("Did not return nil with empty bytes: %s", string(errBytes))
}

err := accumulator.Write([]byte("{}"))
if err != nil {
t.Fatalf("%+v", err)
}

errBytes = accumulator.Bytes()
if len(errBytes) == 0 {
t.Fatalf("Did not return error bytes when has error: %s", string(errBytes))
expected := "{\"error\": \"test1\"}{\"error\": \"test2\"}"
if string(ea.Bytes()) != expected {
t.Fatalf("Expected %q, got %q", expected, ea.Bytes())
}
}

func TestErrorByteWriteErrors(t *testing.T) {
accumulator := &utils.DefaultErrorAccumulator{
Buffer: &test.FailingErrorBuffer{},
func TestDefaultErrorAccumulator_EmptyBuffer(t *testing.T) {
ea, ok := openai.NewErrorAccumulator().(*openai.DefaultErrorAccumulator)
if !ok {
t.Fatal("type assertion to *DefaultErrorAccumulator failed")
}
err := accumulator.Write([]byte("{"))
if !errors.Is(err, test.ErrTestErrorAccumulatorWriteFailed) {
t.Fatalf("Did not return error when write failed: %v", err)
if len(ea.Bytes()) != 0 {
t.Fatal("Buffer should be empty initially")
}
}
3 changes: 3 additions & 0 deletions internal/form_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ func (fb *DefaultFormBuilder) createFormFile(fieldname string, r io.Reader, file
}

func (fb *DefaultFormBuilder) WriteField(fieldname, value string) error {
if fieldname == "" {
return fmt.Errorf("fieldname cannot be empty")
}
return fb.writer.WriteField(fieldname, value)
}

Expand Down
73 changes: 72 additions & 1 deletion internal/form_builder_test.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,57 @@
package openai //nolint:testpackage // testing private field

import (
"errors"
"io"

"github.com/sashabaranov/go-openai/internal/test/checks"

"bytes"
"errors"
"os"
"testing"
)

type mockFormBuilder struct {
mockCreateFormFile func(string, *os.File) error
mockWriteField func(string, string) error
mockClose func() error
}

func (m *mockFormBuilder) CreateFormFile(fieldname string, file *os.File) error {
return m.mockCreateFormFile(fieldname, file)
}

func (m *mockFormBuilder) WriteField(fieldname, value string) error {
return m.mockWriteField(fieldname, value)
}

func (m *mockFormBuilder) Close() error {
return m.mockClose()
}

func (m *mockFormBuilder) FormDataContentType() string {
return ""
}

func TestCloseMethod(t *testing.T) {
t.Run("NormalClose", func(t *testing.T) {
body := &bytes.Buffer{}
builder := NewFormBuilder(body)
checks.NoError(t, builder.Close(), "正常关闭应成功")
})

t.Run("ErrorPropagation", func(t *testing.T) {
errorMock := errors.New("mock close error")
mockBuilder := &mockFormBuilder{
mockClose: func() error {
return errorMock
},
}
err := mockBuilder.Close()
checks.ErrorIs(t, err, errorMock, "应传递关闭错误")
})
}

type failingWriter struct {
}

Expand Down Expand Up @@ -90,3 +131,33 @@ func TestFormBuilderWithReader(t *testing.T) {
err = builder.CreateFormFileReader("file", rnc, "")
checks.NoError(t, err, "formbuilder should not return error")
}

func TestFormDataContentType(t *testing.T) {
t.Run("ReturnsUnderlyingWriterContentType", func(t *testing.T) {
buf := &bytes.Buffer{}
builder := NewFormBuilder(buf)

contentType := builder.FormDataContentType()
if contentType == "" {
t.Errorf("expected non-empty content type, got empty string")
}
})
}

func TestWriteField(t *testing.T) {
t.Run("EmptyFieldNameShouldReturnError", func(t *testing.T) {
buf := &bytes.Buffer{}
builder := NewFormBuilder(buf)

err := builder.WriteField("", "some value")
checks.HasError(t, err, "fieldname is required")
})

t.Run("ValidFieldNameShouldSucceed", func(t *testing.T) {
buf := &bytes.Buffer{}
builder := NewFormBuilder(buf)

err := builder.WriteField("key", "value")
checks.NoError(t, err, "should write field without error")
})
}
34 changes: 34 additions & 0 deletions internal/marshaller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package openai_test

import (
"testing"

openai "github.com/sashabaranov/go-openai/internal"
"github.com/sashabaranov/go-openai/internal/test/checks"
)

func TestJSONMarshaller_Normal(t *testing.T) {
jm := &openai.JSONMarshaller{}
data := map[string]string{"key": "value"}

b, err := jm.Marshal(data)
checks.NoError(t, err)
if len(b) == 0 {
t.Fatal("should return non-empty bytes")
}
}

func TestJSONMarshaller_InvalidInput(t *testing.T) {
jm := &openai.JSONMarshaller{}
_, err := jm.Marshal(make(chan int))
checks.HasError(t, err, "should return error for unsupported type")
}

func TestJSONMarshaller_EmptyValue(t *testing.T) {
jm := &openai.JSONMarshaller{}
b, err := jm.Marshal(nil)
checks.NoError(t, err)
if string(b) != "null" {
t.Fatalf("unexpected marshaled value: %s", string(b))
}
}
37 changes: 37 additions & 0 deletions internal/unmarshaler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package openai_test

import (
"testing"

openai "github.com/sashabaranov/go-openai/internal"
"github.com/sashabaranov/go-openai/internal/test/checks"
)

func TestJSONUnmarshaler_Normal(t *testing.T) {
jm := &openai.JSONUnmarshaler{}
data := []byte(`{"key":"value"}`)
var v map[string]string

err := jm.Unmarshal(data, &v)
checks.NoError(t, err)
if v["key"] != "value" {
t.Fatal("unmarshal result mismatch")
}
}

func TestJSONUnmarshaler_InvalidJSON(t *testing.T) {
jm := &openai.JSONUnmarshaler{}
data := []byte(`{invalid}`)
var v map[string]interface{}

err := jm.Unmarshal(data, &v)
checks.HasError(t, err, "should return error for invalid JSON")
}

func TestJSONUnmarshaler_EmptyInput(t *testing.T) {
jm := &openai.JSONUnmarshaler{}
var v interface{}

err := jm.Unmarshal(nil, &v)
checks.HasError(t, err, "should return error for nil input")
}
Loading