github.com/adwpc/xmobile@v0.0.0-20231212131043-3f9720cf0e99/cmd/gomobile/build_test.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "bytes" 9 "io/ioutil" 10 "os" 11 "os/exec" 12 "path/filepath" 13 "runtime" 14 "strings" 15 "testing" 16 "text/template" 17 18 "github.com/adwpc/xmobile/internal/sdkpath" 19 ) 20 21 func TestRFC1034Label(t *testing.T) { 22 tests := []struct { 23 in, want string 24 }{ 25 {"a", "a"}, 26 {"123", "-23"}, 27 {"a.b.c", "a-b-c"}, 28 {"a-b", "a-b"}, 29 {"a:b", "a-b"}, 30 {"a?b", "a-b"}, 31 {"αβγ", "---"}, 32 {"💩", "--"}, 33 {"My App", "My-App"}, 34 {"...", ""}, 35 {".-.", "--"}, 36 } 37 38 for _, tc := range tests { 39 if got := rfc1034Label(tc.in); got != tc.want { 40 t.Errorf("rfc1034Label(%q) = %q, want %q", tc.in, got, tc.want) 41 } 42 } 43 } 44 45 func TestAndroidPkgName(t *testing.T) { 46 tests := []struct { 47 in, want string 48 }{ 49 {"a", "a"}, 50 {"a123", "a123"}, 51 {"a.b.c", "a_b_c"}, 52 {"a-b", "a_b"}, 53 {"a:b", "a_b"}, 54 {"a?b", "a_b"}, 55 {"αβγ", "go___"}, 56 {"💩", "go_"}, 57 {"My App", "My_App"}, 58 {"...", "go___"}, 59 {".-.", "go___"}, 60 {"abstract", "abstract_"}, 61 {"Abstract", "Abstract"}, 62 {"12345", "go12345"}, 63 } 64 65 for _, tc := range tests { 66 if got := androidPkgName(tc.in); got != tc.want { 67 t.Errorf("len %d", len(tc.in)) 68 t.Errorf("androidPkgName(%q) = %q, want %q", tc.in, got, tc.want) 69 } 70 } 71 } 72 73 func TestAndroidBuild(t *testing.T) { 74 if runtime.GOOS == "android" || runtime.GOOS == "ios" { 75 t.Skipf("not available on %s", runtime.GOOS) 76 } 77 buf := new(bytes.Buffer) 78 defer func() { 79 xout = os.Stderr 80 buildN = false 81 buildX = false 82 }() 83 xout = buf 84 buildN = true 85 buildX = true 86 buildO = "basic.apk" 87 buildTarget = "android/arm" 88 gopath = filepath.ToSlash(filepath.SplitList(goEnv("GOPATH"))[0]) 89 if goos == "windows" { 90 os.Setenv("HOMEDRIVE", "C:") 91 } 92 cmdBuild.flag.Parse([]string{"github.com/adwpc/xmobile/example/basic"}) 93 oldTags := buildTags 94 buildTags = []string{"tag1"} 95 defer func() { 96 buildTags = oldTags 97 }() 98 err := runBuild(cmdBuild) 99 if err != nil { 100 t.Log(buf.String()) 101 t.Fatal(err) 102 } 103 104 diff, err := diffOutput(buf.String(), androidBuildTmpl) 105 if err != nil { 106 t.Fatalf("computing diff failed: %v", err) 107 } 108 if diff != "" { 109 t.Errorf("unexpected output:\n%s", diff) 110 } 111 } 112 113 var androidBuildTmpl = template.Must(template.New("output").Parse(`GOMOBILE={{.GOPATH}}/pkg/gomobile 114 WORK=$WORK 115 mkdir -p $WORK/lib/armeabi-v7a 116 GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=arm CC=$NDK_PATH/toolchains/llvm/prebuilt/{{.NDKARCH}}/bin/armv7a-linux-androideabi16-clang CXX=$NDK_PATH/toolchains/llvm/prebuilt/{{.NDKARCH}}/bin/armv7a-linux-androideabi16-clang++ CGO_ENABLED=1 GOARM=7 go build -tags tag1 -x -buildmode=c-shared -o $WORK/lib/armeabi-v7a/libbasic.so github.com/adwpc/xmobile/example/basic 117 `)) 118 119 func TestParseBuildTarget(t *testing.T) { 120 wantAndroid := "android/" + strings.Join(platformArchs("android"), ",android/") 121 122 tests := []struct { 123 in string 124 wantErr bool 125 want string 126 }{ 127 {"android", false, wantAndroid}, 128 {"android,android/arm", false, wantAndroid}, 129 {"android/arm", false, "android/arm"}, 130 131 {"ios", false, "ios/arm64,iossimulator/arm64,iossimulator/amd64"}, 132 {"ios,ios/arm64", false, "ios/arm64"}, 133 {"ios/arm64", false, "ios/arm64"}, 134 135 {"iossimulator", false, "iossimulator/arm64,iossimulator/amd64"}, 136 {"iossimulator/amd64", false, "iossimulator/amd64"}, 137 138 {"macos", false, "macos/arm64,macos/amd64"}, 139 {"macos,ios/arm64", false, "macos/arm64,macos/amd64,ios/arm64"}, 140 {"macos/arm64", false, "macos/arm64"}, 141 {"macos/amd64", false, "macos/amd64"}, 142 143 {"maccatalyst", false, "maccatalyst/arm64,maccatalyst/amd64"}, 144 {"maccatalyst,ios/arm64", false, "maccatalyst/arm64,maccatalyst/amd64,ios/arm64"}, 145 {"maccatalyst/arm64", false, "maccatalyst/arm64"}, 146 {"maccatalyst/amd64", false, "maccatalyst/amd64"}, 147 148 {"", true, ""}, 149 {"linux", true, ""}, 150 {"android/x86", true, ""}, 151 {"android/arm5", true, ""}, 152 {"ios/mips", true, ""}, 153 {"android,ios", true, ""}, 154 {"ios,android", true, ""}, 155 {"ios/amd64", true, ""}, 156 } 157 158 for _, tc := range tests { 159 t.Run(tc.in, func(t *testing.T) { 160 targets, err := parseBuildTarget(tc.in) 161 var s []string 162 for _, t := range targets { 163 s = append(s, t.String()) 164 } 165 got := strings.Join(s, ",") 166 if tc.wantErr { 167 if err == nil { 168 t.Errorf("-target=%q; want error, got (%q, nil)", tc.in, got) 169 } 170 return 171 } 172 if err != nil || got != tc.want { 173 t.Errorf("-target=%q; want (%q, nil), got (%q, %v)", tc.in, tc.want, got, err) 174 } 175 }) 176 } 177 } 178 179 func TestRegexImportGolangXPackage(t *testing.T) { 180 tests := []struct { 181 in string 182 want string 183 wantLen int 184 }{ 185 {"ffffffff t github.com/adwpc/xmobile", "github.com/adwpc/xmobile", 2}, 186 {"ffffffff t github.com/example/repo/vendor/github.com/adwpc/xmobile", "github.com/adwpc/xmobile", 2}, 187 {"ffffffff t github.com/example/github.com/adwpc/xmobile", "", 0}, 188 {"ffffffff t github.com/example/repo", "", 0}, 189 {"ffffffff t github.com/example/repo/vendor", "", 0}, 190 {"ffffffff t _github.com/adwpc/xmobile/app", "github.com/adwpc/xmobile/app", 2}, 191 } 192 193 for _, tc := range tests { 194 res := nmRE.FindStringSubmatch(tc.in) 195 if len(res) != tc.wantLen { 196 t.Errorf("nmRE returned unexpected result for %q: want len(res) = %d, got %d", 197 tc.in, tc.wantLen, len(res)) 198 continue 199 } 200 if tc.wantLen == 0 { 201 continue 202 } 203 if res[1] != tc.want { 204 t.Errorf("nmRE returned unexpected result. want (%v), got (%v)", 205 tc.want, res[1]) 206 } 207 } 208 } 209 210 func TestBuildWithGoModules(t *testing.T) { 211 if runtime.GOOS == "android" || runtime.GOOS == "ios" { 212 t.Skipf("gomobile are not available on %s", runtime.GOOS) 213 } 214 215 dir, err := ioutil.TempDir("", "gomobile-test") 216 if err != nil { 217 t.Fatal(err) 218 } 219 defer os.RemoveAll(dir) 220 221 if out, err := exec.Command("go", "build", "-o="+dir, "github.com/adwpc/xmobile/cmd/gomobile").CombinedOutput(); err != nil { 222 t.Fatalf("%v: %s", err, string(out)) 223 } 224 path := dir 225 if p := os.Getenv("PATH"); p != "" { 226 path += string(filepath.ListSeparator) + p 227 } 228 229 for _, target := range []string{"android", "ios"} { 230 t.Run(target, func(t *testing.T) { 231 switch target { 232 case "android": 233 if _, err := sdkpath.AndroidAPIPath(minAndroidAPI); err != nil { 234 t.Skip("No compatible android API platform found, skipping bind") 235 } 236 case "ios": 237 if !xcodeAvailable() { 238 t.Skip("Xcode is missing") 239 } 240 } 241 242 var out string 243 switch target { 244 case "android": 245 out = filepath.Join(dir, "basic.apk") 246 case "ios": 247 out = filepath.Join(dir, "Basic.app") 248 } 249 250 tests := []struct { 251 Name string 252 Path string 253 Dir string 254 }{ 255 { 256 Name: "Absolute Path", 257 Path: "github.com/adwpc/xmobile/example/basic", 258 }, 259 { 260 Name: "Relative Path", 261 Path: "./example/basic", 262 Dir: filepath.Join("..", ".."), 263 }, 264 } 265 266 for _, tc := range tests { 267 tc := tc 268 t.Run(tc.Name, func(t *testing.T) { 269 args := []string{"build", "-target=" + target, "-o=" + out} 270 if target == "ios" { 271 args = append(args, "-bundleid=org.golang.gomobiletest") 272 } 273 args = append(args, tc.Path) 274 cmd := exec.Command(filepath.Join(dir, "gomobile"), args...) 275 cmd.Env = append(os.Environ(), "PATH="+path, "GO111MODULE=on") 276 cmd.Dir = tc.Dir 277 if out, err := cmd.CombinedOutput(); err != nil { 278 t.Errorf("gomobile build failed: %v\n%s", err, string(out)) 279 } 280 }) 281 } 282 }) 283 } 284 }