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

     1  package gb
     2  
     3  import (
     4  	"fmt"
     5  	"go/build"
     6  	"path/filepath"
     7  	"reflect"
     8  	"runtime"
     9  	"runtime/debug"
    10  	"strings"
    11  	"testing"
    12  )
    13  
    14  func testImportCycle(pkg string, t *testing.T) {
    15  	ctx := testContext(t)
    16  
    17  	debug.SetMaxStack(1 << 18)
    18  
    19  	_, err := ctx.ResolvePackage(pkg)
    20  	if strings.Index(err.Error(), "cycle detected") == -1 {
    21  		t.Errorf("ctx.ResolvePackage returned wrong error. Expected cycle detection, got: %v", err)
    22  	}
    23  
    24  	if err == nil {
    25  		t.Errorf("ctx.ResolvePackage should have returned an error for cycle, returned nil")
    26  	}
    27  }
    28  
    29  func TestOneElementCycleDetection(t *testing.T) {
    30  	testImportCycle("cycle0", t)
    31  }
    32  
    33  func TestSimpleCycleDetection(t *testing.T) {
    34  	testImportCycle("cycle1/a", t)
    35  }
    36  
    37  func TestLongCycleDetection(t *testing.T) {
    38  	testImportCycle("cycle2/a", t)
    39  }
    40  
    41  func TestContextCtxString(t *testing.T) {
    42  	opts := func(o ...func(*Context) error) []func(*Context) error { return o }
    43  	join := func(s ...string) string { return strings.Join(s, "-") }
    44  	tests := []struct {
    45  		opts []func(*Context) error
    46  		want string
    47  	}{
    48  		{nil, join(runtime.GOOS, runtime.GOARCH)},
    49  		{opts(GOOS("windows")), join("windows", runtime.GOARCH)},
    50  		{opts(GOARCH("arm64")), join(runtime.GOOS, "arm64")},
    51  		{opts(GOARCH("arm64"), GOOS("plan9")), join("plan9", "arm64")},
    52  		{opts(Tags()), join(runtime.GOOS, runtime.GOARCH)},
    53  		{opts(Tags("sphinx", "leon")), join(runtime.GOOS, runtime.GOARCH, "leon", "sphinx")},
    54  		{opts(Tags("sphinx", "leon"), GOARCH("ppc64le")), join(runtime.GOOS, "ppc64le", "leon", "sphinx")},
    55  	}
    56  
    57  	proj := testProject(t)
    58  	for _, tt := range tests {
    59  		ctx, err := NewContext(proj, tt.opts...)
    60  		if err != nil {
    61  			t.Fatal(err)
    62  		}
    63  		defer ctx.Destroy()
    64  		got := ctx.ctxString()
    65  		if got != tt.want {
    66  			t.Errorf("NewContext(%q).ctxString(): got %v, want %v", tt.opts, got, tt.want)
    67  		}
    68  	}
    69  }
    70  
    71  func TestContextOptions(t *testing.T) {
    72  	matches := func(want Context) func(t *testing.T, got *Context) {
    73  		return func(t *testing.T, got *Context) {
    74  			if !reflect.DeepEqual(got, &want) {
    75  				t.Errorf("got %#v, want %#v", got, &want)
    76  			}
    77  		}
    78  	}
    79  
    80  	tests := []struct {
    81  		ctx    Context
    82  		fn     func(*Context) error
    83  		err    error
    84  		expect func(*testing.T, *Context)
    85  	}{{
    86  		// assert that an zero context is not altered by the test rig.
    87  		fn:     func(*Context) error { return nil },
    88  		expect: matches(Context{}),
    89  	}, {
    90  		// test blank GOOS is an error
    91  		fn:  GOOS(""),
    92  		err: fmt.Errorf("GOOS cannot be blank"),
    93  	}, {
    94  		// test blank GOARCH is an error
    95  		fn:  GOARCH(""),
    96  		err: fmt.Errorf("GOARCH cannot be blank"),
    97  	}, {
    98  		ctx: Context{
    99  			gotargetos:   "bar",
   100  			gotargetarch: "baz",
   101  		},
   102  		fn: GOOS("foo"),
   103  		expect: matches(Context{
   104  			gotargetos:   "foo",
   105  			gotargetarch: "baz",
   106  		}),
   107  	}, {
   108  		ctx: Context{
   109  			gotargetos:   "bar",
   110  			gotargetarch: "baz",
   111  		},
   112  		fn: GOARCH("foo"),
   113  		expect: matches(Context{
   114  			gotargetos:   "bar",
   115  			gotargetarch: "foo",
   116  		}),
   117  	}, {
   118  		fn:     Tags(),
   119  		expect: matches(Context{}),
   120  	}, {
   121  		fn:     Tags("foo"),
   122  		expect: matches(Context{buildtags: []string{"foo"}}),
   123  	}, {
   124  		ctx:    Context{buildtags: []string{"foo"}},
   125  		fn:     Tags("bar"),
   126  		expect: matches(Context{buildtags: []string{"foo", "bar"}}),
   127  	}, {
   128  		fn:     Gcflags("foo"),
   129  		expect: matches(Context{gcflags: []string{"foo"}}),
   130  	}, {
   131  		ctx:    Context{gcflags: []string{"foo"}},
   132  		fn:     Gcflags("bar"),
   133  		expect: matches(Context{gcflags: []string{"foo", "bar"}}),
   134  	}, {
   135  		fn:     Ldflags("foo"),
   136  		expect: matches(Context{ldflags: []string{"foo"}}),
   137  	}, {
   138  		ctx:    Context{ldflags: []string{"foo"}},
   139  		fn:     Ldflags("bar"),
   140  		expect: matches(Context{ldflags: []string{"foo", "bar"}}),
   141  	}, {
   142  		fn: WithRace,
   143  		expect: matches(Context{
   144  			buildtags: []string{"race"},
   145  			race:      true,
   146  			gcflags:   []string{"-race"},
   147  			ldflags:   []string{"-race"},
   148  		}),
   149  	}, {
   150  		ctx: Context{buildtags: []string{"zzz"}},
   151  		fn:  WithRace,
   152  		expect: matches(Context{
   153  			buildtags: []string{"zzz", "race"},
   154  			race:      true,
   155  			gcflags:   []string{"-race"},
   156  			ldflags:   []string{"-race"},
   157  		}),
   158  	}}
   159  
   160  	for i, tt := range tests {
   161  		ctx := tt.ctx
   162  		err := tt.fn(&ctx)
   163  		switch {
   164  		case !reflect.DeepEqual(err, tt.err):
   165  			t.Errorf("test %d: expected err: %v, got %v", i+1, tt.err, err)
   166  		case err == nil:
   167  			tt.expect(t, &ctx)
   168  		}
   169  	}
   170  }
   171  
   172  func TestContextLoadPackage(t *testing.T) {
   173  	tests := []struct {
   174  		opts []func(*Context) error
   175  		path string
   176  	}{
   177  		{path: "errors"},
   178  		{path: "net/http"}, // triggers vendor logic on go 1.6+
   179  	}
   180  
   181  	proj := testProject(t)
   182  	for _, tt := range tests {
   183  		ctx, err := NewContext(proj, tt.opts...)
   184  		if err != nil {
   185  			t.Fatal(err)
   186  		}
   187  		defer ctx.Destroy()
   188  		_, err = ctx.loadPackage(nil, tt.path)
   189  		if err != nil {
   190  			t.Errorf("loadPackage(%q): %v", tt.path, err)
   191  		}
   192  	}
   193  }
   194  
   195  func TestCgoEnabled(t *testing.T) {
   196  	tests := []struct {
   197  		gohostos, gohostarch     string
   198  		gotargetos, gotargetarch string
   199  		want                     bool
   200  	}{{
   201  		"linux", "amd64", "linux", "amd64", true,
   202  	}, {
   203  		"linux", "amd64", "linux", "386", false,
   204  	}}
   205  
   206  	for _, tt := range tests {
   207  		got := cgoEnabled(tt.gohostos, tt.gohostarch, tt.gotargetos, tt.gotargetarch)
   208  		if got != tt.want {
   209  			t.Errorf("cgoEnabled(%q, %q, %q, %q): got %v, want %v", tt.gohostos, tt.gohostarch, tt.gotargetos, tt.gotargetarch, got, tt.want)
   210  		}
   211  	}
   212  }
   213  
   214  func TestContextImportPackage(t *testing.T) {
   215  	proj := testProject(t)
   216  	tests := []struct {
   217  		path string
   218  		err  error
   219  	}{{
   220  		path: "a",
   221  	}, {
   222  		path: "cgomain",
   223  	}, {
   224  		path: "net/http", // loaded from GOROOT
   225  	}, {
   226  		path: "cmd",
   227  		err:  &build.NoGoError{Dir: filepath.Join(proj.Projectdir(), "src", "cmd")},
   228  	}}
   229  
   230  	for _, tt := range tests {
   231  		ctx, err := NewContext(proj)
   232  		if err != nil {
   233  			t.Fatal(err)
   234  		}
   235  		_, err = ctx.importer.Import(tt.path)
   236  		if !reflect.DeepEqual(err, tt.err) {
   237  			t.Errorf("importPackage(%q): got %v, want %v", tt.path, err, tt.err)
   238  		}
   239  	}
   240  }