Add comprehensive test suite for v2 module with mock provider
All checks were successful
CI / Lint (push) Successful in 9m36s
CI / V2 Module (push) Successful in 11m33s
CI / Root Module (push) Successful in 11m35s

Cover all core library logic (Client, Model, Chat, middleware, streaming,
message conversion, request building) using a configurable mock provider
that avoids real API calls. ~50 tests across 7 files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-07 22:00:49 -05:00
parent cbe340ced0
commit 6a7eeef619
7 changed files with 1678 additions and 0 deletions

87
v2/mock_provider_test.go Normal file
View File

@@ -0,0 +1,87 @@
package llm
import (
"context"
"sync"
"gitea.stevedudenhoeffer.com/steve/go-llm/v2/provider"
)
// mockProvider is a configurable mock implementation of provider.Provider for testing.
type mockProvider struct {
CompleteFunc func(ctx context.Context, req provider.Request) (provider.Response, error)
StreamFunc func(ctx context.Context, req provider.Request, events chan<- provider.StreamEvent) error
// mu guards Requests
mu sync.Mutex
Requests []provider.Request
}
func (m *mockProvider) Complete(ctx context.Context, req provider.Request) (provider.Response, error) {
m.mu.Lock()
m.Requests = append(m.Requests, req)
m.mu.Unlock()
return m.CompleteFunc(ctx, req)
}
func (m *mockProvider) Stream(ctx context.Context, req provider.Request, events chan<- provider.StreamEvent) error {
m.mu.Lock()
m.Requests = append(m.Requests, req)
m.mu.Unlock()
if m.StreamFunc != nil {
return m.StreamFunc(ctx, req, events)
}
close(events)
return nil
}
// lastRequest returns the most recent request recorded by the mock.
func (m *mockProvider) lastRequest() provider.Request {
m.mu.Lock()
defer m.mu.Unlock()
if len(m.Requests) == 0 {
return provider.Request{}
}
return m.Requests[len(m.Requests)-1]
}
// newMockProvider creates a mock that always returns the given response.
func newMockProvider(resp provider.Response) *mockProvider {
return &mockProvider{
CompleteFunc: func(ctx context.Context, req provider.Request) (provider.Response, error) {
return resp, nil
},
}
}
// newMockProviderFunc creates a mock with a custom Complete function.
func newMockProviderFunc(fn func(ctx context.Context, req provider.Request) (provider.Response, error)) *mockProvider {
return &mockProvider{CompleteFunc: fn}
}
// newMockStreamProvider creates a mock that streams the given events.
func newMockStreamProvider(events []provider.StreamEvent) *mockProvider {
return &mockProvider{
CompleteFunc: func(ctx context.Context, req provider.Request) (provider.Response, error) {
return provider.Response{}, nil
},
StreamFunc: func(ctx context.Context, req provider.Request, ch chan<- provider.StreamEvent) error {
for _, ev := range events {
select {
case ch <- ev:
case <-ctx.Done():
return ctx.Err()
}
}
return nil
},
}
}
// newMockModel creates a *Model backed by the given mock provider.
func newMockModel(p *mockProvider) *Model {
return &Model{
provider: p,
model: "mock-model",
}
}