github.com/kekek/gb@v0.4.5-0.20170222120241-d4ba64b0b297/build_test.go (about)

     1  package gb
     2  
     3  import (
     4  	"errors"
     5  	"go/build"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"reflect"
    10  	"sort"
    11  	"testing"
    12  )
    13  
    14  func TestBuild(t *testing.T) {
    15  	opts := func(o ...func(*Context) error) []func(*Context) error { return o }
    16  	tests := []struct {
    17  		pkg  string
    18  		opts []func(*Context) error
    19  		err  error
    20  	}{{
    21  		pkg: "a",
    22  		err: nil,
    23  	}, {
    24  		pkg: "b", // actually command
    25  		err: nil,
    26  	}, {
    27  		pkg: "c",
    28  		err: nil,
    29  	}, {
    30  		pkg: "d.v1",
    31  		err: nil,
    32  	}, {
    33  		pkg: "x",
    34  		err: errors.New("import cycle detected: x -> y -> x"),
    35  	}, {
    36  		pkg: "cgomain",
    37  		err: nil,
    38  	}, {
    39  		pkg: "cgotest",
    40  		err: nil,
    41  	}, {
    42  		pkg: "notestfiles",
    43  		err: nil,
    44  	}, {
    45  		pkg: "cgoonlynotest",
    46  		err: nil,
    47  	}, {
    48  		pkg: "testonly",
    49  		err: nil,
    50  	}, {
    51  		pkg: "extestonly",
    52  		err: nil,
    53  	}, {
    54  		pkg: "mainnoruntime",
    55  		err: nil,
    56  	}, {
    57  		pkg: "h", // imports "blank", which is blank, see issue #131
    58  		err: &build.NoGoError{Dir: filepath.Join(getwd(t), "testdata", "src", "blank")},
    59  	}, {
    60  		pkg: "cppmain",
    61  	}, {
    62  		pkg:  "tags1",
    63  		opts: opts(Tags("x")), // excludes the test file in package
    64  		err:  nogoerr(filepath.Join(getwd(t), "testdata", "src", "tags1")),
    65  	}, {
    66  		pkg: "tags2",
    67  		err: nogoerr(filepath.Join(getwd(t), "testdata", "src", "tags2")),
    68  	}, {
    69  		pkg:  "tags2",
    70  		opts: opts(Tags("x")),
    71  	}, {
    72  		pkg: "nosource",
    73  		err: &build.NoGoError{Dir: filepath.Join(getwd(t), "testdata", "src", "nosource")},
    74  	}}
    75  
    76  	proj := testProject(t)
    77  	for _, tt := range tests {
    78  		ctx, err := NewContext(proj, tt.opts...)
    79  		ctx.Force = true
    80  		defer ctx.Destroy()
    81  		pkg, err := ctx.ResolvePackage(tt.pkg)
    82  		if !reflect.DeepEqual(err, tt.err) {
    83  			t.Errorf("ctx.ResolvePackage(%v): want %v, got %v", tt.pkg, tt.err, err)
    84  			continue
    85  		}
    86  		if err != nil {
    87  			continue
    88  		}
    89  		if err := Build(pkg); !reflect.DeepEqual(err, tt.err) {
    90  			t.Errorf("ctx.Build(%v): want %v, got %v", tt.pkg, tt.err, err)
    91  		}
    92  	}
    93  }
    94  
    95  func TestBuildPackage(t *testing.T) {
    96  	tests := []struct {
    97  		pkg string
    98  		err error
    99  	}{{
   100  		pkg: "a",
   101  		err: nil,
   102  	}, {
   103  		pkg: "b", // actually command
   104  		err: nil,
   105  	}, {
   106  		pkg: "c",
   107  		err: nil,
   108  	}, {
   109  		pkg: "d.v1",
   110  		err: nil,
   111  	}, {
   112  		pkg: "cgomain",
   113  		err: nil,
   114  	}, {
   115  		pkg: "cgotest",
   116  		err: nil,
   117  	}, {
   118  		pkg: "notestfiles",
   119  		err: nil,
   120  	}, {
   121  		pkg: "cgoonlynotest",
   122  		err: nil,
   123  	}, {
   124  		pkg: "testonly",
   125  		err: errors.New(`compile "testonly": no go files supplied`),
   126  	}, {
   127  		pkg: "extestonly",
   128  		err: errors.New(`compile "extestonly": no go files supplied`),
   129  	}}
   130  
   131  	for _, tt := range tests {
   132  		ctx := testContext(t)
   133  		defer ctx.Destroy()
   134  		pkg, err := ctx.ResolvePackage(tt.pkg)
   135  		if err != nil {
   136  			t.Errorf("ctx.ResolvePackage(%v):  %v", tt.pkg, err)
   137  			continue
   138  		}
   139  		targets := make(map[string]*Action)
   140  		if _, err := BuildPackage(targets, pkg); !reflect.DeepEqual(err, tt.err) {
   141  			t.Errorf("ctx.BuildPackage(%v): want %v, got %v", tt.pkg, tt.err, err)
   142  		}
   143  	}
   144  }
   145  
   146  func TestBuildPackages(t *testing.T) {
   147  	tests := []struct {
   148  		pkgs    []string
   149  		actions []string
   150  		options []func(*Context) error // set of options to apply to the test context
   151  		err     error
   152  	}{{
   153  		pkgs:    []string{"a", "b", "c"},
   154  		actions: []string{"compile: a", "compile: c", "link: b"},
   155  	}, {
   156  		pkgs:    []string{"cgotest", "cgomain", "notestfiles", "cgoonlynotest", "testonly", "extestonly"},
   157  		actions: []string{"compile: notestfiles", "link: cgomain", "pack: cgoonlynotest", "pack: cgotest"},
   158  	}, {
   159  		pkgs:    []string{"a", "b", "c"},
   160  		options: []func(*Context) error{WithRace},
   161  		actions: []string{"compile: a", "compile: c", "link: b"},
   162  	}}
   163  
   164  	for _, tt := range tests {
   165  		ctx := testContext(t, tt.options...)
   166  		defer ctx.Destroy()
   167  		var pkgs []*Package
   168  		for _, pkg := range tt.pkgs {
   169  			pkg, err := ctx.ResolvePackage(pkg)
   170  			if err != nil {
   171  				t.Errorf("ctx.ResolvePackage(%v):  %v", pkg, err)
   172  				continue
   173  			}
   174  			pkgs = append(pkgs, pkg)
   175  		}
   176  		a, err := BuildPackages(pkgs...)
   177  		if !reflect.DeepEqual(err, tt.err) {
   178  			t.Errorf("ctx.BuildPackages(%v): want %v, got %v", pkgs, tt.err, err)
   179  		}
   180  		var names []string
   181  		for _, a := range a.Deps {
   182  			names = append(names, a.Name)
   183  		}
   184  		sort.Strings(names)
   185  		if !reflect.DeepEqual(tt.actions, names) {
   186  			t.Errorf("ctx.BuildPackages(%v): want %v, got %v", pkgs, tt.actions, names)
   187  		}
   188  	}
   189  }
   190  
   191  func TestObjfile(t *testing.T) {
   192  	var tests = []struct {
   193  		pkg  string // package name
   194  		want string // objfile result
   195  	}{
   196  		{pkg: "b", want: "b.a"},
   197  		{pkg: "nested/a", want: "nested/a.a"},
   198  		{pkg: "nested/b", want: "nested/b.a"},
   199  	}
   200  
   201  	for _, tt := range tests {
   202  		ctx := testContext(t)
   203  		defer ctx.Destroy()
   204  		pkg, err := ctx.ResolvePackage(tt.pkg)
   205  		if err != nil {
   206  			t.Fatal(err)
   207  		}
   208  		got := pkg.objfile()
   209  		want := filepath.Join(ctx.Workdir(), tt.want)
   210  		if want != got {
   211  			t.Errorf("(%s).Objdir(): want %s, got %s", tt.pkg, want, got)
   212  		}
   213  	}
   214  }
   215  
   216  func TestCgoobjdir(t *testing.T) {
   217  	var tests = []struct {
   218  		pkg  string // package name
   219  		want string // objdir result
   220  	}{
   221  		{pkg: "b", want: "b/_cgo"},
   222  		{pkg: "nested/a", want: "nested/a/_cgo"},
   223  		{pkg: "nested/b", want: "nested/b/_cgo"},
   224  	}
   225  
   226  	ctx := testContext(t)
   227  	defer ctx.Destroy()
   228  	for _, tt := range tests {
   229  		pkg, err := ctx.ResolvePackage(tt.pkg)
   230  		if err != nil {
   231  			t.Fatal(err)
   232  		}
   233  		got := cgoworkdir(pkg)
   234  		want := filepath.Join(ctx.Workdir(), tt.want)
   235  		if want != got {
   236  			t.Errorf("(%s).cgoobjdir(): want %s, got %s", tt.pkg, want, got)
   237  		}
   238  	}
   239  }
   240  
   241  func TestWorkdir(t *testing.T) {
   242  	var tests = []struct {
   243  		pkg  string // package name
   244  		want string // objdir result
   245  	}{
   246  		{pkg: "b", want: ""},
   247  		{pkg: "nested/a", want: "nested"},
   248  		{pkg: "nested/b", want: "nested"},
   249  	}
   250  
   251  	ctx := testContext(t)
   252  	defer ctx.Destroy()
   253  	for _, tt := range tests {
   254  		pkg, err := ctx.ResolvePackage(tt.pkg)
   255  		if err != nil {
   256  			t.Error(err)
   257  			continue
   258  		}
   259  		got := pkg.Workdir()
   260  		want := filepath.Join(ctx.Workdir(), tt.want)
   261  		if want != got {
   262  			t.Errorf("Workdir(Package{Name: %v, ImportPath: %v, TestScope: %v}): want %s, got %s", pkg.Name, pkg.ImportPath, pkg.TestScope, want, got)
   263  		}
   264  	}
   265  }
   266  
   267  func TestPkgname(t *testing.T) {
   268  	var tests = []struct {
   269  		pkg  *Package
   270  		want string
   271  	}{{
   272  		pkg: &Package{
   273  			Package: &build.Package{
   274  				Name:       "main",
   275  				ImportPath: "main",
   276  			},
   277  		},
   278  		want: "main",
   279  	}, {
   280  		pkg: &Package{
   281  			Package: &build.Package{
   282  				Name:       "a",
   283  				ImportPath: "main",
   284  			},
   285  		},
   286  		want: "main",
   287  	}, {
   288  		pkg: &Package{
   289  			Package: &build.Package{
   290  				Name:       "main",
   291  				ImportPath: "a",
   292  			},
   293  		},
   294  		want: "a",
   295  	}, {
   296  		pkg: &Package{
   297  			Package: &build.Package{
   298  				Name:       "main",
   299  				ImportPath: "testmain",
   300  			},
   301  		},
   302  		want: "testmain",
   303  	}, {
   304  		pkg: &Package{
   305  			Package: &build.Package{
   306  				Name:       "main",
   307  				ImportPath: "main",
   308  			},
   309  			TestScope: true,
   310  		},
   311  		want: "main",
   312  	}, {
   313  		pkg: &Package{
   314  			Package: &build.Package{
   315  				Name:       "a",
   316  				ImportPath: "main",
   317  			},
   318  			TestScope: true,
   319  		},
   320  		want: "main",
   321  	}, {
   322  		pkg: &Package{
   323  			Package: &build.Package{
   324  				Name:       "main",
   325  				ImportPath: "a",
   326  			},
   327  			TestScope: true,
   328  		},
   329  		want: "a",
   330  	}, {
   331  		pkg: &Package{
   332  			Package: &build.Package{
   333  				Name:       "main",
   334  				ImportPath: "a/a",
   335  			},
   336  			TestScope: true,
   337  		},
   338  		want: "a",
   339  	}, {
   340  		pkg: &Package{
   341  			Package: &build.Package{
   342  				Name:       "main",
   343  				ImportPath: "testmain",
   344  			},
   345  			TestScope: true,
   346  		},
   347  		want: "testmain",
   348  	}}
   349  
   350  	for _, tt := range tests {
   351  		got := tt.pkg.pkgname()
   352  		if got != tt.want {
   353  			t.Errorf("pkgname(Package{Name:%q, ImportPath: %q, TestScope:%v}): got %v, want %v", tt.pkg.Name, tt.pkg.ImportPath, tt.pkg.TestScope, got, tt.want)
   354  		}
   355  	}
   356  }
   357  
   358  func getwd(t *testing.T) string {
   359  	cwd, err := os.Getwd()
   360  	if err != nil {
   361  		t.Fatal(err)
   362  	}
   363  	return cwd
   364  }
   365  
   366  func mktemp(t *testing.T) string {
   367  	s, err := mktmp()
   368  	if err != nil {
   369  		t.Fatal(err)
   370  	}
   371  	return s
   372  }
   373  
   374  func mktmp() (string, error) {
   375  	return ioutil.TempDir("", "gb-test-")
   376  }
   377  
   378  func nogoerr(dir string) error {
   379  	return &build.NoGoError{Dir: dir}
   380  }