summaryrefslogtreecommitdiff
path: root/internal/config/config_test.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-19 21:58:20 +0300
committerPaul Buetow <paul@buetow.org>2026-04-19 21:58:20 +0300
commitbaaa2a95b323296992bcce9c8cdc789c1c52d917 (patch)
treedbb2f8a231c1827cb571a1733abd5f7c66d31f4f /internal/config/config_test.go
parenta87e799634280e2b52a5fcacafc44cb28a0d288e (diff)
u4: add core infrastructure scaffolding
Diffstat (limited to 'internal/config/config_test.go')
-rw-r--r--internal/config/config_test.go148
1 files changed, 148 insertions, 0 deletions
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
new file mode 100644
index 0000000..d0a4efe
--- /dev/null
+++ b/internal/config/config_test.go
@@ -0,0 +1,148 @@
+package config
+
+import (
+ "errors"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "codeberg.org/snonux/comicforge/internal/provider"
+)
+
+func TestLoadReturnsDefaultsWhenConfigMissing(t *testing.T) {
+ t.Parallel()
+
+ cfg, err := Load("")
+ if err != nil {
+ t.Fatalf("Load() error = %v", err)
+ }
+
+ if got, want := cfg.Provider.Text, provider.Gemini; got != want {
+ t.Fatalf("Provider.Text = %q, want %q", got, want)
+ }
+ if got, want := cfg.PromptsDir, DefaultPromptsDir; got != want {
+ t.Fatalf("PromptsDir = %q, want %q", got, want)
+ }
+}
+
+func TestLoadReadsFileAndEnvOverrides(t *testing.T) {
+ tmpDir := t.TempDir()
+ configPath := filepath.Join(tmpDir, "config.yaml")
+ if err := os.WriteFile(configPath, []byte(strings.TrimSpace(`
+provider:
+ text: openai
+ image: openai
+ tts: openai
+prompts_dir: ./custom-prompts
+comic:
+ story_pages: 7
+`)), 0o644); err != nil {
+ t.Fatalf("write config: %v", err)
+ }
+
+ t.Setenv("COMICFORGE_PROVIDER_TEXT", "gemini")
+
+ cfg, err := Load(configPath)
+ if err != nil {
+ t.Fatalf("Load() error = %v", err)
+ }
+
+ if got, want := cfg.Provider.Text, provider.Gemini; got != want {
+ t.Fatalf("Provider.Text = %q, want %q", got, want)
+ }
+ if got, want := cfg.Provider.Image, provider.OpenAI; got != want {
+ t.Fatalf("Provider.Image = %q, want %q", got, want)
+ }
+ if got, want := cfg.Comic.StoryPages, 7; got != want {
+ t.Fatalf("Comic.StoryPages = %d, want %d", got, want)
+ }
+ if got, want := cfg.PromptsDir, "./custom-prompts"; got != want {
+ t.Fatalf("PromptsDir = %q, want %q", got, want)
+ }
+}
+
+func TestRenderPrompt(t *testing.T) {
+ t.Parallel()
+
+ tmpDir := t.TempDir()
+ cfg := DefaultConfig()
+ cfg.PromptsDir = tmpDir
+
+ if err := os.WriteFile(filepath.Join(tmpDir, "story.md"), []byte("{{.Word}} -> {{.Translation}}"), 0o644); err != nil {
+ t.Fatalf("write prompt: %v", err)
+ }
+
+ got, err := cfg.RenderPrompt("story.md", map[string]string{
+ "Word": "ябълка",
+ "Translation": "apple",
+ })
+ if err != nil {
+ t.Fatalf("RenderPrompt() error = %v", err)
+ }
+ if got != "ябълка -> apple" {
+ t.Fatalf("RenderPrompt() = %q, want %q", got, "ябълка -> apple")
+ }
+}
+
+func TestRenderPromptMissingKeyReturnsError(t *testing.T) {
+ t.Parallel()
+
+ tmpDir := t.TempDir()
+ cfg := DefaultConfig()
+ cfg.PromptsDir = tmpDir
+
+ if err := os.WriteFile(filepath.Join(tmpDir, "story.md"), []byte("{{.Word}} -> {{.Translation}}"), 0o644); err != nil {
+ t.Fatalf("write prompt: %v", err)
+ }
+
+ _, err := cfg.RenderPrompt("story.md", map[string]string{"Word": "ябълка"})
+ if err == nil {
+ t.Fatal("RenderPrompt() error = nil, want error")
+ }
+ if !strings.Contains(err.Error(), "render prompt") {
+ t.Fatalf("RenderPrompt() error = %v, want wrapped render error", err)
+ }
+}
+
+func TestLoadRejectsUnknownProvider(t *testing.T) {
+ t.Parallel()
+
+ tmpDir := t.TempDir()
+ configPath := filepath.Join(tmpDir, "config.yaml")
+ if err := os.WriteFile(configPath, []byte(strings.TrimSpace(`
+provider:
+ text: mystery
+`)), 0o644); err != nil {
+ t.Fatalf("write config: %v", err)
+ }
+
+ _, err := Load(configPath)
+ if err == nil {
+ t.Fatal("Load() error = nil, want error")
+ }
+ if !strings.Contains(err.Error(), "unknown text provider") {
+ t.Fatalf("Load() error = %v, want unknown provider error", err)
+ }
+}
+
+func TestHomeDirReturnsFallbackWhenResolutionFails(t *testing.T) {
+ t.Parallel()
+
+ oldUserHomeDir := userHomeDir
+ t.Cleanup(func() {
+ userHomeDir = oldUserHomeDir
+ })
+
+ userHomeDir = func() (string, error) {
+ return "", errors.New("boom")
+ }
+
+ homeDir, err := HomeDir()
+ if err == nil {
+ t.Fatal("HomeDir() error = nil, want error")
+ }
+ if homeDir != "." {
+ t.Fatalf("HomeDir() homeDir = %q, want %q", homeDir, ".")
+ }
+}