package config import ( "os" "path/filepath" "testing" ) func writeTestFile(t *testing.T, dir, name, content string) string { t.Helper() p := filepath.Join(dir, name) if err := os.WriteFile(p, []byte(content), 0644); err != nil { t.Fatalf("write %s: %v", p, err) } return p } const exampleMarkdown = `--- listen_addr: "127.0.0.1:9999" db_path: "/tmp/orca/test.db" ca_path: "/tmp/orca/ca.crt" server_cert_path: "/tmp/orca/server.crt" server_key_path: "/tmp/orca/server.key" node_capacity: cpu: 4 memory_mb: 8192 --- # Orca config This is prose body and is ignored by the loader. ` func TestLoadMarkdown_Full(t *testing.T) { p := writeTestFile(t, t.TempDir(), "config.md", exampleMarkdown) cfg, err := LoadMarkdown(p) if err != nil { t.Fatalf("LoadMarkdown: %v", err) } if cfg.DBPath != "/tmp/orca/test.db" { t.Errorf("DBPath=%q", cfg.DBPath) } if cfg.ListenAddr != "127.0.0.1:9999" { t.Errorf("ListenAddr=%q", cfg.ListenAddr) } if cfg.CAPath != "/tmp/orca/ca.crt" { t.Errorf("CAPath=%q", cfg.CAPath) } if cfg.ServerCertPath != "/tmp/orca/server.crt" { t.Errorf("ServerCertPath=%q", cfg.ServerCertPath) } if cfg.ServerKeyPath != "/tmp/orca/server.key" { t.Errorf("ServerKeyPath=%q", cfg.ServerKeyPath) } if cfg.NodeCapacity == nil { t.Fatal("NodeCapacity nil") } if cfg.NodeCapacity.CPU != 4 { t.Errorf("CPU=%d", cfg.NodeCapacity.CPU) } if cfg.NodeCapacity.MemoryMB != 8192 { t.Errorf("MemoryMB=%d", cfg.NodeCapacity.MemoryMB) } } func TestLoadMarkdown_NoFrontmatter(t *testing.T) { // No delimiters: whole file treated as a bare YAML block. body := "listen_addr: 0.0.0.0:1234\ndb_path: /x/y.db\n" p := writeTestFile(t, t.TempDir(), "config.md", body) cfg, err := LoadMarkdown(p) if err != nil { t.Fatalf("LoadMarkdown: %v", err) } if cfg.ListenAddr != "0.0.0.0:1234" { t.Errorf("ListenAddr=%q", cfg.ListenAddr) } if cfg.DBPath != "/x/y.db" { t.Errorf("DBPath=%q", cfg.DBPath) } } func TestLoadMarkdown_OnlyBody(t *testing.T) { body := `--- --- # Just prose, no keys ` p := writeTestFile(t, t.TempDir(), "config.md", body) cfg, err := LoadMarkdown(p) if err != nil { t.Fatalf("LoadMarkdown: %v", err) } if cfg.DBPath != "" || cfg.ListenAddr != "" || cfg.NodeCapacity != nil { t.Errorf("expected zero config, got %+v", cfg) } } func TestLoadMarkdown_CommentsAndBlanks(t *testing.T) { body := `--- # a comment listen_addr: "127.0.0.1:9999" db_path: "/tmp/orca/test.db" # inline comment node_capacity: cpu: 4 # cores memory_mb: 8192 --- ` p := writeTestFile(t, t.TempDir(), "config.md", body) cfg, err := LoadMarkdown(p) if err != nil { t.Fatalf("LoadMarkdown: %v", err) } if cfg.ListenAddr != "127.0.0.1:9999" { t.Errorf("ListenAddr=%q", cfg.ListenAddr) } if cfg.DBPath != "/tmp/orca/test.db" { t.Errorf("DBPath=%q", cfg.DBPath) } if cfg.NodeCapacity == nil || cfg.NodeCapacity.CPU != 4 || cfg.NodeCapacity.MemoryMB != 8192 { t.Errorf("NodeCapacity=%+v", cfg.NodeCapacity) } } func TestLoadMarkdownYAML_Bare(t *testing.T) { body := "listen_addr: 0.0.0.0:5555\ndb_path: /bare.db\nnode_capacity:\n cpu: 2\n memory_mb: 4096\n" p := writeTestFile(t, t.TempDir(), "config.yaml", body) cfg, err := LoadMarkdownYAML(p) if err != nil { t.Fatalf("LoadMarkdownYAML: %v", err) } if cfg.ListenAddr != "0.0.0.0:5555" { t.Errorf("ListenAddr=%q", cfg.ListenAddr) } if cfg.DBPath != "/bare.db" { t.Errorf("DBPath=%q", cfg.DBPath) } if cfg.NodeCapacity == nil || cfg.NodeCapacity.CPU != 2 || cfg.NodeCapacity.MemoryMB != 4096 { t.Errorf("NodeCapacity=%+v", cfg.NodeCapacity) } } func TestLoadMarkdown_ReadError(t *testing.T) { missing := filepath.Join(t.TempDir(), "nope.md") if _, err := LoadMarkdown(missing); err == nil { t.Fatal("expected error for missing file") } } func TestExtractFrontmatter(t *testing.T) { cases := []struct { name string input string block string present bool }{ {"standard", "---\nkey: val\n---\nbody", "key: val", true}, {"leading-blanks", "\n\n---\nkey: val\n---\n", "key: val", true}, {"no-delimiters", "key: val\n", "key: val", false}, {"only-open", "---\nkey: val\n", "key: val", false}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { block, ok := extractFrontmatter(tc.input) if ok != tc.present { t.Errorf("present=%v want %v", ok, tc.present) } if tc.present && block != tc.block { t.Errorf("block=%q want %q", block, tc.block) } }) } } func TestUnquote(t *testing.T) { if got, want := unquote(`"hello"`), "hello"; got != want { t.Errorf("unquote double = %q want %q", got, want) } if got, want := unquote(`'hello'`), "hello"; got != want { t.Errorf("unquote single = %q want %q", got, want) } if got, want := unquote("bare"), "bare"; got != want { t.Errorf("unquote bare = %q want %q", got, want) } }