presets_test.go

  1package config
  2
  3import (
  4	"os"
  5	"path/filepath"
  6	"reflect"
  7	"testing"
  8)
  9
 10const presetsFixtureTOML = `
 11[global]
 12verbose = true
 13
 14[global.backup]
 15exclude-file = "/etc/excludes"
 16
 17[home]
 18repo = "/repos/home"
 19
 20[home.backup]
 21_arguments = ["/home/alice"]
 22
 23["@cloud"]
 24repo = "/repos/cloud"
 25
 26["@cloud".environ]
 27AWS_PROFILE = "restic"
 28
 29["home@"]
 30host = "laptop"
 31
 32["home@cloud"]
 33repo = "/repos/home-cloud"
 34
 35[archive]
 36json = true
 37
 38[vars]
 39cache-root = "/srv"
 40`
 41
 42func TestPresetsFrom(t *testing.T) {
 43	t.Parallel()
 44
 45	dir := t.TempDir()
 46	path := filepath.Join(dir, "config.toml")
 47	if err := os.WriteFile(path, []byte(presetsFixtureTOML), 0o600); err != nil {
 48		t.Fatalf("writing fixture: %v", err)
 49	}
 50
 51	got := presetsFrom([]string{path})
 52
 53	// Plain presets first, then prefixĂ—suffix combos, then explicit full
 54	// presets (already covered by combo), then bare suffixes.
 55	want := []string{
 56		"archive",
 57		"home",
 58		"home@cloud", // home@ Ă— @cloud
 59		"@cloud",     // bare suffix
 60	}
 61
 62	if !reflect.DeepEqual(got, want) {
 63		t.Fatalf("presets mismatch:\n  got:  %#v\n  want: %#v", got, want)
 64	}
 65}
 66
 67func TestPresetsFromExplicitFullPreset(t *testing.T) {
 68	t.Parallel()
 69
 70	// When an explicit full preset exists that can't be generated from
 71	// prefixĂ—suffix, it should still appear.
 72	const fixture = `
 73[global]
 74verbose = true
 75
 76["@cloud"]
 77repo = "/repos/cloud"
 78
 79["special@remote"]
 80repo = "/repos/special-remote"
 81`
 82	dir := t.TempDir()
 83	path := filepath.Join(dir, "config.toml")
 84	if err := os.WriteFile(path, []byte(fixture), 0o600); err != nil {
 85		t.Fatalf("writing fixture: %v", err)
 86	}
 87
 88	got := presetsFrom([]string{path})
 89
 90	want := []string{
 91		"special@remote", // explicit full preset (no prefix@ exists)
 92		"@cloud",         // bare suffix
 93	}
 94
 95	if !reflect.DeepEqual(got, want) {
 96		t.Fatalf("presets mismatch:\n  got:  %#v\n  want: %#v", got, want)
 97	}
 98}
 99
100func TestPresetsFromMultiplePrefixesSuffixes(t *testing.T) {
101	t.Parallel()
102
103	const fixture = `
104[global]
105verbose = true
106
107["music@"]
108tag = "music"
109
110["photos@"]
111tag = "photos"
112
113["@hetzner"]
114repo = "sftp:hetzner"
115
116["@b2"]
117repo = "s3:b2"
118`
119	dir := t.TempDir()
120	path := filepath.Join(dir, "config.toml")
121	if err := os.WriteFile(path, []byte(fixture), 0o600); err != nil {
122		t.Fatalf("writing fixture: %v", err)
123	}
124
125	got := presetsFrom([]string{path})
126
127	// Combos: each prefix Ă— each suffix (prefixes sorted, suffixes sorted).
128	want := []string{
129		"music@b2",
130		"music@hetzner",
131		"photos@b2",
132		"photos@hetzner",
133		"@b2",
134		"@hetzner",
135	}
136
137	if !reflect.DeepEqual(got, want) {
138		t.Fatalf("presets mismatch:\n  got:  %#v\n  want: %#v", got, want)
139	}
140}
141
142func TestPresetsFromEmpty(t *testing.T) {
143	t.Parallel()
144
145	dir := t.TempDir()
146	path := filepath.Join(dir, "config.toml")
147	if err := os.WriteFile(path, []byte("[global]\nverbose = true\n"), 0o600); err != nil {
148		t.Fatalf("writing fixture: %v", err)
149	}
150
151	got := presetsFrom([]string{path})
152	if len(got) != 0 {
153		t.Fatalf("expected no presets, got %#v", got)
154	}
155}
156
157func TestPresetsFromMissing(t *testing.T) {
158	t.Parallel()
159
160	got := presetsFrom([]string{"/nonexistent/path.toml"})
161	if len(got) != 0 {
162		t.Fatalf("expected nil for missing file, got %#v", got)
163	}
164}
165
166func TestPrefixesFrom(t *testing.T) {
167	t.Parallel()
168
169	dir := t.TempDir()
170	path := filepath.Join(dir, "config.toml")
171	if err := os.WriteFile(path, []byte(presetsFixtureTOML), 0o600); err != nil {
172		t.Fatalf("writing fixture: %v", err)
173	}
174
175	got := prefixesFrom([]string{path})
176	want := []string{"home@"}
177
178	if !reflect.DeepEqual(got, want) {
179		t.Fatalf("prefixes mismatch:\n  got:  %#v\n  want: %#v", got, want)
180	}
181}
182
183func TestSuffixesFrom(t *testing.T) {
184	t.Parallel()
185
186	dir := t.TempDir()
187	path := filepath.Join(dir, "config.toml")
188	if err := os.WriteFile(path, []byte(presetsFixtureTOML), 0o600); err != nil {
189		t.Fatalf("writing fixture: %v", err)
190	}
191
192	got := suffixesFrom([]string{path})
193	want := []string{"@cloud"}
194
195	if !reflect.DeepEqual(got, want) {
196		t.Fatalf("suffixes mismatch:\n  got:  %#v\n  want: %#v", got, want)
197	}
198}