github.com/kekek/gb@v0.4.5-0.20170222120241-d4ba64b0b297/package_test.go (about) 1 package gb 2 3 import ( 4 "fmt" 5 "go/build" 6 "os" 7 "path/filepath" 8 "reflect" 9 "runtime" 10 "testing" 11 12 "github.com/pkg/errors" 13 ) 14 15 func testContext(t *testing.T, opts ...func(*Context) error) *Context { 16 ctx, err := NewContext(testProject(t), opts...) 17 if err != nil { 18 t.Fatal(err) 19 } 20 ctx.Force = true 21 return ctx 22 } 23 24 func TestResolvePackage(t *testing.T) { 25 var tests = []struct { 26 pkg string // package name 27 opts []func(*Context) error 28 err error 29 }{{ 30 pkg: "a", 31 }, { 32 pkg: "localimport", 33 err: &importErr{path: "../localimport", msg: "relative import not supported"}, 34 }} 35 proj := testProject(t) 36 for _, tt := range tests { 37 ctx, err := NewContext(proj, tt.opts...) 38 defer ctx.Destroy() 39 _, err = ctx.ResolvePackage(tt.pkg) 40 err = errors.Cause(err) 41 if !reflect.DeepEqual(err, tt.err) { 42 t.Errorf("ResolvePackage(%q): want: %v, got %v", tt.pkg, tt.err, err) 43 } 44 } 45 } 46 47 func TestPackageBinfile(t *testing.T) { 48 opts := func(o ...func(*Context) error) []func(*Context) error { return o } 49 gotargetos := "windows" 50 if runtime.GOOS == "windows" { 51 gotargetos = "linux" 52 } 53 gotargetarch := "386" 54 if runtime.GOARCH == "386" { 55 gotargetarch = "amd64" 56 } 57 var tests = []struct { 58 pkg string // package name 59 opts []func(*Context) error 60 want string // binfile result 61 }{{ 62 pkg: "b", 63 want: "b", 64 }, { 65 pkg: "b", 66 opts: opts(GOOS(gotargetos)), 67 want: fmt.Sprintf("b-%v-%v", gotargetos, runtime.GOARCH), 68 }, { 69 pkg: "b", 70 opts: opts(GOARCH(gotargetarch)), 71 want: fmt.Sprintf("b-%v-%v", runtime.GOOS, gotargetarch), 72 }, { 73 pkg: "b", 74 opts: opts(GOARCH(gotargetarch), GOOS(gotargetos)), 75 want: fmt.Sprintf("b-%v-%v", gotargetos, gotargetarch), 76 }, { 77 pkg: "b", 78 opts: opts(Tags("lol")), 79 want: "b-lol", 80 }, { 81 pkg: "b", 82 opts: opts(GOARCH(gotargetarch), GOOS(gotargetos), Tags("lol")), 83 want: fmt.Sprintf("b-%v-%v-lol", gotargetos, gotargetarch), 84 }} 85 86 proj := testProject(t) 87 for i, tt := range tests { 88 ctx, _ := NewContext(proj, tt.opts...) 89 defer ctx.Destroy() 90 pkg, err := ctx.ResolvePackage(tt.pkg) 91 if err != nil { 92 t.Fatal(err) 93 } 94 got := pkg.Binfile() 95 want := filepath.Join(ctx.bindir(), tt.want) 96 if pkg.gotargetos == "windows" { 97 want += ".exe" 98 } 99 if want != got { 100 t.Errorf("test %v: (%s).Binfile(): want %s, got %s", i+1, tt.pkg, want, got) 101 } 102 } 103 } 104 105 func TestPackageBindir(t *testing.T) { 106 ctx := testContext(t) 107 defer ctx.Destroy() 108 tests := []struct { 109 pkg *Package 110 want string 111 }{{ 112 pkg: &Package{ 113 Context: ctx, 114 }, 115 want: ctx.bindir(), 116 }, { 117 pkg: &Package{ 118 Package: &build.Package{ 119 Name: "testpkg", 120 ImportPath: "github.com/constabulary/gb/testpkg", 121 }, 122 Context: ctx, 123 TestScope: true, 124 }, 125 want: filepath.Join(ctx.Workdir(), "github.com", "constabulary", "gb", "testpkg", "_test"), 126 }} 127 128 for i, tt := range tests { 129 got := tt.pkg.bindir() 130 want := tt.want 131 if got != want { 132 t.Errorf("test %v: Bindir: got %v want %v", i+1, got, want) 133 } 134 } 135 } 136 137 func TestNewPackage(t *testing.T) { 138 tests := []struct { 139 pkg build.Package 140 want Package 141 }{{ 142 pkg: build.Package{ 143 Name: "C", 144 ImportPath: "C", 145 Goroot: true, 146 }, 147 want: Package{ 148 NotStale: true, 149 }, 150 }} 151 proj := testProject(t) 152 for i, tt := range tests { 153 ctx, _ := NewContext(proj) 154 defer ctx.Destroy() 155 156 got, err := ctx.NewPackage(&tt.pkg) 157 if err != nil { 158 t.Error(err) 159 continue 160 } 161 want := tt.want // deep copy 162 want.Package = &tt.pkg 163 want.Context = ctx 164 165 if !reflect.DeepEqual(got, &want) { 166 t.Errorf("%d: pkg: %s: expected %#v, got %#v", i+1, tt.pkg.ImportPath, &want, got) 167 } 168 } 169 } 170 171 func TestStale(t *testing.T) { 172 var tests = []struct { 173 pkgs []string 174 stale map[string]bool 175 }{{ 176 pkgs: []string{"a"}, 177 stale: map[string]bool{ 178 "a": false, 179 }, 180 }, { 181 pkgs: []string{"a", "b"}, 182 stale: map[string]bool{ 183 "a": true, 184 "b": false, 185 }, 186 }, { 187 pkgs: []string{"a", "b"}, 188 stale: map[string]bool{ 189 "a": true, 190 "b": true, 191 }, 192 }} 193 194 proj := tempProject(t) 195 defer os.RemoveAll(proj.rootdir) 196 proj.tempfile("src/a/a.go", `package a 197 198 const A = "A" 199 `) 200 201 proj.tempfile("src/b/b.go", `package main 202 203 import "a" 204 205 func main() { 206 println(a.A) 207 } 208 `) 209 210 newctx := func() *Context { 211 ctx, err := NewContext(proj, 212 GcToolchain(), 213 ) 214 if err != nil { 215 t.Fatal(err) 216 } 217 return ctx 218 } 219 220 resolve := func(ctx *Context, pkg string) *Package { 221 p, err := ctx.ResolvePackage(pkg) 222 if err != nil { 223 t.Fatal(err) 224 } 225 return p 226 } 227 228 for _, tt := range tests { 229 ctx := newctx() 230 ctx.Install = true 231 defer ctx.Destroy() 232 for _, pkg := range tt.pkgs { 233 resolve(ctx, pkg) 234 } 235 236 for p, s := range tt.stale { 237 pkg := resolve(ctx, p) 238 if pkg.NotStale != s { 239 t.Errorf("%q.NotStale: got %v, want %v", pkg.Name, pkg.NotStale, s) 240 } 241 } 242 243 for _, pkg := range tt.pkgs { 244 if err := Build(resolve(ctx, pkg)); err != nil { 245 t.Fatal(err) 246 } 247 } 248 } 249 } 250 251 func TestInstallpath(t *testing.T) { 252 ctx := testContext(t) 253 defer ctx.Destroy() 254 255 tests := []struct { 256 pkg string 257 installpath string 258 }{{ 259 pkg: "a", // from testdata 260 installpath: filepath.Join(ctx.Pkgdir(), "a.a"), 261 }, { 262 pkg: "runtime", // from stdlib 263 installpath: filepath.Join(ctx.Pkgdir(), "runtime.a"), 264 }, { 265 pkg: "unsafe", // synthetic 266 installpath: filepath.Join(ctx.Pkgdir(), "unsafe.a"), 267 }} 268 269 resolve := func(pkg string) *Package { 270 p, err := ctx.ResolvePackage(pkg) 271 if err != nil { 272 t.Fatal(err) 273 } 274 return p 275 } 276 277 for _, tt := range tests { 278 pkg := resolve(tt.pkg) 279 got := pkg.installpath() 280 if got != tt.installpath { 281 t.Errorf("installpath(%q): expected: %v, got %v", tt.pkg, tt.installpath, got) 282 } 283 } 284 } 285 286 func TestPkgpath(t *testing.T) { 287 opts := func(o ...func(*Context) error) []func(*Context) error { return o } 288 gotargetos := "windows" 289 if runtime.GOOS == gotargetos { 290 gotargetos = "linux" 291 } 292 gotargetarch := "arm64" 293 if runtime.GOARCH == "arm64" { 294 gotargetarch = "amd64" 295 } 296 tests := []struct { 297 opts []func(*Context) error 298 pkg string 299 pkgpath func(*Context) string 300 }{{ 301 pkg: "a", // from testdata 302 pkgpath: func(ctx *Context) string { return filepath.Join(ctx.Pkgdir(), "a.a") }, 303 }, { 304 opts: opts(GOOS(gotargetos), GOARCH(gotargetarch)), 305 pkg: "a", // from testdata 306 pkgpath: func(ctx *Context) string { return filepath.Join(ctx.Pkgdir(), "a.a") }, 307 }, { 308 opts: opts(WithRace), 309 pkg: "a", // from testdata 310 pkgpath: func(ctx *Context) string { return filepath.Join(ctx.Pkgdir(), "a.a") }, 311 }, { 312 opts: opts(Tags("foo", "bar")), 313 pkg: "a", // from testdata 314 pkgpath: func(ctx *Context) string { return filepath.Join(ctx.Pkgdir(), "a.a") }, 315 }, { 316 pkg: "runtime", // from stdlib 317 pkgpath: func(ctx *Context) string { 318 return filepath.Join(runtime.GOROOT(), "pkg", ctx.gohostos+"_"+ctx.gohostarch, "runtime.a") 319 }, 320 }, { 321 opts: opts(Tags("foo", "bar")), 322 pkg: "runtime", // from stdlib 323 pkgpath: func(ctx *Context) string { 324 return filepath.Join(runtime.GOROOT(), "pkg", ctx.gohostos+"_"+ctx.gohostarch, "runtime.a") 325 }, 326 }, { 327 opts: opts(WithRace), 328 pkg: "runtime", // from stdlib 329 pkgpath: func(ctx *Context) string { 330 return filepath.Join(runtime.GOROOT(), "pkg", ctx.gohostos+"_"+ctx.gohostarch+"_race", "runtime.a") 331 }, 332 }, { 333 opts: opts(WithRace, Tags("foo", "bar")), 334 pkg: "runtime", // from stdlib 335 pkgpath: func(ctx *Context) string { 336 return filepath.Join(runtime.GOROOT(), "pkg", ctx.gohostos+"_"+ctx.gohostarch+"_race", "runtime.a") 337 }, 338 }, { 339 opts: opts(GOOS(gotargetos), GOARCH(gotargetarch)), 340 pkg: "runtime", // from stdlib 341 pkgpath: func(ctx *Context) string { 342 return filepath.Join(ctx.Pkgdir(), "runtime.a") 343 }, 344 }, { 345 pkg: "unsafe", // synthetic 346 pkgpath: func(ctx *Context) string { 347 return filepath.Join(runtime.GOROOT(), "pkg", ctx.gohostos+"_"+ctx.gohostarch, "unsafe.a") 348 }, 349 }, { 350 pkg: "unsafe", // synthetic 351 opts: opts(GOOS(gotargetos), GOARCH(gotargetarch), WithRace), 352 pkgpath: func(ctx *Context) string { 353 return filepath.Join(ctx.Pkgdir(), "unsafe.a") 354 }, 355 }} 356 357 for _, tt := range tests { 358 ctx := testContext(t, tt.opts...) 359 defer ctx.Destroy() 360 pkg, err := ctx.ResolvePackage(tt.pkg) 361 if err != nil { 362 t.Fatal(err) 363 } 364 got := pkg.pkgpath() 365 want := tt.pkgpath(ctx) 366 if got != want { 367 t.Errorf("pkgpath(%q): expected: %v, got %v", tt.pkg, want, got) 368 } 369 } 370 } 371 372 func TestPackageIncludePaths(t *testing.T) { 373 ctx := testContext(t) 374 tests := []struct { 375 pkg *Package 376 want []string 377 }{{ 378 pkg: &Package{ 379 Context: ctx, 380 Package: &build.Package{ 381 ImportPath: "github.com/foo/bar", 382 }, 383 }, 384 want: []string{ 385 ctx.Workdir(), 386 ctx.Pkgdir(), 387 }, 388 }, { 389 pkg: &Package{ 390 Context: ctx, 391 Package: &build.Package{ 392 ImportPath: "github.com/foo/bar", 393 }, 394 Main: true, 395 }, 396 want: []string{ 397 ctx.Workdir(), 398 ctx.Pkgdir(), 399 }, 400 }, { 401 pkg: &Package{ 402 Context: ctx, 403 Package: &build.Package{ 404 ImportPath: "github.com/foo/bar", 405 }, 406 TestScope: true, 407 }, 408 want: []string{ 409 filepath.Join(ctx.Workdir(), "github.com", "foo", "bar", "_test"), 410 ctx.Workdir(), 411 ctx.Pkgdir(), 412 }, 413 }, { 414 pkg: &Package{ 415 Context: ctx, 416 Package: &build.Package{ 417 ImportPath: "github.com/foo/bar", 418 }, 419 TestScope: true, 420 Main: true, 421 }, 422 want: []string{ 423 filepath.Join(ctx.Workdir(), "github.com", "foo", "_test"), // TODO(dfc) WTF 424 ctx.Workdir(), 425 ctx.Pkgdir(), 426 }, 427 }} 428 429 for i, tt := range tests { 430 got := tt.pkg.includePaths() 431 if !reflect.DeepEqual(got, tt.want) { 432 t.Errorf("%d: Package: ImportPath: %v, TestScope: %v, Main: %v: got %v, want %v", i, tt.pkg.ImportPath, tt.pkg.TestScope, tt.pkg.Main, got, tt.want) 433 } 434 } 435 }