github.com/TimaSlipko/gomobile@v1.0.8/internal/importers/java/java_test.go (about)

     1  // Copyright 2016 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 java
     6  
     7  import (
     8  	"reflect"
     9  	"testing"
    10  
    11  	"github.com/TimaSlipko/gomobile/internal/importers"
    12  )
    13  
    14  func TestImport(t *testing.T) {
    15  	if !IsAvailable() {
    16  		t.Skipf("javap not available")
    17  	}
    18  	tests := []struct {
    19  		ref     importers.PkgRef
    20  		name    string
    21  		methods []*FuncSet
    22  	}{
    23  		{
    24  			ref:  importers.PkgRef{Pkg: "java/lang/Object", Name: "equals"},
    25  			name: "java.lang.Object",
    26  			methods: []*FuncSet{
    27  				&FuncSet{
    28  					Name:   "equals",
    29  					GoName: "Equals",
    30  					CommonSig: CommonSig{
    31  						Params: []*Type{&Type{Kind: Object, Class: "java.lang.Object"}}, Ret: &Type{Kind: Boolean}, HasRet: true,
    32  					},
    33  					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}}},
    34  				},
    35  			},
    36  		},
    37  		{
    38  			ref:  importers.PkgRef{Pkg: "java/lang/Runnable", Name: "run"},
    39  			name: "java.lang.Runnable",
    40  			methods: []*FuncSet{
    41  				&FuncSet{
    42  					Name:      "run",
    43  					GoName:    "Run",
    44  					CommonSig: CommonSig{},
    45  					Funcs:     []*Func{&Func{FuncSig: FuncSig{Name: "run", Desc: "()V"}, ArgDesc: "", JNIName: "run", Public: true, Abstract: true}},
    46  				},
    47  			},
    48  		},
    49  	}
    50  	toString := &FuncSet{
    51  		Name:   "toString",
    52  		GoName: "ToString",
    53  		CommonSig: CommonSig{
    54  			Ret: &Type{Kind: String}, HasRet: true,
    55  		},
    56  		Funcs: []*Func{&Func{FuncSig: FuncSig{Name: "toString", Desc: "()Ljava/lang/String;"}, ArgDesc: "", JNIName: "toString", Public: true, Ret: &Type{Kind: String}}},
    57  	}
    58  	for _, test := range tests {
    59  		refs := &importers.References{
    60  			Refs:  []importers.PkgRef{test.ref},
    61  			Names: make(map[string]struct{}),
    62  		}
    63  		for _, m := range test.methods {
    64  			refs.Names[m.GoName] = struct{}{}
    65  		}
    66  		classes, err := (&Importer{}).Import(refs)
    67  		if err != nil {
    68  			t.Fatal(err)
    69  		}
    70  		if len(classes) != 1 {
    71  			t.Fatalf("got %d classes, expected 1", len(classes))
    72  		}
    73  		cls := classes[0]
    74  		if cls.Name != test.name {
    75  			t.Errorf("got class name %s, expected %s", cls.Name, test.name)
    76  		}
    77  		methods := test.methods
    78  		if !cls.Interface {
    79  			methods = append(methods, toString)
    80  		}
    81  	loop:
    82  		for _, exp := range methods {
    83  			for _, got := range cls.AllMethods {
    84  				if reflect.DeepEqual(exp, got) {
    85  					continue loop
    86  				}
    87  			}
    88  			t.Errorf("failed to find method: %+v", exp)
    89  		}
    90  	}
    91  }
    92  
    93  func testClsMap() map[string]*Class {
    94  	//
    95  	//    A--
    96  	//   / \  \
    97  	//  B   C  \
    98  	//   \ / \  \
    99  	//    D   E  F
   100  	//
   101  	return map[string]*Class{
   102  		"A": &Class{},
   103  		"B": &Class{
   104  			Supers: []string{"A"},
   105  		},
   106  		"C": &Class{
   107  			Supers: []string{"A"},
   108  		},
   109  		"D": &Class{
   110  			Supers: []string{"B", "C"},
   111  		},
   112  		"E": &Class{
   113  			Supers: []string{"C"},
   114  		},
   115  		"F": &Class{
   116  			Supers: []string{"A"},
   117  		},
   118  	}
   119  }
   120  
   121  func TestCommonTypes(t *testing.T) {
   122  	clsMap := testClsMap()
   123  	tests := [][3]*Type{
   124  		{nil, nil, nil},
   125  		{&Type{Kind: Int}, nil, nil},
   126  		{&Type{Kind: Int}, &Type{Kind: Float}, nil},
   127  		{&Type{Kind: Int}, &Type{Kind: Int}, &Type{Kind: Int}},
   128  		{&Type{Kind: Object, Class: "D"}, &Type{Kind: Object, Class: "D"}, &Type{Kind: Object, Class: "D"}},
   129  		{&Type{Kind: Object, Class: "D"}, &Type{Kind: Object, Class: "E"}, &Type{Kind: Object, Class: "C"}},
   130  		{&Type{Kind: Object, Class: "D"}, &Type{Kind: Object, Class: "F"}, &Type{Kind: Object, Class: "A"}},
   131  		{&Type{Kind: Object, Class: "B"}, &Type{Kind: Object, Class: "E"}, &Type{Kind: Object, Class: "A"}},
   132  	}
   133  	for _, test := range tests {
   134  		t1, t2, exp := test[0], test[1], test[2]
   135  		got := commonType(clsMap, t1, t2)
   136  		if !reflect.DeepEqual(got, exp) {
   137  			t.Errorf("commonType(%+v, %+v) = %+v, expected %+v", t1, t2, got, exp)
   138  		}
   139  	}
   140  }
   141  
   142  func TestCommonSig(t *testing.T) {
   143  	tests := []struct {
   144  		Sigs []CommonSig
   145  		CommonSig
   146  	}{
   147  		{
   148  			Sigs: []CommonSig{
   149  				CommonSig{}, // f()
   150  			},
   151  			CommonSig: CommonSig{}, // f()
   152  		},
   153  		{
   154  			Sigs: []CommonSig{
   155  				CommonSig{Throws: true, HasRet: true, Ret: &Type{Kind: Int}}, // int f() throws
   156  			},
   157  			// int f() throws
   158  			CommonSig: CommonSig{Throws: true, HasRet: true, Ret: &Type{Kind: Int}},
   159  		},
   160  		{
   161  			Sigs: []CommonSig{
   162  				CommonSig{}, // f()
   163  				CommonSig{Params: []*Type{&Type{Kind: Int}}}, // f(int)
   164  			},
   165  			CommonSig: CommonSig{ // f(int...)
   166  				Variadic: true,
   167  				Params:   []*Type{&Type{Kind: Int}},
   168  			},
   169  		},
   170  		{
   171  			Sigs: []CommonSig{
   172  				CommonSig{Params: []*Type{&Type{Kind: Int}}},   // f(int)
   173  				CommonSig{Params: []*Type{&Type{Kind: Float}}}, // f(float)
   174  			},
   175  			CommonSig: CommonSig{ // f(interface{})
   176  				Params: []*Type{nil},
   177  			},
   178  		},
   179  		{
   180  			Sigs: []CommonSig{
   181  				CommonSig{Params: []*Type{&Type{Kind: Int}}},                   // f(int)
   182  				CommonSig{Params: []*Type{&Type{Kind: Int}, &Type{Kind: Int}}}, // f(int, int)
   183  			},
   184  			CommonSig: CommonSig{ // f(int, int...)
   185  				Variadic: true,
   186  				Params:   []*Type{&Type{Kind: Int}, &Type{Kind: Int}},
   187  			},
   188  		},
   189  		{
   190  			Sigs: []CommonSig{
   191  				CommonSig{Params: []*Type{&Type{Kind: Object, Class: "A"}}}, // f(A)
   192  				CommonSig{Params: []*Type{&Type{Kind: Object, Class: "B"}}}, // f(B)
   193  			},
   194  			CommonSig: CommonSig{ // f(A)
   195  				Params: []*Type{&Type{Kind: Object, Class: "A"}},
   196  			},
   197  		},
   198  	}
   199  	clsMap := testClsMap()
   200  	for _, test := range tests {
   201  		got := combineSigs(clsMap, test.Sigs...)
   202  		if !reflect.DeepEqual(got, test.CommonSig) {
   203  			t.Errorf("commonSig(%+v) = %+v, expected %+v", test.Sigs, got, test.CommonSig)
   204  		}
   205  	}
   206  }