1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.http.remote;
18
19 import static org.apache.juneau.TestUtils.*;
20 import static org.apache.juneau.http.HttpParts.*;
21 import static org.junit.jupiter.api.Assertions.*;
22
23 import java.io.*;
24 import java.math.*;
25 import java.util.*;
26 import java.util.concurrent.atomic.*;
27
28 import org.apache.http.*;
29 import org.apache.juneau.*;
30 import org.apache.juneau.annotation.*;
31 import org.apache.juneau.collections.*;
32 import org.apache.juneau.http.annotation.*;
33 import org.apache.juneau.http.part.*;
34 import org.apache.juneau.internal.*;
35 import org.apache.juneau.rest.RestRequest;
36 import org.apache.juneau.rest.annotation.*;
37 import org.apache.juneau.rest.client.*;
38 import org.apache.juneau.rest.mock.*;
39 import org.apache.juneau.uon.*;
40 import org.apache.juneau.utest.utils.*;
41 import org.junit.jupiter.api.*;
42
43 class Remote_QueryAnnotation_Test extends TestBase {
44
45 public static class Bean {
46 public int f;
47
48 public static Bean create() {
49 var b = new Bean();
50 b.f = 1;
51 return b;
52 }
53 }
54
55
56
57
58
59 @Rest
60 public static class A {
61 @RestGet
62 public String a(@Query("*") JsonMap m) {
63 return m.toString();
64 }
65 }
66
67 @Remote
68 public interface A1 {
69 @RemoteOp(path="a") String getX1(@Query("x") int b);
70 @RemoteOp(path="a") String getX2(@Query("x") float b);
71 @RemoteOp(path="a") String getX3(@Query("x") Bean b);
72 @RemoteOp(path="a") String getX4(@Query("*") Bean b);
73 @RemoteOp(path="a") String getX5(@Query Bean b);
74 @RemoteOp(path="a") String getX6(@Query("x") Bean[] b);
75 @RemoteOp(path="a") String getX7(@Query("x") @Schema(cf="uon") Bean[] b);
76 @RemoteOp(path="a") String getX8(@Query("x") List<Bean> b);
77 @RemoteOp(path="a") String getX9(@Query("x") @Schema(cf="uon") List<Bean> b);
78 @RemoteOp(path="a") String getX10(@Query("x") Map<String,Bean> b);
79 @RemoteOp(path="a") String getX11(@Query("*") Map<String,Bean> b);
80 @RemoteOp(path="a") String getX12(@Query Map<String,Bean> b);
81 @RemoteOp(path="a") String getX13(@Query("x") @Schema(cf="uon") Map<String,Bean> b);
82 @RemoteOp(path="a") String getX14(@Query() @Schema(f="uon") Map<String,Bean> b);
83 @RemoteOp(path="a") String getX15(@Query("*") Reader b);
84 @RemoteOp(path="a") String getX16(@Query Reader b);
85 @RemoteOp(path="a") String getX17(@Query("*") InputStream b);
86 @RemoteOp(path="a") String getX18(@Query InputStream b);
87 @RemoteOp(path="a") String getX19(@Query("*") PartList b);
88 @RemoteOp(path="a") String getX20(@Query PartList b);
89 @RemoteOp(path="a") String getX21(@Query NameValuePair b);
90 @RemoteOp(path="a") String getX22(@Query NameValuePair[] b);
91 @RemoteOp(path="a") String getX24(@Query String b);
92 @RemoteOp(path="a") String getX25(@Query List<NameValuePair> b);
93 }
94
95 @Test void a01_objectTypes() {
96 var x = remote(A.class,A1.class);
97 assertEquals("{x:'1'}",x.getX1(1));
98 assertEquals("{x:'1.0'}",x.getX2(1));
99 assertEquals("{x:'f=1'}",x.getX3(Bean.create()));
100 assertEquals("{f:'1'}",x.getX4(Bean.create()));
101 assertEquals("{f:'1'}",x.getX5(Bean.create()));
102 assertEquals("{x:'f=1,f=1'}",x.getX6(new Bean[]{Bean.create(),Bean.create()}));
103 assertEquals("{x:'@((f=1),(f=1))'}",x.getX7(new Bean[]{Bean.create(),Bean.create()}));
104 assertEquals("{x:'f=1,f=1'}",x.getX8(alist(Bean.create(),Bean.create())));
105 assertEquals("{x:'@((f=1),(f=1))'}",x.getX9(alist(Bean.create(),Bean.create())));
106 assertEquals("{x:'k1=f\\\\=1'}",x.getX10(map("k1",Bean.create())));
107 assertEquals("{k1:'f=1'}",x.getX11(map("k1",Bean.create())));
108 assertEquals("{k1:'f=1'}",x.getX12(map("k1",Bean.create())));
109 assertEquals("{x:'(k1=(f=1))'}",x.getX13(map("k1",Bean.create())));
110 assertEquals("{k1:'f=1'}",x.getX14(map("k1",Bean.create())));
111 assertEquals("{x:'1'}",x.getX15(reader("x=1")));
112 assertEquals("{x:'1'}",x.getX16(reader("x=1")));
113 assertEquals("{x:'1'}",x.getX17(inputStream("x=1")));
114 assertEquals("{x:'1'}",x.getX18(inputStream("x=1")));
115 assertEquals("{foo:'bar'}",x.getX19(parts("foo","bar")));
116 assertEquals("{foo:'bar'}",x.getX20(parts("foo","bar")));
117 assertEquals("{foo:'bar'}",x.getX21(part("foo","bar")));
118 assertEquals("{foo:'bar'}",x.getX22(parts("foo","bar").getAll()));
119 assertEquals("{foo:'bar'}",x.getX24("foo=bar"));
120 assertEquals("{}",x.getX24(null));
121 assertEquals("{foo:'bar'}",x.getX25(alist(part("foo","bar"))));
122 }
123
124
125
126
127
128 @Rest
129 public static class B {
130 @RestOp
131 public String get(@Query("*") JsonMap m) {
132 return m.toString();
133 }
134 }
135
136 @Remote
137 public interface B1 {
138 @RemoteOp(path="/") String getX1(@Query("x") @Schema(df="foo") String b);
139 @RemoteOp(path="/") String getX2(@Query("x") @Schema(df="foo",aev=true) String b);
140 @RemoteOp(path="/") String getX3(@Query("x") @Schema(df="") String b);
141 @RemoteOp(path="/") String getX4(@Query("x") @Schema(df="",aev=true) String b);
142 }
143
144 @Test void b01_default_aev() {
145 var x = remote(B.class,B1.class);
146 assertEquals("{x:'foo'}",x.getX1(null));
147 assertThrowsWithMessage(Exception.class, "Empty value not allowed.", ()->x.getX1(""));
148 assertEquals("{x:'foo'}",x.getX2(null));
149 assertEquals("{x:''}",x.getX2(""));
150 assertEquals("{x:''}",x.getX3(null));
151 assertThrowsWithMessage(Exception.class, "Empty value not allowed.", ()->x.getX3(""));
152 assertEquals("{x:''}",x.getX4(null));
153 assertEquals("{x:''}",x.getX4(""));
154 }
155
156
157
158
159
160 @Rest
161 public static class C {
162 @RestGet
163 public String a(@Query("*") JsonMap m) {
164 return m.toString();
165 }
166 @RestGet
167 public Reader b(RestRequest req) {
168 return reader(req.getQueryString());
169 }
170 }
171
172 @Remote
173 public interface C1 {
174 @RemoteOp(path="/a") String getX1(@Query("x") String...b);
175 @RemoteOp(path="/b") String getX2(@Query("x") String...b);
176 @RemoteOp(path="/a") String getX3(@Query("x") @Schema(cf="csv") String...b);
177 @RemoteOp(path="/b") String getX4(@Query("x") @Schema(cf="csv") String...b);
178 @RemoteOp(path="/a") String getX5(@Query("x") @Schema(cf="ssv") String...b);
179 @RemoteOp(path="/b") String getX6(@Query("x") @Schema(cf="ssv") String...b);
180 @RemoteOp(path="/a") String getX7(@Query("x") @Schema(cf="tsv") String...b);
181 @RemoteOp(path="/b") String getX8(@Query("x") @Schema(cf="tsv") String...b);
182 @RemoteOp(path="/a") String getX9(@Query("x") @Schema(cf="pipes") String...b);
183 @RemoteOp(path="/b") String getX10(@Query("x") @Schema(cf="pipes") String...b);
184 @RemoteOp(path="/a") String getX11(@Query("x") @Schema(cf="multi") String...b);
185 @RemoteOp(path="/b") String getX12(@Query("x") @Schema(cf="multi") String...b);
186 @RemoteOp(path="/a") String getX13(@Query("x") @Schema(cf="uon") String...b);
187 @RemoteOp(path="/b") String getX14(@Query("x") @Schema(cf="uon") String...b);
188 }
189
190 @Test void c01_collectionFormat() {
191 var x = remote(C.class,C1.class);
192 assertEquals("{x:'foo,bar'}",x.getX1("foo","bar"));
193 assertEquals("x=foo%2Cbar",x.getX2("foo","bar"));
194 assertEquals("{x:'foo,bar'}",x.getX3("foo","bar"));
195 assertEquals("x=foo%2Cbar",x.getX4("foo","bar"));
196 assertEquals("{x:'foo bar'}",x.getX5("foo","bar"));
197 assertEquals("x=foo+bar",x.getX6("foo","bar"));
198 assertEquals("{x:'foo\\tbar'}",x.getX7("foo","bar"));
199 assertEquals("x=foo%09bar",x.getX8("foo","bar"));
200 assertEquals("{x:'foo|bar'}",x.getX9("foo","bar"));
201 assertEquals("x=foo%7Cbar",x.getX10("foo","bar"));
202 assertEquals("{x:'foo,bar'}",x.getX11("foo","bar"));
203 assertEquals("x=foo%2Cbar",x.getX12("foo","bar"));
204 assertEquals("{x:'@(foo,bar)'}",x.getX13("foo","bar"));
205 assertEquals("x=%40%28foo%2Cbar%29",x.getX14("foo","bar"));
206 }
207
208
209
210
211
212 @Rest
213 public static class D {
214 @RestOp
215 public String get(@Query("*") JsonMap m) {
216 return m.toString();
217 }
218 }
219
220 @Remote
221 public interface D1 {
222 @RemoteOp(path="/") String getX1(@Query("x") @Schema(min="1",max="10") int b);
223 @RemoteOp(path="/") String getX2(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) int b);
224 @RemoteOp(path="/") String getX3(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) int b);
225 @RemoteOp(path="/") String getX4(@Query("x") @Schema(min="1",max="10") short b);
226 @RemoteOp(path="/") String getX5(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) short b);
227 @RemoteOp(path="/") String getX6(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) short b);
228 @RemoteOp(path="/") String getX7(@Query("x") @Schema(min="1",max="10") long b);
229 @RemoteOp(path="/") String getX8(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) long b);
230 @RemoteOp(path="/") String getX9(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) long b);
231 @RemoteOp(path="/") String getX10(@Query("x") @Schema(min="1",max="10") float b);
232 @RemoteOp(path="/") String getX11(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) float b);
233 @RemoteOp(path="/") String getX12(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) float b);
234 @RemoteOp(path="/") String getX13(@Query("x") @Schema(min="1",max="10") double b);
235 @RemoteOp(path="/") String getX14(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) double b);
236 @RemoteOp(path="/") String getX15(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) double b);
237 @RemoteOp(path="/") String getX16(@Query("x") @Schema(min="1",max="10") byte b);
238 @RemoteOp(path="/") String getX17(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) byte b);
239 @RemoteOp(path="/") String getX18(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) byte b);
240 @RemoteOp(path="/") String getX19(@Query("x") @Schema(min="1",max="10") AtomicInteger b);
241 @RemoteOp(path="/") String getX20(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) AtomicInteger b);
242 @RemoteOp(path="/") String getX21(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) AtomicInteger b);
243 @RemoteOp(path="/") String getX22(@Query("x") @Schema(min="1",max="10") BigDecimal b);
244 @RemoteOp(path="/") String getX23(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) BigDecimal b);
245 @RemoteOp(path="/") String getX24(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) BigDecimal b);
246 @RemoteOp(path="/") String getX25(@Query("x") @Schema(min="1",max="10") Integer b);
247 @RemoteOp(path="/") String getX26(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) Integer b);
248 @RemoteOp(path="/") String getX27(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) Integer b);
249 @RemoteOp(path="/") String getX28(@Query("x") @Schema(min="1",max="10") Short b);
250 @RemoteOp(path="/") String getX29(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) Short b);
251 @RemoteOp(path="/") String getX30(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) Short b);
252 @RemoteOp(path="/") String getX31(@Query("x") @Schema(min="1",max="10") Long b);
253 @RemoteOp(path="/") String getX32(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) Long b);
254 @RemoteOp(path="/") String getX33(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) Long b);
255 @RemoteOp(path="/") String getX34(@Query("x") @Schema(min="1",max="10") Float b);
256 @RemoteOp(path="/") String getX35(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) Float b);
257 @RemoteOp(path="/") String getX36(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) Float b);
258 @RemoteOp(path="/") String getX37(@Query("x") @Schema(min="1",max="10") Double b);
259 @RemoteOp(path="/") String getX38(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) Double b);
260 @RemoteOp(path="/") String getX39(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) Double b);
261 @RemoteOp(path="/") String getX40(@Query("x") @Schema(min="1",max="10") Byte b);
262 @RemoteOp(path="/") String getX41(@Query("x") @Schema(min="1",max="10",emin=false,emax=false) Byte b);
263 @RemoteOp(path="/") String getX42(@Query("x") @Schema(min="1",max="10",emin=true,emax=true) Byte b);
264 }
265
266 @Test void d01_min_max_emin_emax() {
267 var x = remote(D.class,D1.class);
268 assertEquals("{x:'1'}",x.getX1(1));
269 assertEquals("{x:'10'}",x.getX1(10));
270 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX1(0));
271 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX1(11));
272 assertEquals("{x:'1'}",x.getX2(1));
273 assertEquals("{x:'10'}",x.getX2(10));
274 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX2(0));
275 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX2(11));
276 assertEquals("{x:'2'}",x.getX3(2));
277 assertEquals("{x:'9'}",x.getX3(9));
278 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX3(1));
279 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX3(10));
280 assertEquals("{x:'1'}",x.getX4((short)1));
281 assertEquals("{x:'10'}",x.getX4((short)10));
282 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX4((short)0));
283 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX4((short)11));
284 assertEquals("{x:'1'}",x.getX5((short)1));
285 assertEquals("{x:'10'}",x.getX5((short)10));
286 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX5((short)0));
287 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX5((short)11));
288 assertEquals("{x:'2'}",x.getX6((short)2));
289 assertEquals("{x:'9'}",x.getX6((short)9));
290 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX6((short)1));
291 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX6((short)10));
292 assertEquals("{x:'1'}",x.getX7(1L));
293 assertEquals("{x:'10'}",x.getX7(10L));
294 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX7(0L));
295 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX7(11L));
296 assertEquals("{x:'1'}",x.getX8(1L));
297 assertEquals("{x:'10'}",x.getX8(10L));
298 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX8(0L));
299 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX8(11L));
300 assertEquals("{x:'2'}",x.getX9(2L));
301 assertEquals("{x:'9'}",x.getX9(9L));
302 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX9(1L));
303 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX9(10L));
304 assertEquals("{x:'1.0'}",x.getX10(1f));
305 assertEquals("{x:'10.0'}",x.getX10(10f));
306 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX10(0.9f));
307 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX10(10.1f));
308 assertEquals("{x:'1.0'}",x.getX11(1f));
309 assertEquals("{x:'10.0'}",x.getX11(10f));
310 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX11(0.9f));
311 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX11(10.1f));
312 assertEquals("{x:'1.1'}",x.getX12(1.1f));
313 assertEquals("{x:'9.9'}",x.getX12(9.9f));
314 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX12(1f));
315 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX12(10f));
316 assertEquals("{x:'1.0'}",x.getX13(1d));
317 assertEquals("{x:'10.0'}",x.getX13(10d));
318 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX13(0.9d));
319 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX13(10.1d));
320 assertEquals("{x:'1.0'}",x.getX14(1d));
321 assertEquals("{x:'10.0'}",x.getX14(10d));
322 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX14(0.9d));
323 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX14(10.1d));
324 assertEquals("{x:'1.1'}",x.getX15(1.1d));
325 assertEquals("{x:'9.9'}",x.getX15(9.9d));
326 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX15(1d));
327 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX15(10d));
328 assertEquals("{x:'1'}",x.getX16((byte)1));
329 assertEquals("{x:'10'}",x.getX16((byte)10));
330 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX16((byte)0));
331 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX16((byte)11));
332 assertEquals("{x:'1'}",x.getX17((byte)1));
333 assertEquals("{x:'10'}",x.getX17((byte)10));
334 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX17((byte)0));
335 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX17((byte)11));
336 assertEquals("{x:'2'}",x.getX18((byte)2));
337 assertEquals("{x:'9'}",x.getX18((byte)9));
338 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX18((byte)1));
339 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX18((byte)10));
340 assertEquals("{x:'1'}",x.getX19(new AtomicInteger(1)));
341 assertEquals("{x:'10'}",x.getX19(new AtomicInteger(10)));
342 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX19(new AtomicInteger(0)));
343 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX19(new AtomicInteger(11)));
344 assertEquals("{x:'1'}",x.getX20(new AtomicInteger(1)));
345 assertEquals("{x:'10'}",x.getX20(new AtomicInteger(10)));
346 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX20(new AtomicInteger(0)));
347 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX20(new AtomicInteger(11)));
348 assertEquals("{x:'2'}",x.getX21(new AtomicInteger(2)));
349 assertEquals("{x:'9'}",x.getX21(new AtomicInteger(9)));
350 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX21(new AtomicInteger(1)));
351 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX21(new AtomicInteger(10)));
352 assertEquals("{x:'1'}",x.getX22(new BigDecimal(1)));
353 assertEquals("{x:'10'}",x.getX22(new BigDecimal(10)));
354 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX22(new BigDecimal(0)));
355 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX22(new BigDecimal(11)));
356 assertEquals("{x:'1'}",x.getX23(new BigDecimal(1)));
357 assertEquals("{x:'10'}",x.getX23(new BigDecimal(10)));
358 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX23(new BigDecimal(0)));
359 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX23(new BigDecimal(11)));
360 assertEquals("{x:'2'}",x.getX24(new BigDecimal(2)));
361 assertEquals("{x:'9'}",x.getX24(new BigDecimal(9)));
362 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX24(new BigDecimal(1)));
363 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX24(new BigDecimal(10)));
364 assertEquals("{x:'1'}",x.getX25(1));
365 assertEquals("{x:'10'}",x.getX25(10));
366 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX25(0));
367 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX25(11));
368 assertEquals("{}",x.getX25(null));
369 assertEquals("{x:'1'}",x.getX26(1));
370 assertEquals("{x:'10'}",x.getX26(10));
371 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX26(0));
372 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX26(11));
373 assertEquals("{}",x.getX26(null));
374 assertEquals("{x:'2'}",x.getX27(2));
375 assertEquals("{x:'9'}",x.getX27(9));
376 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX27(1));
377 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX27(10));
378 assertEquals("{}",x.getX27(null));
379 assertEquals("{x:'1'}",x.getX28((short)1));
380 assertEquals("{x:'10'}",x.getX28((short)10));
381 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX28((short)0));
382 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX28((short)11));
383 assertEquals("{}",x.getX28(null));
384 assertEquals("{x:'1'}",x.getX29((short)1));
385 assertEquals("{x:'10'}",x.getX29((short)10));
386 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX29((short)0));
387 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX29((short)11));
388 assertEquals("{}",x.getX29(null));
389 assertEquals("{x:'2'}",x.getX30((short)2));
390 assertEquals("{x:'9'}",x.getX30((short)9));
391 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX30((short)1));
392 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX30((short)10));
393 assertEquals("{}",x.getX30(null));
394 assertEquals("{x:'1'}",x.getX31(1L));
395 assertEquals("{x:'10'}",x.getX31(10L));
396 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX31(0L));
397 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX31(11L));
398 assertEquals("{}",x.getX31(null));
399 assertEquals("{x:'1'}",x.getX32(1L));
400 assertEquals("{x:'10'}",x.getX32(10L));
401 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX32(0L));
402 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX32(11L));
403 assertEquals("{}",x.getX32(null));
404 assertEquals("{x:'2'}",x.getX33(2L));
405 assertEquals("{x:'9'}",x.getX33(9L));
406 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX33(1L));
407 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX33(10L));
408 assertEquals("{}",x.getX33(null));
409 assertEquals("{x:'1.0'}",x.getX34(1f));
410 assertEquals("{x:'10.0'}",x.getX34(10f));
411 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX34(0.9f));
412 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX34(10.1f));
413 assertEquals("{}",x.getX34(null));
414 assertEquals("{x:'1.0'}",x.getX35(1f));
415 assertEquals("{x:'10.0'}",x.getX35(10f));
416 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX35(0.9f));
417 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX35(10.1f));
418 assertEquals("{}",x.getX35(null));
419 assertEquals("{x:'1.1'}",x.getX36(1.1f));
420 assertEquals("{x:'9.9'}",x.getX36(9.9f));
421 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX36(1f));
422 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX36(10f));
423 assertEquals("{}",x.getX36(null));
424 assertEquals("{x:'1.0'}",x.getX37(1d));
425 assertEquals("{x:'10.0'}",x.getX37(10d));
426 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX37(0.9d));
427 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX37(10.1d));
428 assertEquals("{}",x.getX37(null));
429 assertEquals("{x:'1.0'}",x.getX38(1d));
430 assertEquals("{x:'10.0'}",x.getX38(10d));
431 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX38(0.9d));
432 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX38(10.1d));
433 assertEquals("{}",x.getX38(null));
434 assertEquals("{x:'1.1'}",x.getX39(1.1d));
435 assertEquals("{x:'9.9'}",x.getX39(9.9d));
436 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX39(1d));
437 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX39(10d));
438 assertEquals("{}",x.getX39(null));
439 assertEquals("{x:'1'}",x.getX40((byte)1));
440 assertEquals("{x:'10'}",x.getX40((byte)10));
441 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX40((byte)0));
442 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX40((byte)11));
443 assertEquals("{}",x.getX40(null));
444 assertEquals("{x:'1'}",x.getX41((byte)1));
445 assertEquals("{x:'10'}",x.getX41((byte)10));
446 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX41((byte)0));
447 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX41((byte)11));
448 assertEquals("{}",x.getX41(null));
449 assertEquals("{x:'2'}",x.getX42((byte)2));
450 assertEquals("{x:'9'}",x.getX42((byte)9));
451 assertThrowsWithMessage(Exception.class, "Minimum value not met.", ()->x.getX42((byte)1));
452 assertThrowsWithMessage(Exception.class, "Maximum value exceeded.", ()->x.getX42((byte)10));
453 assertEquals("{}",x.getX42(null));
454 }
455
456
457
458
459
460 @Rest
461 public static class E {
462 @RestOp
463 public String get(@Query("*") JsonMap m) {
464 return m.toString();
465 }
466 }
467
468 @Remote
469 public interface E1 {
470 @RemoteOp(path="/") String getX1(@Query("x") @Schema(cf="pipes",mini=1,maxi=2) String...b);
471 @RemoteOp(path="/") String getX2(@Query("x") @Schema(items=@Items(cf="pipes",mini=1,maxi=2)) String[]...b);
472 @RemoteOp(path="/") String getX3(@Query("x") @Schema(cf="pipes",ui=false) String...b);
473 @RemoteOp(path="/") String getX4(@Query("x") @Schema(items=@Items(cf="pipes",ui=false)) String[]...b);
474 @RemoteOp(path="/") String getX5(@Query("x") @Schema(cf="pipes",ui=true) String...b);
475 @RemoteOp(path="/") String getX6(@Query("x") @Schema(items=@Items(cf="pipes",ui=true)) String[]...b);
476 }
477
478 @Test void e01_mini_maxi_ui() {
479 var x = remote(E.class,E1.class);
480 assertEquals("{x:'1'}",x.getX1("1"));
481 assertEquals("{x:'1|2'}",x.getX1("1","2"));
482 assertThrowsWithMessage(Exception.class, "Minimum number of items not met.", x::getX1);
483 assertThrowsWithMessage(Exception.class, "Maximum number of items exceeded.", ()->x.getX1("1","2","3"));
484 assertEquals("{x:null}",x.getX1((String)null));
485 assertEquals("{x:'1'}",x.getX2(new String[]{"1"}));
486 assertEquals("{x:'1|2'}",x.getX2(new String[]{"1","2"}));
487 assertThrowsWithMessage(Exception.class, "Minimum number of items not met.", ()->x.getX2(new String[]{}));
488 assertThrowsWithMessage(Exception.class, "Maximum number of items exceeded.", ()->x.getX2(new String[]{"1","2","3"}));
489 assertEquals("{x:null}",x.getX2(new String[]{null}));
490 assertEquals("{x:'1|1'}",x.getX3("1","1"));
491 assertEquals("{x:'1|1'}",x.getX4(new String[]{"1","1"}));
492 assertEquals("{x:'1|2'}",x.getX5("1","2"));
493 assertThrowsWithMessage(Exception.class, "Duplicate items not allowed.", ()->x.getX5("1","1"));
494 assertEquals("{x:'1|2'}",x.getX6(new String[]{"1","2"}));
495 assertThrowsWithMessage(Exception.class, "Duplicate items not allowed.", ()->x.getX6(new String[]{"1","1"}));
496 }
497
498
499
500
501
502 @Rest
503 public static class F {
504 @RestOp
505 public String get(@Query("*") JsonMap m) {
506 return m.toString();
507 }
508 }
509
510 @Remote
511 public interface F1 {
512 @RemoteOp(path="/") String getX1(@Query("x") @Schema(minl=2,maxl=3) String b);
513 @RemoteOp(path="/") String getX2(@Query("x") @Schema(cf="pipes",items=@Items(minl=2,maxl=3)) String...b);
514 @RemoteOp(path="/") String getX3(@Query("x") @Schema(e={"foo"}) String b);
515 @RemoteOp(path="/") String getX4(@Query("x") @Schema(cf="pipes",items=@Items(e={"foo"})) String...b);
516 @RemoteOp(path="/") String getX5(@Query("x") @Schema(p="foo\\d{1,3}") String b);
517 @RemoteOp(path="/") String getX6(@Query("x") @Schema(cf="pipes",items=@Items(p="foo\\d{1,3}")) String...b);
518 }
519
520 @Test void f01_minl_maxl_enum() {
521 var x = remote(F.class,F1.class);
522 assertEquals("{x:'12'}",x.getX1("12"));
523 assertEquals("{x:'123'}",x.getX1("123"));
524 assertThrowsWithMessage(Exception.class, "Minimum length of value not met.", ()->x.getX1("1"));
525 assertThrowsWithMessage(Exception.class, "Maximum length of value exceeded.", ()->x.getX1("1234"));
526 assertEquals("{}",x.getX1(null));
527 assertEquals("{x:'12|34'}",x.getX2("12","34"));
528 assertEquals("{x:'123|456'}",x.getX2("123","456"));
529 assertThrowsWithMessage(Exception.class, "Minimum length of value not met.", ()->x.getX2("1","2"));
530 assertThrowsWithMessage(Exception.class, "Maximum length of value exceeded.", ()->x.getX2("1234","5678"));
531 assertEquals("{x:'12|null'}",x.getX2("12",null));
532 assertEquals("{x:'foo'}",x.getX3("foo"));
533 assertThrowsWithMessage(Exception.class, "Value does not match one of the expected values. Must be one of the following: foo", ()->x.getX3("bar"));
534 assertEquals("{}",x.getX3(null));
535 assertEquals("{x:'foo'}",x.getX4("foo"));
536 assertThrowsWithMessage(Exception.class, "Value does not match one of the expected values. Must be one of the following: foo", ()->x.getX4("bar"));
537 assertEquals("{x:null}",x.getX4((String)null));
538 assertEquals("{x:'foo123'}",x.getX5("foo123"));
539 assertThrowsWithMessage(Exception.class, "Value does not match expected pattern. Must match pattern: foo\\d{1,3}", ()->x.getX5("bar"));
540 assertEquals("{}",x.getX5(null));
541 assertEquals("{x:'foo123'}",x.getX6("foo123"));
542 assertThrowsWithMessage(Exception.class, "Value does not match expected pattern. Must match pattern: foo\\d{1,3}", ()->x.getX6("foo"));
543 assertEquals("{x:null}",x.getX6((String)null));
544 }
545
546
547
548
549
550 @Rest
551 public static class G {
552 @RestOp
553 public String get(@Query("*") JsonMap m) {
554 return m.toString();
555 }
556 }
557
558 @Remote
559 public interface G1 {
560 @RemoteOp(path="/") String getX1(@Query("x") @Schema(mo="2") int b);
561 @RemoteOp(path="/") String getX2(@Query("x") @Schema(mo="2") short b);
562 @RemoteOp(path="/") String getX3(@Query("x") @Schema(mo="2") long b);
563 @RemoteOp(path="/") String getX4(@Query("x") @Schema(mo="2") float b);
564 @RemoteOp(path="/") String getX5(@Query("x") @Schema(mo="2") double b);
565 @RemoteOp(path="/") String getX6(@Query("x") @Schema(mo="2") byte b);
566 @RemoteOp(path="/") String getX7(@Query("x") @Schema(mo="2") AtomicInteger b);
567 @RemoteOp(path="/") String getX8(@Query("x") @Schema(mo="2") BigDecimal b);
568 @RemoteOp(path="/") String getX9(@Query("x") @Schema(mo="2") Integer b);
569 @RemoteOp(path="/") String getX10(@Query("x") @Schema(mo="2") Short b);
570 @RemoteOp(path="/") String getX11(@Query("x") @Schema(mo="2") Long b);
571 @RemoteOp(path="/") String getX12(@Query("x") @Schema(mo="2") Float b);
572 @RemoteOp(path="/") String getX13(@Query("x") @Schema(mo="2") Double b);
573 @RemoteOp(path="/") String getX14(@Query("x") @Schema(mo="2") Byte b);
574 }
575
576 @Test void g01_multipleOf() {
577 var x = remote(G.class,G1.class);
578 assertEquals("{x:'4'}",x.getX1(4));
579 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX1(5));
580 assertEquals("{x:'4'}",x.getX2((short)4));
581 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX2((short)5));
582 assertEquals("{x:'4'}",x.getX3(4));
583 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX3(5));
584 assertEquals("{x:'4.0'}",x.getX4(4));
585 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX4(5));
586 assertEquals("{x:'4.0'}",x.getX5(4));
587 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX5(5));
588 assertEquals("{x:'4'}",x.getX6((byte)4));
589 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX6((byte)5));
590 assertEquals("{x:'4'}",x.getX7(new AtomicInteger(4)));
591 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX7(new AtomicInteger(5)));
592 assertEquals("{x:'4'}",x.getX8(new BigDecimal(4)));
593 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX8(new BigDecimal(5)));
594 assertEquals("{x:'4'}",x.getX9(4));
595 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX9(5));
596 assertEquals("{x:'4'}",x.getX10((short)4));
597 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX10((short)5));
598 assertEquals("{x:'4'}",x.getX11(4L));
599 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX11(5L));
600 assertEquals("{x:'4.0'}",x.getX12(4f));
601 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX12(5f));
602 assertEquals("{x:'4.0'}",x.getX13(4d));
603 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX13(5d));
604 assertEquals("{x:'4'}",x.getX14((byte)4));
605 assertThrowsWithMessage(Exception.class, "Multiple-of not met.", ()->x.getX14((byte)5));
606 }
607
608
609
610
611
612 @Rest
613 public static class H {
614 @RestOp
615 public String get(@Query("*") JsonMap m) {
616 return m.toString();
617 }
618 }
619
620 @Remote
621 public interface H1 {
622 @RemoteOp(path="/") String getX1(@Query("x") String b);
623 @RemoteOp(path="/") String getX2(@Query("x") @Schema(r=false) String b);
624 @RemoteOp(path="/") String getX3(@Query("x") @Schema(r=true) String b);
625 }
626
627 @Test void h01_required() {
628 var x = remote(H.class,H1.class);
629 assertEquals("{}",x.getX1(null));
630 assertEquals("{}",x.getX2(null));
631 assertEquals("{x:'1'}",x.getX3("1"));
632 assertThrowsWithMessage(Exception.class, "Required value not provided.", ()->x.getX3(null));
633 }
634
635
636
637
638
639 @Rest
640 public static class I {
641 @RestOp
642 public String get(@Query("*") JsonMap m) {
643 return m.toString();
644 }
645 }
646
647 @Remote
648 public interface I1 {
649 @RemoteOp(path="/") String getX1(@Query("x") @Schema(aev=true) String b);
650 @RemoteOp(path="/") String getX2(@Query("x") @Schema(aev=true,sie=false) String b);
651 @RemoteOp(path="/") String getX3(@Query("x") @Schema(sie=true) String b);
652 }
653
654 @Test void i01_skipIfEmpty() {
655 var x = remote(I.class,I1.class);
656 assertEquals("{x:''}",x.getX1(""));
657 assertEquals("{x:''}",x.getX2(""));
658 assertEquals("{}",x.getX3(""));
659 }
660
661
662
663
664
665 @Rest
666 public static class J {
667 @RestOp
668 public String get(@Query("*") JsonMap m) {
669 return m.toString();
670 }
671 }
672
673 @Remote
674 public interface J1 {
675 @RemoteOp(path="/") String getX1(@Query(name="x",serializer=FakeWriterSerializer.X.class) String b);
676 }
677
678 @Test void j01_serializer() {
679 var x = remote(J.class,J1.class);
680 assertEquals("{x:'xXx'}",x.getX1("X"));
681 }
682
683
684
685
686
687 @Rest
688 public static class K {
689 @RestOp
690 public String get(RestRequest req) {
691 return req.getQueryParams().toString();
692 }
693 }
694
695
696
697
698
699 @Remote(path="/")
700 public interface K1 {
701 @RemoteOp(path="/") String getX1(@Request K1b rb);
702 @RemoteOp(path="/") String getX2(@Request(serializer=FakeWriterSerializer.X.class) K1b rb);
703 }
704
705 public interface K1a {
706 @Query String getA();
707 @Query("b") String getX1();
708 @Query("c") String getX2();
709 @Query("e") @Schema(allowEmptyValue=true) String getX4();
710 @Query("f") String getX5();
711 @Query("g") String getX6();
712 @Query("h") String getX7();
713 @Query("i1") @Schema(sie=true) String getX8();
714 @Query("i2") @Schema(sie=true) String getX9();
715 @Query("i3") @Schema(sie=true) String getX10();
716 }
717
718 public static class K1b implements K1a {
719 @Override public String getA() { return "a1"; }
720 @Override public String getX1() { return "b1"; }
721 @Override public String getX2() { return "c1"; }
722 @Override public String getX4() { return ""; }
723 @Override public String getX5() { return null; }
724 @Override public String getX6() { return "true"; }
725 @Override public String getX7() { return "123"; }
726 @Override public String getX8() { return "foo"; }
727 @Override public String getX9() { return ""; }
728 @Override public String getX10() { return null; }
729 }
730
731 @Test void k01_requestBean_simpleVals() {
732 var x1 = remote(K.class,K1.class);
733 var x2 = client(K.class).partSerializer(UonSerializer.class).build().getRemote(K1.class);
734 assertEquals("{a:'a1',b:'b1',c:'c1',e:'',g:'true',h:'123',i1:'foo'}",x1.getX1(new K1b()));
735 assertEquals("{a:'a1',b:'b1',c:'c1',e:'',g:'\\'true\\'',h:'\\'123\\'',i1:'foo'}",x2.getX1(new K1b()));
736 assertEquals("{a:'xa1x',b:'xb1x',c:'xc1x',e:'xx',g:'xtruex',h:'x123x',i1:'xfoox'}",x2.getX2(new K1b()));
737 }
738
739
740
741
742
743 @Remote(path="/")
744 public interface K2 {
745 @RemoteOp(path="/") String getX1(@Request K2a rb);
746 @RemoteOp(path="/") String getX2(@Request(serializer=FakeWriterSerializer.X.class) K2a rb);
747 }
748
749 public static class K2a {
750 @Query public Map<String,Object> getA() { return CollectionUtils.mapBuilder(String.class,Object.class).add("a1","v1").add("a2",123).add("a3",null).add("a4","").build(); }
751 @Query("*") public Map<String,Object> getB() { return map("b1","true","b2","123","b3","null"); }
752 @Query("*") @Schema(allowEmptyValue=true) public Map<String,Object> getC() { return CollectionUtils.mapBuilder(String.class,Object.class).add("c1","v1").add("c2",123).add("c3",null).add("c4","").build(); }
753 @Query("*")
754 public Map<String,Object> getD() { return null; }
755 }
756
757 @Test void k02_requestBean_maps() {
758 var x1 = remote(K.class,K2.class);
759 var x2 = client(K.class).partSerializer(UonSerializer.class).build().getRemote(K2.class);
760 assertEquals("{a:'a1=v1,a2=123,a3=null,a4=',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}",x1.getX1(new K2a()));
761 assertEquals("{a:'(a1=v1,a2=123,a3=null,a4=\\'\\')',b1:'\\'true\\'',b2:'\\'123\\'',b3:'\\'null\\'',c1:'v1',c2:'123',c4:''}",x2.getX1(new K2a()));
762 assertEquals("{a:'x{a1=v1, a2=123, a3=null, a4=}x',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x',c4:'xx'}",x2.getX2(new K2a()));
763 }
764
765
766
767
768
769 @Remote(path="/")
770 public interface K3 {
771 @RemoteOp(path="/") String getX1(@Request K3a rb);
772 @RemoteOp(path="/") String getX2(@Request(serializer=FakeWriterSerializer.X.class) K3a rb);
773 }
774
775 public static class K3a {
776 @Query() @Schema(aev=true) public PartList getA() { return parts("a1","v1","a2","123","a3",null,"a4",""); }
777 @Query("*") public PartList getB() { return parts("b1","true","b2","123","b3","null"); }
778 @Query("*") @Schema(aev=true) public PartList getC() { return parts("c1","v1","c2","123","c3",null,"c4",""); }
779 @Query("*")
780 public PartList getD() { return null; }
781 @Query() @Schema(aev=true) public NameValuePair[] getE() { return parts("e1","v1","e2","123","e3",null,"e4","").getAll(); }
782 }
783
784 @Test void k03_requestBean_nameValuePairs() {
785 var x1 = remote(K.class,K3.class);
786 var x2 = client(K.class).partSerializer(UonSerializer.class).build().getRemote(K3.class);
787 assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:'',e1:'v1',e2:'123',e4:''}",x1.getX1(new K3a()));
788 assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:'',e1:'v1',e2:'123',e4:''}",x2.getX1(new K3a()));
789 }
790
791
792
793
794
795 @Remote(path="/")
796 public interface K4 {
797 String get(@Request K4a rb);
798 }
799
800 public static class K4a {
801 @Query("*") public StringBuilder getA() { return new StringBuilder("foo=bar&baz=qux"); }
802 }
803
804 @Test void k04_requestBean_charSequence() {
805 var x = remote(K.class,K4.class);
806 assertEquals("{foo:'bar',baz:'qux'}",x.get(new K4a()));
807 }
808
809
810
811
812
813 @Remote(path="/")
814 public interface K5 {
815 String get(@Request K5a rb);
816 }
817
818 public static class K5a {
819 @Query("*") public Reader getA() { return reader("foo=bar&baz=qux"); }
820 }
821
822 @Test void k05_requestBean_reader() {
823 var x = remote(K.class,K5.class);
824 assertEquals("{foo:'bar',baz:'qux'}",x.get(new K5a()));
825 }
826
827
828
829
830
831 @Remote(path="/")
832 public interface K6 {
833 @RemoteOp(path="/") String getX1(@Request K6a rb);
834 @RemoteOp(path="/") String getX2(@Request(serializer=FakeWriterSerializer.X.class) K6a rb);
835 }
836
837 public static class K6a {
838 @Query public List<Object> getA() { return alist("foo","","true","123","null",true,123,null); }
839 @Query("b") public List<Object> getX1() { return alist("foo","","true","123","null",true,123,null); }
840 @Query(name="c",serializer=FakeWriterSerializer.X.class) public List<Object> getX2() { return alist("foo","","true","123","null",true,123,null); }
841 @Query("d") @Schema(allowEmptyValue=true) public List<Object> getX3() { return alist(); }
842 @Query("e") public List<Object> getX4() { return null; }
843 @Query("f") public Object[] getX5() { return new Object[]{"foo","","true","123","null",true,123,null}; }
844 @Query(name="g",serializer=FakeWriterSerializer.X.class) public Object[] getX6() { return new Object[]{"foo","","true","123","null",true,123,null}; }
845 @Query("h") @Schema(allowEmptyValue=true) public Object[] getX7() { return new Object[]{}; }
846 @Query("i") public Object[] getX8() { return null; }
847 }
848
849 @Test void k06_requestBean_collections() {
850 var x1 = remote(K.class,K6.class);
851 var x2 = client(K.class).partSerializer(UonSerializer.class).build().getRemote(K6.class);
852 assertEquals("{a:'foo,,true,123,null,true,123,null',b:'foo,,true,123,null,true,123,null',c:'xfoo||true|123|null|true|123|nullx',d:'',f:'foo,,true,123,null,true,123,null',g:'xfoo||true|123|null|true|123|nullx',h:''}", x1.getX1(new K6a()));
853 assertEquals("{a:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',b:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',c:'xfoo||true|123|null|true|123|nullx',d:'@()',f:'@(foo,\\'\\',\\'true\\',\\'123\\',\\'null\\',true,123,null)',g:'xfoo||true|123|null|true|123|nullx',h:'@()'}", x2.getX1(new K6a()));
854 assertEquals("{a:'xfoo||true|123|null|true|123|nullx',b:'xfoo||true|123|null|true|123|nullx',c:'xfoo||true|123|null|true|123|nullx',d:'xx',f:'xfoo||true|123|null|true|123|nullx',g:'xfoo||true|123|null|true|123|nullx',h:'xx'}", x2.getX2(new K6a()));
855 }
856
857
858
859
860
861 private static PartList parts(String...pairs) {
862 return partList(pairs);
863 }
864
865 private static NameValuePair part(String key,Object val) {
866 return basicPart(key,val);
867 }
868
869 private static RestClient.Builder client(Class<?> c) {
870 return MockRestClient.create(c);
871 }
872
873 private static <T> T remote(Class<?> rest,Class<T> t) {
874 return MockRestClient.build(rest).getRemote(t);
875 }
876 }