blob: f2ff5cddadb2b7a8ffd390bb548d3453f81498e7 [file] [log] [blame]
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package generate
import (
"bytes"
"fmt"
"log"
"path/filepath"
"reflect"
"testing"
"android.googlesource.com/platform/tools/gpu/binary/schema"
)
var (
structType = &schema.Struct{Name: "objects.Terminator"}
fields = []schema.Field{
{Declared: "u8", Type: &schema.Primitive{Name: "uint8", Method: schema.Uint8}},
{Declared: "u16", Type: &schema.Primitive{Name: "uint16", Method: schema.Uint16}},
{Declared: "u32", Type: &schema.Primitive{Name: "uint32", Method: schema.Uint32}},
{Declared: "u64", Type: &schema.Primitive{Name: "uint64", Method: schema.Uint64}},
{Declared: "i8", Type: &schema.Primitive{Name: "int8", Method: schema.Int8}},
{Declared: "i16", Type: &schema.Primitive{Name: "int16", Method: schema.Int16}},
{Declared: "i32", Type: &schema.Primitive{Name: "int32", Method: schema.Int32}},
{Declared: "i64", Type: &schema.Primitive{Name: "int64", Method: schema.Int64}},
{Declared: "f32", Type: &schema.Primitive{Name: "float32", Method: schema.Float32}},
{Declared: "f64", Type: &schema.Primitive{Name: "float64", Method: schema.Float64}},
{Declared: "bool", Type: &schema.Primitive{Name: "bool", Method: schema.Bool}},
{Declared: "byte", Type: &schema.Primitive{Name: "byte", Method: schema.Uint8}},
{Declared: "int", Type: &schema.Primitive{Name: "int", Method: schema.Int32}},
{Declared: "str", Type: &schema.Primitive{Name: "string", Method: schema.String}},
{Declared: "codeable", Type: structType},
{Declared: "pointer", Type: &schema.Pointer{Type: structType}},
{Declared: "object", Type: &schema.Interface{Name: "binary.Object"}},
{Declared: "slice", Type: &schema.Slice{ValueType: structType}},
{Declared: "alias", Type: &schema.Slice{Alias: "Other", ValueType: &schema.Primitive{Name: "int", Method: schema.Int32}}},
{Declared: "stream", Type: &schema.Stream{ValueType: structType}},
{Declared: "array", Type: &schema.Array{ValueType: &schema.Primitive{Name: "int", Method: schema.Int32}, Size: 10}},
{Declared: "dict", Type: &schema.Map{KeyType: &schema.Primitive{Name: "string", Method: schema.String}, ValueType: structType}},
{Declared: "data", Type: &schema.Slice{ValueType: &schema.Primitive{Name: "uint8", Method: schema.Uint8}}},
{Declared: "id", Type: &schema.Primitive{Name: "binary.ID", Method: schema.ID}},
{Declared: "", Type: structType},
}
)
var loader *Loader
var testId int
func init() {
pwd, _ := filepath.Abs(".")
loader = NewLoader(pwd, false)
}
func parseStructs(source string) []*Struct {
testId++
fakeFile := fmt.Sprintf(`
package fake
import "android.googlesource.com/platform/tools/gpu/binary/objects"
import "android.googlesource.com/platform/tools/gpu/binary"
%s`, source)
name := fmt.Sprintf("fake_%d.go", testId)
loader.ScanFile(name, fakeFile)
if err := loader.Process(); err != nil {
log.Fatal("Process failed:", err)
}
dir := loader.GetDir(name)
return dir.Module.Output.Structs
}
func parseStruct(t *testing.T, name string, source string) *Struct {
s := parseStructs(source)
if len(s) != 1 {
log.Fatalf("Parsed %d structs, expected 1", len(s))
}
if s[0].Name != name {
t.Errorf("Got struct %s, expected %s", s[0].Name, name)
}
return s[0]
}
func TestEmpty(t *testing.T) {
s := parseStruct(t, "MyStruct", "type MyStruct struct {binary.Generate}")
if len(s.Fields) != 0 {
t.Errorf("Got %d fields, expected none", len(s.Fields))
}
}
func TestDisable(t *testing.T) {
s := parseStructs("type MyStruct struct {binary.Generate `disable:\"true\"`}")
if len(s) != 0 {
t.Errorf("Got %d structs, expected none", len(s))
}
}
func TestStableID(t *testing.T) {
source := "type MyStruct struct {binary.Generate}"
a := parseStruct(t, "MyStruct", source)
b := parseStruct(t, "MyStruct", source)
if a.TypeID != b.TypeID {
t.Errorf("ID was not stable")
}
}
func TestNameAffectsID(t *testing.T) {
a := parseStruct(t, "MyStruct", "type MyStruct struct {binary.Generate}")
b := parseStruct(t, "YourStruct", "type YourStruct struct {binary.Generate}")
if a.TypeID == b.TypeID {
t.Errorf("Name change did not change ID")
}
}
func TestFieldCountAffectsID(t *testing.T) {
a := parseStruct(t, "MyStruct", "type MyStruct struct {binary.Generate; a int}")
b := parseStruct(t, "MyStruct", "type MyStruct struct {binary.Generate}")
if a.TypeID == b.TypeID {
t.Errorf("Field count did not change ID")
}
}
func TestFieldNameAffectsID(t *testing.T) {
a := parseStruct(t, "MyStruct", "type MyStruct struct {binary.Generate; a int}")
b := parseStruct(t, "MyStruct", "type MyStruct struct {binary.Generate; b int}")
if a.TypeID == b.TypeID {
t.Errorf("Field name did not change ID")
}
}
func TestFieldTypeAffectsID(t *testing.T) {
a := parseStruct(t, "MyStruct", "type MyStruct struct {binary.Generate; a int}")
b := parseStruct(t, "MyStruct", "type MyStruct struct {binary.Generate; a byte}")
if a.TypeID == b.TypeID {
t.Errorf("Field type did not change ID")
}
}
func TestTypes(t *testing.T) {
prefix := "type Other []int\n"
source := &bytes.Buffer{}
fmt.Fprintln(source, prefix)
fmt.Fprint(source, "type MyStruct struct {binary.Generate;\n")
for _, f := range fields {
fmt.Fprintf(source, " %s %s", f.Declared, f.Type)
if _, isstream := f.Type.(*schema.Stream); isstream {
fmt.Fprint(source, " `stream:\"true\"`")
}
fmt.Fprintln(source)
}
fmt.Fprint(source, "}\n")
s := parseStruct(t, "MyStruct", source.String())
if len(s.Fields) != len(fields) {
t.Errorf("Got %d fields, expected %d", len(s.Fields), len(fields))
}
for i, got := range s.Fields {
expected := fields[i]
if got.Declared != expected.Declared {
t.Errorf("Got field %s, expected %s", got.Declared, expected.Declared)
}
if reflect.TypeOf(got.Type) != reflect.TypeOf(expected.Type) {
t.Errorf("Got field type %T, expected %T for %s", got.Type, expected.Type, expected.Name())
}
if got.Type.String() != expected.Type.String() {
t.Errorf("Got field type %s, expected %s for %s", got.Type, expected.Type, expected.Name())
}
}
}