package infra import ( "os" "path/filepath" "runtime" "strings" "testing" ) func registryRoot() string { _, thisFile, _, _ := runtime.Caller(0) return filepath.Join(filepath.Dir(thisFile), "..", "..") } func TestParseIssueMd(t *testing.T) { root := registryRoot() t.Run("parsea 0130-kanban-cpp-v2 correctamente", func(t *testing.T) { path := filepath.Join(root, "dev", "issues", "0130-kanban-cpp-v2.md") iss, body, err := ParseIssueMd(path) if err != nil { t.Fatalf("ParseIssueMd error: %v", err) } if iss.ID != "0130" { t.Errorf("ID: got %q, want %q", iss.ID, "0130") } if !strings.Contains(iss.Title, "Kanban C++ v2") { t.Errorf("Title %q does not contain 'Kanban C++ v2'", iss.Title) } if iss.Status != "pendiente" { t.Errorf("Status: got %q, want %q", iss.Status, "pendiente") } if len(iss.Domain) < 3 { t.Errorf("Domain: got %d items, want >=3: %v", len(iss.Domain), iss.Domain) } if iss.FilePath != path { t.Errorf("FilePath: got %q, want %q", iss.FilePath, path) } if iss.MtimeNs == 0 { t.Error("MtimeNs should be non-zero") } if iss.Completed { t.Error("Completed should be false for non-completed issue") } if len(body) == 0 { t.Error("body should not be empty") } }) t.Run("completed flag se deduce del path", func(t *testing.T) { fixturePath := filepath.Join(root, "functions", "infra", "testdata", "issue_fixture.fixture") data, err := os.ReadFile(fixturePath) if err != nil { t.Fatalf("read fixture: %v", err) } completedDir := filepath.Join(t.TempDir(), "completed") if err := os.MkdirAll(completedDir, 0755); err != nil { t.Fatalf("mkdir: %v", err) } completedPath := filepath.Join(completedDir, "9999-fixture.md") if err := os.WriteFile(completedPath, data, 0644); err != nil { t.Fatalf("write: %v", err) } iss, _, err := ParseIssueMd(completedPath) if err != nil { t.Fatalf("ParseIssueMd error: %v", err) } if !iss.Completed { t.Error("Completed should be true for path with /completed/") } }) t.Run("error en archivo inexistente", func(t *testing.T) { _, _, err := ParseIssueMd("/nonexistent/path/issue.md") if err == nil { t.Error("expected error for nonexistent file") } }) t.Run("fixture preserva campos", func(t *testing.T) { fixturePath := filepath.Join(root, "functions", "infra", "testdata", "issue_fixture.fixture") iss, body, err := ParseIssueMd(fixturePath) if err != nil { t.Fatalf("ParseIssueMd error: %v", err) } if iss.ID != "9999" { t.Errorf("ID: got %q, want %q", iss.ID, "9999") } if iss.Flow != "0001" { t.Errorf("Flow: got %q, want %q", iss.Flow, "0001") } if len(iss.Depends) != 1 || iss.Depends[0] != "0001" { t.Errorf("Depends: got %v, want [0001]", iss.Depends) } if !strings.Contains(string(body), "Este es el body") { t.Errorf("body should contain fixture text, got: %s", string(body)) } }) }