Files
beardrive/internal/config/project_test.go
056c883204 fix(sync): anchor --shared include entries to the mount root (BEA-5) (#56)
`bdrive init --shared wiki` wrote `include: ["wiki/"]`, which compile()
treats as an unanchored gitignore pattern — so any nested directory named
`wiki` synced too. Shared-subfolder mode is what people use to keep private
material out of a project, and it was silently widening the scope: 15 files
under .agents/, .claude/ and .gemini/ leaked into a real project from
.../detector/shared/ dirs.

cleanShared now emits "/wiki/", which fixes both callers (init --shared and
bdrive scope add). config.LoadProject anchors legacy single-segment entries
on read, so the existing mounts are fixed without a re-init — and that also
keeps `bdrive scope rm wiki` working against pre-fix configs, with a
belt-and-braces unanchored candidate key in scopeRemove for any config that
bypasses LoadProject.

Not touched: compile() itself, and no delete op for the already-leaked
remote files (BEA-20 — a delete would unlink teammates' local copies).

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 18:44:05 +09:00

28 lines
888 B
Go

package config
import (
"reflect"
"testing"
)
func TestNormalizeInclude(t *testing.T) {
for _, tc := range []struct {
in []string
want []string
}{
{in: nil, want: nil},
{in: []string{"wiki/"}, want: []string{"/wiki/"}}, // legacy config, anchored on read
{in: []string{"wiki"}, want: []string{"/wiki"}},
{in: []string{"/wiki/"}, want: []string{"/wiki/"}}, // already anchored
{in: []string{"a/b/"}, want: []string{"a/b/"}}, // compile() anchors these already
{in: []string{"*.md"}, want: []string{"*.md"}}, // deliberate pattern, left alone
{in: []string{"!keep"}, want: []string{"!keep"}},
{in: []string{"wiki/", "*.md"}, want: []string{"/wiki/", "*.md"}},
} {
in := append([]string(nil), tc.in...)
if got := normalizeInclude(tc.in); !reflect.DeepEqual(got, tc.want) {
t.Errorf("normalizeInclude(%q) = %q, want %q", in, got, tc.want)
}
}
}