106 lines
3.4 KiB
Go
106 lines
3.4 KiB
Go
package managedruntime
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
)
|
|
|
|
type memorySettings struct {
|
|
values map[string][]byte
|
|
err error
|
|
}
|
|
|
|
func (s *memorySettings) Get(_ context.Context, key string) ([]byte, bool, error) {
|
|
if s.err != nil {
|
|
return nil, false, s.err
|
|
}
|
|
value, ok := s.values[key]
|
|
return append([]byte(nil), value...), ok, nil
|
|
}
|
|
|
|
func (s *memorySettings) Save(_ context.Context, key string, value []byte) error {
|
|
if s.err != nil {
|
|
return s.err
|
|
}
|
|
if s.values == nil {
|
|
s.values = make(map[string][]byte)
|
|
}
|
|
s.values[key] = append([]byte(nil), value...)
|
|
return nil
|
|
}
|
|
|
|
func (s *memorySettings) Delete(_ context.Context, key string) error {
|
|
if s.err != nil {
|
|
return s.err
|
|
}
|
|
delete(s.values, key)
|
|
return nil
|
|
}
|
|
|
|
func TestStoreRoundTripAndPerAgentIsolation(t *testing.T) {
|
|
settings := &memorySettings{}
|
|
store := NewStore(settings)
|
|
ctx := context.Background()
|
|
|
|
if _, found, err := store.Get(ctx, "opencode-acp", "opencode-ai"); err != nil || found {
|
|
t.Fatalf("missing selection = found %v, err %v", found, err)
|
|
}
|
|
if err := store.Save(ctx, "opencode-acp", "opencode-ai", "1.18.5"); err != nil {
|
|
t.Fatalf("save opencode: %v", err)
|
|
}
|
|
if err := store.Save(ctx, "claude-acp", "@example/claude", "2.0.0"); err != nil {
|
|
t.Fatalf("save claude: %v", err)
|
|
}
|
|
|
|
got, found, err := store.Get(ctx, "opencode-acp", "opencode-ai")
|
|
if err != nil || !found || got.Package != "opencode-ai" || got.Version != "1.18.5" {
|
|
t.Fatalf("opencode selection = %#v, found %v, err %v", got, found, err)
|
|
}
|
|
got, found, err = store.Get(ctx, "claude-acp", "@example/claude")
|
|
if err != nil || !found || got.Version != "2.0.0" {
|
|
t.Fatalf("claude selection = %#v, found %v, err %v", got, found, err)
|
|
}
|
|
}
|
|
|
|
func TestStoreRejectsInvalidStoredValueAndPackageMismatch(t *testing.T) {
|
|
settings := &memorySettings{values: map[string][]byte{
|
|
selectionKey("opencode-acp"): []byte(`{"package":"opencode-ai","version":"latest"}`),
|
|
selectionKey("claude-acp"): []byte(`{"package":"old-claude","version":"1.0.0"}`),
|
|
}}
|
|
store := NewStore(settings)
|
|
|
|
if _, _, err := store.Get(context.Background(), "opencode-acp", "opencode-ai"); !errors.Is(err, ErrInvalidSelection) {
|
|
t.Fatalf("invalid stored selection error = %v, want %v", err, ErrInvalidSelection)
|
|
}
|
|
if _, found, err := store.Get(context.Background(), "claude-acp", "@example/claude"); err != nil || found {
|
|
t.Fatalf("package mismatch = found %v, err %v; want no selection", found, err)
|
|
}
|
|
}
|
|
|
|
func TestStorePropagatesSettingsErrors(t *testing.T) {
|
|
wantErr := errors.New("settings unavailable")
|
|
store := NewStore(&memorySettings{err: wantErr})
|
|
if _, _, err := store.Get(context.Background(), "opencode-acp", "opencode-ai"); !errors.Is(err, wantErr) {
|
|
t.Fatalf("get error = %v, want %v", err, wantErr)
|
|
}
|
|
if err := store.Save(context.Background(), "opencode-acp", "opencode-ai", "1.18.5"); !errors.Is(err, wantErr) {
|
|
t.Fatalf("save error = %v, want %v", err, wantErr)
|
|
}
|
|
}
|
|
|
|
func TestStoreDeleteRemovesSelection(t *testing.T) {
|
|
settings := &memorySettings{}
|
|
store := NewStore(settings)
|
|
ctx := context.Background()
|
|
if err := store.Save(ctx, "opencode-acp", "opencode-ai", "1.18.5"); err != nil {
|
|
t.Fatalf("save selection: %v", err)
|
|
}
|
|
if err := store.Delete(ctx, "opencode-acp", "opencode-ai"); err != nil {
|
|
t.Fatalf("delete selection: %v", err)
|
|
}
|
|
if _, found, err := store.Get(ctx, "opencode-acp", "opencode-ai"); err != nil || found {
|
|
t.Fatalf("selection after delete = found %v, err %v; want absent", found, err)
|
|
}
|
|
}
|