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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user