1package agent
2
3import (
4 "context"
5 "encoding/json"
6 "strings"
7 "testing"
8
9 "github.com/bnema/zut/packages/provider"
10)
11
12func TestParseArgsFastModeChildFlag(t *testing.T) {
13 args, err := ParseArgs([]string{"--fast-mode"})
14 if err != nil {
15 t.Fatalf("ParseArgs failed: %v", err)
16 }
17 if !args.FastMode {
18 t.Fatal("FastMode = false, want true")
19 }
20 if !args.FastModeSet {
21 t.Fatal("FastModeSet = false, want true")
22 }
23}
24
25func TestResolveFastModeDefaultsOff(t *testing.T) {
26 t.Setenv("ZUT_HOME", t.TempDir())
27 if err := SaveConfig(Config{Provider: "openai", Model: "gpt-5"}); err != nil {
28 t.Fatal(err)
29 }
30
31 r, err := Resolve(Args{}, false)
32 if err != nil {
33 t.Fatalf("Resolve failed: %v", err)
34 }
35 if r.FastMode {
36 t.Fatal("FastMode = true by default, want false")
37 }
38}
39
40func TestResolveFastModeFromConfig(t *testing.T) {
41 t.Setenv("ZUT_HOME", t.TempDir())
42 enabled := true
43 if err := SaveConfig(Config{Provider: "openai", Model: "gpt-5", FastMode: &enabled}); err != nil {
44 t.Fatal(err)
45 }
46
47 r, err := Resolve(Args{}, false)
48 if err != nil {
49 t.Fatalf("Resolve failed: %v", err)
50 }
51 if !r.FastMode {
52 t.Fatal("FastMode = false, want true from config")
53 }
54}
55
56func TestResolveFastModeRemainsEnabledForUnsupportedProviderUntilRequest(t *testing.T) {
57 t.Setenv("ZUT_HOME", t.TempDir())
58 enabled := true
59 if err := SaveConfig(Config{Provider: "anthropic", Model: "claude-sonnet-4-5", FastMode: &enabled}); err != nil {
60 t.Fatal(err)
61 }
62
63 r, err := Resolve(Args{}, false)
64 if err != nil {
65 t.Fatalf("Resolve failed: %v", err)
66 }
67 if !r.FastMode {
68 t.Fatal("FastMode = false, want true from config")
69 }
70}
71
72func TestResolveFastModeRequiresExplicitChildOverride(t *testing.T) {
73 t.Setenv("ZUT_HOME", t.TempDir())
74 if err := SaveConfig(Config{Provider: "openai", Model: "gpt-5"}); err != nil {
75 t.Fatal(err)
76 }
77
78 r, err := Resolve(Args{FastMode: true}, false)
79 if err != nil {
80 t.Fatalf("Resolve failed: %v", err)
81 }
82 if r.FastMode {
83 t.Fatal("FastMode = true, want unmarked programmatic value to be ignored")
84 }
85}
86
87func TestResolveFastModeExplicitChildDisableOverridesConfig(t *testing.T) {
88 t.Setenv("ZUT_HOME", t.TempDir())
89 enabled := true
90 if err := SaveConfig(Config{Provider: "openai", Model: "gpt-5", FastMode: &enabled}); err != nil {
91 t.Fatal(err)
92 }
93 args, err := ParseArgs([]string{"--no-fast-mode"})
94 if err != nil {
95 t.Fatalf("ParseArgs failed: %v", err)
96 }
97
98 r, err := Resolve(args, false)
99 if err != nil {
100 t.Fatalf("Resolve failed: %v", err)
101 }
102 if r.FastMode {
103 t.Fatal("FastMode = true, want explicit child disable to override config")
104 }
105}
106
107func TestConfigSettingsStorePersistsFastMode(t *testing.T) {
108 t.Setenv("ZUT_HOME", t.TempDir())
109 if err := SaveConfig(Config{Theme: "dark"}); err != nil {
110 t.Fatal(err)
111 }
112
113 if err := (configSettingsStore{}).SetFastMode(true); err != nil {
114 t.Fatal(err)
115 }
116 cfg, err := LoadConfig()
117 if err != nil {
118 t.Fatal(err)
119 }
120 if cfg.FastMode == nil || !*cfg.FastMode {
121 t.Fatalf("fast_mode = %v, want true", cfg.FastMode)
122 }
123 if cfg.Theme != "dark" {
124 t.Fatalf("unrelated config changed: theme = %q, want dark", cfg.Theme)
125 }
126}
127
128func TestFastModeConfigJSONUsesSnakeCase(t *testing.T) {
129 enabled := true
130 data, err := json.Marshal(Config{FastMode: &enabled})
131 if err != nil {
132 t.Fatal(err)
133 }
134 if !strings.Contains(string(data), `"fast_mode":true`) {
135 t.Fatalf("config JSON = %s, want fast_mode", data)
136 }
137}
138
139func TestResolvedOllamaClientRejectsFastMode(t *testing.T) {
140 client := (Resolved{
141 Provider: "ollama",
142 Credential: "ollama",
143 BaseURL: "http://localhost:11434",
144 }).NewClient()
145 if client.Name() != "ollama" {
146 t.Fatalf("client name = %q, want ollama", client.Name())
147 }
148 _, err := client.Stream(context.Background(), provider.Request{Model: "local", FastMode: true})
149 if err == nil || !strings.Contains(err.Error(), "only supported for OpenAI providers") {
150 t.Fatalf("Stream error = %v, want unsupported-provider error", err)
151 }
152}