package exclude_test import ( "slices" "strings" "testing" "github.com/gobwas/glob" "sneak.berlin/go/vaultik/internal/exclude" ) // TestCompile checks the error, the anchoring and the globs that Compile // returns for one exclude pattern. func TestCompile(t *testing.T) { t.Parallel() tests := []struct { name string pattern string wantErr string wantAnchored bool // wantMatches lists paths that one of the globs must match. When // it is empty, Compile must return no globs. wantMatches []string }{ {name: "does not compile", pattern: "build[", wantErr: `"build[" is not a valid exclude pattern`}, {name: "empty", pattern: ""}, {name: "leading slash anchors", pattern: "/build", wantAnchored: true, wantMatches: []string{"build"}}, {name: "double star after the slash clears anchoring", pattern: "/**/build", wantMatches: []string{"build"}}, {name: "double star in the middle", pattern: "a/**/*.log", wantMatches: []string{"a/x.log", "a/b/x.log"}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() globs, anchored, err := exclude.Compile(tt.pattern) if tt.wantErr == "" && err != nil { t.Fatalf("Compile(%q) error = %v, want none", tt.pattern, err) } if tt.wantErr != "" && (err == nil || !strings.HasPrefix(err.Error(), tt.wantErr)) { t.Fatalf("Compile(%q) error = %v, want one starting with %q", tt.pattern, err, tt.wantErr) } if anchored != tt.wantAnchored { t.Errorf("Compile(%q) anchored = %t, want %t", tt.pattern, anchored, tt.wantAnchored) } if len(tt.wantMatches) == 0 && len(globs) != 0 { t.Errorf("Compile(%q) returned %d globs, want none", tt.pattern, len(globs)) } for _, path := range tt.wantMatches { matched := slices.ContainsFunc(globs, func(g glob.Glob) bool { return g.Match(path) }) if !matched { t.Errorf("Compile(%q) globs do not match %q", tt.pattern, path) } } }) } }