github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/internal/lsp/cache/view_test.go (about)

     1  // Copyright 2020 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  package cache
     5  
     6  import (
     7  	"context"
     8  	"io/ioutil"
     9  	"os"
    10  	"path/filepath"
    11  	"testing"
    12  
    13  	"github.com/powerman/golang-tools/internal/lsp/fake"
    14  	"github.com/powerman/golang-tools/internal/lsp/source"
    15  	"github.com/powerman/golang-tools/internal/span"
    16  )
    17  
    18  func TestCaseInsensitiveFilesystem(t *testing.T) {
    19  	base, err := ioutil.TempDir("", t.Name())
    20  	if err != nil {
    21  		t.Fatal(err)
    22  	}
    23  
    24  	inner := filepath.Join(base, "a/B/c/DEFgh")
    25  	if err := os.MkdirAll(inner, 0777); err != nil {
    26  		t.Fatal(err)
    27  	}
    28  	file := filepath.Join(inner, "f.go")
    29  	if err := ioutil.WriteFile(file, []byte("hi"), 0777); err != nil {
    30  		t.Fatal(err)
    31  	}
    32  	if _, err := os.Stat(filepath.Join(inner, "F.go")); err != nil {
    33  		t.Skip("filesystem is case-sensitive")
    34  	}
    35  
    36  	tests := []struct {
    37  		path string
    38  		err  bool
    39  	}{
    40  		{file, false},
    41  		{filepath.Join(inner, "F.go"), true},
    42  		{filepath.Join(base, "a/b/c/defgh/f.go"), true},
    43  	}
    44  	for _, tt := range tests {
    45  		err := checkPathCase(tt.path)
    46  		if err != nil != tt.err {
    47  			t.Errorf("checkPathCase(%q) = %v, wanted error: %v", tt.path, err, tt.err)
    48  		}
    49  	}
    50  }
    51  
    52  func TestFindWorkspaceRoot(t *testing.T) {
    53  	workspace := `
    54  -- a/go.mod --
    55  module a
    56  -- a/x/x.go
    57  package x
    58  -- a/x/y/y.go
    59  package x
    60  -- b/go.mod --
    61  module b
    62  -- b/c/go.mod --
    63  module bc
    64  -- d/gopls.mod --
    65  module d-goplsworkspace
    66  -- d/e/go.mod --
    67  module de
    68  -- f/g/go.mod --
    69  module fg
    70  `
    71  	dir, err := fake.Tempdir(fake.UnpackTxt(workspace))
    72  	if err != nil {
    73  		t.Fatal(err)
    74  	}
    75  	defer os.RemoveAll(dir)
    76  
    77  	tests := []struct {
    78  		folder, want string
    79  		experimental bool
    80  	}{
    81  		{"", "", false}, // no module at root, and more than one nested module
    82  		{"a", "a", false},
    83  		{"a/x", "a", false},
    84  		{"a/x/y", "a", false},
    85  		{"b/c", "b/c", false},
    86  		{"d", "d/e", false},
    87  		{"d", "d", true},
    88  		{"d/e", "d/e", false},
    89  		{"d/e", "d", true},
    90  		{"f", "f/g", false},
    91  		{"f", "f", true},
    92  	}
    93  
    94  	for _, test := range tests {
    95  		ctx := context.Background()
    96  		rel := fake.RelativeTo(dir)
    97  		folderURI := span.URIFromPath(rel.AbsPath(test.folder))
    98  		excludeNothing := func(string) bool { return false }
    99  		got, err := findWorkspaceRoot(ctx, folderURI, &osFileSource{}, excludeNothing, test.experimental)
   100  		if err != nil {
   101  			t.Fatal(err)
   102  		}
   103  		if gotf, wantf := filepath.Clean(got.Filename()), rel.AbsPath(test.want); gotf != wantf {
   104  			t.Errorf("findWorkspaceRoot(%q, %t) = %q, want %q", test.folder, test.experimental, gotf, wantf)
   105  		}
   106  	}
   107  }
   108  
   109  func TestInVendor(t *testing.T) {
   110  	for _, tt := range []struct {
   111  		path     string
   112  		inVendor bool
   113  	}{
   114  		{
   115  			path:     "foo/vendor/x.go",
   116  			inVendor: false,
   117  		},
   118  		{
   119  			path:     "foo/vendor/x/x.go",
   120  			inVendor: true,
   121  		},
   122  		{
   123  			path:     "foo/x.go",
   124  			inVendor: false,
   125  		},
   126  	} {
   127  		if got := inVendor(span.URIFromPath(tt.path)); got != tt.inVendor {
   128  			t.Errorf("expected %s inVendor %v, got %v", tt.path, tt.inVendor, got)
   129  		}
   130  	}
   131  }
   132  
   133  func TestFilters(t *testing.T) {
   134  	tests := []struct {
   135  		filters  []string
   136  		included []string
   137  		excluded []string
   138  	}{
   139  		{
   140  			included: []string{"x"},
   141  		},
   142  		{
   143  			filters:  []string{"-"},
   144  			excluded: []string{"x", "x/a"},
   145  		},
   146  		{
   147  			filters:  []string{"-x", "+y"},
   148  			included: []string{"y", "y/a", "z"},
   149  			excluded: []string{"x", "x/a"},
   150  		},
   151  		{
   152  			filters:  []string{"-x", "+x/y", "-x/y/z"},
   153  			included: []string{"x/y", "x/y/a", "a"},
   154  			excluded: []string{"x", "x/a", "x/y/z/a"},
   155  		},
   156  		{
   157  			filters:  []string{"+foobar", "-foo"},
   158  			included: []string{"foobar", "foobar/a"},
   159  			excluded: []string{"foo", "foo/a"},
   160  		},
   161  	}
   162  
   163  	for _, tt := range tests {
   164  		opts := &source.Options{}
   165  		opts.DirectoryFilters = tt.filters
   166  		for _, inc := range tt.included {
   167  			if pathExcludedByFilter(inc, "root", "root/gopath/pkg/mod", opts) {
   168  				t.Errorf("filters %q excluded %v, wanted included", tt.filters, inc)
   169  			}
   170  		}
   171  		for _, exc := range tt.excluded {
   172  			if !pathExcludedByFilter(exc, "root", "root/gopath/pkg/mod", opts) {
   173  				t.Errorf("filters %q included %v, wanted excluded", tt.filters, exc)
   174  			}
   175  		}
   176  	}
   177  }
   178  
   179  func TestSuffixes(t *testing.T) {
   180  	type file struct {
   181  		path string
   182  		want bool
   183  	}
   184  	type cases struct {
   185  		option []string
   186  		files  []file
   187  	}
   188  	tests := []cases{
   189  		{[]string{"tmpl", "gotmpl"}, []file{ // default
   190  			{"foo", false},
   191  			{"foo.tmpl", true},
   192  			{"foo.gotmpl", true},
   193  			{"tmpl", false},
   194  			{"tmpl.go", false}},
   195  		},
   196  		{[]string{"tmpl", "gotmpl", "html", "gohtml"}, []file{
   197  			{"foo.gotmpl", true},
   198  			{"foo.html", true},
   199  			{"foo.gohtml", true},
   200  			{"html", false}},
   201  		},
   202  		{[]string{"tmpl", "gotmpl", ""}, []file{ // possible user mistake
   203  			{"foo.gotmpl", true},
   204  			{"foo.go", false},
   205  			{"foo", false}},
   206  		},
   207  	}
   208  	for _, a := range tests {
   209  		suffixes := a.option
   210  		for _, b := range a.files {
   211  			got := fileHasExtension(b.path, suffixes)
   212  			if got != b.want {
   213  				t.Errorf("got %v, want %v, option %q, file %q (%+v)",
   214  					got, b.want, a.option, b.path, b)
   215  			}
   216  		}
   217  	}
   218  }