|
@@ -675,7 +675,7 @@ func errp(e error) string {
|
|
return e.Error()
|
|
return e.Error()
|
|
}
|
|
}
|
|
|
|
|
|
-// TestMatch test's our version of filepath.Match, called regexpMatch.
|
|
|
|
|
|
+// TestMatch tests our version of filepath.Match, called Matches.
|
|
func TestMatch(t *testing.T) {
|
|
func TestMatch(t *testing.T) {
|
|
for _, tt := range matchTests {
|
|
for _, tt := range matchTests {
|
|
pattern := tt.pattern
|
|
pattern := tt.pattern
|
|
@@ -694,3 +694,73 @@ func TestMatch(t *testing.T) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+type compileTestCase struct {
|
|
|
|
+ pattern string
|
|
|
|
+ matchType matchType
|
|
|
|
+ compiledRegexp string
|
|
|
|
+ windowsCompiledRegexp string
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+var compileTests = []compileTestCase{
|
|
|
|
+ {"*", regexpMatch, `^[^/]*$`, `^[^\\]*$`},
|
|
|
|
+ {"file*", regexpMatch, `^file[^/]*$`, `^file[^\\]*$`},
|
|
|
|
+ {"*file", regexpMatch, `^[^/]*file$`, `^[^\\]*file$`},
|
|
|
|
+ {"a*/b", regexpMatch, `^a[^/]*/b$`, `^a[^\\]*\\b$`},
|
|
|
|
+ {"**", suffixMatch, "", ""},
|
|
|
|
+ {"**/**", regexpMatch, `^(.*/)?.*$`, `^(.*\\)?.*$`},
|
|
|
|
+ {"dir/**", prefixMatch, "", ""},
|
|
|
|
+ {"**/dir", suffixMatch, "", ""},
|
|
|
|
+ {"**/dir2/*", regexpMatch, `^(.*/)?dir2/[^/]*$`, `^(.*\\)?dir2\\[^\\]*$`},
|
|
|
|
+ {"**/dir2/**", regexpMatch, `^(.*/)?dir2/.*$`, `^(.*\\)?dir2\\.*$`},
|
|
|
|
+ {"**file", suffixMatch, "", ""},
|
|
|
|
+ {"**/file*txt", regexpMatch, `^(.*/)?file[^/]*txt$`, `^(.*\\)?file[^\\]*txt$`},
|
|
|
|
+ {"**/**/*.txt", regexpMatch, `^(.*/)?(.*/)?[^/]*\.txt$`, `^(.*\\)?(.*\\)?[^\\]*\.txt$`},
|
|
|
|
+ {"a[b-d]e", regexpMatch, `^a[b-d]e$`, `^a[b-d]e$`},
|
|
|
|
+ {".*", regexpMatch, `^\.[^/]*$`, `^\.[^\\]*$`},
|
|
|
|
+ {"abc.def", exactMatch, "", ""},
|
|
|
|
+ {"abc?def", regexpMatch, `^abc[^/]def$`, `^abc[^\\]def$`},
|
|
|
|
+ {"**/foo/bar", suffixMatch, "", ""},
|
|
|
|
+ {"a(b)c/def", exactMatch, "", ""},
|
|
|
|
+ {"a.|)$(}+{bc", exactMatch, "", ""},
|
|
|
|
+ {"dist/proxy.py-2.4.0rc3.dev36+g08acad9-py3-none-any.whl", exactMatch, "", ""},
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// TestCompile confirms that "compile" assigns the correct match type to a
|
|
|
|
+// variety of test case patterns. If the match type is regexp, it also confirms
|
|
|
|
+// that the compiled regexp matches the expected regexp.
|
|
|
|
+func TestCompile(t *testing.T) {
|
|
|
|
+ t.Run("slash", testCompile("/"))
|
|
|
|
+ t.Run("backslash", testCompile(`\`))
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testCompile(sl string) func(*testing.T) {
|
|
|
|
+ return func(t *testing.T) {
|
|
|
|
+ for _, tt := range compileTests {
|
|
|
|
+ pattern := tt.pattern
|
|
|
|
+ if sl != "/" {
|
|
|
|
+ pattern = strings.ReplaceAll(pattern, "/", sl)
|
|
|
|
+ }
|
|
|
|
+ pm, err := NewPatternMatcher([]string{pattern})
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatalf("Failed to create PatternMatcher for pattern %q: %v", pattern, err)
|
|
|
|
+ }
|
|
|
|
+ if err := pm.patterns[0].compile(sl); err != nil {
|
|
|
|
+ t.Fatalf("Failed to compile pattern %q: %v", pattern, err)
|
|
|
|
+ }
|
|
|
|
+ if pm.patterns[0].matchType != tt.matchType {
|
|
|
|
+ t.Errorf("pattern %q: matchType = %v, want %v", pattern, pm.patterns[0].matchType, tt.matchType)
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if tt.matchType == regexpMatch {
|
|
|
|
+ if sl == `\` {
|
|
|
|
+ if pm.patterns[0].regexp.String() != tt.windowsCompiledRegexp {
|
|
|
|
+ t.Errorf("pattern %q: regexp = %s, want %s", pattern, pm.patterns[0].regexp, tt.windowsCompiledRegexp)
|
|
|
|
+ }
|
|
|
|
+ } else if pm.patterns[0].regexp.String() != tt.compiledRegexp {
|
|
|
|
+ t.Errorf("pattern %q: regexp = %s, want %s", pattern, pm.patterns[0].regexp, tt.compiledRegexp)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|