golang.org/x/tools@v0.21.0/go/packages/packagestest/export_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 packagestest_test 6 7 import ( 8 "os" 9 "path/filepath" 10 "reflect" 11 "sort" 12 "testing" 13 14 "golang.org/x/tools/go/packages/packagestest" 15 ) 16 17 var testdata = []packagestest.Module{{ 18 Name: "golang.org/fake1", 19 Files: map[string]interface{}{ 20 "a.go": packagestest.Symlink("testdata/a.go"), // broken symlink 21 "b.go": "invalid file contents", 22 }, 23 Overlay: map[string][]byte{ 24 "b.go": []byte("package fake1"), 25 "c.go": []byte("package fake1"), 26 }, 27 }, { 28 Name: "golang.org/fake2", 29 Files: map[string]interface{}{ 30 "other/a.go": "package fake2", 31 }, 32 }, { 33 Name: "golang.org/fake2/v2", 34 Files: map[string]interface{}{ 35 "other/a.go": "package fake2", 36 }, 37 }, { 38 Name: "golang.org/fake3@v1.0.0", 39 Files: map[string]interface{}{ 40 "other/a.go": "package fake3", 41 }, 42 }, { 43 Name: "golang.org/fake3@v1.1.0", 44 Files: map[string]interface{}{ 45 "other/a.go": "package fake3", 46 }, 47 }} 48 49 type fileTest struct { 50 module, fragment, expect string 51 check func(t *testing.T, exported *packagestest.Exported, filename string) 52 } 53 54 func checkFiles(t *testing.T, exported *packagestest.Exported, tests []fileTest) { 55 for _, test := range tests { 56 expect := filepath.Join(exported.Temp(), filepath.FromSlash(test.expect)) 57 got := exported.File(test.module, test.fragment) 58 if got == "" { 59 t.Errorf("File %v missing from the output", expect) 60 } else if got != expect { 61 t.Errorf("Got file %v, expected %v", got, expect) 62 } 63 if test.check != nil { 64 test.check(t, exported, got) 65 } 66 } 67 } 68 69 func checkLink(expect string) func(t *testing.T, exported *packagestest.Exported, filename string) { 70 expect = filepath.FromSlash(expect) 71 return func(t *testing.T, exported *packagestest.Exported, filename string) { 72 if target, err := os.Readlink(filename); err != nil { 73 t.Errorf("Error checking link %v: %v", filename, err) 74 } else if target != expect { 75 t.Errorf("Link %v does not match, got %v expected %v", filename, target, expect) 76 } 77 } 78 } 79 80 func checkContent(expect string) func(t *testing.T, exported *packagestest.Exported, filename string) { 81 return func(t *testing.T, exported *packagestest.Exported, filename string) { 82 if content, err := exported.FileContents(filename); err != nil { 83 t.Errorf("Error reading %v: %v", filename, err) 84 } else if string(content) != expect { 85 t.Errorf("Content of %v does not match, got %v expected %v", filename, string(content), expect) 86 } 87 } 88 } 89 90 func TestGroupFilesByModules(t *testing.T) { 91 for _, tt := range []struct { 92 testdir string 93 want []packagestest.Module 94 }{ 95 { 96 testdir: "testdata/groups/one", 97 want: []packagestest.Module{ 98 { 99 Name: "testdata/groups/one", 100 Files: map[string]interface{}{ 101 "main.go": true, 102 }, 103 }, 104 { 105 Name: "example.com/extra", 106 Files: map[string]interface{}{ 107 "help.go": true, 108 }, 109 }, 110 }, 111 }, 112 { 113 testdir: "testdata/groups/two", 114 want: []packagestest.Module{ 115 { 116 Name: "testdata/groups/two", 117 Files: map[string]interface{}{ 118 "main.go": true, 119 "expect/yo.go": true, 120 "expect/yo_test.go": true, 121 }, 122 }, 123 { 124 Name: "example.com/extra", 125 Files: map[string]interface{}{ 126 "yo.go": true, 127 "geez/help.go": true, 128 }, 129 }, 130 { 131 Name: "example.com/extra/v2", 132 Files: map[string]interface{}{ 133 "me.go": true, 134 "geez/help.go": true, 135 }, 136 }, 137 { 138 Name: "example.com/tempmod", 139 Files: map[string]interface{}{ 140 "main.go": true, 141 }, 142 }, 143 { 144 Name: "example.com/what@v1.0.0", 145 Files: map[string]interface{}{ 146 "main.go": true, 147 }, 148 }, 149 { 150 Name: "example.com/what@v1.1.0", 151 Files: map[string]interface{}{ 152 "main.go": true, 153 }, 154 }, 155 }, 156 }, 157 } { 158 t.Run(tt.testdir, func(t *testing.T) { 159 got, err := packagestest.GroupFilesByModules(tt.testdir) 160 if err != nil { 161 t.Fatalf("could not group files %v", err) 162 } 163 if len(got) != len(tt.want) { 164 t.Fatalf("%s: wanted %d modules but got %d", tt.testdir, len(tt.want), len(got)) 165 } 166 for i, w := range tt.want { 167 g := got[i] 168 if filepath.FromSlash(g.Name) != filepath.FromSlash(w.Name) { 169 t.Fatalf("%s: wanted module[%d].Name to be %s but got %s", tt.testdir, i, filepath.FromSlash(w.Name), filepath.FromSlash(g.Name)) 170 } 171 for fh := range w.Files { 172 if _, ok := g.Files[fh]; !ok { 173 t.Fatalf("%s, module[%d]: wanted %s but could not find", tt.testdir, i, fh) 174 } 175 } 176 for fh := range g.Files { 177 if _, ok := w.Files[fh]; !ok { 178 t.Fatalf("%s, module[%d]: found unexpected file %s", tt.testdir, i, fh) 179 } 180 } 181 } 182 }) 183 } 184 } 185 186 func TestMustCopyFiles(t *testing.T) { 187 // Create the following test directory structure in a temporary directory. 188 src := map[string]string{ 189 // copies all files under the specified directory. 190 "go.mod": "module example.com", 191 "m.go": "package m", 192 "a/a.go": "package a", 193 // contents from a nested module shouldn't be copied. 194 "nested/go.mod": "module example.com/nested", 195 "nested/m.go": "package nested", 196 "nested/b/b.go": "package b", 197 } 198 199 tmpDir, err := os.MkdirTemp("", t.Name()) 200 if err != nil { 201 t.Fatalf("failed to create a temporary directory: %v", err) 202 } 203 defer os.RemoveAll(tmpDir) 204 205 for fragment, contents := range src { 206 fullpath := filepath.Join(tmpDir, filepath.FromSlash(fragment)) 207 if err := os.MkdirAll(filepath.Dir(fullpath), 0755); err != nil { 208 t.Fatal(err) 209 } 210 if err := os.WriteFile(fullpath, []byte(contents), 0644); err != nil { 211 t.Fatal(err) 212 } 213 } 214 215 copied := packagestest.MustCopyFileTree(tmpDir) 216 var got []string 217 for fragment := range copied { 218 got = append(got, filepath.ToSlash(fragment)) 219 } 220 want := []string{"go.mod", "m.go", "a/a.go"} 221 222 sort.Strings(got) 223 sort.Strings(want) 224 if !reflect.DeepEqual(got, want) { 225 t.Errorf("packagestest.MustCopyFileTree = %v, want %v", got, want) 226 } 227 228 // packagestest.Export is happy. 229 exported := packagestest.Export(t, packagestest.Modules, []packagestest.Module{{ 230 Name: "example.com", 231 Files: packagestest.MustCopyFileTree(tmpDir), 232 }}) 233 defer exported.Cleanup() 234 }