|
10 | 10 | let(:response_class) {Class.new} |
11 | 11 |
|
12 | 12 | it "can define and retrieve RPC methods" do |
13 | | - req_class = request_class |
14 | | - res_class = response_class |
| 13 | + request_class = self.request_class |
| 14 | + response_class = self.response_class |
15 | 15 |
|
16 | 16 | interface_class = Class.new(Protocol::GRPC::Interface) do |
17 | | - rpc :say_hello, request_class: req_class, response_class: res_class |
| 17 | + rpc :say_hello, request_class: request_class, response_class: response_class |
18 | 18 | end |
19 | 19 |
|
20 | 20 | rpc = interface_class.lookup_rpc(:say_hello) |
|
30 | 30 | end |
31 | 31 |
|
32 | 32 | it "can retrieve all RPCs" do |
33 | | - req_class = request_class |
34 | | - res_class = response_class |
| 33 | + request_class = self.request_class |
| 34 | + response_class = self.response_class |
35 | 35 |
|
36 | 36 | interface_class = Class.new(Protocol::GRPC::Interface) do |
37 | | - rpc :method1, request_class: req_class, response_class: res_class |
38 | | - rpc :method2, request_class: req_class, response_class: res_class, streaming: :server_streaming |
| 37 | + rpc :method1, request_class: request_class, response_class: response_class |
| 38 | + rpc :method2, request_class: request_class, response_class: response_class, streaming: :server_streaming |
39 | 39 | end |
40 | 40 |
|
41 | 41 | rpcs = interface_class.rpcs |
|
45 | 45 | end |
46 | 46 |
|
47 | 47 | it "inherits RPCs from parent class" do |
48 | | - req_class = request_class |
49 | | - res_class = response_class |
| 48 | + request_class = self.request_class |
| 49 | + response_class = self.response_class |
50 | 50 |
|
51 | 51 | base_class = Class.new(Protocol::GRPC::Interface) do |
52 | | - rpc :base_method, request_class: req_class, response_class: res_class |
| 52 | + rpc :base_method, request_class: request_class, response_class: response_class |
53 | 53 | end |
54 | 54 |
|
55 | 55 | subclass = Class.new(base_class) do |
56 | | - rpc :sub_method, request_class: req_class, response_class: res_class |
| 56 | + rpc :sub_method, request_class: request_class, response_class: response_class |
57 | 57 | end |
58 | 58 |
|
59 | 59 | # Subclass should have both methods |
|
71 | 71 | end |
72 | 72 |
|
73 | 73 | it "can override RPCs in subclass" do |
74 | | - req_class = request_class |
75 | | - res_class = response_class |
| 74 | + request_class = self.request_class |
| 75 | + response_class = self.response_class |
76 | 76 | other_request_class = Class.new |
77 | 77 | other_response_class = Class.new |
78 | 78 |
|
79 | 79 | base_class = Class.new(Protocol::GRPC::Interface) do |
80 | | - rpc :method, request_class: req_class, response_class: res_class |
| 80 | + rpc :method, request_class: request_class, response_class: response_class |
81 | 81 | end |
82 | 82 |
|
83 | 83 | subclass = Class.new(base_class) do |
|
98 | 98 | end |
99 | 99 |
|
100 | 100 | it "supports multiple levels of inheritance" do |
101 | | - req_class = request_class |
102 | | - res_class = response_class |
| 101 | + request_class = self.request_class |
| 102 | + response_class = self.response_class |
103 | 103 |
|
104 | 104 | level1 = Class.new(Protocol::GRPC::Interface) do |
105 | | - rpc :level1_method, request_class: req_class, response_class: res_class |
| 105 | + rpc :level1_method, request_class: request_class, response_class: response_class |
106 | 106 | end |
107 | 107 |
|
108 | 108 | level2 = Class.new(level1) do |
109 | | - rpc :level2_method, request_class: req_class, response_class: res_class |
| 109 | + rpc :level2_method, request_class: request_class, response_class: response_class |
110 | 110 | end |
111 | 111 |
|
112 | 112 | level3 = Class.new(level2) do |
113 | | - rpc :level3_method, request_class: req_class, response_class: res_class |
| 113 | + rpc :level3_method, request_class: request_class, response_class: response_class |
114 | 114 | end |
115 | 115 |
|
116 | 116 | # Level 3 should have all methods |
|
130 | 130 | end |
131 | 131 |
|
132 | 132 | it "maintains separate RPC definitions for different classes" do |
133 | | - req_class = request_class |
134 | | - res_class = response_class |
| 133 | + request_class = self.request_class |
| 134 | + response_class = self.response_class |
135 | 135 |
|
136 | 136 | class1 = Class.new(Protocol::GRPC::Interface) do |
137 | | - rpc :method1, request_class: req_class, response_class: res_class |
| 137 | + rpc :method1, request_class: request_class, response_class: response_class |
138 | 138 | end |
139 | 139 |
|
140 | 140 | class2 = Class.new(Protocol::GRPC::Interface) do |
141 | | - rpc :method2, request_class: req_class, response_class: res_class |
| 141 | + rpc :method2, request_class: request_class, response_class: response_class |
142 | 142 | end |
143 | 143 |
|
144 | 144 | # Each class should only have its own RPCs |
|
150 | 150 | end |
151 | 151 |
|
152 | 152 | it "supports explicit method name in RPC definition" do |
153 | | - req_class = request_class |
154 | | - res_class = response_class |
| 153 | + request_class = self.request_class |
| 154 | + response_class = self.response_class |
155 | 155 |
|
156 | 156 | # Create interface with explicit method name |
157 | 157 | explicit_interface = Class.new(Protocol::GRPC::Interface) do |
158 | | - rpc :XMLParser, request_class: req_class, response_class: res_class, |
| 158 | + rpc :XMLParser, request_class: request_class, response_class: response_class, |
159 | 159 | method: :xml_parser |
160 | 160 | end |
161 | 161 |
|
162 | 162 | rpc = explicit_interface.lookup_rpc(:XMLParser) |
163 | | - expect(rpc).to be_a(Protocol::GRPC::RPC) |
| 163 | + expect(rpc).to be_a(Protocol::GRPC::Interface::RPC) |
164 | 164 | expect(rpc.method).to be == :xml_parser |
165 | | - expect(rpc.request_class).to be == req_class |
166 | | - expect(rpc.response_class).to be == res_class |
| 165 | + expect(rpc.request_class).to be == request_class |
| 166 | + expect(rpc.response_class).to be == response_class |
| 167 | + end |
| 168 | + |
| 169 | + with "method field auto-conversion" do |
| 170 | + it "always sets method field when not explicitly provided" do |
| 171 | + request_class = self.request_class |
| 172 | + response_class = self.response_class |
| 173 | + |
| 174 | + interface_class = Class.new(Protocol::GRPC::Interface) do |
| 175 | + rpc :SayHello, request_class: request_class, response_class: response_class |
| 176 | + end |
| 177 | + |
| 178 | + rpc = interface_class.lookup_rpc(:SayHello) |
| 179 | + expect(rpc.method).not.to be_nil |
| 180 | + expect(rpc.method).to be == :say_hello |
| 181 | + end |
| 182 | + |
| 183 | + it "converts PascalCase to snake_case correctly" do |
| 184 | + request_class = self.request_class |
| 185 | + response_class = self.response_class |
| 186 | + |
| 187 | + interface_class = Class.new(Protocol::GRPC::Interface) do |
| 188 | + rpc :SayHello, request_class: request_class, response_class: response_class |
| 189 | + rpc :UnaryCall, request_class: request_class, response_class: response_class |
| 190 | + rpc :ServerStreamingCall, request_class: request_class, response_class: response_class |
| 191 | + rpc :XMLParser, request_class: request_class, response_class: response_class |
| 192 | + end |
| 193 | + |
| 194 | + expect(interface_class.lookup_rpc(:SayHello).method).to be == :say_hello |
| 195 | + expect(interface_class.lookup_rpc(:UnaryCall).method).to be == :unary_call |
| 196 | + expect(interface_class.lookup_rpc(:ServerStreamingCall).method).to be == :server_streaming_call |
| 197 | + expect(interface_class.lookup_rpc(:XMLParser).method).to be == :xml_parser |
| 198 | + end |
| 199 | + |
| 200 | + it "uses explicit method name when provided" do |
| 201 | + request_class = self.request_class |
| 202 | + response_class = self.response_class |
| 203 | + |
| 204 | + interface_class = Class.new(Protocol::GRPC::Interface) do |
| 205 | + rpc :SayHello, request_class: request_class, response_class: response_class, |
| 206 | + method: :greet_user |
| 207 | + rpc :XMLParser, request_class: request_class, response_class: response_class, |
| 208 | + method: :parse_xml |
| 209 | + end |
| 210 | + |
| 211 | + expect(interface_class.lookup_rpc(:SayHello).method).to be == :greet_user |
| 212 | + expect(interface_class.lookup_rpc(:XMLParser).method).to be == :parse_xml |
| 213 | + end |
| 214 | + |
| 215 | + it "ensures method field is never nil" do |
| 216 | + request_class = self.request_class |
| 217 | + response_class = self.response_class |
| 218 | + |
| 219 | + interface_class = Class.new(Protocol::GRPC::Interface) do |
| 220 | + rpc :SayHello, request_class: request_class, response_class: response_class |
| 221 | + rpc :UnaryCall, request_class: request_class, response_class: response_class, |
| 222 | + method: :unary_call |
| 223 | + end |
| 224 | + |
| 225 | + # Both should have method set |
| 226 | + rpc1 = interface_class.lookup_rpc(:SayHello) |
| 227 | + rpc2 = interface_class.lookup_rpc(:UnaryCall) |
| 228 | + |
| 229 | + expect(rpc1.method).not.to be_nil |
| 230 | + expect(rpc2.method).not.to be_nil |
| 231 | + expect(rpc1.method).to be_a(Symbol) |
| 232 | + expect(rpc2.method).to be_a(Symbol) |
| 233 | + end |
| 234 | + |
| 235 | + it "handles edge cases in PascalCase conversion" do |
| 236 | + request_class = self.request_class |
| 237 | + response_class = self.response_class |
| 238 | + |
| 239 | + interface_class = Class.new(Protocol::GRPC::Interface) do |
| 240 | + rpc :HTTPRequest, request_class: request_class, response_class: response_class |
| 241 | + rpc :XMLHTTPRequest, request_class: request_class, response_class: response_class |
| 242 | + rpc :GetUserByID, request_class: request_class, response_class: response_class |
| 243 | + end |
| 244 | + |
| 245 | + expect(interface_class.lookup_rpc(:HTTPRequest).method).to be == :http_request |
| 246 | + expect(interface_class.lookup_rpc(:XMLHTTPRequest).method).to be == :xmlhttp_request |
| 247 | + expect(interface_class.lookup_rpc(:GetUserByID).method).to be == :get_user_by_id |
| 248 | + end |
167 | 249 | end |
168 | 250 | end |
169 | 251 |
|
0 commit comments