Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / internal / fastwalk / fastwalk_test.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/internal/fastwalk/fastwalk_test.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/internal/fastwalk/fastwalk_test.go
new file mode 100644 (file)
index 0000000..d896aeb
--- /dev/null
@@ -0,0 +1,252 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fastwalk_test
+
+import (
+       "bytes"
+       "flag"
+       "fmt"
+       "io/ioutil"
+       "os"
+       "path/filepath"
+       "reflect"
+       "runtime"
+       "sort"
+       "strings"
+       "sync"
+       "testing"
+
+       "golang.org/x/tools/internal/fastwalk"
+)
+
+func formatFileModes(m map[string]os.FileMode) string {
+       var keys []string
+       for k := range m {
+               keys = append(keys, k)
+       }
+       sort.Strings(keys)
+       var buf bytes.Buffer
+       for _, k := range keys {
+               fmt.Fprintf(&buf, "%-20s: %v\n", k, m[k])
+       }
+       return buf.String()
+}
+
+func testFastWalk(t *testing.T, files map[string]string, callback func(path string, typ os.FileMode) error, want map[string]os.FileMode) {
+       tempdir, err := ioutil.TempDir("", "test-fast-walk")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer os.RemoveAll(tempdir)
+
+       symlinks := map[string]string{}
+       for path, contents := range files {
+               file := filepath.Join(tempdir, "/src", path)
+               if err := os.MkdirAll(filepath.Dir(file), 0755); err != nil {
+                       t.Fatal(err)
+               }
+               var err error
+               if strings.HasPrefix(contents, "LINK:") {
+                       symlinks[file] = filepath.FromSlash(strings.TrimPrefix(contents, "LINK:"))
+               } else {
+                       err = ioutil.WriteFile(file, []byte(contents), 0644)
+               }
+               if err != nil {
+                       t.Fatal(err)
+               }
+       }
+
+       // Create symlinks after all other files. Otherwise, directory symlinks on
+       // Windows are unusable (see https://golang.org/issue/39183).
+       for file, dst := range symlinks {
+               err = os.Symlink(dst, file)
+               if err != nil {
+                       if writeErr := ioutil.WriteFile(file, []byte(dst), 0644); writeErr == nil {
+                               // Couldn't create symlink, but could write the file.
+                               // Probably this filesystem doesn't support symlinks.
+                               // (Perhaps we are on an older Windows and not running as administrator.)
+                               t.Skipf("skipping because symlinks appear to be unsupported: %v", err)
+                       }
+               }
+       }
+
+       got := map[string]os.FileMode{}
+       var mu sync.Mutex
+       err = fastwalk.Walk(tempdir, func(path string, typ os.FileMode) error {
+               mu.Lock()
+               defer mu.Unlock()
+               if !strings.HasPrefix(path, tempdir) {
+                       t.Errorf("bogus prefix on %q, expect %q", path, tempdir)
+               }
+               key := filepath.ToSlash(strings.TrimPrefix(path, tempdir))
+               if old, dup := got[key]; dup {
+                       t.Errorf("callback called twice for key %q: %v -> %v", key, old, typ)
+               }
+               got[key] = typ
+               return callback(path, typ)
+       })
+
+       if err != nil {
+               t.Fatalf("callback returned: %v", err)
+       }
+       if !reflect.DeepEqual(got, want) {
+               t.Errorf("walk mismatch.\n got:\n%v\nwant:\n%v", formatFileModes(got), formatFileModes(want))
+       }
+}
+
+func TestFastWalk_Basic(t *testing.T) {
+       testFastWalk(t, map[string]string{
+               "foo/foo.go":   "one",
+               "bar/bar.go":   "two",
+               "skip/skip.go": "skip",
+       },
+               func(path string, typ os.FileMode) error {
+                       return nil
+               },
+               map[string]os.FileMode{
+                       "":                  os.ModeDir,
+                       "/src":              os.ModeDir,
+                       "/src/bar":          os.ModeDir,
+                       "/src/bar/bar.go":   0,
+                       "/src/foo":          os.ModeDir,
+                       "/src/foo/foo.go":   0,
+                       "/src/skip":         os.ModeDir,
+                       "/src/skip/skip.go": 0,
+               })
+}
+
+func TestFastWalk_LongFileName(t *testing.T) {
+       longFileName := strings.Repeat("x", 255)
+
+       testFastWalk(t, map[string]string{
+               longFileName: "one",
+       },
+               func(path string, typ os.FileMode) error {
+                       return nil
+               },
+               map[string]os.FileMode{
+                       "":                     os.ModeDir,
+                       "/src":                 os.ModeDir,
+                       "/src/" + longFileName: 0,
+               },
+       )
+}
+
+func TestFastWalk_Symlink(t *testing.T) {
+       testFastWalk(t, map[string]string{
+               "foo/foo.go":       "one",
+               "bar/bar.go":       "LINK:../foo/foo.go",
+               "symdir":           "LINK:foo",
+               "broken/broken.go": "LINK:../nonexistent",
+       },
+               func(path string, typ os.FileMode) error {
+                       return nil
+               },
+               map[string]os.FileMode{
+                       "":                      os.ModeDir,
+                       "/src":                  os.ModeDir,
+                       "/src/bar":              os.ModeDir,
+                       "/src/bar/bar.go":       os.ModeSymlink,
+                       "/src/foo":              os.ModeDir,
+                       "/src/foo/foo.go":       0,
+                       "/src/symdir":           os.ModeSymlink,
+                       "/src/broken":           os.ModeDir,
+                       "/src/broken/broken.go": os.ModeSymlink,
+               })
+}
+
+func TestFastWalk_SkipDir(t *testing.T) {
+       testFastWalk(t, map[string]string{
+               "foo/foo.go":   "one",
+               "bar/bar.go":   "two",
+               "skip/skip.go": "skip",
+       },
+               func(path string, typ os.FileMode) error {
+                       if typ == os.ModeDir && strings.HasSuffix(path, "skip") {
+                               return filepath.SkipDir
+                       }
+                       return nil
+               },
+               map[string]os.FileMode{
+                       "":                os.ModeDir,
+                       "/src":            os.ModeDir,
+                       "/src/bar":        os.ModeDir,
+                       "/src/bar/bar.go": 0,
+                       "/src/foo":        os.ModeDir,
+                       "/src/foo/foo.go": 0,
+                       "/src/skip":       os.ModeDir,
+               })
+}
+
+func TestFastWalk_SkipFiles(t *testing.T) {
+       // Directory iteration order is undefined, so there's no way to know
+       // which file to expect until the walk happens. Rather than mess
+       // with the test infrastructure, just mutate want.
+       var mu sync.Mutex
+       want := map[string]os.FileMode{
+               "":              os.ModeDir,
+               "/src":          os.ModeDir,
+               "/src/zzz":      os.ModeDir,
+               "/src/zzz/c.go": 0,
+       }
+
+       testFastWalk(t, map[string]string{
+               "a_skipfiles.go": "a",
+               "b_skipfiles.go": "b",
+               "zzz/c.go":       "c",
+       },
+               func(path string, typ os.FileMode) error {
+                       if strings.HasSuffix(path, "_skipfiles.go") {
+                               mu.Lock()
+                               defer mu.Unlock()
+                               want["/src/"+filepath.Base(path)] = 0
+                               return fastwalk.ErrSkipFiles
+                       }
+                       return nil
+               },
+               want)
+       if len(want) != 5 {
+               t.Errorf("saw too many files: wanted 5, got %v (%v)", len(want), want)
+       }
+}
+
+func TestFastWalk_TraverseSymlink(t *testing.T) {
+       testFastWalk(t, map[string]string{
+               "foo/foo.go":   "one",
+               "bar/bar.go":   "two",
+               "skip/skip.go": "skip",
+               "symdir":       "LINK:foo",
+       },
+               func(path string, typ os.FileMode) error {
+                       if typ == os.ModeSymlink {
+                               return fastwalk.ErrTraverseLink
+                       }
+                       return nil
+               },
+               map[string]os.FileMode{
+                       "":                   os.ModeDir,
+                       "/src":               os.ModeDir,
+                       "/src/bar":           os.ModeDir,
+                       "/src/bar/bar.go":    0,
+                       "/src/foo":           os.ModeDir,
+                       "/src/foo/foo.go":    0,
+                       "/src/skip":          os.ModeDir,
+                       "/src/skip/skip.go":  0,
+                       "/src/symdir":        os.ModeSymlink,
+                       "/src/symdir/foo.go": 0,
+               })
+}
+
+var benchDir = flag.String("benchdir", runtime.GOROOT(), "The directory to scan for BenchmarkFastWalk")
+
+func BenchmarkFastWalk(b *testing.B) {
+       b.ReportAllocs()
+       for i := 0; i < b.N; i++ {
+               err := fastwalk.Walk(*benchDir, func(path string, typ os.FileMode) error { return nil })
+               if err != nil {
+                       b.Fatal(err)
+               }
+       }
+}