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