gomcp/internal/infrastructure/sqlite/crystal_repo_test.go

160 lines
4.2 KiB
Go

package sqlite
import (
"context"
"testing"
"github.com/syntrex-lab/gomcp/internal/domain/crystal"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func newTestCrystalRepo(t *testing.T) *CrystalRepo {
t.Helper()
db, err := OpenMemory()
require.NoError(t, err)
t.Cleanup(func() { db.Close() })
repo, err := NewCrystalRepo(db)
require.NoError(t, err)
return repo
}
func makeCrystal(path, name string) *crystal.Crystal {
return &crystal.Crystal{
Path: path,
Name: name,
TokenCount: 150,
ContentHash: "hash123",
PrimitivesCount: 2,
Primitives: []crystal.Primitive{
{PType: "function", Name: "main", Value: "func main()", SourceLine: 1, Confidence: 1.0},
{PType: "function", Name: "init", Value: "func init()", SourceLine: 5, Confidence: 0.9},
},
IndexedAt: 1700000000.0,
SourceMtime: 1699999000.0,
SourceHash: "src_hash",
}
}
func TestCrystalRepo_Upsert_Get(t *testing.T) {
repo := newTestCrystalRepo(t)
ctx := context.Background()
c := makeCrystal("cmd/main.go", "main.go")
require.NoError(t, repo.Upsert(ctx, c))
got, err := repo.Get(ctx, "cmd/main.go")
require.NoError(t, err)
require.NotNil(t, got)
assert.Equal(t, "cmd/main.go", got.Path)
assert.Equal(t, "main.go", got.Name)
assert.Equal(t, 150, got.TokenCount)
assert.Equal(t, 2, got.PrimitivesCount)
assert.Len(t, got.Primitives, 2)
assert.Equal(t, "function", got.Primitives[0].PType)
}
func TestCrystalRepo_Upsert_Overwrite(t *testing.T) {
repo := newTestCrystalRepo(t)
ctx := context.Background()
c := makeCrystal("main.go", "main.go")
require.NoError(t, repo.Upsert(ctx, c))
c.TokenCount = 300
c.PrimitivesCount = 5
require.NoError(t, repo.Upsert(ctx, c))
got, err := repo.Get(ctx, "main.go")
require.NoError(t, err)
assert.Equal(t, 300, got.TokenCount)
assert.Equal(t, 5, got.PrimitivesCount)
}
func TestCrystalRepo_Get_NotFound(t *testing.T) {
repo := newTestCrystalRepo(t)
ctx := context.Background()
got, err := repo.Get(ctx, "nonexistent.go")
assert.Error(t, err)
assert.Nil(t, got)
}
func TestCrystalRepo_Delete(t *testing.T) {
repo := newTestCrystalRepo(t)
ctx := context.Background()
c := makeCrystal("delete_me.go", "delete_me.go")
require.NoError(t, repo.Upsert(ctx, c))
require.NoError(t, repo.Delete(ctx, "delete_me.go"))
got, err := repo.Get(ctx, "delete_me.go")
assert.Error(t, err)
assert.Nil(t, got)
}
func TestCrystalRepo_List(t *testing.T) {
repo := newTestCrystalRepo(t)
ctx := context.Background()
for _, p := range []string{"cmd/main.go", "internal/foo.go", "internal/bar.go", "README.md"} {
require.NoError(t, repo.Upsert(ctx, makeCrystal(p, p)))
}
// List all
all, err := repo.List(ctx, "", 100)
require.NoError(t, err)
assert.Len(t, all, 4)
// List with pattern
internal, err := repo.List(ctx, "internal%", 100)
require.NoError(t, err)
assert.Len(t, internal, 2)
}
func TestCrystalRepo_Search(t *testing.T) {
repo := newTestCrystalRepo(t)
ctx := context.Background()
c1 := makeCrystal("server.go", "server.go")
c1.Primitives = []crystal.Primitive{
{PType: "function", Name: "handleRequest", Value: "func handleRequest()", SourceLine: 10, Confidence: 1.0},
}
c2 := makeCrystal("client.go", "client.go")
c2.Primitives = []crystal.Primitive{
{PType: "function", Name: "sendRequest", Value: "func sendRequest()", SourceLine: 5, Confidence: 1.0},
}
c3 := makeCrystal("utils.go", "utils.go")
c3.Primitives = []crystal.Primitive{
{PType: "function", Name: "helper", Value: "func helper()", SourceLine: 1, Confidence: 1.0},
}
for _, c := range []*crystal.Crystal{c1, c2, c3} {
require.NoError(t, repo.Upsert(ctx, c))
}
results, err := repo.Search(ctx, "Request", 10)
require.NoError(t, err)
assert.Len(t, results, 2)
}
func TestCrystalRepo_Stats(t *testing.T) {
repo := newTestCrystalRepo(t)
ctx := context.Background()
c1 := makeCrystal("main.go", "main.go")
c1.TokenCount = 100
c2 := makeCrystal("server.py", "server.py")
c2.TokenCount = 200
c2.PrimitivesCount = 5
require.NoError(t, repo.Upsert(ctx, c1))
require.NoError(t, repo.Upsert(ctx, c2))
stats, err := repo.Stats(ctx)
require.NoError(t, err)
assert.Equal(t, 2, stats.TotalCrystals)
assert.Equal(t, 300, stats.TotalTokens)
}