From d9f5f432e89e4b8dcc3eafe1d626a65a99b451cd Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Sat, 28 Mar 2026 02:04:21 +0100 Subject: [PATCH] test: tests para insert, get, FTS search, purge y drop 5 tests que validan el flujo completo del registry: - Insert y Get de funciones con tags y campos correctos - Insert y Get de tipos algebraicos - Busqueda FTS con filtros combinados (purity, domain) - Purge limpia ambas tablas - Drop elimina el archivo de BD Co-Authored-By: Claude Opus 4.6 (1M context) --- registry/store_test.go | 168 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 registry/store_test.go diff --git a/registry/store_test.go b/registry/store_test.go new file mode 100644 index 00000000..c3a4204c --- /dev/null +++ b/registry/store_test.go @@ -0,0 +1,168 @@ +package registry + +import ( + "os" + "path/filepath" + "testing" +) + +func tempDB(t *testing.T) *DB { + t.Helper() + path := filepath.Join(t.TempDir(), "test.db") + db, err := Open(path) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { db.Close() }) + return db +} + +func TestInsertAndGetFunction(t *testing.T) { + db := tempDB(t) + + f := &Function{ + Name: "filter_slice", + Kind: KindFunction, + Lang: "go", + Domain: "core", + Version: "1.0.0", + Purity: PurityPure, + Signature: "func FilterSlice[T any](xs []T, pred func(T) bool) []T", + Description: "Filtra un slice con un predicado sin mutar el original", + Tags: []string{"slice", "functional", "generic"}, + FilePath: "functions/core/filter_slice.go", + } + + if err := db.InsertFunction(f); err != nil { + t.Fatal(err) + } + + if f.ID != "filter_slice_go_core" { + t.Fatalf("expected ID filter_slice_go_core, got %s", f.ID) + } + + got, err := db.GetFunction("filter_slice_go_core") + if err != nil { + t.Fatal(err) + } + + if got.Name != "filter_slice" { + t.Errorf("name: got %q, want %q", got.Name, "filter_slice") + } + if got.Purity != PurityPure { + t.Errorf("purity: got %q, want %q", got.Purity, PurityPure) + } + if len(got.Tags) != 3 { + t.Errorf("tags: got %d, want 3", len(got.Tags)) + } +} + +func TestInsertAndGetType(t *testing.T) { + db := tempDB(t) + + typ := &Type{ + Name: "ohlcv", + Lang: "go", + Domain: "finance", + Version: "1.0.0", + Algebraic: AlgebraicProduct, + Definition: `type OHLCV struct { + Open, High, Low, Close, Volume float64 +}`, + Description: "Vela de mercado con precios OHLCV", + Tags: []string{"finance", "market", "candle"}, + FilePath: "types/finance/ohlcv.go", + } + + if err := db.InsertType(typ); err != nil { + t.Fatal(err) + } + + got, err := db.GetType("ohlcv_go_finance") + if err != nil { + t.Fatal(err) + } + + if got.Algebraic != AlgebraicProduct { + t.Errorf("algebraic: got %q, want %q", got.Algebraic, AlgebraicProduct) + } +} + +func TestSearchFunctionsFTS(t *testing.T) { + db := tempDB(t) + + fns := []*Function{ + {Name: "filter_slice", Kind: KindFunction, Lang: "go", Domain: "core", Purity: PurityPure, Description: "Filtra un slice con un predicado", Version: "1.0.0"}, + {Name: "map_slice", Kind: KindFunction, Lang: "go", Domain: "core", Purity: PurityPure, Description: "Transforma cada elemento de un slice", Version: "1.0.0"}, + {Name: "fetch_ticks", Kind: KindFunction, Lang: "go", Domain: "io", Purity: PurityImpure, Description: "Obtiene ticks de un exchange", ErrorType: "error_go_core", Version: "1.0.0"}, + } + for _, f := range fns { + if err := db.InsertFunction(f); err != nil { + t.Fatal(err) + } + } + + // FTS search + results, err := db.SearchFunctions("slice", "", "", "", "") + if err != nil { + t.Fatal(err) + } + if len(results) != 2 { + t.Errorf("FTS 'slice': got %d results, want 2", len(results)) + } + + // Filter by purity + results, err = db.SearchFunctions("", "", PurityImpure, "", "") + if err != nil { + t.Fatal(err) + } + if len(results) != 1 || results[0].Name != "fetch_ticks" { + t.Errorf("filter impure: unexpected results %v", results) + } + + // Filter by domain + results, err = db.SearchFunctions("", "", "", "", "core") + if err != nil { + t.Fatal(err) + } + if len(results) != 2 { + t.Errorf("filter domain=core: got %d, want 2", len(results)) + } +} + +func TestPurge(t *testing.T) { + db := tempDB(t) + + db.InsertFunction(&Function{Name: "test_fn", Kind: KindFunction, Lang: "go", Domain: "core", Purity: PurityPure, Description: "test", Version: "1.0.0"}) + db.InsertType(&Type{Name: "test_type", Lang: "go", Domain: "core", Algebraic: AlgebraicProduct, Description: "test", Version: "1.0.0"}) + + if err := db.Purge(); err != nil { + t.Fatal(err) + } + + fns, _ := db.SearchFunctions("", "", "", "", "") + if len(fns) != 0 { + t.Errorf("after purge: got %d functions, want 0", len(fns)) + } + + ts, _ := db.SearchTypes("", "", "") + if len(ts) != 0 { + t.Errorf("after purge: got %d types, want 0", len(ts)) + } +} + +func TestDrop(t *testing.T) { + path := filepath.Join(t.TempDir(), "drop.db") + db, err := Open(path) + if err != nil { + t.Fatal(err) + } + + if err := db.Drop(); err != nil { + t.Fatal(err) + } + + if _, err := os.Stat(path); !os.IsNotExist(err) { + t.Error("db file should not exist after Drop") + } +}