Adding upstream version 0.0~git20250520.a1d9079+dfsg.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
590ac7ff5f
commit
20149b7f3a
456 changed files with 70406 additions and 0 deletions
663
internal/binres/binres_test.go
Normal file
663
internal/binres/binres_test.go
Normal file
|
@ -0,0 +1,663 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package binres
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/mobile/internal/sdkpath"
|
||||
)
|
||||
|
||||
func init() {
|
||||
skipSynthesize = true
|
||||
}
|
||||
|
||||
func printrecurse(t *testing.T, pl *Pool, el *Element, ws string) {
|
||||
|
||||
t.Logf("%s+elem:ns(%v) name(%s)", ws, el.NS, el.Name.Resolve(pl))
|
||||
|
||||
for _, attr := range el.attrs {
|
||||
ns := ""
|
||||
if attr.NS != math.MaxUint32 {
|
||||
ns = pl.strings[int(attr.NS)]
|
||||
nss := strings.Split(ns, "/")
|
||||
ns = nss[len(nss)-1]
|
||||
}
|
||||
|
||||
val := ""
|
||||
if attr.RawValue != NoEntry {
|
||||
val = pl.strings[int(attr.RawValue)]
|
||||
} else {
|
||||
switch attr.TypedValue.Type {
|
||||
case DataIntDec:
|
||||
val = fmt.Sprintf("%v", attr.TypedValue.Value)
|
||||
case DataIntBool:
|
||||
val = fmt.Sprintf("%v", attr.TypedValue.Value == 0xFFFFFFFF)
|
||||
default:
|
||||
val = fmt.Sprintf("0x%08X", attr.TypedValue.Value)
|
||||
}
|
||||
}
|
||||
dt := attr.TypedValue.Type
|
||||
|
||||
t.Logf("%s|attr:ns(%v) name(%s) val(%s) valtyp(%s)\n", ws, ns, pl.strings[int(attr.Name)], val, dt)
|
||||
}
|
||||
t.Logf("\n")
|
||||
for _, e := range el.Children {
|
||||
printrecurse(t, pl, e, ws+" ")
|
||||
}
|
||||
}
|
||||
|
||||
func compareBytes(a, b []byte) error {
|
||||
if bytes.Equal(a, b) {
|
||||
return nil
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
x, y := len(a), len(b)
|
||||
if x != y {
|
||||
fmt.Fprintf(buf, "byte length does not match, have %v, want %v\n", y, x)
|
||||
}
|
||||
if x > y {
|
||||
x, y = y, x
|
||||
}
|
||||
mismatch := false
|
||||
for i := 0; i < x; i++ {
|
||||
if mismatch = a[i] != b[i]; mismatch {
|
||||
fmt.Fprintf(buf, "first byte mismatch at %v\n", i)
|
||||
break
|
||||
}
|
||||
}
|
||||
if mismatch {
|
||||
// print out a reasonable amount of data to help identify issues
|
||||
truncate := x > 3300
|
||||
if truncate {
|
||||
x = 3300
|
||||
}
|
||||
buf.WriteString(" HAVE WANT\n")
|
||||
for i := 0; i < x; i += 4 {
|
||||
he, we := 4, 4
|
||||
if i+he >= x {
|
||||
he = x - i
|
||||
}
|
||||
if i+we >= y {
|
||||
we = y - i
|
||||
}
|
||||
notequal := ""
|
||||
if !bytes.Equal(b[i:i+he], a[i:i+we]) {
|
||||
notequal = "***"
|
||||
}
|
||||
fmt.Fprintf(buf, "%3v | % X % X %s\n", i, b[i:i+he], a[i:i+we], notequal)
|
||||
}
|
||||
if truncate {
|
||||
fmt.Fprint(buf, "... output truncated.\n")
|
||||
}
|
||||
}
|
||||
return errors.New(buf.String())
|
||||
}
|
||||
|
||||
func TestBootstrap(t *testing.T) {
|
||||
bin, err := os.ReadFile("testdata/bootstrap.bin")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// unmarshal binary xml and store byte indices of decoded resources.
|
||||
debugIndices := make(map[encoding.BinaryMarshaler]int)
|
||||
trackUnmarshal := func(buf []byte) (*XML, error) {
|
||||
bx := new(XML)
|
||||
if err := (&bx.chunkHeader).UnmarshalBinary(buf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf = buf[8:]
|
||||
debugIndex := 8
|
||||
for len(buf) > 0 {
|
||||
k, err := bx.unmarshalBinaryKind(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
debugIndices[k.(encoding.BinaryMarshaler)] = debugIndex
|
||||
debugIndex += k.size()
|
||||
buf = buf[k.size():]
|
||||
}
|
||||
return bx, nil
|
||||
}
|
||||
|
||||
checkMarshal := func(res encoding.BinaryMarshaler, bsize int) {
|
||||
b, err := res.MarshalBinary()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
idx := debugIndices[res]
|
||||
a := bin[idx : idx+bsize]
|
||||
if !bytes.Equal(a, b) {
|
||||
x, y := len(a), len(b)
|
||||
if x != y {
|
||||
t.Errorf("%v: %T: byte length does not match, have %v, want %v", idx, res, y, x)
|
||||
}
|
||||
if x > y {
|
||||
x, y = y, x
|
||||
}
|
||||
mismatch := false
|
||||
for i := 0; i < x; i++ {
|
||||
if mismatch = a[i] != b[i]; mismatch {
|
||||
t.Errorf("%v: %T: first byte mismatch at %v of %v", idx, res, i, bsize)
|
||||
break
|
||||
}
|
||||
}
|
||||
if mismatch {
|
||||
// print out a reasonable amount of data to help identify issues
|
||||
truncate := x > 1300
|
||||
if truncate {
|
||||
x = 1300
|
||||
}
|
||||
t.Log(" HAVE WANT")
|
||||
for i := 0; i < x; i += 4 {
|
||||
he, we := 4, 4
|
||||
if i+he >= x {
|
||||
he = x - i
|
||||
}
|
||||
if i+we >= y {
|
||||
we = y - i
|
||||
}
|
||||
t.Logf("%3v | % X % X\n", i, b[i:i+he], a[i:i+we])
|
||||
}
|
||||
if truncate {
|
||||
t.Log("... output truncated.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bxml, err := trackUnmarshal(bin)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for i, x := range bxml.Pool.strings {
|
||||
t.Logf("Pool(%v): %q\n", i, x)
|
||||
}
|
||||
|
||||
for _, e := range bxml.Children {
|
||||
printrecurse(t, bxml.Pool, e, "")
|
||||
}
|
||||
|
||||
checkMarshal(&bxml.chunkHeader, int(bxml.headerByteSize))
|
||||
checkMarshal(bxml.Pool, bxml.Pool.size())
|
||||
checkMarshal(bxml.Map, bxml.Map.size())
|
||||
checkMarshal(bxml.Namespace, bxml.Namespace.size())
|
||||
|
||||
for el := range bxml.iterElements() {
|
||||
checkMarshal(el, el.size())
|
||||
checkMarshal(el.end, el.end.size())
|
||||
}
|
||||
|
||||
checkMarshal(bxml.Namespace.end, bxml.Namespace.end.size())
|
||||
checkMarshal(bxml, bxml.size())
|
||||
}
|
||||
|
||||
func TestEncode(t *testing.T) {
|
||||
f, err := os.Open("testdata/bootstrap.xml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
bx, err := UnmarshalXML(f, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
bin, err := os.ReadFile("testdata/bootstrap.bin")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
bxml := new(XML)
|
||||
if err := bxml.UnmarshalBinary(bin); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := compareStrings(t, bxml.Pool.strings, bx.Pool.strings); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if err := compareUint32s(t, rtou(bxml.Map.rs), rtou(bx.Map.rs)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if err := compareNamespaces(bx.Namespace, bxml.Namespace); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if err := compareElements(bx, bxml); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// Current output byte-for-byte of pkg binres is close, but not exact, to output of aapt.
|
||||
// The current exceptions to this are as follows:
|
||||
// * sort order of certain attributes
|
||||
// * typed value of minSdkVersion
|
||||
// The below check will produce an error, listing differences in the byte output of each.
|
||||
// have, err := bx.MarshalBinary()
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
// if err := compareBytes(bin, have); err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
}
|
||||
|
||||
func TestRawValueByName(t *testing.T) {
|
||||
f, err := os.Open("testdata/bootstrap.xml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
bx, err := UnmarshalXML(f, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
pkgname, err := bx.RawValueByName("manifest", xml.Name{Local: "package"})
|
||||
if want := "com.zentus.balloon"; err != nil || pkgname != want {
|
||||
t.Fatalf("have (%q, %v), want (%q, nil)", pkgname, err, want)
|
||||
}
|
||||
}
|
||||
|
||||
type byAttrName []*Attribute
|
||||
|
||||
func (a byAttrName) Len() int { return len(a) }
|
||||
func (a byAttrName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a byAttrName) Less(i, j int) bool { return a[i].Name < a[j].Name }
|
||||
|
||||
func compareElements(have, want *XML) error {
|
||||
h, w := have.iterElements(), want.iterElements()
|
||||
buf := new(bytes.Buffer)
|
||||
for {
|
||||
a, b := <-h, <-w
|
||||
if a == nil || b == nil {
|
||||
break
|
||||
}
|
||||
if a.Name.Resolve(have.Pool) == "uses-sdk" {
|
||||
a = <-h // discard uses-sdk token from tests since it's synthesized internally
|
||||
}
|
||||
if a.NS != b.NS ||
|
||||
a.Name != b.Name {
|
||||
return fmt.Errorf("elements don't match, have %+v, want %+v", a, b)
|
||||
}
|
||||
if a.end.NS != b.end.NS ||
|
||||
a.end.Name != b.end.Name {
|
||||
return fmt.Errorf("element ends don't match, have %+v, want %+v", a.end, b.end)
|
||||
}
|
||||
if len(a.attrs) != len(b.attrs) {
|
||||
return fmt.Errorf("element attribute lengths don't match, have %v, want %v", len(a.attrs), len(b.attrs))
|
||||
}
|
||||
|
||||
// discards order of aapt and binres as some sorting details of apt have eluded this package but do not
|
||||
// affect final output from functioning correctly
|
||||
sort.Sort(byAttrName(a.attrs))
|
||||
sort.Sort(byAttrName(b.attrs))
|
||||
|
||||
for i, attr := range a.attrs {
|
||||
bttr := b.attrs[i]
|
||||
if attr.NS != bttr.NS ||
|
||||
attr.Name != bttr.Name ||
|
||||
attr.RawValue != bttr.RawValue ||
|
||||
attr.TypedValue.Type != bttr.TypedValue.Type ||
|
||||
attr.TypedValue.Value != bttr.TypedValue.Value {
|
||||
// single exception to check for minSdkVersion which has peculiar output from aapt
|
||||
// but following same format of all other like-types appears to work correctly.
|
||||
// BUG(dskinner) this check is brittle as it will skip over any attribute in
|
||||
// bootstrap.xml that has value == MinSDK.
|
||||
if attr.TypedValue.Value == MinSDK {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(buf, "attrs don't match\nhave: %+v\nwant: %+v\n", attr, bttr)
|
||||
}
|
||||
}
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteString("-------------\n")
|
||||
}
|
||||
}
|
||||
if buf.Len() > 0 {
|
||||
return errors.New(buf.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func compareNamespaces(have, want *Namespace) error {
|
||||
if have == nil || want == nil ||
|
||||
have.LineNumber != want.LineNumber ||
|
||||
have.Comment != want.Comment ||
|
||||
have.prefix != want.prefix ||
|
||||
have.uri != want.uri {
|
||||
return fmt.Errorf("namespaces don't match, have %+v, want %+v", have, want)
|
||||
}
|
||||
if have.end != nil || want.end != nil {
|
||||
return compareNamespaces(have.end, want.end)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func rtou(a []TableRef) (b []uint32) {
|
||||
for _, x := range a {
|
||||
b = append(b, uint32(x))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func compareUint32s(t *testing.T, a, b []uint32) error {
|
||||
var err error
|
||||
if len(a) != len(b) {
|
||||
err = fmt.Errorf("lengths do not match")
|
||||
}
|
||||
|
||||
n := len(a)
|
||||
if n < len(b) {
|
||||
n = len(b)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString("a.Map.rs b.Map.rs\n")
|
||||
for i := 0; i < n; i++ {
|
||||
var c, d string
|
||||
if i < len(a) {
|
||||
c = fmt.Sprintf("%0#8x ", a[i])
|
||||
} else {
|
||||
c = "__________ "
|
||||
}
|
||||
if i < len(b) {
|
||||
d = fmt.Sprintf("%0#8x ", b[i])
|
||||
} else {
|
||||
d = "__________ "
|
||||
}
|
||||
if err == nil && c != d {
|
||||
err = fmt.Errorf("has missing/incorrect values")
|
||||
}
|
||||
buf.WriteString(c + " " + d + "\n")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%s\n%s", err, buf.String())
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func compareStrings(t *testing.T, a, b []string) error {
|
||||
var err error
|
||||
if len(a) != len(b) {
|
||||
err = fmt.Errorf("lengths do not match")
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
for i, x := range a {
|
||||
v := "__"
|
||||
for j, y := range b {
|
||||
if x == y {
|
||||
v = fmt.Sprintf("%2v", j)
|
||||
break
|
||||
}
|
||||
}
|
||||
if err == nil && v == "__" {
|
||||
if !strings.HasPrefix(x, "4.1.") {
|
||||
// as of the time of this writing, the current version of build tools being targeted
|
||||
// reports 4.1.2-1425332.
|
||||
//
|
||||
// TODO this check has the potential to hide real errors but can be fixed once more
|
||||
// of the xml document is unmarshalled and XML can be queried to assure this is related
|
||||
// to platformBuildVersionName.
|
||||
err = fmt.Errorf("has missing/incorrect values")
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(buf, "Pool(%2v, %s) %q\n", i, v, x)
|
||||
}
|
||||
|
||||
contains := func(xs []string, a string) bool {
|
||||
for _, x := range xs {
|
||||
if x == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
buf.WriteString("\n## only in var a\n")
|
||||
for i, x := range a {
|
||||
if !contains(b, x) {
|
||||
fmt.Fprintf(buf, "Pool(%2v) %q\n", i, x)
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString("\n## only in var b\n")
|
||||
for i, x := range b {
|
||||
if !contains(a, x) {
|
||||
fmt.Fprintf(buf, "Pool(%2v) %q\n", i, x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%s\n%s", err, buf.String())
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func TestOpenTable(t *testing.T) {
|
||||
if _, err := sdkpath.AndroidHome(); err != nil {
|
||||
t.Skipf("Could not locate Android SDK: %v", err)
|
||||
}
|
||||
tbl, err := OpenTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(tbl.pkgs) == 0 {
|
||||
t.Fatal("failed to decode any resource packages")
|
||||
}
|
||||
|
||||
pkg := tbl.pkgs[0]
|
||||
|
||||
t.Log("package name:", pkg.name)
|
||||
|
||||
for i, x := range pkg.typePool.strings {
|
||||
t.Logf("typePool[i=%v]: %s\n", i, x)
|
||||
}
|
||||
|
||||
for i, spec := range pkg.specs {
|
||||
t.Logf("spec[i=%v]: %v %q\n", i, spec.id, pkg.typePool.strings[spec.id-1])
|
||||
for j, typ := range spec.types {
|
||||
t.Logf("\ttype[i=%v]: %v\n", j, typ.id)
|
||||
for k, nt := range typ.entries {
|
||||
if nt == nil { // NoEntry
|
||||
continue
|
||||
}
|
||||
t.Logf("\t\tentry[i=%v]: %v %q\n", k, nt.key, pkg.keyPool.strings[nt.key])
|
||||
if k > 5 {
|
||||
t.Logf("\t\t... truncating output")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTableRefByName(t *testing.T) {
|
||||
checkResources(t)
|
||||
tbl, err := OpenSDKTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(tbl.pkgs) == 0 {
|
||||
t.Fatal("failed to decode any resource packages")
|
||||
}
|
||||
|
||||
ref, err := tbl.RefByName("@android:style/Theme.NoTitleBar.Fullscreen")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if want := uint32(0x01030007); uint32(ref) != want {
|
||||
t.Fatalf("RefByName does not match expected result, have %0#8x, want %0#8x", ref, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTableMarshal(t *testing.T) {
|
||||
checkResources(t)
|
||||
tbl, err := OpenSDKTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
bin, err := tbl.MarshalBinary()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
xtbl := new(Table)
|
||||
if err := xtbl.UnmarshalBinary(bin); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(tbl.pool.strings) != len(xtbl.pool.strings) {
|
||||
t.Fatal("tbl.pool lengths don't match")
|
||||
}
|
||||
if len(tbl.pkgs) != len(xtbl.pkgs) {
|
||||
t.Fatal("tbl.pkgs lengths don't match")
|
||||
}
|
||||
|
||||
pkg, xpkg := tbl.pkgs[0], xtbl.pkgs[0]
|
||||
if err := compareStrings(t, pkg.typePool.strings, xpkg.typePool.strings); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := compareStrings(t, pkg.keyPool.strings, xpkg.keyPool.strings); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(pkg.specs) != len(xpkg.specs) {
|
||||
t.Fatal("pkg.specs lengths don't match")
|
||||
}
|
||||
|
||||
for i, spec := range pkg.specs {
|
||||
xspec := xpkg.specs[i]
|
||||
if spec.id != xspec.id {
|
||||
t.Fatal("spec.id doesn't match")
|
||||
}
|
||||
if spec.entryCount != xspec.entryCount {
|
||||
t.Fatal("spec.entryCount doesn't match")
|
||||
}
|
||||
if len(spec.entries) != len(xspec.entries) {
|
||||
t.Fatal("spec.entries lengths don't match")
|
||||
}
|
||||
for j, mask := range spec.entries {
|
||||
xmask := xspec.entries[j]
|
||||
if mask != xmask {
|
||||
t.Fatal("entry mask doesn't match")
|
||||
}
|
||||
}
|
||||
if len(spec.types) != len(xspec.types) {
|
||||
t.Fatal("spec.types length don't match")
|
||||
}
|
||||
for j, typ := range spec.types {
|
||||
xtyp := xspec.types[j]
|
||||
if typ.id != xtyp.id {
|
||||
t.Fatal("typ.id doesn't match")
|
||||
}
|
||||
if typ.entryCount != xtyp.entryCount {
|
||||
t.Fatal("typ.entryCount doesn't match")
|
||||
}
|
||||
// Config size can differ after serialization due to the loss of extended fields
|
||||
// during reserialization, but the fixed portions of the Type header must not change.
|
||||
if uint32(typ.headerByteSize)-typ.config.size != uint32(xtyp.headerByteSize)-uint32(xtyp.config.size) {
|
||||
t.Fatal("fixed size header portions don't match")
|
||||
}
|
||||
if len(typ.indices) != len(xtyp.indices) {
|
||||
t.Fatal("typ.indices length don't match")
|
||||
}
|
||||
for k, index := range typ.indices {
|
||||
xindex := xtyp.indices[k]
|
||||
if index != xindex {
|
||||
t.Errorf("type index doesn't match at %v, have %v, want %v", k, xindex, index)
|
||||
}
|
||||
}
|
||||
if len(typ.entries) != len(xtyp.entries) {
|
||||
t.Fatal("typ.entries lengths don't match")
|
||||
}
|
||||
for k, nt := range typ.entries {
|
||||
xnt := xtyp.entries[k]
|
||||
if nt == nil {
|
||||
if xnt != nil {
|
||||
t.Fatal("nt is nil but xnt is not")
|
||||
}
|
||||
continue
|
||||
}
|
||||
if nt.size != xnt.size {
|
||||
t.Fatal("entry.size doesn't match")
|
||||
}
|
||||
if nt.flags != xnt.flags {
|
||||
t.Fatal("entry.flags don't match")
|
||||
}
|
||||
if nt.key != xnt.key {
|
||||
t.Fatal("entry.key doesn't match")
|
||||
}
|
||||
|
||||
if nt.parent != xnt.parent {
|
||||
t.Fatal("entry.parent doesn't match")
|
||||
}
|
||||
if nt.count != xnt.count {
|
||||
t.Fatal("entry.count doesn't match")
|
||||
}
|
||||
for l, val := range nt.values {
|
||||
xval := xnt.values[l]
|
||||
if val.name != xval.name {
|
||||
t.Fatal("value.name doesn't match")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkResources(t *testing.T) {
|
||||
t.Helper()
|
||||
if _, err := sdkpath.AndroidHome(); err != nil {
|
||||
t.Skip("Could not locate Android SDK")
|
||||
}
|
||||
rscPath, err := apiResourcesPath()
|
||||
if err != nil {
|
||||
t.Skipf("failed to find resources: %v", err)
|
||||
}
|
||||
if _, err := os.Stat(rscPath); err != nil {
|
||||
t.Skipf("failed to find resources: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkTableRefByName(b *testing.B) {
|
||||
if _, err := sdkpath.AndroidHome(); err != nil {
|
||||
b.Fatal("Could not locate Android SDK")
|
||||
}
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for n := 0; n < b.N; n++ {
|
||||
tbl, err := OpenTable()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
_, err = tbl.RefByName("@android:style/Theme.NoTitleBar.Fullscreen")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue