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 18library thrift.test.transport.t_json_protocol_test; 19 20import 'dart:async'; 21import 'dart:typed_data' show Uint8List; 22 23import 'package:dart2_constant/convert.dart' show utf8; 24import 'package:test/test.dart'; 25import 'package:thrift/thrift.dart'; 26 27void 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 400class Primitive { 401 final Function read; 402 final Function write; 403 final defaultValue; 404 405 Primitive(this.read, this.write, this.defaultValue); 406} 407