]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | // Licensed to the Apache Software Foundation (ASF) under one |
2 | // or more contributor license agreements. See the NOTICE file | |
3 | // distributed with this work for additional information | |
4 | // regarding copyright ownership. The ASF licenses this file | |
5 | // to you under the Apache License, Version 2.0 (the | |
6 | // "License"); you may not use this file except in compliance | |
7 | // with the License. You may obtain a copy of the License at | |
8 | // | |
9 | // http://www.apache.org/licenses/LICENSE-2.0 | |
10 | // | |
11 | // Unless required by applicable law or agreed to in writing, | |
12 | // software distributed under the License is distributed on an | |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
14 | // KIND, either express or implied. See the License for the | |
15 | // specific language governing permissions and limitations | |
16 | // under the License. | |
17 | ||
18 | library thrift.test.transport.t_json_protocol_test; | |
19 | ||
20 | import 'dart:async'; | |
21 | import 'dart:typed_data' show Uint8List; | |
22 | ||
23 | import 'package:dart2_constant/convert.dart' show utf8; | |
24 | import 'package:test/test.dart'; | |
25 | import 'package:thrift/thrift.dart'; | |
26 | ||
27 | void main() { | |
28 | final message = new TMessage('my message', TMessageType.ONEWAY, 123); | |
29 | ||
30 | TProtocol protocol; | |
31 | ||
32 | Primitive getPrimitive(int tType) { | |
33 | switch (tType) { | |
34 | case TType.BOOL: | |
35 | return new Primitive(protocol.readBool, protocol.writeBool, false); | |
36 | ||
37 | case TType.BYTE: | |
38 | return new Primitive(protocol.readByte, protocol.writeByte, 0); | |
39 | ||
40 | case TType.I16: | |
41 | return new Primitive(protocol.readI16, protocol.writeI16, 0); | |
42 | ||
43 | case TType.I32: | |
44 | return new Primitive(protocol.readI32, protocol.writeI32, 0); | |
45 | ||
46 | case TType.I64: | |
47 | return new Primitive(protocol.readI64, protocol.writeI64, 0); | |
48 | ||
49 | case TType.DOUBLE: | |
50 | return new Primitive(protocol.readDouble, protocol.writeDouble, 0); | |
51 | ||
52 | case TType.STRING: | |
53 | return new Primitive(protocol.readString, protocol.writeString, ''); | |
54 | ||
55 | default: | |
56 | throw new UnsupportedError("Unsupported TType $tType"); | |
57 | } | |
58 | } | |
59 | ||
60 | Future primitiveTest(Primitive primitive, input) async { | |
61 | primitive.write(input); | |
62 | protocol.writeMessageEnd(); | |
63 | ||
64 | await protocol.transport.flush(); | |
65 | ||
66 | protocol.readMessageBegin(); | |
67 | var output = primitive.read(); | |
68 | ||
69 | expect(output, input); | |
70 | } | |
71 | ||
72 | Future primitiveNullTest(Primitive primitive) async { | |
73 | primitive.write(null); | |
74 | protocol.writeMessageEnd(); | |
75 | ||
76 | await protocol.transport.flush(); | |
77 | ||
78 | protocol.readMessageBegin(); | |
79 | var output = primitive.read(); | |
80 | ||
81 | expect(output, primitive.defaultValue); | |
82 | } | |
83 | ||
84 | var sharedTests = () { | |
85 | test('Test message', () async { | |
86 | protocol.writeMessageEnd(); | |
87 | ||
88 | await protocol.transport.flush(); | |
89 | ||
90 | var subject = protocol.readMessageBegin(); | |
91 | ||
92 | expect(subject.name, message.name); | |
93 | expect(subject.type, message.type); | |
94 | expect(subject.seqid, message.seqid); | |
95 | }); | |
96 | ||
97 | test('Test struct', () async { | |
98 | var input = new TStruct(); | |
99 | ||
100 | protocol.writeStructBegin(input); | |
101 | protocol.writeStructEnd(); | |
102 | protocol.writeMessageEnd(); | |
103 | ||
104 | await protocol.transport.flush(); | |
105 | ||
106 | protocol.readMessageBegin(); | |
107 | var output = protocol.readStructBegin(); | |
108 | ||
109 | // name is not serialized, see C# version for reference | |
110 | expect(output, isNotNull); | |
111 | }); | |
112 | ||
113 | test('Test field', () async { | |
114 | var input = new TField('my field', TType.MAP, 123); | |
115 | ||
116 | protocol.writeFieldBegin(input); | |
117 | protocol.writeFieldEnd(); | |
118 | protocol.writeMessageEnd(); | |
119 | ||
120 | await protocol.transport.flush(); | |
121 | ||
122 | protocol.readMessageBegin(); | |
123 | var output = protocol.readFieldBegin(); | |
124 | ||
125 | // name is not serialized, see C# version for reference | |
126 | expect(output.type, input.type); | |
127 | expect(output.id, input.id); | |
128 | }); | |
129 | ||
130 | test('Test map', () async { | |
131 | var input = new TMap(TType.STRING, TType.STRUCT, 123); | |
132 | ||
133 | protocol.writeMapBegin(input); | |
134 | protocol.writeMapEnd(); | |
135 | protocol.writeMessageEnd(); | |
136 | ||
137 | await protocol.transport.flush(); | |
138 | ||
139 | protocol.readMessageBegin(); | |
140 | var output = protocol.readMapBegin(); | |
141 | ||
142 | expect(output.keyType, input.keyType); | |
143 | expect(output.valueType, input.valueType); | |
144 | expect(output.length, input.length); | |
145 | }); | |
146 | ||
147 | test('Test list', () async { | |
148 | var input = new TList(TType.STRING, 123); | |
149 | ||
150 | protocol.writeListBegin(input); | |
151 | protocol.writeListEnd(); | |
152 | protocol.writeMessageEnd(); | |
153 | ||
154 | await protocol.transport.flush(); | |
155 | ||
156 | protocol.readMessageBegin(); | |
157 | var output = protocol.readListBegin(); | |
158 | ||
159 | expect(output.elementType, input.elementType); | |
160 | expect(output.length, input.length); | |
161 | }); | |
162 | ||
163 | test('Test set', () async { | |
164 | var input = new TSet(TType.STRING, 123); | |
165 | ||
166 | protocol.writeSetBegin(input); | |
167 | protocol.writeSetEnd(); | |
168 | protocol.writeMessageEnd(); | |
169 | ||
170 | await protocol.transport.flush(); | |
171 | ||
172 | protocol.readMessageBegin(); | |
173 | var output = protocol.readListBegin(); | |
174 | ||
175 | expect(output.elementType, input.elementType); | |
176 | expect(output.length, input.length); | |
177 | }); | |
178 | ||
179 | test('Test bool', () async { | |
180 | await primitiveTest(getPrimitive(TType.BOOL), true); | |
181 | }); | |
182 | ||
183 | test('Test bool null', () async { | |
184 | await primitiveNullTest(getPrimitive(TType.BOOL)); | |
185 | }); | |
186 | ||
187 | test('Test byte', () async { | |
188 | await primitiveTest(getPrimitive(TType.BYTE), 64); | |
189 | }); | |
190 | ||
191 | test('Test byte null', () async { | |
192 | await primitiveNullTest(getPrimitive(TType.BYTE)); | |
193 | }); | |
194 | ||
195 | test('Test I16', () async { | |
196 | await primitiveTest(getPrimitive(TType.I16), 32767); | |
197 | }); | |
198 | ||
199 | test('Test I16 null', () async { | |
200 | await primitiveNullTest(getPrimitive(TType.I16)); | |
201 | }); | |
202 | ||
203 | test('Test I32', () async { | |
204 | await primitiveTest(getPrimitive(TType.I32), 2147483647); | |
205 | }); | |
206 | ||
207 | test('Test I32 null', () async { | |
208 | await primitiveNullTest(getPrimitive(TType.I32)); | |
209 | }); | |
210 | ||
211 | test('Test I64', () async { | |
212 | await primitiveTest(getPrimitive(TType.I64), 9223372036854775807); | |
213 | }); | |
214 | ||
215 | test('Test I64 null', () async { | |
216 | await primitiveNullTest(getPrimitive(TType.I64)); | |
217 | }); | |
218 | ||
219 | test('Test double', () async { | |
220 | await primitiveTest(getPrimitive(TType.DOUBLE), 3.1415926); | |
221 | }); | |
222 | ||
223 | test('Test double null', () async { | |
224 | await primitiveNullTest(getPrimitive(TType.DOUBLE)); | |
225 | }); | |
226 | ||
227 | test('Test string', () async { | |
228 | var input = 'There are only two hard things in computer science: ' | |
229 | 'cache invalidation, naming things, and off-by-one errors.'; | |
230 | await primitiveTest(getPrimitive(TType.STRING), input); | |
231 | }); | |
232 | ||
233 | test('Test string null', () async { | |
234 | await primitiveNullTest(getPrimitive(TType.STRING)); | |
235 | }); | |
236 | ||
237 | test('Test binary', () async { | |
238 | var input = new Uint8List.fromList(new List.filled(100, 123)); | |
239 | ||
240 | protocol.writeBinary(input); | |
241 | protocol.writeMessageEnd(); | |
242 | ||
243 | await protocol.transport.flush(); | |
244 | ||
245 | protocol.readMessageBegin(); | |
246 | var output = protocol.readBinary(); | |
247 | ||
248 | expect(output.length, input.length); | |
249 | expect(output.every((i) => i == 123), isTrue); | |
250 | }); | |
251 | ||
252 | test('Test complex struct', () async { | |
253 | // {1: {10: 20}, 2: {30: 40}} | |
254 | protocol.writeStructBegin(new TStruct()); | |
255 | protocol.writeFieldBegin(new TField('success', TType.MAP, 0)); | |
256 | protocol.writeMapBegin(new TMap(TType.I32, TType.MAP, 2)); | |
257 | ||
258 | protocol.writeI32(1); // key | |
259 | protocol.writeMapBegin(new TMap(TType.I32, TType.I32, 1)); | |
260 | protocol.writeI32(10); // key | |
261 | protocol.writeI32(20); // value | |
262 | protocol.writeMapEnd(); | |
263 | ||
264 | protocol.writeI32(2); // key | |
265 | protocol.writeMapBegin(new TMap(TType.I32, TType.I32, 1)); | |
266 | protocol.writeI32(30); // key | |
267 | protocol.writeI32(40); // value | |
268 | protocol.writeMapEnd(); | |
269 | ||
270 | protocol.writeMapEnd(); | |
271 | protocol.writeFieldEnd(); | |
272 | protocol.writeFieldStop(); | |
273 | protocol.writeStructEnd(); | |
274 | protocol.writeMessageEnd(); | |
275 | ||
276 | await protocol.transport.flush(); | |
277 | ||
278 | protocol.readMessageBegin(); | |
279 | protocol.readStructBegin(); | |
280 | expect(protocol.readFieldBegin().type, TType.MAP); | |
281 | expect(protocol.readMapBegin().length, 2); | |
282 | ||
283 | expect(protocol.readI32(), 1); // key | |
284 | expect(protocol.readMapBegin().length, 1); | |
285 | expect(protocol.readI32(), 10); // key | |
286 | expect(protocol.readI32(), 20); // value | |
287 | protocol.readMapEnd(); | |
288 | ||
289 | expect(protocol.readI32(), 2); // key | |
290 | expect(protocol.readMapBegin().length, 1); | |
291 | expect(protocol.readI32(), 30); // key | |
292 | expect(protocol.readI32(), 40); // value | |
293 | protocol.readMapEnd(); | |
294 | ||
295 | protocol.readMapEnd(); | |
296 | protocol.readFieldEnd(); | |
297 | protocol.readStructEnd(); | |
298 | protocol.readMessageEnd(); | |
299 | }); | |
300 | ||
301 | test('Test nested maps and lists', () async { | |
302 | // {1: [{10: 20}], 2: [{30: 40}]} | |
303 | protocol.writeMapBegin(new TMap(TType.I32, TType.LIST, 2)); | |
304 | ||
305 | protocol.writeI32(1); // key | |
306 | protocol.writeListBegin(new TList(TType.MAP, 1)); | |
307 | protocol.writeMapBegin(new TMap(TType.I32, TType.I32, 1)); | |
308 | protocol.writeI32(10); // key | |
309 | protocol.writeI32(20); // value | |
310 | protocol.writeMapEnd(); | |
311 | protocol.writeListEnd(); | |
312 | ||
313 | protocol.writeI32(2); // key | |
314 | protocol.writeListBegin(new TList(TType.MAP, 1)); | |
315 | protocol.writeMapBegin(new TMap(TType.I32, TType.I32, 1)); | |
316 | protocol.writeI32(30); // key | |
317 | protocol.writeI32(40); // value | |
318 | protocol.writeMapEnd(); | |
319 | protocol.writeListEnd(); | |
320 | ||
321 | protocol.writeMapEnd(); | |
322 | protocol.writeMessageEnd(); | |
323 | ||
324 | await protocol.transport.flush(); | |
325 | ||
326 | protocol.readMessageBegin(); | |
327 | expect(protocol.readMapBegin().length, 2); | |
328 | ||
329 | expect(protocol.readI32(), 1); // key | |
330 | expect(protocol.readListBegin().length, 1); | |
331 | expect(protocol.readMapBegin().length, 1); | |
332 | expect(protocol.readI32(), 10); // key | |
333 | expect(protocol.readI32(), 20); // value | |
334 | protocol.readMapEnd(); | |
335 | protocol.readListEnd(); | |
336 | ||
337 | expect(protocol.readI32(), 2); // key | |
338 | expect(protocol.readListBegin().length, 1); | |
339 | expect(protocol.readMapBegin().length, 1); | |
340 | expect(protocol.readI32(), 30); // key | |
341 | expect(protocol.readI32(), 40); // value | |
342 | protocol.readMapEnd(); | |
343 | protocol.readListEnd(); | |
344 | ||
345 | protocol.readMapEnd(); | |
346 | protocol.readMessageEnd(); | |
347 | }); | |
348 | }; | |
349 | ||
350 | group('JSON', () { | |
351 | setUp(() { | |
352 | protocol = new TJsonProtocol(new TBufferedTransport()); | |
353 | protocol.writeMessageBegin(message); | |
354 | }); | |
355 | ||
356 | test('Test escaped unicode', () async { | |
357 | /* | |
358 | KOR_KAI | |
359 | UTF-8: 0xE0 0xB8 0x81 | |
360 | UTF-16: 0x0E01 | |
361 | G clef: | |
362 | UTF-8: 0xF0 0x9D 0x84 0x9E | |
363 | UTF-16: 0xD834 0xDD1E | |
364 | */ | |
365 | var buffer = utf8.encode(r'"\u0001\u0e01 \ud834\udd1e"'); | |
366 | var transport = new TBufferedTransport(); | |
367 | transport.writeAll(buffer); | |
368 | ||
369 | var protocol = new TJsonProtocol(transport); | |
370 | ||
371 | await protocol.transport.flush(); | |
372 | ||
373 | var subject = protocol.readString(); | |
374 | expect(subject, | |
375 | utf8.decode([0x01, 0xE0, 0xB8, 0x81, 0x20, 0xF0, 0x9D, 0x84, 0x9E])); | |
376 | }); | |
377 | ||
378 | group('shared tests', sharedTests); | |
379 | }); | |
380 | ||
381 | group('binary', () { | |
382 | setUp(() { | |
383 | protocol = new TBinaryProtocol(new TBufferedTransport()); | |
384 | protocol.writeMessageBegin(message); | |
385 | }); | |
386 | ||
387 | group('shared tests', sharedTests); | |
388 | }); | |
389 | ||
390 | group('compact', () { | |
391 | setUp(() { | |
392 | protocol = new TCompactProtocol(new TBufferedTransport()); | |
393 | protocol.writeMessageBegin(message); | |
394 | }); | |
395 | ||
396 | group('shared tests', sharedTests); | |
397 | }); | |
398 | } | |
399 | ||
400 | class Primitive { | |
401 | final Function read; | |
402 | final Function write; | |
403 | final defaultValue; | |
404 | ||
405 | Primitive(this.read, this.write, this.defaultValue); | |
406 | } |