github.com/jd-ly/tools@v0.5.7/internal/gopathwalk/walk_test.go (about)

     1  // Copyright 2018 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.
     4  
     5  package gopathwalk
     6  
     7  import (
     8  	"io/ioutil"
     9  	"log"
    10  	"os"
    11  	"path/filepath"
    12  	"reflect"
    13  	"runtime"
    14  	"strings"
    15  	"sync"
    16  	"testing"
    17  )
    18  
    19  func TestShouldTraverse(t *testing.T) {
    20  	switch runtime.GOOS {
    21  	case "windows", "plan9":
    22  		t.Skipf("skipping symlink-requiring test on %s", runtime.GOOS)
    23  	}
    24  
    25  	dir, err := ioutil.TempDir("", "goimports-")
    26  	if err != nil {
    27  		t.Fatal(err)
    28  	}
    29  	defer os.RemoveAll(dir)
    30  
    31  	// Note: mapToDir prepends "src" to each element, since
    32  	// mapToDir was made for creating GOPATHs.
    33  	if err := mapToDir(dir, map[string]string{
    34  		"foo/foo2/file.txt":        "",
    35  		"foo/foo2/link-to-src":     "LINK:../../",
    36  		"foo/foo2/link-to-src-foo": "LINK:../../foo",
    37  		"foo/foo2/link-to-dot":     "LINK:.",
    38  		"bar/bar2/file.txt":        "",
    39  		"bar/bar2/link-to-src-foo": "LINK:../../foo",
    40  
    41  		"a/b/c": "LINK:../../a/d",
    42  		"a/d/e": "LINK:../../a/b",
    43  	}); err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	tests := []struct {
    47  		dir  string
    48  		file string
    49  		want bool
    50  	}{
    51  		{
    52  			dir:  "src/foo/foo2",
    53  			file: "link-to-src-foo",
    54  			want: false, // loop
    55  		},
    56  		{
    57  			dir:  "src/foo/foo2",
    58  			file: "link-to-src",
    59  			want: false, // loop
    60  		},
    61  		{
    62  			dir:  "src/foo/foo2",
    63  			file: "link-to-dot",
    64  			want: false, // loop
    65  		},
    66  		{
    67  			dir:  "src/bar/bar2",
    68  			file: "link-to-src-foo",
    69  			want: true, // not a loop
    70  		},
    71  		{
    72  			dir:  "src/a/b/c",
    73  			file: "e",
    74  			want: false, // loop: "e" is the same as "b".
    75  		},
    76  	}
    77  	for i, tt := range tests {
    78  		fi, err := os.Stat(filepath.Join(dir, tt.dir, tt.file))
    79  		if err != nil {
    80  			t.Errorf("%d. Stat = %v", i, err)
    81  			continue
    82  		}
    83  		var w walker
    84  		got := w.shouldTraverse(filepath.Join(dir, tt.dir), fi)
    85  		if got != tt.want {
    86  			t.Errorf("%d. shouldTraverse(%q, %q) = %v; want %v", i, tt.dir, tt.file, got, tt.want)
    87  		}
    88  	}
    89  }
    90  
    91  // TestSkip tests that various goimports rules are followed in non-modules mode.
    92  func TestSkip(t *testing.T) {
    93  	dir, err := ioutil.TempDir("", "goimports-")
    94  	if err != nil {
    95  		t.Fatal(err)
    96  	}
    97  	defer os.RemoveAll(dir)
    98  
    99  	if err := mapToDir(dir, map[string]string{
   100  		"ignoreme/f.go":     "package ignoreme",     // ignored by .goimportsignore
   101  		"node_modules/f.go": "package nodemodules;", // ignored by hardcoded node_modules filter
   102  		"v/f.go":            "package v;",           // ignored by hardcoded vgo cache rule
   103  		"mod/f.go":          "package mod;",         // ignored by hardcoded vgo cache rule
   104  		"shouldfind/f.go":   "package shouldfind;",  // not ignored
   105  
   106  		".goimportsignore": "ignoreme\n",
   107  	}); err != nil {
   108  		t.Fatal(err)
   109  	}
   110  
   111  	var found []string
   112  	var mu sync.Mutex
   113  	walkDir(Root{filepath.Join(dir, "src"), RootGOPATH},
   114  		func(root Root, dir string) {
   115  			mu.Lock()
   116  			defer mu.Unlock()
   117  			found = append(found, dir[len(root.Path)+1:])
   118  		}, func(root Root, dir string) bool {
   119  			return false
   120  		}, Options{ModulesEnabled: false, Logf: log.Printf})
   121  	if want := []string{"shouldfind"}; !reflect.DeepEqual(found, want) {
   122  		t.Errorf("expected to find only %v, got %v", want, found)
   123  	}
   124  }
   125  
   126  // TestSkipFunction tests that scan successfully skips directories from user callback.
   127  func TestSkipFunction(t *testing.T) {
   128  	dir, err := ioutil.TempDir("", "goimports-")
   129  	if err != nil {
   130  		t.Fatal(err)
   131  	}
   132  	defer os.RemoveAll(dir)
   133  
   134  	if err := mapToDir(dir, map[string]string{
   135  		"ignoreme/f.go":           "package ignoreme",    // ignored by skip
   136  		"ignoreme/subignore/f.go": "package subignore",   // also ignored by skip
   137  		"shouldfind/f.go":         "package shouldfind;", // not ignored
   138  	}); err != nil {
   139  		t.Fatal(err)
   140  	}
   141  
   142  	var found []string
   143  	var mu sync.Mutex
   144  	walkDir(Root{filepath.Join(dir, "src"), RootGOPATH},
   145  		func(root Root, dir string) {
   146  			mu.Lock()
   147  			defer mu.Unlock()
   148  			found = append(found, dir[len(root.Path)+1:])
   149  		}, func(root Root, dir string) bool {
   150  			return strings.HasSuffix(dir, "ignoreme")
   151  		},
   152  		Options{ModulesEnabled: false})
   153  	if want := []string{"shouldfind"}; !reflect.DeepEqual(found, want) {
   154  		t.Errorf("expected to find only %v, got %v", want, found)
   155  	}
   156  }
   157  
   158  func mapToDir(destDir string, files map[string]string) error {
   159  	for path, contents := range files {
   160  		file := filepath.Join(destDir, "src", path)
   161  		if err := os.MkdirAll(filepath.Dir(file), 0755); err != nil {
   162  			return err
   163  		}
   164  		var err error
   165  		if strings.HasPrefix(contents, "LINK:") {
   166  			err = os.Symlink(strings.TrimPrefix(contents, "LINK:"), file)
   167  		} else {
   168  			err = ioutil.WriteFile(file, []byte(contents), 0644)
   169  		}
   170  		if err != nil {
   171  			return err
   172  		}
   173  	}
   174  	return nil
   175  }