v0.4.0 a622146

fast_mode_test.go RawHistoryFolder

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}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 476

↑↓ moveenter openesc close