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  }