package api import ( "encoding/json" "errors" "math" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestKeepAliveParsingFromJSON(t *testing.T) { tests := []struct { name string req string exp *Duration }{ { name: "Positive Integer", req: `{ "keep_alive": 42 }`, exp: &Duration{42 * time.Second}, }, { name: "Positive Float", req: `{ "keep_alive": 42.5 }`, exp: &Duration{42 * time.Second}, }, { name: "Positive Integer String", req: `{ "keep_alive": "42m" }`, exp: &Duration{42 * time.Minute}, }, { name: "Negative Integer", req: `{ "keep_alive": -1 }`, exp: &Duration{math.MaxInt64}, }, { name: "Negative Float", req: `{ "keep_alive": -3.14 }`, exp: &Duration{math.MaxInt64}, }, { name: "Negative Integer String", req: `{ "keep_alive": "-1m" }`, exp: &Duration{math.MaxInt64}, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { var dec ChatRequest err := json.Unmarshal([]byte(test.req), &dec) require.NoError(t, err) assert.Equal(t, test.exp, dec.KeepAlive) }) } } func TestDurationMarshalUnmarshal(t *testing.T) { tests := []struct { name string input time.Duration expected time.Duration }{ { "negative duration", time.Duration(-1), time.Duration(math.MaxInt64), }, { "positive duration", 42 * time.Second, 42 * time.Second, }, { "another positive duration", 42 * time.Minute, 42 * time.Minute, }, { "zero duration", time.Duration(0), time.Duration(0), }, { "max duration", time.Duration(math.MaxInt64), time.Duration(math.MaxInt64), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { b, err := json.Marshal(Duration{test.input}) require.NoError(t, err) var d Duration err = json.Unmarshal(b, &d) require.NoError(t, err) assert.Equal(t, test.expected, d.Duration, "input %v, marshalled %v, got %v", test.input, string(b), d.Duration) }) } } func TestUseMmapParsingFromJSON(t *testing.T) { tr := true fa := false tests := []struct { name string req string exp *bool }{ { name: "Undefined", req: `{ }`, exp: nil, }, { name: "True", req: `{ "use_mmap": true }`, exp: &tr, }, { name: "False", req: `{ "use_mmap": false }`, exp: &fa, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { var oMap map[string]any err := json.Unmarshal([]byte(test.req), &oMap) require.NoError(t, err) opts := DefaultOptions() err = opts.FromMap(oMap) require.NoError(t, err) assert.Equal(t, test.exp, opts.UseMMap) }) } } func TestUseMmapFormatParams(t *testing.T) { tr := true fa := false tests := []struct { name string req map[string][]string exp *bool err error }{ { name: "True", req: map[string][]string{ "use_mmap": {"true"}, }, exp: &tr, err: nil, }, { name: "False", req: map[string][]string{ "use_mmap": {"false"}, }, exp: &fa, err: nil, }, { name: "Numeric True", req: map[string][]string{ "use_mmap": {"1"}, }, exp: &tr, err: nil, }, { name: "Numeric False", req: map[string][]string{ "use_mmap": {"0"}, }, exp: &fa, err: nil, }, { name: "invalid string", req: map[string][]string{ "use_mmap": {"foo"}, }, exp: nil, err: errors.New("invalid bool value [foo]"), }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { resp, err := FormatParams(test.req) require.Equal(t, test.err, err) respVal, ok := resp["use_mmap"] if test.exp != nil { assert.True(t, ok, "resp: %v", resp) assert.Equal(t, *test.exp, *respVal.(*bool)) } }) } } func TestMessage_UnmarshalJSON(t *testing.T) { tests := []struct { input string expected string }{ {`{"role": "USER", "content": "Hello!"}`, "user"}, {`{"role": "System", "content": "Initialization complete."}`, "system"}, {`{"role": "assistant", "content": "How can I help you?"}`, "assistant"}, {`{"role": "TOOl", "content": "Access granted."}`, "tool"}, } for _, test := range tests { var msg Message if err := json.Unmarshal([]byte(test.input), &msg); err != nil { t.Errorf("Unexpected error: %v", err) } if msg.Role != test.expected { t.Errorf("role not lowercased: got %v, expected %v", msg.Role, test.expected) } } } func TestToolFunction_UnmarshalJSON(t *testing.T) { tests := []struct { name string input string wantErr string }{ { name: "valid enum with same types", input: `{ "name": "test", "description": "test function", "parameters": { "type": "object", "required": ["test"], "properties": { "test": { "type": "string", "description": "test prop", "enum": ["a", "b", "c"] } } } }`, wantErr: "", }, { name: "empty enum array", input: `{ "name": "test", "description": "test function", "parameters": { "type": "object", "required": ["test"], "properties": { "test": { "type": "string", "description": "test prop", "enum": [] } } } }`, wantErr: "", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var tf ToolFunction err := json.Unmarshal([]byte(tt.input), &tf) if tt.wantErr != "" { require.Error(t, err) assert.Contains(t, err.Error(), tt.wantErr) } else { require.NoError(t, err) } }) } } func TestPropertyType_UnmarshalJSON(t *testing.T) { tests := []struct { name string input string expected PropertyType }{ { name: "string type", input: `"string"`, expected: PropertyType{"string"}, }, { name: "array of types", input: `["string", "number"]`, expected: PropertyType{"string", "number"}, }, { name: "array with single type", input: `["string"]`, expected: PropertyType{"string"}, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { var pt PropertyType if err := json.Unmarshal([]byte(test.input), &pt); err != nil { t.Errorf("Unexpected error: %v", err) } if len(pt) != len(test.expected) { t.Errorf("Length mismatch: got %v, expected %v", len(pt), len(test.expected)) } for i, v := range pt { if v != test.expected[i] { t.Errorf("Value mismatch at index %d: got %v, expected %v", i, v, test.expected[i]) } } }) } } func TestPropertyType_MarshalJSON(t *testing.T) { tests := []struct { name string input PropertyType expected string }{ { name: "single type", input: PropertyType{"string"}, expected: `"string"`, }, { name: "multiple types", input: PropertyType{"string", "number"}, expected: `["string","number"]`, }, { name: "empty type", input: PropertyType{}, expected: `[]`, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { data, err := json.Marshal(test.input) if err != nil { t.Errorf("Unexpected error: %v", err) } if string(data) != test.expected { t.Errorf("Marshaled data mismatch: got %v, expected %v", string(data), test.expected) } }) } }