@@ -100,6 +100,19 @@ func TestGenerateInterface_Simple(t *testing.T) {
100100 // Check proxy methods use parcel operations.
101101 assert .Contains (t , srcStr , "WriteInterfaceToken(DescriptorIServiceManager)" )
102102 assert .Contains (t , srcStr , "binder.ReadStatus(_reply)" )
103+
104+ // Check stub struct.
105+ assert .Contains (t , srcStr , "type ServiceManagerStub struct" )
106+ assert .Contains (t , srcStr , "Impl IServiceManager" )
107+ assert .Contains (t , srcStr , "var _ binder.TransactionReceiver = (*ServiceManagerStub)(nil)" )
108+
109+ // Check stub OnTransaction method.
110+ assert .Contains (t , srcStr , "func (s *ServiceManagerStub) OnTransaction(" )
111+ assert .Contains (t , srcStr , "case TransactionIServiceManagerGetService:" )
112+ assert .Contains (t , srcStr , "case TransactionIServiceManagerIsDeclared:" )
113+ assert .Contains (t , srcStr , "s.Impl.IsDeclared(ctx, _arg_name)" )
114+ assert .Contains (t , srcStr , "binder.WriteStatus(_reply, _err)" )
115+ assert .Contains (t , srcStr , "binder.WriteStatus(_reply, nil)" )
103116}
104117
105118func TestGenerateInterface_Oneway (t * testing.T ) {
@@ -919,3 +932,130 @@ func TestElementTypeSpec(t *testing.T) {
919932 assert .Equal (t , "int" , elem .Name )
920933 })
921934}
935+
936+ func TestDeriveStubName (t * testing.T ) {
937+ tests := []struct {
938+ input string
939+ expected string
940+ }{
941+ {"IServiceManager" , "ServiceManagerStub" },
942+ {"IFoo" , "FooStub" },
943+ {"Foo" , "FooStub" },
944+ {"I" , "IStub" },
945+ }
946+
947+ for _ , tt := range tests {
948+ t .Run (tt .input , func (t * testing.T ) {
949+ assert .Equal (t , tt .expected , deriveStubName (tt .input ))
950+ })
951+ }
952+ }
953+
954+ func TestGenerateInterface_StubPrimitiveReturn (t * testing.T ) {
955+ doc := parseAIDL (t , `
956+ package test;
957+ interface ICounter {
958+ int getCount();
959+ void setCount(int count);
960+ }
961+ ` )
962+
963+ require .Len (t , doc .Definitions , 1 )
964+ decl := doc .Definitions [0 ].(* aidlparser.InterfaceDecl )
965+
966+ src , err := GenerateInterface (decl , "test" , "test.ICounter" )
967+ require .NoError (t , err )
968+
969+ assertValidGo (t , src )
970+ assertFormattedGo (t , src )
971+
972+ srcStr := string (src )
973+
974+ // Stub struct and compliance.
975+ assert .Contains (t , srcStr , "type CounterStub struct" )
976+ assert .Contains (t , srcStr , "Impl ICounter" )
977+ assert .Contains (t , srcStr , "var _ binder.TransactionReceiver = (*CounterStub)(nil)" )
978+
979+ // OnTransaction dispatcher.
980+ assert .Contains (t , srcStr , "func (s *CounterStub) OnTransaction(" )
981+ assert .Contains (t , srcStr , "case TransactionICounterGetCount:" )
982+ assert .Contains (t , srcStr , "case TransactionICounterSetCount:" )
983+
984+ // GetCount: calls impl and writes result.
985+ assert .Contains (t , srcStr , "s.Impl.GetCount(ctx)" )
986+ assert .Contains (t , srcStr , "_reply.WriteInt32(_result)" )
987+
988+ // SetCount: reads param from data, calls impl.
989+ assert .Contains (t , srcStr , "s.Impl.SetCount(ctx, _arg_count)" )
990+ }
991+
992+ func TestGenerateInterface_StubOneway (t * testing.T ) {
993+ doc := parseAIDL (t , `
994+ package test;
995+ oneway interface INotify {
996+ void onEvent(int eventId, String detail);
997+ }
998+ ` )
999+
1000+ require .Len (t , doc .Definitions , 1 )
1001+ decl := doc .Definitions [0 ].(* aidlparser.InterfaceDecl )
1002+
1003+ src , err := GenerateInterface (decl , "test" , "test.INotify" )
1004+ require .NoError (t , err )
1005+
1006+ assertValidGo (t , src )
1007+ assertFormattedGo (t , src )
1008+
1009+ srcStr := string (src )
1010+
1011+ // Oneway stubs return nil, nil (no reply).
1012+ assert .Contains (t , srcStr , "type NotifyStub struct" )
1013+ assert .Contains (t , srcStr , "return nil, nil" )
1014+ assert .Contains (t , srcStr , "s.Impl.OnEvent(ctx, _arg_eventId, _arg_detail)" )
1015+ }
1016+
1017+ func TestGenerateInterface_StubNoMethods (t * testing.T ) {
1018+ doc := parseAIDL (t , `
1019+ package test;
1020+ interface IEmpty {
1021+ }
1022+ ` )
1023+
1024+ require .Len (t , doc .Definitions , 1 )
1025+ decl := doc .Definitions [0 ].(* aidlparser.InterfaceDecl )
1026+
1027+ src , err := GenerateInterface (decl , "test" , "test.IEmpty" )
1028+ require .NoError (t , err )
1029+
1030+ assertValidGo (t , src )
1031+
1032+ srcStr := string (src )
1033+
1034+ // Stub is still generated for empty interfaces.
1035+ assert .Contains (t , srcStr , "type EmptyStub struct" )
1036+ assert .Contains (t , srcStr , "Impl IEmpty" )
1037+ }
1038+
1039+ func TestGenerateInterface_StubVoidNoParams (t * testing.T ) {
1040+ doc := parseAIDL (t , `
1041+ package test;
1042+ interface IPing {
1043+ void ping();
1044+ }
1045+ ` )
1046+
1047+ require .Len (t , doc .Definitions , 1 )
1048+ decl := doc .Definitions [0 ].(* aidlparser.InterfaceDecl )
1049+
1050+ src , err := GenerateInterface (decl , "test" , "test.IPing" )
1051+ require .NoError (t , err )
1052+
1053+ assertValidGo (t , src )
1054+ assertFormattedGo (t , src )
1055+
1056+ srcStr := string (src )
1057+
1058+ assert .Contains (t , srcStr , "type PingStub struct" )
1059+ // void + no params: should use := for _err since it's the first declaration.
1060+ assert .Contains (t , srcStr , "s.Impl.Ping(ctx)" )
1061+ }
0 commit comments