git-lfs/filepathfilter/filepathfilter_test.go
brian m. carlson 22a7fbdb4a
filepathfilter: switch to strict pattern matching
There are two types of pattern matching with wildmatch patterns in Git:
gitignore and gitattributes patterns.  We'd like to support both, but
without the lazy matching that was the cause of so many problems before.

Add a type of pattern to use when creating a new filepathfilter and use
it to instantiate the wildmatch pattern with the proper flags.  Remove
the dirs flag, which is unused and has been for sometime, and also the
stripping of trailing slashes, which we want to use to indicate a
directory.  Drop the non-strict mode since our pattern matching is now
much improved and compatible with Git.
2021-08-26 15:48:54 +00:00

155 lines
3.8 KiB
Go

package filepathfilter
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestPatternMatch(t *testing.T) {
assertPatternMatch(t, "*",
"a",
"a.a",
"a/b",
"a/b.b",
"a/b/c",
"a/b/c.c",
)
assertPatternMatch(t, "filename.txt", "filename.txt")
assertPatternMatch(t, "*.txt", "filename.txt")
refutePatternMatch(t, "*.tx", "filename.txt")
assertPatternMatch(t, "f*.txt", "filename.txt")
refutePatternMatch(t, "g*.txt", "filename.txt")
assertPatternMatch(t, "file*", "filename.txt")
refutePatternMatch(t, "file", "filename.txt")
// With no path separators, should match in subfolders
assertPatternMatch(t, "*.txt", "sub/filename.txt")
refutePatternMatch(t, "*.tx", "sub/filename.txt")
assertPatternMatch(t, "f*.txt", "sub/filename.txt")
refutePatternMatch(t, "g*.txt", "sub/filename.txt")
assertPatternMatch(t, "file*", "sub/filename.txt")
refutePatternMatch(t, "file", "sub/filename.txt")
// matches only in subdir
assertPatternMatch(t, "sub/*.txt", "sub/filename.txt")
refutePatternMatch(t, "sub/*.txt",
"top/sub/filename.txt",
"sub/filename.dat",
"other/filename.txt",
)
// Needs wildcard for exact filename
assertPatternMatch(t, "**/filename.txt", "sub/sub/sub/filename.txt")
// Should not match dots to subparts
refutePatternMatch(t, "*.ign", "sub/shouldignoreme.txt")
// Path specific
assertPatternMatch(t, "sub",
"sub",
"top/sub",
)
refutePatternMatch(t, "sub",
"subfilename.txt",
"sub/filename.txt",
"top/sub/filename.txt",
)
assertPatternMatch(t, "/sub",
"sub",
)
refutePatternMatch(t, "/sub",
"subfilename.txt",
"sub/filename.txt",
"top/sub",
"top/sub/filename.txt",
)
refutePatternMatch(t, "sub/",
"sub",
"subfilename.txt",
"sub/filename.txt",
"top/sub",
"top/sub/filename.txt",
)
assertPatternMatchIgnore(t, "sub/",
"sub/",
"sub/filename.txt",
"top/sub/",
"top/sub/filename.txt",
)
refutePatternMatchIgnore(t, "sub/",
"subfilename.txt",
)
refutePatternMatch(t, "/sub/",
"sub",
"subfilename.txt",
"sub/filename.txt",
"top/sub",
"top/sub/filename.txt",
)
assertPatternMatchIgnore(t, "/sub/",
"sub/",
"sub/filename.txt",
)
refutePatternMatchIgnore(t, "/sub/",
"subfilename.txt",
"top/sub",
"top/sub/filename.txt",
)
// Absolute
assertPatternMatch(t, "*.dat", "/path/to/sub/.git/test.dat")
assertPatternMatch(t, "**/.git", "/path/to/sub/.git")
}
func assertPatternMatch(t *testing.T, pattern string, filenames ...string) {
p := NewPattern(pattern, GitAttributes)
for _, filename := range filenames {
assert.True(t, p.Match(filename), "%q should match pattern %q", filename, pattern)
}
}
func assertPatternMatchIgnore(t *testing.T, pattern string, filenames ...string) {
p := NewPattern(pattern, GitIgnore)
for _, filename := range filenames {
assert.True(t, p.Match(filename), "%q should match pattern %q", filename, pattern)
}
}
func refutePatternMatch(t *testing.T, pattern string, filenames ...string) {
p := NewPattern(pattern, GitAttributes)
for _, filename := range filenames {
assert.False(t, p.Match(filename), "%q should not match pattern %q", filename, pattern)
}
}
func refutePatternMatchIgnore(t *testing.T, pattern string, filenames ...string) {
p := NewPattern(pattern, GitIgnore)
for _, filename := range filenames {
assert.False(t, p.Match(filename), "%q should not match pattern %q", filename, pattern)
}
}
type filterTest struct {
expectedResult bool
expectedPattern string
includes []string
excludes []string
}
func TestFilterReportsIncludePatterns(t *testing.T) {
filter := New([]string{"*.foo", "*.bar"}, nil, GitAttributes)
assert.Equal(t, []string{"*.foo", "*.bar"}, filter.Include())
}
func TestFilterReportsExcludePatterns(t *testing.T) {
filter := New(nil, []string{"*.baz", "*.quux"}, GitAttributes)
assert.Equal(t, []string{"*.baz", "*.quux"}, filter.Exclude())
}