package scriptopts import ( "errors" "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestQuotedHashRoundTripKeepsOnlyUnquotedComment(t *testing.T) { path := filepath.Join(t.TempDir(), "quoted.conf") require.NoError(t, os.WriteFile(path, []byte(`title="a # b" # visible comment`+"\n"), 0o644)) spec := &Spec{Name: "quoted.conf", Options: []Option{{Key: "title", ValueType: TypeString}}} parsed, err := Parse(spec, path) require.NoError(t, err) assert.Equal(t, `"a # b"`, parsed.GetValue("title")) require.NoError(t, parsed.SetValue("title", `"c # d"`)) require.NoError(t, parsed.Write()) content, err := os.ReadFile(path) require.NoError(t, err) assert.Equal(t, `title="c # d" # visible comment`+"\n", string(content)) } func TestParsedWriteRejectsStaleDiskSnapshot(t *testing.T) { path := filepath.Join(t.TempDir(), "stale.conf") require.NoError(t, os.WriteFile(path, []byte("title=initial\n"), 0o644)) spec := &Spec{Name: "stale.conf", Options: []Option{{Key: "title", ValueType: TypeString}}} first, err := Parse(spec, path) require.NoError(t, err) second, err := Parse(spec, path) require.NoError(t, err) require.NoError(t, first.SetValue("title", "first")) require.NoError(t, first.Write()) require.NoError(t, second.SetValue("title", "stale")) err = second.Write() require.Error(t, err) assert.True(t, errors.Is(err, ErrStaleSnapshot), err) content, readErr := os.ReadFile(path) require.NoError(t, readErr) assert.Equal(t, "title=first\n", string(content)) } func TestParsedMissingWriteRejectsFileCreatedByAnotherWriter(t *testing.T) { path := filepath.Join(t.TempDir(), "created.conf") spec := &Spec{Name: "created.conf", Options: []Option{{Key: "title", ValueType: TypeString}}} parsed, err := Parse(spec, path) require.NoError(t, err) require.NoError(t, parsed.SetValue("title", "stale")) require.NoError(t, os.WriteFile(path, []byte("title=newer\n"), 0o644)) err = parsed.Write() require.Error(t, err) assert.True(t, errors.Is(err, ErrStaleSnapshot), err) content, readErr := os.ReadFile(path) require.NoError(t, readErr) assert.Equal(t, "title=newer\n", string(content)) } func TestBackupsPreserveModeAndApplyRetention(t *testing.T) { path := filepath.Join(t.TempDir(), "private.conf") require.NoError(t, os.WriteFile(path, []byte("title=secret\n"), 0o600)) spec := &Spec{Name: "private.conf", Options: []Option{{Key: "title", ValueType: TypeString}}} parsed, err := Parse(spec, path) require.NoError(t, err) for index := 0; index < maxBackupsPerScriptOptsFile+5; index++ { require.NoError(t, parsed.createBackup()) } backups, err := filepath.Glob(path + "-" + spec.Name + ".bak.*") require.NoError(t, err) require.Len(t, backups, maxBackupsPerScriptOptsFile) for _, backup := range backups { info, err := os.Stat(backup) require.NoError(t, err) assert.Equal(t, os.FileMode(0o600), info.Mode().Perm()) } }