github.com/c-darwin/mobile@v0.0.0-20160313183840-ff625c46f7c9/cmd/gomobile/writer_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 "crypto/x509" 9 "encoding/pem" 10 "io" 11 "io/ioutil" 12 "os" 13 "os/exec" 14 "testing" 15 ) 16 17 func TestWriter(t *testing.T) { 18 block, _ := pem.Decode([]byte(debugCert)) 19 if block == nil { 20 t.Fatal("no cert") 21 } 22 privKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) 23 if err != nil { 24 t.Fatal(err) 25 } 26 27 f, err := ioutil.TempFile("", "testapk-") 28 if err != nil { 29 t.Fatal(err) 30 } 31 f.Close() 32 defer os.Remove(f.Name()) 33 apkPath := f.Name() + ".apk" 34 35 f, err = os.Create(apkPath) 36 if err != nil { 37 t.Fatal(err) 38 } 39 defer os.Remove(apkPath) 40 41 apkw := NewWriter(f, privKey) 42 43 w, err := apkw.Create("AndroidManifest.xml") 44 if err != nil { 45 t.Fatalf("could not create AndroidManifest.xml: %v", err) 46 } 47 if _, err := w.Write([]byte(androidManifest)); err != nil { 48 t.Errorf("could not write AndroidManifest.xml: %v", err) 49 } 50 51 w, err = apkw.Create("assets/hello_world.txt") 52 if err != nil { 53 t.Fatalf("could not create assets/hello_world.txt: %v", err) 54 } 55 if _, err := w.Write([]byte("Hello, 世界")); err != nil { 56 t.Errorf("could not write assets/hello_world.txt: %v", err) 57 } 58 59 if err := apkw.Close(); err != nil { 60 t.Fatal(err) 61 } 62 63 if exec.Command("which", "aapt").Run() != nil { 64 t.Skip("command aapt not found, skipping") 65 } 66 67 out, err := exec.Command("aapt", "list", "-a", apkPath).CombinedOutput() 68 aaptGot := string(out) 69 if err != nil { 70 t.Logf("aapt:\n%s", aaptGot) 71 t.Fatalf("aapt failed: %v", err) 72 } 73 74 if aaptGot != aaptWant { 75 t.Errorf("unexpected output from aapt") 76 d, err := diff(aaptGot, aaptWant) 77 if err != nil { 78 t.Errorf("diff failed: %v", err) 79 } else { 80 t.Logf("%s", d) 81 } 82 } 83 } 84 85 const aaptWant = `AndroidManifest.xml 86 assets/hello_world.txt 87 META-INF/MANIFEST.MF 88 META-INF/CERT.SF 89 META-INF/CERT.RSA 90 91 Resource table: 92 Package Groups (0) 93 94 Android manifest: 95 N: android=http://schemas.android.com/apk/res/android 96 E: manifest (line=2) 97 A: package="org.golang.fakeapp" (Raw: "org.golang.fakeapp") 98 A: android:versionCode(0x0101021b)=(type 0x10)0x1 99 A: android:versionName(0x0101021c)="1.0" (Raw: "1.0") 100 E: uses-sdk (line=8) 101 A: android:minSdkVersion(0x0101020c)=(type 0x10)0x9 102 E: application (line=9) 103 A: android:label(0x01010001)="FakeApp" (Raw: "FakeApp") 104 A: android:hasCode(0x0101000c)=(type 0x12)0x0 105 A: android:debuggable(0x0101000f)=(type 0x12)0xffffffff 106 E: activity (line=10) 107 A: android:name(0x01010003)="android.app.NativeActivity" (Raw: "android.app.NativeActivity") 108 A: android:label(0x01010001)="FakeApp" (Raw: "FakeApp") 109 A: android:configChanges(0x0101001f)=(type 0x11)0xa0 110 E: intent-filter (line=14) 111 E: action (line=15) 112 A: android:name(0x01010003)="android.intent.action.MAIN" (Raw: "android.intent.action.MAIN") 113 E: category (line=16) 114 A: android:name(0x01010003)="android.intent.category.LAUNCHER" (Raw: "android.intent.category.LAUNCHER") 115 ` 116 117 const androidManifest = ` 118 <manifest 119 xmlns:android="http://schemas.android.com/apk/res/android" 120 package="org.golang.fakeapp" 121 android:versionCode="1" 122 android:versionName="1.0"> 123 124 <uses-sdk android:minSdkVersion="9" /> 125 <application android:label="FakeApp" android:hasCode="false" android:debuggable="true"> 126 <activity android:name="android.app.NativeActivity" 127 android:label="FakeApp" 128 android:configChanges="orientation|keyboardHidden"> 129 130 <intent-filter> 131 <action android:name="android.intent.action.MAIN" /> 132 <category android:name="android.intent.category.LAUNCHER" /> 133 </intent-filter> 134 </activity> 135 </application> 136 </manifest> 137 ` 138 139 func writeTempFile(data string) (string, error) { 140 f, err := ioutil.TempFile("", "gofmt") 141 if err != nil { 142 return "", err 143 } 144 _, err = io.WriteString(f, data) 145 errc := f.Close() 146 if err == nil { 147 return f.Name(), errc 148 } 149 return f.Name(), err 150 } 151 152 func diff(got, want string) (string, error) { 153 wantPath, err := writeTempFile(want) 154 if err != nil { 155 return "", err 156 } 157 defer os.Remove(wantPath) 158 159 gotPath, err := writeTempFile(got) 160 if err != nil { 161 return "", err 162 } 163 defer os.Remove(gotPath) 164 165 data, err := exec.Command("diff", "-u", wantPath, gotPath).CombinedOutput() 166 if len(data) > 0 { 167 // diff exits with a non-zero status when the files don't match. 168 // Ignore that failure as long as we get output. 169 err = nil 170 } 171 return string(data), err 172 }