1
2
3
4
5 package search
6
7 import (
8 "strings"
9 "testing"
10 )
11
12 var matchPatternTests = `
13 pattern ...
14 match foo
15
16 pattern net
17 match net
18 not net/http
19
20 pattern net/http
21 match net/http
22 not net
23
24 pattern net...
25 match net net/http netchan
26 not not/http not/net/http
27
28 # Special cases. Quoting docs:
29
30 # First, /... at the end of the pattern can match an empty string,
31 # so that net/... matches both net and packages in its subdirectories, like net/http.
32 pattern net/...
33 match net net/http
34 not not/http not/net/http netchan
35
36 # Second, any slash-separated pattern element containing a wildcard never
37 # participates in a match of the "vendor" element in the path of a vendored
38 # package, so that ./... does not match packages in subdirectories of
39 # ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
40 # Note, however, that a directory named vendor that itself contains code
41 # is not a vendored package: cmd/vendor would be a command named vendor,
42 # and the pattern cmd/... matches it.
43 pattern ./...
44 match ./vendor ./mycode/vendor
45 not ./vendor/foo ./mycode/vendor/foo
46
47 pattern ./vendor/...
48 match ./vendor/foo ./vendor/foo/vendor
49 not ./vendor/foo/vendor/bar
50
51 pattern mycode/vendor/...
52 match mycode/vendor mycode/vendor/foo mycode/vendor/foo/vendor
53 not mycode/vendor/foo/vendor/bar
54
55 pattern x/vendor/y
56 match x/vendor/y
57 not x/vendor
58
59 pattern x/vendor/y/...
60 match x/vendor/y x/vendor/y/z x/vendor/y/vendor x/vendor/y/z/vendor
61 not x/vendor/y/vendor/z
62
63 pattern .../vendor/...
64 match x/vendor/y x/vendor/y/z x/vendor/y/vendor x/vendor/y/z/vendor
65 `
66
67 func TestMatchPattern(t *testing.T) {
68 testPatterns(t, "MatchPattern", matchPatternTests, func(pattern, name string) bool {
69 return MatchPattern(pattern)(name)
70 })
71 }
72
73 var treeCanMatchPatternTests = `
74 pattern ...
75 match foo
76
77 pattern net
78 match net
79 not net/http
80
81 pattern net/http
82 match net net/http
83
84 pattern net...
85 match net netchan net/http
86 not not/http not/net/http
87
88 pattern net/...
89 match net net/http
90 not not/http netchan
91
92 pattern abc.../def
93 match abcxyz
94 not xyzabc
95
96 pattern x/y/z/...
97 match x x/y x/y/z x/y/z/w
98
99 pattern x/y/z
100 match x x/y x/y/z
101 not x/y/z/w
102
103 pattern x/.../y/z
104 match x/a/b/c
105 not y/x/a/b/c
106 `
107
108 func TestTreeCanMatchPattern(t *testing.T) {
109 testPatterns(t, "TreeCanMatchPattern", treeCanMatchPatternTests, func(pattern, name string) bool {
110 return TreeCanMatchPattern(pattern)(name)
111 })
112 }
113
114 var hasPathPrefixTests = []stringPairTest{
115 {"abc", "a", false},
116 {"a/bc", "a", true},
117 {"a", "a", true},
118 {"a/bc", "a/", true},
119 }
120
121 func TestHasPathPrefix(t *testing.T) {
122 testStringPairs(t, "hasPathPrefix", hasPathPrefixTests, hasPathPrefix)
123 }
124
125 type stringPairTest struct {
126 in1 string
127 in2 string
128 out bool
129 }
130
131 func testStringPairs(t *testing.T, name string, tests []stringPairTest, f func(string, string) bool) {
132 for _, tt := range tests {
133 if out := f(tt.in1, tt.in2); out != tt.out {
134 t.Errorf("%s(%q, %q) = %v, want %v", name, tt.in1, tt.in2, out, tt.out)
135 }
136 }
137 }
138
139 func testPatterns(t *testing.T, name, tests string, fn func(string, string) bool) {
140 var patterns []string
141 for _, line := range strings.Split(tests, "\n") {
142 if i := strings.Index(line, "#"); i >= 0 {
143 line = line[:i]
144 }
145 f := strings.Fields(line)
146 if len(f) == 0 {
147 continue
148 }
149 switch f[0] {
150 default:
151 t.Fatalf("unknown directive %q", f[0])
152 case "pattern":
153 patterns = f[1:]
154 case "match", "not":
155 want := f[0] == "match"
156 for _, pattern := range patterns {
157 for _, in := range f[1:] {
158 if fn(pattern, in) != want {
159 t.Errorf("%s(%q, %q) = %v, want %v", name, pattern, in, !want, want)
160 }
161 }
162 }
163 }
164 }
165 }
166
View as plain text