@@ -0,0 +1,152 @@
1+package config
2+
3+import (
4+ "errors"
5+ "os"
6+ "path/filepath"
7+ "testing"
8+
9+ "github.com/stretchr/testify/require"
10+)
11+
12+func TestConfigStore_ConfigPath_GlobalAlwaysWorks(t *testing.T) {
13+ t.Parallel()
14+
15+ store := &ConfigStore{
16+ globalDataPath: "/some/global/crush.json",
17+ }
18+
19+ path, err := store.configPath(ScopeGlobal)
20+ require.NoError(t, err)
21+ require.Equal(t, "/some/global/crush.json", path)
22+}
23+
24+func TestConfigStore_ConfigPath_WorkspaceReturnsPath(t *testing.T) {
25+ t.Parallel()
26+
27+ store := &ConfigStore{
28+ workspacePath: "/some/workspace/.crush/crush.json",
29+ }
30+
31+ path, err := store.configPath(ScopeWorkspace)
32+ require.NoError(t, err)
33+ require.Equal(t, "/some/workspace/.crush/crush.json", path)
34+}
35+
36+func TestConfigStore_ConfigPath_WorkspaceErrorsWhenEmpty(t *testing.T) {
37+ t.Parallel()
38+
39+ store := &ConfigStore{
40+ globalDataPath: "/some/global/crush.json",
41+ workspacePath: "",
42+ }
43+
44+ _, err := store.configPath(ScopeWorkspace)
45+ require.Error(t, err)
46+ require.True(t, errors.Is(err, ErrNoWorkspaceConfig))
47+}
48+
49+func TestConfigStore_SetConfigField_WorkspaceScopeGuard(t *testing.T) {
50+ t.Parallel()
51+
52+ store := &ConfigStore{
53+ config: &Config{},
54+ globalDataPath: filepath.Join(t.TempDir(), "global.json"),
55+ workspacePath: "",
56+ }
57+
58+ err := store.SetConfigField(ScopeWorkspace, "foo", "bar")
59+ require.Error(t, err)
60+ require.True(t, errors.Is(err, ErrNoWorkspaceConfig))
61+}
62+
63+func TestConfigStore_SetConfigField_GlobalScopeAlwaysWorks(t *testing.T) {
64+ t.Parallel()
65+
66+ dir := t.TempDir()
67+ globalPath := filepath.Join(dir, "crush.json")
68+ store := &ConfigStore{
69+ config: &Config{},
70+ globalDataPath: globalPath,
71+ }
72+
73+ err := store.SetConfigField(ScopeGlobal, "foo", "bar")
74+ require.NoError(t, err)
75+
76+ data, err := os.ReadFile(globalPath)
77+ require.NoError(t, err)
78+ require.Contains(t, string(data), `"foo"`)
79+}
80+
81+func TestConfigStore_RemoveConfigField_WorkspaceScopeGuard(t *testing.T) {
82+ t.Parallel()
83+
84+ store := &ConfigStore{
85+ config: &Config{},
86+ globalDataPath: filepath.Join(t.TempDir(), "global.json"),
87+ workspacePath: "",
88+ }
89+
90+ err := store.RemoveConfigField(ScopeWorkspace, "foo")
91+ require.Error(t, err)
92+ require.True(t, errors.Is(err, ErrNoWorkspaceConfig))
93+}
94+
95+func TestConfigStore_HasConfigField_WorkspaceScopeGuard(t *testing.T) {
96+ t.Parallel()
97+
98+ store := &ConfigStore{
99+ config: &Config{},
100+ globalDataPath: filepath.Join(t.TempDir(), "global.json"),
101+ workspacePath: "",
102+ }
103+
104+ has := store.HasConfigField(ScopeWorkspace, "foo")
105+ require.False(t, has)
106+}
107+
108+func TestConfigStore_RuntimeOverrides_Independent(t *testing.T) {
109+ t.Parallel()
110+
111+ store1 := &ConfigStore{config: &Config{}}
112+ store2 := &ConfigStore{config: &Config{}}
113+
114+ require.False(t, store1.Overrides().SkipPermissionRequests)
115+ require.False(t, store2.Overrides().SkipPermissionRequests)
116+
117+ store1.Overrides().SkipPermissionRequests = true
118+
119+ require.True(t, store1.Overrides().SkipPermissionRequests)
120+ require.False(t, store2.Overrides().SkipPermissionRequests)
121+}
122+
123+func TestConfigStore_RuntimeOverrides_MutableViaPointer(t *testing.T) {
124+ t.Parallel()
125+
126+ store := &ConfigStore{config: &Config{}}
127+ overrides := store.Overrides()
128+
129+ require.False(t, overrides.SkipPermissionRequests)
130+
131+ overrides.SkipPermissionRequests = true
132+ require.True(t, store.Overrides().SkipPermissionRequests)
133+}
134+
135+func TestGlobalWorkspaceDir(t *testing.T) {
136+ dir := t.TempDir()
137+ t.Setenv("CRUSH_GLOBAL_DATA", dir)
138+
139+ wsDir := GlobalWorkspaceDir()
140+ globalData := GlobalConfigData()
141+
142+ require.Equal(t, filepath.Dir(globalData), wsDir)
143+ require.Equal(t, dir, wsDir)
144+}
145+
146+func TestScope_String(t *testing.T) {
147+ t.Parallel()
148+
149+ require.Equal(t, "global", ScopeGlobal.String())
150+ require.Equal(t, "workspace", ScopeWorkspace.String())
151+ require.Contains(t, Scope(99).String(), "Scope(99)")
152+}