c++: address deduction and concepts [CWG2918]
[official-gcc.git] / libgo / go / path / filepath / match_test.go
blob3d90982cab92d9b06de3af0e1901a1541521ee27
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package filepath_test
7 import (
8 "fmt"
9 "internal/testenv"
10 "os"
11 . "path/filepath"
12 "reflect"
13 "runtime"
14 "sort"
15 "strings"
16 "testing"
19 type MatchTest struct {
20 pattern, s string
21 match bool
22 err error
25 var matchTests = []MatchTest{
26 {"abc", "abc", true, nil},
27 {"*", "abc", true, nil},
28 {"*c", "abc", true, nil},
29 {"a*", "a", true, nil},
30 {"a*", "abc", true, nil},
31 {"a*", "ab/c", false, nil},
32 {"a*/b", "abc/b", true, nil},
33 {"a*/b", "a/c/b", false, nil},
34 {"a*b*c*d*e*/f", "axbxcxdxe/f", true, nil},
35 {"a*b*c*d*e*/f", "axbxcxdxexxx/f", true, nil},
36 {"a*b*c*d*e*/f", "axbxcxdxe/xxx/f", false, nil},
37 {"a*b*c*d*e*/f", "axbxcxdxexxx/fff", false, nil},
38 {"a*b?c*x", "abxbbxdbxebxczzx", true, nil},
39 {"a*b?c*x", "abxbbxdbxebxczzy", false, nil},
40 {"ab[c]", "abc", true, nil},
41 {"ab[b-d]", "abc", true, nil},
42 {"ab[e-g]", "abc", false, nil},
43 {"ab[^c]", "abc", false, nil},
44 {"ab[^b-d]", "abc", false, nil},
45 {"ab[^e-g]", "abc", true, nil},
46 {"a\\*b", "a*b", true, nil},
47 {"a\\*b", "ab", false, nil},
48 {"a?b", "a☺b", true, nil},
49 {"a[^a]b", "a☺b", true, nil},
50 {"a???b", "a☺b", false, nil},
51 {"a[^a][^a][^a]b", "a☺b", false, nil},
52 {"[a-ζ]*", "α", true, nil},
53 {"*[a-ζ]", "A", false, nil},
54 {"a?b", "a/b", false, nil},
55 {"a*b", "a/b", false, nil},
56 {"[\\]a]", "]", true, nil},
57 {"[\\-]", "-", true, nil},
58 {"[x\\-]", "x", true, nil},
59 {"[x\\-]", "-", true, nil},
60 {"[x\\-]", "z", false, nil},
61 {"[\\-x]", "x", true, nil},
62 {"[\\-x]", "-", true, nil},
63 {"[\\-x]", "a", false, nil},
64 {"[]a]", "]", false, ErrBadPattern},
65 {"[-]", "-", false, ErrBadPattern},
66 {"[x-]", "x", false, ErrBadPattern},
67 {"[x-]", "-", false, ErrBadPattern},
68 {"[x-]", "z", false, ErrBadPattern},
69 {"[-x]", "x", false, ErrBadPattern},
70 {"[-x]", "-", false, ErrBadPattern},
71 {"[-x]", "a", false, ErrBadPattern},
72 {"\\", "a", false, ErrBadPattern},
73 {"[a-b-c]", "a", false, ErrBadPattern},
74 {"[", "a", false, ErrBadPattern},
75 {"[^", "a", false, ErrBadPattern},
76 {"[^bc", "a", false, ErrBadPattern},
77 {"a[", "a", false, ErrBadPattern},
78 {"a[", "ab", false, ErrBadPattern},
79 {"a[", "x", false, ErrBadPattern},
80 {"a/b[", "x", false, ErrBadPattern},
81 {"*x", "xxx", true, nil},
84 func errp(e error) string {
85 if e == nil {
86 return "<nil>"
88 return e.Error()
91 func TestMatch(t *testing.T) {
92 for _, tt := range matchTests {
93 pattern := tt.pattern
94 s := tt.s
95 if runtime.GOOS == "windows" {
96 if strings.Contains(pattern, "\\") {
97 // no escape allowed on windows.
98 continue
100 pattern = Clean(pattern)
101 s = Clean(s)
103 ok, err := Match(pattern, s)
104 if ok != tt.match || err != tt.err {
105 t.Errorf("Match(%#q, %#q) = %v, %q want %v, %q", pattern, s, ok, errp(err), tt.match, errp(tt.err))
110 // contains reports whether vector contains the string s.
111 func contains(vector []string, s string) bool {
112 for _, elem := range vector {
113 if elem == s {
114 return true
117 return false
120 var globTests = []struct {
121 pattern, result string
123 {"match.go", "match.go"},
124 {"mat?h.go", "match.go"},
125 {"*", "match.go"},
126 // Does not work in gccgo test environment.
127 // {"../*/match.go", "../filepath/match.go"},
130 func TestGlob(t *testing.T) {
131 for _, tt := range globTests {
132 pattern := tt.pattern
133 result := tt.result
134 if runtime.GOOS == "windows" {
135 pattern = Clean(pattern)
136 result = Clean(result)
138 matches, err := Glob(pattern)
139 if err != nil {
140 t.Errorf("Glob error for %q: %s", pattern, err)
141 continue
143 if !contains(matches, result) {
144 t.Errorf("Glob(%#q) = %#v want %v", pattern, matches, result)
147 for _, pattern := range []string{"no_match", "../*/no_match"} {
148 matches, err := Glob(pattern)
149 if err != nil {
150 t.Errorf("Glob error for %q: %s", pattern, err)
151 continue
153 if len(matches) != 0 {
154 t.Errorf("Glob(%#q) = %#v want []", pattern, matches)
159 func TestGlobError(t *testing.T) {
160 bad := []string{`[]`, `nonexist/[]`}
161 for _, pattern := range bad {
162 if _, err := Glob(pattern); err != ErrBadPattern {
163 t.Errorf("Glob(%#q) returned err=%v, want ErrBadPattern", pattern, err)
168 func TestGlobUNC(t *testing.T) {
169 // Just make sure this runs without crashing for now.
170 // See issue 15879.
171 Glob(`\\?\C:\*`)
174 var globSymlinkTests = []struct {
175 path, dest string
176 brokenLink bool
178 {"test1", "link1", false},
179 {"test2", "link2", true},
182 func TestGlobSymlink(t *testing.T) {
183 testenv.MustHaveSymlink(t)
185 tmpDir := t.TempDir()
186 for _, tt := range globSymlinkTests {
187 path := Join(tmpDir, tt.path)
188 dest := Join(tmpDir, tt.dest)
189 f, err := os.Create(path)
190 if err != nil {
191 t.Fatal(err)
193 if err := f.Close(); err != nil {
194 t.Fatal(err)
196 err = os.Symlink(path, dest)
197 if err != nil {
198 t.Fatal(err)
200 if tt.brokenLink {
201 // Break the symlink.
202 os.Remove(path)
204 matches, err := Glob(dest)
205 if err != nil {
206 t.Errorf("GlobSymlink error for %q: %s", dest, err)
208 if !contains(matches, dest) {
209 t.Errorf("Glob(%#q) = %#v want %v", dest, matches, dest)
214 type globTest struct {
215 pattern string
216 matches []string
219 func (test *globTest) buildWant(root string) []string {
220 want := make([]string, 0)
221 for _, m := range test.matches {
222 want = append(want, root+FromSlash(m))
224 sort.Strings(want)
225 return want
228 func (test *globTest) globAbs(root, rootPattern string) error {
229 p := FromSlash(rootPattern + `\` + test.pattern)
230 have, err := Glob(p)
231 if err != nil {
232 return err
234 sort.Strings(have)
235 want := test.buildWant(root + `\`)
236 if strings.Join(want, "_") == strings.Join(have, "_") {
237 return nil
239 return fmt.Errorf("Glob(%q) returns %q, but %q expected", p, have, want)
242 func (test *globTest) globRel(root string) error {
243 p := root + FromSlash(test.pattern)
244 have, err := Glob(p)
245 if err != nil {
246 return err
248 sort.Strings(have)
249 want := test.buildWant(root)
250 if strings.Join(want, "_") == strings.Join(have, "_") {
251 return nil
253 // try also matching version without root prefix
254 wantWithNoRoot := test.buildWant("")
255 if strings.Join(wantWithNoRoot, "_") == strings.Join(have, "_") {
256 return nil
258 return fmt.Errorf("Glob(%q) returns %q, but %q expected", p, have, want)
261 func TestWindowsGlob(t *testing.T) {
262 if runtime.GOOS != "windows" {
263 t.Skipf("skipping windows specific test")
266 tmpDir := tempDirCanonical(t)
267 if len(tmpDir) < 3 {
268 t.Fatalf("tmpDir path %q is too short", tmpDir)
270 if tmpDir[1] != ':' {
271 t.Fatalf("tmpDir path %q must have drive letter in it", tmpDir)
274 dirs := []string{
275 "a",
276 "b",
277 "dir/d/bin",
279 files := []string{
280 "dir/d/bin/git.exe",
282 for _, dir := range dirs {
283 err := os.MkdirAll(Join(tmpDir, dir), 0777)
284 if err != nil {
285 t.Fatal(err)
288 for _, file := range files {
289 err := os.WriteFile(Join(tmpDir, file), nil, 0666)
290 if err != nil {
291 t.Fatal(err)
295 tests := []globTest{
296 {"a", []string{"a"}},
297 {"b", []string{"b"}},
298 {"c", []string{}},
299 {"*", []string{"a", "b", "dir"}},
300 {"d*", []string{"dir"}},
301 {"*i*", []string{"dir"}},
302 {"*r", []string{"dir"}},
303 {"?ir", []string{"dir"}},
304 {"?r", []string{}},
305 {"d*/*/bin/git.exe", []string{"dir/d/bin/git.exe"}},
308 // test absolute paths
309 for _, test := range tests {
310 var p string
311 if err := test.globAbs(tmpDir, tmpDir); err != nil {
312 t.Error(err)
314 // test C:\*Documents and Settings\...
315 p = tmpDir
316 p = strings.Replace(p, `:\`, `:\*`, 1)
317 if err := test.globAbs(tmpDir, p); err != nil {
318 t.Error(err)
320 // test C:\Documents and Settings*\...
321 p = tmpDir
322 p = strings.Replace(p, `:\`, `:`, 1)
323 p = strings.Replace(p, `\`, `*\`, 1)
324 p = strings.Replace(p, `:`, `:\`, 1)
325 if err := test.globAbs(tmpDir, p); err != nil {
326 t.Error(err)
330 // test relative paths
331 wd, err := os.Getwd()
332 if err != nil {
333 t.Fatal(err)
335 err = os.Chdir(tmpDir)
336 if err != nil {
337 t.Fatal(err)
339 defer func() {
340 err := os.Chdir(wd)
341 if err != nil {
342 t.Fatal(err)
345 for _, test := range tests {
346 err := test.globRel("")
347 if err != nil {
348 t.Error(err)
350 err = test.globRel(`.\`)
351 if err != nil {
352 t.Error(err)
354 err = test.globRel(tmpDir[:2]) // C:
355 if err != nil {
356 t.Error(err)
361 func TestNonWindowsGlobEscape(t *testing.T) {
362 if runtime.GOOS == "windows" {
363 t.Skipf("skipping non-windows specific test")
365 pattern := `\match.go`
366 want := []string{"match.go"}
367 matches, err := Glob(pattern)
368 if err != nil {
369 t.Fatalf("Glob error for %q: %s", pattern, err)
371 if !reflect.DeepEqual(matches, want) {
372 t.Fatalf("Glob(%#q) = %v want %v", pattern, matches, want)