feat: modelos y CRUD para unit_tests y e2e_tests

UnitTest en registry con Insert, GetByFunction, Search FTS5, Purge. E2ETest en fn_operations con Insert, Get, List, UpdateResult, Delete. Ambos con scan helpers y serialización JSON.
This commit is contained in:
2026-04-05 18:19:10 +02:00
parent 256e038cbe
commit 9660a1c432
4 changed files with 243 additions and 0 deletions
+12
View File
@@ -180,6 +180,18 @@ type Proposal struct {
UpdatedAt time.Time `json:"updated_at"`
}
// UnitTest represents an individual test case extracted from a test file.
type UnitTest struct {
ID string `json:"id"`
FunctionID string `json:"function_id"`
Name string `json:"name"`
Code string `json:"code"`
FilePath string `json:"file_path"`
Lang string `json:"lang"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// GenerateID builds the canonical ID: {name}_{lang}_{domain}
func GenerateID(name, lang, domain string) string {
return name + "_" + lang + "_" + domain
+85
View File
@@ -614,6 +614,91 @@ func scanTypes(rows interface{ Next() bool; Scan(...any) error }) ([]Type, error
return result, nil
}
// --- Unit Tests CRUD ---
// InsertUnitTest inserts or replaces a unit test entry.
func (db *DB) InsertUnitTest(ut *UnitTest) error {
now := time.Now().UTC()
if ut.CreatedAt.IsZero() {
ut.CreatedAt = now
}
if ut.UpdatedAt.IsZero() {
ut.UpdatedAt = now
}
_, err := db.conn.Exec(`
INSERT OR REPLACE INTO unit_tests (
id, function_id, name, code, file_path, lang, created_at, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
ut.ID, ut.FunctionID, ut.Name, ut.Code, ut.FilePath, ut.Lang,
ut.CreatedAt.Format(time.RFC3339), ut.UpdatedAt.Format(time.RFC3339),
)
return err
}
// GetUnitTestsByFunction returns all unit tests for a given function ID.
func (db *DB) GetUnitTestsByFunction(functionID string) ([]UnitTest, error) {
rows, err := db.conn.Query(
"SELECT id, function_id, name, code, file_path, lang, created_at, updated_at FROM unit_tests WHERE function_id = ? ORDER BY name",
functionID,
)
if err != nil {
return nil, err
}
defer rows.Close()
return scanUnitTests(rows)
}
// SearchUnitTests performs FTS search on unit tests.
func (db *DB) SearchUnitTests(query string, lang string) ([]UnitTest, error) {
where := []string{}
args := []any{}
if query != "" {
where = append(where, "ut.id IN (SELECT id FROM unit_tests_fts WHERE unit_tests_fts MATCH ?)")
args = append(args, query)
}
if lang != "" {
where = append(where, "ut.lang = ?")
args = append(args, lang)
}
sql := "SELECT id, function_id, name, code, file_path, lang, created_at, updated_at FROM unit_tests ut"
if len(where) > 0 {
sql += " WHERE " + strings.Join(where, " AND ")
}
sql += " ORDER BY ut.function_id, ut.name"
rows, err := db.conn.Query(sql, args...)
if err != nil {
return nil, fmt.Errorf("search unit tests: %w", err)
}
defer rows.Close()
return scanUnitTests(rows)
}
func scanUnitTests(rows interface{ Next() bool; Scan(...any) error }) ([]UnitTest, error) {
var result []UnitTest
for rows.Next() {
var ut UnitTest
var createdAt, updatedAt string
err := rows.Scan(&ut.ID, &ut.FunctionID, &ut.Name, &ut.Code, &ut.FilePath, &ut.Lang, &createdAt, &updatedAt)
if err != nil {
return nil, fmt.Errorf("scanning unit test: %w", err)
}
ut.CreatedAt, _ = time.Parse(time.RFC3339, createdAt)
ut.UpdatedAt, _ = time.Parse(time.RFC3339, updatedAt)
result = append(result, ut)
}
return result, nil
}
// PurgeUnitTests deletes all unit test entries. Used before re-indexing.
func (db *DB) PurgeUnitTests() error {
_, err := db.conn.Exec("DELETE FROM unit_tests")
return err
}
// --- Proposal CRUD ---
// InsertProposal inserts or replaces a proposal.