206 lines
5.4 KiB
Go
206 lines
5.4 KiB
Go
// Copyright 2016 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 java
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"golang.org/x/mobile/internal/importers"
|
|
)
|
|
|
|
func TestImport(t *testing.T) {
|
|
if !IsAvailable() {
|
|
t.Skipf("javap not available")
|
|
}
|
|
tests := []struct {
|
|
ref importers.PkgRef
|
|
name string
|
|
methods []*FuncSet
|
|
}{
|
|
{
|
|
ref: importers.PkgRef{Pkg: "java/lang/Object", Name: "equals"},
|
|
name: "java.lang.Object",
|
|
methods: []*FuncSet{
|
|
&FuncSet{
|
|
Name: "equals",
|
|
GoName: "Equals",
|
|
CommonSig: CommonSig{
|
|
Params: []*Type{&Type{Kind: Object, Class: "java.lang.Object"}}, Ret: &Type{Kind: Boolean}, HasRet: true,
|
|
},
|
|
Funcs: []*Func{&Func{FuncSig: FuncSig{Name: "equals", Desc: "(Ljava/lang/Object;)Z"}, ArgDesc: "Ljava/lang/Object;", JNIName: "equals", Public: true, Params: []*Type{&Type{Kind: Object, Class: "java.lang.Object"}}, Ret: &Type{Kind: Boolean}}},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
ref: importers.PkgRef{Pkg: "java/lang/Runnable", Name: "run"},
|
|
name: "java.lang.Runnable",
|
|
methods: []*FuncSet{
|
|
&FuncSet{
|
|
Name: "run",
|
|
GoName: "Run",
|
|
CommonSig: CommonSig{},
|
|
Funcs: []*Func{&Func{FuncSig: FuncSig{Name: "run", Desc: "()V"}, ArgDesc: "", JNIName: "run", Public: true, Abstract: true}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
toString := &FuncSet{
|
|
Name: "toString",
|
|
GoName: "ToString",
|
|
CommonSig: CommonSig{
|
|
Ret: &Type{Kind: String}, HasRet: true,
|
|
},
|
|
Funcs: []*Func{&Func{FuncSig: FuncSig{Name: "toString", Desc: "()Ljava/lang/String;"}, ArgDesc: "", JNIName: "toString", Public: true, Ret: &Type{Kind: String}}},
|
|
}
|
|
for _, test := range tests {
|
|
refs := &importers.References{
|
|
Refs: []importers.PkgRef{test.ref},
|
|
Names: make(map[string]struct{}),
|
|
}
|
|
for _, m := range test.methods {
|
|
refs.Names[m.GoName] = struct{}{}
|
|
}
|
|
classes, err := (&Importer{}).Import(refs)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(classes) != 1 {
|
|
t.Fatalf("got %d classes, expected 1", len(classes))
|
|
}
|
|
cls := classes[0]
|
|
if cls.Name != test.name {
|
|
t.Errorf("got class name %s, expected %s", cls.Name, test.name)
|
|
}
|
|
methods := test.methods
|
|
if !cls.Interface {
|
|
methods = append(methods, toString)
|
|
}
|
|
loop:
|
|
for _, exp := range methods {
|
|
for _, got := range cls.AllMethods {
|
|
if reflect.DeepEqual(exp, got) {
|
|
continue loop
|
|
}
|
|
}
|
|
t.Errorf("failed to find method: %+v", exp)
|
|
}
|
|
}
|
|
}
|
|
|
|
func testClsMap() map[string]*Class {
|
|
//
|
|
// A--
|
|
// / \ \
|
|
// B C \
|
|
// \ / \ \
|
|
// D E F
|
|
//
|
|
return map[string]*Class{
|
|
"A": &Class{},
|
|
"B": &Class{
|
|
Supers: []string{"A"},
|
|
},
|
|
"C": &Class{
|
|
Supers: []string{"A"},
|
|
},
|
|
"D": &Class{
|
|
Supers: []string{"B", "C"},
|
|
},
|
|
"E": &Class{
|
|
Supers: []string{"C"},
|
|
},
|
|
"F": &Class{
|
|
Supers: []string{"A"},
|
|
},
|
|
}
|
|
}
|
|
|
|
func TestCommonTypes(t *testing.T) {
|
|
clsMap := testClsMap()
|
|
tests := [][3]*Type{
|
|
{nil, nil, nil},
|
|
{&Type{Kind: Int}, nil, nil},
|
|
{&Type{Kind: Int}, &Type{Kind: Float}, nil},
|
|
{&Type{Kind: Int}, &Type{Kind: Int}, &Type{Kind: Int}},
|
|
{&Type{Kind: Object, Class: "D"}, &Type{Kind: Object, Class: "D"}, &Type{Kind: Object, Class: "D"}},
|
|
{&Type{Kind: Object, Class: "D"}, &Type{Kind: Object, Class: "E"}, &Type{Kind: Object, Class: "C"}},
|
|
{&Type{Kind: Object, Class: "D"}, &Type{Kind: Object, Class: "F"}, &Type{Kind: Object, Class: "A"}},
|
|
{&Type{Kind: Object, Class: "B"}, &Type{Kind: Object, Class: "E"}, &Type{Kind: Object, Class: "A"}},
|
|
}
|
|
for _, test := range tests {
|
|
t1, t2, exp := test[0], test[1], test[2]
|
|
got := commonType(clsMap, t1, t2)
|
|
if !reflect.DeepEqual(got, exp) {
|
|
t.Errorf("commonType(%+v, %+v) = %+v, expected %+v", t1, t2, got, exp)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCommonSig(t *testing.T) {
|
|
tests := []struct {
|
|
Sigs []CommonSig
|
|
CommonSig
|
|
}{
|
|
{
|
|
Sigs: []CommonSig{
|
|
CommonSig{}, // f()
|
|
},
|
|
CommonSig: CommonSig{}, // f()
|
|
},
|
|
{
|
|
Sigs: []CommonSig{
|
|
CommonSig{Throws: true, HasRet: true, Ret: &Type{Kind: Int}}, // int f() throws
|
|
},
|
|
// int f() throws
|
|
CommonSig: CommonSig{Throws: true, HasRet: true, Ret: &Type{Kind: Int}},
|
|
},
|
|
{
|
|
Sigs: []CommonSig{
|
|
CommonSig{}, // f()
|
|
CommonSig{Params: []*Type{&Type{Kind: Int}}}, // f(int)
|
|
},
|
|
CommonSig: CommonSig{ // f(int...)
|
|
Variadic: true,
|
|
Params: []*Type{&Type{Kind: Int}},
|
|
},
|
|
},
|
|
{
|
|
Sigs: []CommonSig{
|
|
CommonSig{Params: []*Type{&Type{Kind: Int}}}, // f(int)
|
|
CommonSig{Params: []*Type{&Type{Kind: Float}}}, // f(float)
|
|
},
|
|
CommonSig: CommonSig{ // f(interface{})
|
|
Params: []*Type{nil},
|
|
},
|
|
},
|
|
{
|
|
Sigs: []CommonSig{
|
|
CommonSig{Params: []*Type{&Type{Kind: Int}}}, // f(int)
|
|
CommonSig{Params: []*Type{&Type{Kind: Int}, &Type{Kind: Int}}}, // f(int, int)
|
|
},
|
|
CommonSig: CommonSig{ // f(int, int...)
|
|
Variadic: true,
|
|
Params: []*Type{&Type{Kind: Int}, &Type{Kind: Int}},
|
|
},
|
|
},
|
|
{
|
|
Sigs: []CommonSig{
|
|
CommonSig{Params: []*Type{&Type{Kind: Object, Class: "A"}}}, // f(A)
|
|
CommonSig{Params: []*Type{&Type{Kind: Object, Class: "B"}}}, // f(B)
|
|
},
|
|
CommonSig: CommonSig{ // f(A)
|
|
Params: []*Type{&Type{Kind: Object, Class: "A"}},
|
|
},
|
|
},
|
|
}
|
|
clsMap := testClsMap()
|
|
for _, test := range tests {
|
|
got := combineSigs(clsMap, test.Sigs...)
|
|
if !reflect.DeepEqual(got, test.CommonSig) {
|
|
t.Errorf("commonSig(%+v) = %+v, expected %+v", test.Sigs, got, test.CommonSig)
|
|
}
|
|
}
|
|
}
|