• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2014 Google Inc. All rights reserved.
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 pathtools
16
17import (
18	"os"
19	"path/filepath"
20	"reflect"
21	"testing"
22)
23
24var pwd, _ = os.Getwd()
25
26var globTestCases = []struct {
27	pattern  string
28	matches  []string
29	excludes []string
30	dirs     []string
31	err      error
32}{
33	// Current directory tests
34	{
35		pattern: "*",
36		matches: []string{"a", "b", "c", "d.ext", "e.ext"},
37		dirs:    []string{"."},
38	},
39	{
40		pattern: "*.ext",
41		matches: []string{"d.ext", "e.ext"},
42		dirs:    []string{"."},
43	},
44	{
45		pattern: "*/a",
46		matches: []string{"a/a", "b/a"},
47		dirs:    []string{".", "a", "b", "c"},
48	},
49	{
50		pattern: "*/*/a",
51		matches: []string{"a/a/a"},
52		dirs:    []string{".", "a", "b", "c", "a/a", "a/b", "c/f", "c/g", "c/h"},
53	},
54	{
55		pattern: "*/a/a",
56		matches: []string{"a/a/a"},
57		dirs:    []string{".", "a", "b", "c", "a/a"},
58	},
59
60	// ./ directory tests
61	{
62		pattern: "./*",
63		matches: []string{"a", "b", "c", "d.ext", "e.ext"},
64		dirs:    []string{"."},
65	},
66	{
67		pattern: "./*.ext",
68		matches: []string{"d.ext", "e.ext"},
69		dirs:    []string{"."},
70	},
71	{
72		pattern: "./*/a",
73		matches: []string{"a/a", "b/a"},
74		dirs:    []string{".", "a", "b", "c"},
75	},
76	{
77		pattern: "./[ac]/a",
78		matches: []string{"a/a"},
79		dirs:    []string{".", "a", "c"},
80	},
81
82	// subdirectory tests
83	{
84		pattern: "c/*/*.ext",
85		matches: []string{"c/f/f.ext", "c/g/g.ext"},
86		dirs:    []string{"c", "c/f", "c/g", "c/h"},
87	},
88	{
89		pattern: "a/*/a",
90		matches: []string{"a/a/a"},
91		dirs:    []string{"a", "a/a", "a/b"},
92	},
93
94	// absolute tests
95	{
96		pattern: filepath.Join(pwd, "testdata/c/*/*.ext"),
97		matches: []string{
98			filepath.Join(pwd, "testdata/c/f/f.ext"),
99			filepath.Join(pwd, "testdata/c/g/g.ext"),
100		},
101		dirs: []string{
102			filepath.Join(pwd, "testdata/c"),
103			filepath.Join(pwd, "testdata/c/f"),
104			filepath.Join(pwd, "testdata/c/g"),
105			filepath.Join(pwd, "testdata/c/h"),
106		},
107	},
108
109	// no-wild tests
110	{
111		pattern: "a",
112		matches: []string{"a"},
113		dirs:    nil,
114	},
115	{
116		pattern: "a/a",
117		matches: []string{"a/a"},
118		dirs:    nil,
119	},
120
121	// clean tests
122	{
123		pattern: "./c/*/*.ext",
124		matches: []string{"c/f/f.ext", "c/g/g.ext"},
125		dirs:    []string{"c", "c/f", "c/g", "c/h"},
126	},
127	{
128		pattern: "c/../c/*/*.ext",
129		matches: []string{"c/f/f.ext", "c/g/g.ext"},
130		dirs:    []string{"c", "c/f", "c/g", "c/h"},
131	},
132
133	// recursive tests
134	{
135		pattern: "**/a",
136		matches: []string{"a", "a/a", "a/a/a", "b/a"},
137		dirs:    []string{".", "a", "a/a", "a/b", "b", "c", "c/f", "c/g", "c/h"},
138	},
139	{
140		pattern: "a/**/a",
141		matches: []string{"a/a", "a/a/a"},
142		dirs:    []string{"a", "a/a", "a/b"},
143	},
144	{
145		pattern: "a/**/*",
146		matches: []string{"a/a", "a/b", "a/a/a", "a/b/b"},
147		dirs:    []string{"a", "a/a", "a/b"},
148	},
149
150	// absolute recursive tests
151	{
152		pattern: filepath.Join(pwd, "testdata/**/*.ext"),
153		matches: []string{
154			filepath.Join(pwd, "testdata/d.ext"),
155			filepath.Join(pwd, "testdata/e.ext"),
156			filepath.Join(pwd, "testdata/c/f/f.ext"),
157			filepath.Join(pwd, "testdata/c/g/g.ext"),
158		},
159		dirs: []string{
160			filepath.Join(pwd, "testdata"),
161			filepath.Join(pwd, "testdata/a"),
162			filepath.Join(pwd, "testdata/a/a"),
163			filepath.Join(pwd, "testdata/a/b"),
164			filepath.Join(pwd, "testdata/b"),
165			filepath.Join(pwd, "testdata/c"),
166			filepath.Join(pwd, "testdata/c/f"),
167			filepath.Join(pwd, "testdata/c/g"),
168			filepath.Join(pwd, "testdata/c/h"),
169		},
170	},
171
172	// recursive error tests
173	{
174		pattern: "**/**/*",
175		err:     GlobMultipleRecursiveErr,
176	},
177	{
178		pattern: "a/**/**/*",
179		err:     GlobMultipleRecursiveErr,
180	},
181	{
182		pattern: "**/a/**/*",
183		err:     GlobMultipleRecursiveErr,
184	},
185	{
186		pattern: "**/**/a/*",
187		err:     GlobMultipleRecursiveErr,
188	},
189	{
190		pattern: "a/**",
191		err:     GlobLastRecursiveErr,
192	},
193	{
194		pattern: "**/**",
195		err:     GlobLastRecursiveErr,
196	},
197
198	// exclude tests
199	{
200		pattern:  "*.ext",
201		excludes: []string{"d.ext"},
202		matches:  []string{"e.ext"},
203		dirs:     []string{"."},
204	},
205	{
206		pattern:  "*/*",
207		excludes: []string{"a/b"},
208		matches:  []string{"a/a", "b/a", "c/c", "c/f", "c/g", "c/h"},
209		dirs:     []string{".", "a", "b", "c"},
210	},
211	{
212		pattern:  "*/*",
213		excludes: []string{"a/b", "c/c"},
214		matches:  []string{"a/a", "b/a", "c/f", "c/g", "c/h"},
215		dirs:     []string{".", "a", "b", "c"},
216	},
217	{
218		pattern:  "*/*",
219		excludes: []string{"c/*", "*/a"},
220		matches:  []string{"a/b"},
221		dirs:     []string{".", "a", "b", "c"},
222	},
223	{
224		pattern:  "*/*",
225		excludes: []string{"*/*"},
226		matches:  nil,
227		dirs:     []string{".", "a", "b", "c"},
228	},
229
230	// absolute exclude tests
231	{
232		pattern:  filepath.Join(pwd, "testdata/c/*/*.ext"),
233		excludes: []string{filepath.Join(pwd, "testdata/c/*/f.ext")},
234		matches: []string{
235			filepath.Join(pwd, "testdata/c/g/g.ext"),
236		},
237		dirs: []string{
238			filepath.Join(pwd, "testdata/c"),
239			filepath.Join(pwd, "testdata/c/f"),
240			filepath.Join(pwd, "testdata/c/g"),
241			filepath.Join(pwd, "testdata/c/h"),
242		},
243	},
244	{
245		pattern:  filepath.Join(pwd, "testdata/c/*/*.ext"),
246		excludes: []string{filepath.Join(pwd, "testdata/c/f/*.ext")},
247		matches: []string{
248			filepath.Join(pwd, "testdata/c/g/g.ext"),
249		},
250		dirs: []string{
251			filepath.Join(pwd, "testdata/c"),
252			filepath.Join(pwd, "testdata/c/f"),
253			filepath.Join(pwd, "testdata/c/g"),
254			filepath.Join(pwd, "testdata/c/h"),
255		},
256	},
257
258	// recursive exclude tests
259	{
260		pattern:  "*.ext",
261		excludes: []string{"**/*.ext"},
262		matches:  nil,
263		dirs:     []string{"."},
264	},
265	{
266		pattern:  "*/*",
267		excludes: []string{"**/b"},
268		matches:  []string{"a/a", "b/a", "c/c", "c/f", "c/g", "c/h"},
269		dirs:     []string{".", "a", "b", "c"},
270	},
271	{
272		pattern:  "*/*",
273		excludes: []string{"a/**/*"},
274		matches:  []string{"b/a", "c/c", "c/f", "c/g", "c/h"},
275		dirs:     []string{".", "a", "b", "c"},
276	},
277	{
278		pattern:  "**/*",
279		excludes: []string{"**/*"},
280		matches:  nil,
281		dirs:     []string{".", "a", "a/a", "a/b", "b", "c", "c/f", "c/g", "c/h"},
282	},
283	{
284		pattern:  "*/*/*",
285		excludes: []string{"a/**/a"},
286		matches:  []string{"a/b/b", "c/f/f.ext", "c/g/g.ext", "c/h/h"},
287		dirs:     []string{".", "a", "b", "c", "a/a", "a/b", "c/f", "c/g", "c/h"},
288	},
289	{
290		pattern:  "*/*/*",
291		excludes: []string{"**/a"},
292		matches:  []string{"a/b/b", "c/f/f.ext", "c/g/g.ext", "c/h/h"},
293		dirs:     []string{".", "a", "b", "c", "a/a", "a/b", "c/f", "c/g", "c/h"},
294	},
295	{
296		pattern:  "c/*/*.ext",
297		excludes: []string{"c/**/f.ext"},
298		matches:  []string{"c/g/g.ext"},
299		dirs:     []string{"c", "c/f", "c/g", "c/h"},
300	},
301
302	// absoulte recursive exclude tests
303	{
304		pattern:  filepath.Join(pwd, "testdata/c/*/*.ext"),
305		excludes: []string{filepath.Join(pwd, "testdata/**/f.ext")},
306		matches: []string{
307			filepath.Join(pwd, "testdata/c/g/g.ext"),
308		},
309		dirs: []string{
310			filepath.Join(pwd, "testdata/c"),
311			filepath.Join(pwd, "testdata/c/f"),
312			filepath.Join(pwd, "testdata/c/g"),
313			filepath.Join(pwd, "testdata/c/h"),
314		},
315	},
316
317	// clean exclude tests
318	{
319		pattern:  "./c/*/*.ext",
320		excludes: []string{"./c/*/f.ext"},
321		matches:  []string{"c/g/g.ext"},
322		dirs:     []string{"c", "c/f", "c/g", "c/h"},
323	},
324	{
325		pattern:  "c/*/*.ext",
326		excludes: []string{"./c/*/f.ext"},
327		matches:  []string{"c/g/g.ext"},
328		dirs:     []string{"c", "c/f", "c/g", "c/h"},
329	},
330	{
331		pattern:  "./c/*/*.ext",
332		excludes: []string{"c/*/f.ext"},
333		matches:  []string{"c/g/g.ext"},
334		dirs:     []string{"c", "c/f", "c/g", "c/h"},
335	},
336
337	// non-existant non-wild path tests
338	{
339		pattern: "d/*",
340		matches: nil,
341		dirs:    []string{"."},
342	},
343	{
344		pattern: "d",
345		matches: nil,
346		dirs:    []string{"."},
347	},
348	{
349		pattern: "a/d/*",
350		matches: nil,
351		dirs:    []string{"a"},
352	},
353	{
354		pattern: "a/d",
355		matches: nil,
356		dirs:    []string{"a"},
357	},
358	{
359		pattern: "a/a/d/*",
360		matches: nil,
361		dirs:    []string{"a/a"},
362	},
363	{
364		pattern: "a/a/d",
365		matches: nil,
366		dirs:    []string{"a/a"},
367	},
368	{
369		pattern: "a/d/a/*",
370		matches: nil,
371		dirs:    []string{"a"},
372	},
373	{
374		pattern: "a/d/a",
375		matches: nil,
376		dirs:    []string{"a"},
377	},
378	{
379		pattern: "a/d/a/*/a",
380		matches: nil,
381		dirs:    []string{"a"},
382	},
383	{
384		pattern: "a/d/a/**/a",
385		matches: nil,
386		dirs:    []string{"a"},
387	},
388
389	// recursive exclude error tests
390	{
391		pattern:  "**/*",
392		excludes: []string{"**/**/*"},
393		err:      GlobMultipleRecursiveErr,
394	},
395	{
396		pattern:  "**/*",
397		excludes: []string{"a/**/**/*"},
398		err:      GlobMultipleRecursiveErr,
399	},
400	{
401		pattern:  "**/*",
402		excludes: []string{"**/a/**/*"},
403		err:      GlobMultipleRecursiveErr,
404	},
405	{
406		pattern:  "**/*",
407		excludes: []string{"**/**/a/*"},
408		err:      GlobMultipleRecursiveErr,
409	},
410	{
411		pattern:  "**/*",
412		excludes: []string{"a/**"},
413		err:      GlobLastRecursiveErr,
414	},
415	{
416		pattern:  "**/*",
417		excludes: []string{"**/**"},
418		err:      GlobLastRecursiveErr,
419	},
420}
421
422func TestGlob(t *testing.T) {
423	os.Chdir("testdata")
424	defer os.Chdir("..")
425	for _, testCase := range globTestCases {
426		matches, dirs, err := GlobWithExcludes(testCase.pattern, testCase.excludes)
427		if err != testCase.err {
428			t.Errorf(" pattern: %q", testCase.pattern)
429			if testCase.excludes != nil {
430				t.Errorf("excludes: %q", testCase.excludes)
431			}
432			t.Errorf("   error: %s", err)
433			continue
434		}
435
436		if !reflect.DeepEqual(matches, testCase.matches) {
437			t.Errorf("incorrect matches list:")
438			t.Errorf(" pattern: %q", testCase.pattern)
439			if testCase.excludes != nil {
440				t.Errorf("excludes: %q", testCase.excludes)
441			}
442			t.Errorf("     got: %#v", matches)
443			t.Errorf("expected: %#v", testCase.matches)
444		}
445		if !reflect.DeepEqual(dirs, testCase.dirs) {
446			t.Errorf("incorrect dirs list:")
447			t.Errorf(" pattern: %q", testCase.pattern)
448			if testCase.excludes != nil {
449				t.Errorf("excludes: %q", testCase.excludes)
450			}
451			t.Errorf("     got: %#v", dirs)
452			t.Errorf("expected: %#v", testCase.dirs)
453		}
454	}
455}
456