Line data Source code
1 : #include <wjrpc/handler.hpp>
2 : #include <wjrpc/method.hpp>
3 : #include <wjrpc/method/default_schema.hpp>
4 :
5 : #include <fas/testing.hpp>
6 : #include "req.hpp"
7 : #include <algorithm>
8 : #include <memory>
9 :
10 2 : struct nomethod:
11 : ::wjrpc::method_list<>
12 : {
13 : };
14 :
15 : typedef wjrpc::handler<nomethod> nohandler;
16 :
17 : int test_count = 0;
18 :
19 3 : UNIT(nohandler_unit, "")
20 : {
21 : using namespace fas::testing;
22 : using namespace ::wjrpc;
23 :
24 1 : nohandler h;
25 7 : for (auto r: bad_request)
26 : {
27 6 : auto req = std::make_unique<data_type>( r[0].begin(), r[0].end() );
28 12 : incoming_holder hold( std::move(req) );
29 6 : hold.parse(nullptr);
30 12 : h.invoke(std::move(hold), [&t, r](outgoing_holder holder)
31 : {
32 6 : data_ptr res = holder.detach();
33 6 : t << message("request: ") << r[0];
34 6 : t << message("response: ") << std::string(res->begin(), res->end());
35 6 : if ( std::string(res->begin(), res->end()) != r[1] )
36 : {
37 0 : t << ::fas::testing::error("should be:") << r[1];
38 : }
39 6 : ++test_count;
40 6 : });
41 : }
42 :
43 1 : t << equal<expect>(test_count, 6) << FAS_TESTING_FILE_LINE;
44 :
45 1 : }
46 :
47 :
48 : // ////////////////////////////////////////////////////////////////////////////
49 : // ////////////////////////////////////////////////////////////////////////////
50 : // ////////////////////////////////////////////////////////////////////////////
51 :
52 : typedef std::vector<int> test1_params;
53 : typedef wjson::array< std::vector< wjson::value<int> > > test1_json;
54 :
55 :
56 2 : struct itest1
57 : {
58 2 : virtual ~itest1() {}
59 : virtual void method1(std::unique_ptr<test1_params> req, std::function< void(std::unique_ptr<test1_params>) > callback) = 0;
60 : virtual void method2(std::unique_ptr<test1_params> req, std::function< void(std::unique_ptr<test1_params>) > callback) = 0;
61 : };
62 :
63 2 : class test1 final: public itest1
64 : {
65 : public:
66 2 : virtual ~test1() = default;
67 2 : virtual void method1(std::unique_ptr<test1_params> req, std::function< void(std::unique_ptr<test1_params>) > callback) override
68 : {
69 2 : if ( req==nullptr )
70 : {
71 1 : if (callback!=nullptr)
72 1 : return callback( std::make_unique<test1_params>() );
73 0 : return;
74 : }
75 :
76 1 : std::reverse(req->begin(), req->end());
77 :
78 1 : if ( callback )
79 1 : callback(std::move(req));
80 : }
81 :
82 1 : virtual void method2(std::unique_ptr<test1_params> , std::function< void(std::unique_ptr<test1_params>) > callback) override
83 : {
84 1 : if ( callback )
85 1 : callback(nullptr);
86 1 : }
87 : };
88 :
89 :
90 11 : JSONRPC_TAG(method1)
91 5 : JSONRPC_TAG(method2)
92 :
93 :
94 4 : struct method_list: wjrpc::method_list
95 : <
96 : wjrpc::target<itest1>,
97 : wjrpc::invoke_method< _method1_, test1_json, test1_json, itest1, &itest1::method1>,
98 : wjrpc::invoke_method< _method2_, test1_json, test1_json, itest1, &itest1::method2>
99 : >
100 : {};
101 :
102 : typedef wjrpc::handler<method_list> handler1;
103 :
104 :
105 3 : UNIT(handler1_unit, "")
106 : {
107 : using namespace fas::testing;
108 : using namespace ::wjrpc;
109 :
110 1 : std::string unavailable = "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32003,\"message\":\"Service unavailable\"},\"id\":1}";
111 :
112 1 : test_count = 0;
113 2 : handler1 h;
114 1 : auto r = good_request[0];
115 : {
116 1 : auto req = std::make_unique< data_type>( r[0].begin(), r[0].end() );
117 2 : incoming_holder hold( std::move(req) );
118 1 : hold.parse(nullptr);
119 :
120 11 : h.invoke(std::move(hold), [&t, unavailable, r](outgoing_holder holder)
121 : {
122 1 : data_ptr res = holder.detach();
123 1 : t << message("request: ") << r[0];
124 1 : t << message("response: ") << std::string(res->begin(), res->end());
125 1 : if ( std::string(res->begin(), res->end()) != unavailable )
126 : {
127 0 : t << ::fas::testing::error("should be:") << unavailable;
128 : }
129 1 : ++test_count;
130 2 : });
131 1 : }
132 1 : }
133 :
134 3 : UNIT(gen1, "")
135 : {
136 : using namespace fas::testing;
137 :
138 : typedef method_list::aspect::template advice_cast<_method1_>::type method1_t;
139 : typedef method1_t::aspect::template advice_cast< wjrpc::_invoke_>::type::params_json_t request1_json;
140 :
141 : typedef request1_json::target value_type;
142 1 : value_type val;
143 1 : val.push_back(1);
144 1 : val.push_back(2);
145 2 : std::string json;
146 1 : request1_json::serializer()(val, std::back_inserter(json) );
147 1 : t << equal<expect, std::string>(json, "[1,2]") << FAS_FL;
148 :
149 2 : auto sch = method1_t::create_schema_t<wjrpc::default_schema>();
150 1 : fas::ignore_arg(sch);
151 :
152 : typedef std::vector<wjrpc::default_schema> schema_list_t;
153 2 : schema_list_t schl = method_list::create_schema_t<wjrpc::default_schema>();
154 1 : t << equal<assert, size_t>(schl.size(), 2) << FAS_FL;
155 1 : t << flush;
156 1 : t << equal<assert, std::string>(schl[0].name, "method1") << FAS_FL;
157 1 : t << equal<assert, std::string>(schl[0].params, "[]") << FAS_FL;
158 1 : t << equal<assert, std::string>(schl[0].result, "[]") << FAS_FL;
159 1 : t << equal<assert, std::string>(schl[1].name, "method2") << FAS_FL;
160 1 : t << equal<assert, std::string>(schl[1].params, "[]") << FAS_FL;
161 2 : t << equal<assert, std::string>(schl[1].result, "[]") << FAS_FL;
162 1 : }
163 :
164 3 : UNIT(handler2_unit, "")
165 : {
166 : using namespace fas::testing;
167 : using namespace wjrpc;
168 :
169 1 : std::shared_ptr<itest1> t1 = std::make_shared<test1>();
170 1 : test_count = 0;
171 2 : handler1::options_type opt;
172 1 : opt.target = t1;
173 2 : handler1 h;
174 1 : h.start(opt, 1);
175 1 : h.target() = t1;
176 4 : for (auto r: good_request)
177 : {
178 3 : auto req = std::make_unique< data_type>( r[0].begin(), r[0].end() );
179 6 : incoming_holder hold( std::move(req) );
180 3 : hold.parse(nullptr);
181 :
182 6 : h.invoke( std::move(hold), [&t,r](outgoing_holder holder)
183 : {
184 3 : data_ptr res = holder.detach();
185 3 : t << message("request: ") << r[0];
186 3 : t << message("response: ") << std::string(res->begin(), res->end());
187 3 : if ( std::string(res->begin(), res->end()) != r[1] )
188 : {
189 0 : t << ::fas::testing::error("should be:") << r[1];
190 : }
191 3 : ++test_count;
192 3 : });
193 1 : }
194 :
195 1 : }
196 :
197 1 : struct method_list2: wjrpc::method_list
198 : <
199 : wjrpc::target<itest1>,
200 : wjrpc::interface_<itest1>,
201 : wjrpc::peeper< itest1 >,
202 : wjrpc::dual_method< _method1_, test1_json, test1_json, itest1, &itest1::method1>,
203 : wjrpc::dual_method< _method2_, test1_json, test1_json, itest1, &itest1::method2>
204 : >
205 : {
206 1 : virtual ~method_list2() = default;
207 1 : virtual void method1(std::unique_ptr<test1_params> req, std::function< void(std::unique_ptr<test1_params>) > callback) final
208 : {
209 1 : this->call<_method1_>(std::move(req), std::move(callback), nullptr);
210 1 : }
211 :
212 1 : virtual void method2(std::unique_ptr<test1_params> req, std::function< void(std::unique_ptr<test1_params>) > callback) final
213 : {
214 1 : this->call<_method2_>(std::move(req), std::move(callback), nullptr);
215 1 : }
216 : };
217 :
218 : typedef wjrpc::handler<method_list2> handler2;
219 :
220 3 : UNIT(handler4_unit, "")
221 : {
222 : using namespace fas::testing;
223 : using namespace wjrpc;
224 :
225 1 : auto t1 = std::make_shared<test1>();
226 2 : handler2::options_type opt;
227 1 : opt.peeper = t1;
228 :
229 2 : std::string str_notify;
230 :
231 3 : opt.sender_handler = [&t, &str_notify]( const char* name, handler2::notify_serializer_t ser, handler2::request_serializer_t, handler2::result_handler_t ) -> void
232 : {
233 2 : auto d = ser(name);
234 2 : str_notify = std::string(d->begin(), d->end() );
235 2 : t << message("send: ") << str_notify;
236 2 : };
237 :
238 :
239 2 : auto h2 = std::make_shared<handler2>();
240 1 : h2->start(opt, 1);
241 : //auto h2 = std::make_shared<handler2>(nullptr, t1);
242 2 : auto p1 = std::make_unique<test1_params>(test1_params{1,2,3,4,5});
243 :
244 :
245 1 : h2->method1( std::make_unique<test1_params>(*p1), nullptr);
246 1 : h2->method2( std::move(p1), nullptr);
247 :
248 2 : t << nothing;
249 1 : }
250 :
251 3 : UNIT(gen2, "")
252 : {
253 : using namespace fas::testing;
254 :
255 : typedef method_list2::aspect::template advice_cast<_method1_>::type method1_t;
256 : typedef method1_t::aspect::template advice_cast< wjrpc::_invoke_>::type::params_json_t request1_json;
257 :
258 : typedef request1_json::target value_type;
259 1 : value_type val;
260 1 : val.push_back(1);
261 1 : val.push_back(2);
262 2 : std::string json;
263 1 : request1_json::serializer()(val, std::back_inserter(json) );
264 1 : t << equal<expect, std::string>(json, "[1,2]") << FAS_FL;
265 :
266 2 : auto sch = method1_t::create_schema_t<wjrpc::default_schema>();
267 1 : fas::ignore_arg(sch);
268 :
269 : typedef std::vector<wjrpc::default_schema> schema_list_t;
270 2 : schema_list_t schl = method_list::create_schema_t<wjrpc::default_schema>();
271 1 : t << equal<assert, size_t>(schl.size(), 2) << FAS_FL;
272 1 : t << flush;
273 1 : t << equal<assert, std::string>(schl[0].name, "method1") << FAS_FL;
274 1 : t << equal<assert, std::string>(schl[0].params, "[]") << FAS_FL;
275 1 : t << equal<assert, std::string>(schl[0].result, "[]") << FAS_FL;
276 1 : t << equal<assert, std::string>(schl[1].name, "method2") << FAS_FL;
277 1 : t << equal<assert, std::string>(schl[1].params, "[]") << FAS_FL;
278 2 : t << equal<assert, std::string>(schl[1].result, "[]") << FAS_FL;
279 1 : }
280 :
281 : struct method_list3: wjrpc::method_list
282 : <
283 : wjrpc::interface_<itest1>,
284 : wjrpc::call_method< _method1_, test1_json, test1_json>,
285 : wjrpc::call_method< _method2_, test1_json, test1_json>
286 : >
287 : {
288 : virtual ~method_list3() = default;
289 : virtual void method1(std::unique_ptr<test1_params> req, std::function< void(std::unique_ptr<test1_params>) > callback)
290 : {
291 : this->call<_method1_>(std::move(req), std::move(callback), nullptr);
292 : }
293 :
294 : virtual void method2(std::unique_ptr<test1_params> req, std::function< void(std::unique_ptr<test1_params>) > callback)
295 : {
296 : this->call<_method2_>(std::move(req), std::move(callback), nullptr);
297 : }
298 : };
299 :
300 : typedef wjrpc::handler<method_list3> handler3;
301 :
302 3 : UNIT(gen3, "")
303 : {
304 : using namespace fas::testing;
305 :
306 : typedef method_list3::aspect::template advice_cast<_method1_>::type method1_t;
307 1 : auto sch = method1_t::create_schema_t<wjrpc::default_schema>();
308 1 : fas::ignore_arg(sch);
309 :
310 : typedef std::vector<wjrpc::default_schema> schema_list_t;
311 2 : schema_list_t schl = method_list::create_schema_t<wjrpc::default_schema>();
312 1 : t << equal<assert, size_t>(schl.size(), 2) << FAS_FL;
313 1 : t << flush;
314 1 : t << equal<assert, std::string>(schl[0].name, "method1") << FAS_FL;
315 1 : t << equal<assert, std::string>(schl[0].params, "[]") << FAS_FL;
316 1 : t << equal<assert, std::string>(schl[0].result, "[]") << FAS_FL;
317 1 : t << equal<assert, std::string>(schl[1].name, "method2") << FAS_FL;
318 1 : t << equal<assert, std::string>(schl[1].params, "[]") << FAS_FL;
319 2 : t << equal<assert, std::string>(schl[1].result, "[]") << FAS_FL;
320 1 : }
321 :
322 1 : BEGIN_SUITE(handler_suite, "")
323 : ADD_UNIT(nohandler_unit)
324 : ADD_UNIT(handler1_unit)
325 : ADD_UNIT(gen1)
326 : ADD_UNIT(handler2_unit)
327 : ADD_UNIT(handler4_unit)
328 : ADD_UNIT(gen2)
329 : ADD_UNIT(gen3)
330 7 : END_SUITE(handler_suite)
|