golang.org/x/tools/gopls@v0.15.3/internal/cache/filemap_test.go (about) 1 // Copyright 2023 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 cache 6 7 import ( 8 "path/filepath" 9 "sort" 10 "testing" 11 12 "github.com/google/go-cmp/cmp" 13 "golang.org/x/tools/gopls/internal/file" 14 "golang.org/x/tools/gopls/internal/protocol" 15 ) 16 17 func TestFileMap(t *testing.T) { 18 const ( 19 set = iota 20 del 21 ) 22 type op struct { 23 op int // set or remove 24 path string 25 overlay bool 26 } 27 tests := []struct { 28 label string 29 ops []op 30 wantFiles []string 31 wantOverlays []string 32 wantDirs []string 33 }{ 34 {"empty", nil, nil, nil, nil}, 35 {"singleton", []op{ 36 {set, "/a/b", false}, 37 }, []string{"/a/b"}, nil, []string{"/", "/a"}}, 38 {"overlay", []op{ 39 {set, "/a/b", true}, 40 }, []string{"/a/b"}, []string{"/a/b"}, []string{"/", "/a"}}, 41 {"replace overlay", []op{ 42 {set, "/a/b", true}, 43 {set, "/a/b", false}, 44 }, []string{"/a/b"}, nil, []string{"/", "/a"}}, 45 {"multi dir", []op{ 46 {set, "/a/b", false}, 47 {set, "/c/d", false}, 48 }, []string{"/a/b", "/c/d"}, nil, []string{"/", "/a", "/c"}}, 49 {"empty dir", []op{ 50 {set, "/a/b", false}, 51 {set, "/c/d", false}, 52 {del, "/a/b", false}, 53 }, []string{"/c/d"}, nil, []string{"/", "/c"}}, 54 } 55 56 // Normalize paths for windows compatibility. 57 normalize := func(path string) string { 58 y := filepath.ToSlash(path) 59 // Windows paths may start with a drive letter 60 if len(y) > 2 && y[1] == ':' && y[0] >= 'A' && y[0] <= 'Z' { 61 y = y[2:] 62 } 63 return y 64 } 65 66 for _, test := range tests { 67 t.Run(test.label, func(t *testing.T) { 68 m := newFileMap() 69 for _, op := range test.ops { 70 uri := protocol.URIFromPath(filepath.FromSlash(op.path)) 71 switch op.op { 72 case set: 73 var fh file.Handle 74 if op.overlay { 75 fh = &overlay{uri: uri} 76 } else { 77 fh = &diskFile{uri: uri} 78 } 79 m.set(uri, fh) 80 case del: 81 m.delete(uri) 82 } 83 } 84 85 var gotFiles []string 86 m.foreach(func(uri protocol.DocumentURI, _ file.Handle) { 87 gotFiles = append(gotFiles, normalize(uri.Path())) 88 }) 89 sort.Strings(gotFiles) 90 if diff := cmp.Diff(test.wantFiles, gotFiles); diff != "" { 91 t.Errorf("Files mismatch (-want +got):\n%s", diff) 92 } 93 94 var gotOverlays []string 95 for _, o := range m.getOverlays() { 96 gotOverlays = append(gotOverlays, normalize(o.URI().Path())) 97 } 98 if diff := cmp.Diff(test.wantOverlays, gotOverlays); diff != "" { 99 t.Errorf("Overlays mismatch (-want +got):\n%s", diff) 100 } 101 102 var gotDirs []string 103 m.getDirs().Range(func(dir string) { 104 gotDirs = append(gotDirs, normalize(dir)) 105 }) 106 sort.Strings(gotDirs) 107 if diff := cmp.Diff(test.wantDirs, gotDirs); diff != "" { 108 t.Errorf("Dirs mismatch (-want +got):\n%s", diff) 109 } 110 }) 111 } 112 }