github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/refactor/rename/mvpkg_test.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // licence that can be found in the LICENSE file. 4 5 package rename 6 7 import ( 8 "fmt" 9 "go/build" 10 "io/ioutil" 11 "path/filepath" 12 "regexp" 13 "strings" 14 "testing" 15 16 "golang.org/x/tools/go/buildutil" 17 ) 18 19 func TestErrors(t *testing.T) { 20 tests := []struct { 21 ctxt *build.Context 22 from, to string 23 want string // regexp to match error, or "OK" 24 }{ 25 // Simple example. 26 { 27 ctxt: fakeContext(map[string][]string{ 28 "foo": {`package foo; type T int`}, 29 "bar": {`package bar`}, 30 "main": {`package main 31 32 import "foo" 33 34 var _ foo.T 35 `}, 36 }), 37 from: "foo", to: "bar", 38 want: `invalid move destination: bar conflicts with directory .go.src.bar`, 39 }, 40 // Subpackage already exists. 41 { 42 ctxt: fakeContext(map[string][]string{ 43 "foo": {`package foo; type T int`}, 44 "foo/sub": {`package sub`}, 45 "bar/sub": {`package sub`}, 46 "main": {`package main 47 48 import "foo" 49 50 var _ foo.T 51 `}, 52 }), 53 from: "foo", to: "bar", 54 want: "invalid move destination: bar; package or subpackage bar/sub already exists", 55 }, 56 // Invalid base name. 57 { 58 ctxt: fakeContext(map[string][]string{ 59 "foo": {`package foo; type T int`}, 60 "main": {`package main 61 62 import "foo" 63 64 var _ foo.T 65 `}, 66 }), 67 from: "foo", to: "bar-v2.0", 68 want: "invalid move destination: bar-v2.0; gomvpkg does not " + 69 "support move destinations whose base names are not valid " + 70 "go identifiers", 71 }, 72 } 73 74 for _, test := range tests { 75 ctxt := test.ctxt 76 77 got := make(map[string]string) 78 writeFile = func(filename string, content []byte) error { 79 got[filename] = string(content) 80 return nil 81 } 82 moveDirectory = func(from, to string) error { 83 for path, contents := range got { 84 if strings.HasPrefix(path, from) { 85 newPath := strings.Replace(path, from, to, 1) 86 delete(got, path) 87 got[newPath] = contents 88 } 89 } 90 return nil 91 } 92 93 err := Move(ctxt, test.from, test.to, "") 94 prefix := fmt.Sprintf("-from %q -to %q", test.from, test.to) 95 if err == nil { 96 t.Errorf("%s: nil error. Expected error: %s", prefix, test.want) 97 continue 98 } 99 matched, err2 := regexp.MatchString(test.want, err.Error()) 100 if err2 != nil { 101 t.Errorf("regexp.MatchString failed %s", err2) 102 continue 103 } 104 if !matched { 105 t.Errorf("%s: conflict does not match expectation:\n"+ 106 "Error: %q\n"+ 107 "Pattern: %q", 108 prefix, err.Error(), test.want) 109 } 110 } 111 } 112 113 func TestMoves(t *testing.T) { 114 tests := []struct { 115 ctxt *build.Context 116 from, to string 117 want map[string]string 118 }{ 119 // Simple example. 120 { 121 ctxt: fakeContext(map[string][]string{ 122 "foo": {`package foo; type T int`}, 123 "main": {`package main 124 125 import "foo" 126 127 var _ foo.T 128 `}, 129 }), 130 from: "foo", to: "bar", 131 want: map[string]string{ 132 "/go/src/main/0.go": `package main 133 134 import "bar" 135 136 var _ bar.T 137 `, 138 "/go/src/bar/0.go": `package bar 139 140 type T int 141 `, 142 }, 143 }, 144 145 // Example with subpackage. 146 { 147 ctxt: fakeContext(map[string][]string{ 148 "foo": {`package foo; type T int`}, 149 "foo/sub": {`package sub; type T int`}, 150 "main": {`package main 151 152 import "foo" 153 import "foo/sub" 154 155 var _ foo.T 156 var _ sub.T 157 `}, 158 }), 159 from: "foo", to: "bar", 160 want: map[string]string{ 161 "/go/src/main/0.go": `package main 162 163 import "bar" 164 import "bar/sub" 165 166 var _ bar.T 167 var _ sub.T 168 `, 169 "/go/src/bar/0.go": `package bar 170 171 type T int 172 `, 173 "/go/src/bar/sub/0.go": `package sub; type T int`, 174 }, 175 }, 176 177 // References into subpackages 178 { 179 ctxt: fakeContext(map[string][]string{ 180 "foo": {`package foo; import "foo/a"; var _ a.T`}, 181 "foo/a": {`package a; type T int`}, 182 "foo/b": {`package b; import "foo/a"; var _ a.T`}, 183 }), 184 from: "foo", to: "bar", 185 want: map[string]string{ 186 "/go/src/bar/0.go": `package bar 187 188 import "bar/a" 189 190 var _ a.T 191 `, 192 "/go/src/bar/a/0.go": `package a; type T int`, 193 "/go/src/bar/b/0.go": `package b 194 195 import "bar/a" 196 197 var _ a.T 198 `, 199 }, 200 }, 201 202 // External test packages 203 { 204 ctxt: buildutil.FakeContext(map[string]map[string]string{ 205 "foo": { 206 "0.go": `package foo; type T int`, 207 "0_test.go": `package foo_test; import "foo"; var _ foo.T`, 208 }, 209 "baz": { 210 "0_test.go": `package baz_test; import "foo"; var _ foo.T`, 211 }, 212 }), 213 from: "foo", to: "bar", 214 want: map[string]string{ 215 "/go/src/bar/0.go": `package bar 216 217 type T int 218 `, 219 "/go/src/bar/0_test.go": `package bar_test 220 221 import "bar" 222 223 var _ bar.T 224 `, 225 "/go/src/baz/0_test.go": `package baz_test 226 227 import "bar" 228 229 var _ bar.T 230 `, 231 }, 232 }, 233 // package import comments 234 { 235 ctxt: fakeContext(map[string][]string{"foo": {`package foo // import "baz"`}}), 236 from: "foo", to: "bar", 237 want: map[string]string{"/go/src/bar/0.go": `package bar // import "bar" 238 `}, 239 }, 240 { 241 ctxt: fakeContext(map[string][]string{"foo": {`package foo /* import "baz" */`}}), 242 from: "foo", to: "bar", 243 want: map[string]string{"/go/src/bar/0.go": `package bar /* import "bar" */ 244 `}, 245 }, 246 { 247 ctxt: fakeContext(map[string][]string{"foo": {`package foo // import "baz"`}}), 248 from: "foo", to: "bar", 249 want: map[string]string{"/go/src/bar/0.go": `package bar // import "bar" 250 `}, 251 }, 252 { 253 ctxt: fakeContext(map[string][]string{"foo": {`package foo 254 // import " this is not an import comment`}}), 255 from: "foo", to: "bar", 256 want: map[string]string{"/go/src/bar/0.go": `package bar 257 258 // import " this is not an import comment 259 `}, 260 }, 261 { 262 ctxt: fakeContext(map[string][]string{"foo": {`package foo 263 /* import " this is not an import comment */`}}), 264 from: "foo", to: "bar", 265 want: map[string]string{"/go/src/bar/0.go": `package bar 266 267 /* import " this is not an import comment */ 268 `}, 269 }, 270 } 271 272 for _, test := range tests { 273 ctxt := test.ctxt 274 275 got := make(map[string]string) 276 // Populate got with starting file set. rewriteFile and moveDirectory 277 // will mutate got to produce resulting file set. 278 buildutil.ForEachPackage(ctxt, func(importPath string, err error) { 279 if err != nil { 280 return 281 } 282 path := filepath.Join("/go/src", importPath, "0.go") 283 if !buildutil.FileExists(ctxt, path) { 284 return 285 } 286 f, err := ctxt.OpenFile(path) 287 if err != nil { 288 t.Errorf("unexpected error opening file: %s", err) 289 return 290 } 291 bytes, err := ioutil.ReadAll(f) 292 f.Close() 293 if err != nil { 294 t.Errorf("unexpected error reading file: %s", err) 295 return 296 } 297 got[path] = string(bytes) 298 }) 299 writeFile = func(filename string, content []byte) error { 300 got[filename] = string(content) 301 return nil 302 } 303 moveDirectory = func(from, to string) error { 304 for path, contents := range got { 305 if strings.HasPrefix(path, from) { 306 newPath := strings.Replace(path, from, to, 1) 307 delete(got, path) 308 got[newPath] = contents 309 } 310 } 311 return nil 312 } 313 314 err := Move(ctxt, test.from, test.to, "") 315 prefix := fmt.Sprintf("-from %q -to %q", test.from, test.to) 316 if err != nil { 317 t.Errorf("%s: unexpected error: %s", prefix, err) 318 continue 319 } 320 321 for file, wantContent := range test.want { 322 k := filepath.FromSlash(file) 323 gotContent, ok := got[k] 324 delete(got, k) 325 if !ok { 326 // TODO(matloob): some testcases might have files that won't be 327 // rewritten 328 t.Errorf("%s: file %s not rewritten", prefix, file) 329 continue 330 } 331 if gotContent != wantContent { 332 t.Errorf("%s: rewritten file %s does not match expectation; got <<<%s>>>\n"+ 333 "want <<<%s>>>", prefix, file, gotContent, wantContent) 334 } 335 } 336 // got should now be empty 337 for file := range got { 338 t.Errorf("%s: unexpected rewrite of file %s", prefix, file) 339 } 340 } 341 }