package shellconfig import ( "context" "os" "path/filepath" "strings" "testing" "gitlab.hive-brain.de/MDietermann/Archduino/internal/config" "gitlab.hive-brain.de/MDietermann/Archduino/internal/module" ) type nop struct{} func (nop) Progress(string, int, int, string) {} func (nop) Log(string, string) {} func TestShellConfigWritesBlocks(t *testing.T) { home := t.TempDir() t.Setenv("HOME", home) m := New(config.ShellConfigSection{ Blocks: []config.ShellConfigBlock{ {Name: "path", File: ".zshrc", Content: `export PATH="$HOME/.local/bin:$PATH"`}, }, }) st, _ := m.Detect(context.Background()) p, _ := m.Plan(context.Background(), st) if err := m.Apply(context.Background(), p, nop{}); err != nil { t.Fatal(err) } data, _ := os.ReadFile(filepath.Join(home, ".zshrc")) if !strings.Contains(string(data), ">>> path >>>") { t.Fatalf("block not present: %q", data) } if !strings.Contains(string(data), `export PATH="$HOME/.local/bin:$PATH"`) { t.Fatalf("content missing: %q", data) } } func TestShellConfigIdempotent(t *testing.T) { home := t.TempDir() t.Setenv("HOME", home) cfg := config.ShellConfigSection{Blocks: []config.ShellConfigBlock{ {Name: "x", File: ".zshrc", Content: "echo x"}, }} m := New(cfg) st, _ := m.Detect(context.Background()) p, _ := m.Plan(context.Background(), st) _ = m.Apply(context.Background(), p, nop{}) st2, _ := m.Detect(context.Background()) p2, _ := m.Plan(context.Background(), st2) if !p2.IsEmpty() { t.Fatalf("second plan not empty: %+v", p2.Actions) } } func TestPlanForceRewritesBlocks(t *testing.T) { home := t.TempDir() t.Setenv("HOME", home) cfg := config.ShellConfigSection{Blocks: []config.ShellConfigBlock{ {Name: "path", File: ".zshrc", Content: `export PATH="$HOME/.local/bin:$PATH"`}, }} m := New(cfg) st, _ := m.Detect(context.Background()) p, _ := m.Plan(context.Background(), st) if err := m.Apply(context.Background(), p, nop{}); err != nil { t.Fatal(err) } st2, _ := m.Detect(context.Background()) p2, _ := m.Plan(context.Background(), st2) if !p2.IsEmpty() { t.Fatalf("precondition: regular plan should be empty") } plan, err := m.PlanForce(context.Background()) if err != nil { t.Fatalf("PlanForce: %v", err) } if plan.IsEmpty() { t.Fatal("force plan must not be empty") } for _, a := range plan.Actions { if err := a.Exec(context.Background()); err != nil { t.Fatalf("Exec: %v", err) } } data, _ := os.ReadFile(filepath.Join(home, ".zshrc")) if !strings.Contains(string(data), `export PATH="$HOME/.local/bin:$PATH"`) { t.Fatalf("content missing after force: %q", data) } if !strings.Contains(string(data), ">>> path >>>") { t.Fatalf("block marker missing: %q", data) } } var _ module.Module = Module{}