9c0d24d3ef
Nuevas funciones Go con tests en tres dominios: - core: parse_cron_expr, next_cron_time, join_by_key, validate_struct_fields + tipo CronSchedule - datascience: pivot (tabla dinámica), diff_entities (comparación de entidades) - infra: http_get_json, http_post_json, http_download_file, cache_to_sqlite, cron_ticker Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
139 lines
4.0 KiB
Go
139 lines
4.0 KiB
Go
package datascience
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestDiffEntities(t *testing.T) {
|
|
t.Run("entity añadida", func(t *testing.T) {
|
|
before := []map[string]any{
|
|
{"id": "1", "name": "Alice"},
|
|
}
|
|
after := []map[string]any{
|
|
{"id": "1", "name": "Alice"},
|
|
{"id": "2", "name": "Bob"},
|
|
}
|
|
result := DiffEntities(before, after, "id", nil)
|
|
added := result["added"].([]map[string]any)
|
|
if len(added) != 1 {
|
|
t.Errorf("expected 1 added, got %d", len(added))
|
|
}
|
|
if added[0]["id"] != "2" {
|
|
t.Errorf("expected added id=2, got %v", added[0]["id"])
|
|
}
|
|
if result["unchanged"].(int) != 1 {
|
|
t.Errorf("expected 1 unchanged, got %v", result["unchanged"])
|
|
}
|
|
})
|
|
|
|
t.Run("entity eliminada", func(t *testing.T) {
|
|
before := []map[string]any{
|
|
{"id": "1", "name": "Alice"},
|
|
{"id": "2", "name": "Bob"},
|
|
}
|
|
after := []map[string]any{
|
|
{"id": "1", "name": "Alice"},
|
|
}
|
|
result := DiffEntities(before, after, "id", nil)
|
|
removed := result["removed"].([]map[string]any)
|
|
if len(removed) != 1 {
|
|
t.Errorf("expected 1 removed, got %d", len(removed))
|
|
}
|
|
if removed[0]["id"] != "2" {
|
|
t.Errorf("expected removed id=2, got %v", removed[0]["id"])
|
|
}
|
|
})
|
|
|
|
t.Run("entity modificada con detalle de campos", func(t *testing.T) {
|
|
before := []map[string]any{
|
|
{"id": "1", "name": "Alice", "status": "active"},
|
|
}
|
|
after := []map[string]any{
|
|
{"id": "1", "name": "Alice", "status": "inactive"},
|
|
}
|
|
result := DiffEntities(before, after, "id", nil)
|
|
modified := result["modified"].([]map[string]any)
|
|
if len(modified) != 1 {
|
|
t.Errorf("expected 1 modified, got %d", len(modified))
|
|
}
|
|
changes := modified[0]["changes"].(map[string]any)
|
|
statusChange, ok := changes["status"].(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("expected status change, got %v", changes)
|
|
}
|
|
if statusChange["old"] != "active" {
|
|
t.Errorf("expected old=active, got %v", statusChange["old"])
|
|
}
|
|
if statusChange["new"] != "inactive" {
|
|
t.Errorf("expected new=inactive, got %v", statusChange["new"])
|
|
}
|
|
})
|
|
|
|
t.Run("entities identicas → unchanged", func(t *testing.T) {
|
|
entities := []map[string]any{
|
|
{"id": "1", "name": "Alice"},
|
|
{"id": "2", "name": "Bob"},
|
|
}
|
|
result := DiffEntities(entities, entities, "id", nil)
|
|
if result["unchanged"].(int) != 2 {
|
|
t.Errorf("expected 2 unchanged, got %v", result["unchanged"])
|
|
}
|
|
if len(result["added"].([]map[string]any)) != 0 {
|
|
t.Errorf("expected 0 added")
|
|
}
|
|
if len(result["modified"].([]map[string]any)) != 0 {
|
|
t.Errorf("expected 0 modified")
|
|
}
|
|
})
|
|
|
|
t.Run("ignore_fields funciona", func(t *testing.T) {
|
|
before := []map[string]any{
|
|
{"id": "1", "name": "Alice", "updated_at": "2024-01-01"},
|
|
}
|
|
after := []map[string]any{
|
|
{"id": "1", "name": "Alice", "updated_at": "2024-06-01"},
|
|
}
|
|
// Default ignores updated_at
|
|
result := DiffEntities(before, after, "id", nil)
|
|
if result["unchanged"].(int) != 1 {
|
|
t.Errorf("expected 1 unchanged (updated_at ignored), got %v", result["unchanged"])
|
|
}
|
|
modified := result["modified"].([]map[string]any)
|
|
if len(modified) != 0 {
|
|
t.Errorf("expected 0 modified when updated_at is ignored, got %d", len(modified))
|
|
}
|
|
})
|
|
|
|
t.Run("lista vacia vs lista con datos", func(t *testing.T) {
|
|
before := []map[string]any{}
|
|
after := []map[string]any{
|
|
{"id": "1", "name": "Alice"},
|
|
}
|
|
result := DiffEntities(before, after, "id", nil)
|
|
added := result["added"].([]map[string]any)
|
|
if len(added) != 1 {
|
|
t.Errorf("expected 1 added, got %d", len(added))
|
|
}
|
|
if result["unchanged"].(int) != 0 {
|
|
t.Errorf("expected 0 unchanged")
|
|
}
|
|
})
|
|
|
|
t.Run("summary format correcto", func(t *testing.T) {
|
|
before := []map[string]any{
|
|
{"id": "1", "name": "Alice"},
|
|
{"id": "3", "name": "Carol"},
|
|
}
|
|
after := []map[string]any{
|
|
{"id": "1", "name": "Alice Changed"},
|
|
{"id": "2", "name": "Bob"},
|
|
}
|
|
result := DiffEntities(before, after, "id", nil)
|
|
summary := result["summary"].(string)
|
|
expected := "1 added, 1 removed, 1 modified, 0 unchanged"
|
|
if summary != expected {
|
|
t.Errorf("expected summary %q, got %q", expected, summary)
|
|
}
|
|
})
|
|
}
|