blob: 3c83b8f5434f4787450562150e9859d9c01e5e07 [file] [log] [blame]
Marcel van Lohuizenbc4d65d2018-12-10 15:40:02 +01001// Copyright 2018 The CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package load
16
17import (
18 "strings"
19 "testing"
20)
21
22var matchPatternTests = `
23 pattern ...
24 match foo
25
26 pattern net
27 match net
28 not net/http
29
30 pattern net/http
31 match net/http
32 not net
33
34 pattern net...
35 match net net/http netchan
36 not not/http not/net/http
37
38 # Special cases. Quoting docs:
39
40 # First, /... at the end of the pattern can match an empty string,
41 # so that net/... matches both net and packages in its subdirectories, like net/http.
42 pattern net/...
43 match net net/http
44 not not/http not/net/http netchan
45
46 # Second, any slash-separted pattern element containing a wildcard never
47 # participates in a match of the "vendor" element in the path of a vendored
48 # package, so that ./... does not match packages in subdirectories of
49 # ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
50 # Note, however, that a directory named vendor that itself contains code
51 # is not a vendored package: cmd/vendor would be a command named vendor,
52 # and the pattern cmd/... matches it.
53 pattern ./...
54 match ./vendor ./mycode/vendor
55 not ./vendor/foo ./mycode/vendor/foo
56
57 pattern ./vendor/...
58 match ./vendor/foo ./vendor/foo/vendor
59 not ./vendor/foo/vendor/bar
60
61 pattern mycode/vendor/...
62 match mycode/vendor mycode/vendor/foo mycode/vendor/foo/vendor
63 not mycode/vendor/foo/vendor/bar
64
65 pattern x/vendor/y
66 match x/vendor/y
67 not x/vendor
68
69 pattern x/vendor/y/...
70 match x/vendor/y x/vendor/y/z x/vendor/y/vendor x/vendor/y/z/vendor
71 not x/vendor/y/vendor/z
72
73 pattern .../vendor/...
74 match x/vendor/y x/vendor/y/z x/vendor/y/vendor x/vendor/y/z/vendor
75`
76
77func TestMatchPattern(t *testing.T) {
78 testPatterns(t, "MatchPattern", matchPatternTests, func(pattern, name string) bool {
79 return matchPattern(pattern)(name)
80 })
81}
82
83var treeCanMatchPatternTests = `
84 pattern ...
85 match foo
86
87 pattern net
88 match net
89 not net/http
90
91 pattern net/http
92 match net net/http
93
94 pattern net...
95 match net netchan net/http
96 not not/http not/net/http
97
98 pattern net/...
99 match net net/http
100 not not/http netchan
101
102 pattern abc.../def
103 match abcxyz
104 not xyzabc
105
106 pattern x/y/z/...
107 match x x/y x/y/z x/y/z/w
108
109 pattern x/y/z
110 match x x/y x/y/z
111 not x/y/z/w
112
113 pattern x/.../y/z
114 match x/a/b/c
115 not y/x/a/b/c
116`
117
118func TestTreeCanMatchPattern(t *testing.T) {
119 testPatterns(t, "TreeCanMatchPattern", treeCanMatchPatternTests, func(pattern, name string) bool {
120 return treeCanMatchPattern(pattern)(name)
121 })
122}
123
124var hasPathPrefixTests = []stringPairTest{
125 {"abc", "a", false},
126 {"a/bc", "a", true},
127 {"a", "a", true},
128 {"a/bc", "a/", true},
129}
130
131func TestHasPathPrefix(t *testing.T) {
132 testStringPairs(t, "hasPathPrefix", hasPathPrefixTests, hasPathPrefix)
133}
134
135type stringPairTest struct {
136 in1 string
137 in2 string
138 out bool
139}
140
141func testStringPairs(t *testing.T, name string, tests []stringPairTest, f func(string, string) bool) {
142 for _, tt := range tests {
143 if out := f(tt.in1, tt.in2); out != tt.out {
144 t.Errorf("%s(%q, %q) = %v, want %v", name, tt.in1, tt.in2, out, tt.out)
145 }
146 }
147}
148
149func testPatterns(t *testing.T, name, tests string, fn func(string, string) bool) {
150 var patterns []string
151 for _, line := range strings.Split(tests, "\n") {
152 if i := strings.Index(line, "#"); i >= 0 {
153 line = line[:i]
154 }
155 f := strings.Fields(line)
156 if len(f) == 0 {
157 continue
158 }
159 switch f[0] {
160 default:
161 t.Fatalf("unknown directive %q", f[0])
162 case "pattern":
163 patterns = f[1:]
164 case "match", "not":
165 want := f[0] == "match"
166 for _, pattern := range patterns {
167 for _, in := range f[1:] {
168 if fn(pattern, in) != want {
169 t.Errorf("%s(%q, %q) = %v, want %v", name, pattern, in, !want, want)
170 }
171 }
172 }
173 }
174 }
175}