encode_decode_test.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. <?php
  2. require_once('test_base.php');
  3. require_once('test_util.php');
  4. use Google\Protobuf\RepeatedField;
  5. use Google\Protobuf\GPBType;
  6. use Foo\TestEnum;
  7. use Foo\TestMessage;
  8. use Foo\TestMessage\Sub;
  9. use Foo\TestPackedMessage;
  10. use Foo\TestRandomFieldOrder;
  11. use Foo\TestUnpackedMessage;
  12. use Google\Protobuf\DoubleValue;
  13. use Google\Protobuf\FloatValue;
  14. use Google\Protobuf\Int32Value;
  15. use Google\Protobuf\UInt32Value;
  16. use Google\Protobuf\Int64Value;
  17. use Google\Protobuf\UInt64Value;
  18. use Google\Protobuf\BoolValue;
  19. use Google\Protobuf\StringValue;
  20. use Google\Protobuf\BytesValue;
  21. class EncodeDecodeTest extends TestBase
  22. {
  23. public function testDecodeJsonSimple()
  24. {
  25. $m = new TestMessage();
  26. $m->mergeFromJsonString("{\"optionalInt32\":1}");
  27. }
  28. public function testDecodeTopLevelBoolValue()
  29. {
  30. $m = new BoolValue();
  31. $m->mergeFromJsonString("true");
  32. $this->assertEquals(true, $m->getValue());
  33. $m->mergeFromJsonString("false");
  34. $this->assertEquals(false, $m->getValue());
  35. }
  36. public function testDecodeTopLevelDoubleValue()
  37. {
  38. $m = new DoubleValue();
  39. $m->mergeFromJsonString("1.5");
  40. $this->assertEquals(1.5, $m->getValue());
  41. }
  42. public function testDecodeTopLevelFloatValue()
  43. {
  44. $m = new FloatValue();
  45. $m->mergeFromJsonString("1.5");
  46. $this->assertEquals(1.5, $m->getValue());
  47. }
  48. public function testDecodeTopLevelInt32Value()
  49. {
  50. $m = new Int32Value();
  51. $m->mergeFromJsonString("1");
  52. $this->assertEquals(1, $m->getValue());
  53. }
  54. public function testDecodeTopLevelUInt32Value()
  55. {
  56. $m = new UInt32Value();
  57. $m->mergeFromJsonString("1");
  58. $this->assertEquals(1, $m->getValue());
  59. }
  60. public function testDecodeTopLevelInt64Value()
  61. {
  62. $m = new Int64Value();
  63. $m->mergeFromJsonString("1");
  64. $this->assertEquals(1, $m->getValue());
  65. }
  66. public function testDecodeTopLevelUInt64Value()
  67. {
  68. $m = new UInt64Value();
  69. $m->mergeFromJsonString("1");
  70. $this->assertEquals(1, $m->getValue());
  71. }
  72. public function testDecodeTopLevelStringValue()
  73. {
  74. $m = new StringValue();
  75. $m->mergeFromJsonString("\"a\"");
  76. $this->assertSame("a", $m->getValue());
  77. }
  78. public function testDecodeTopLevelBytesValue()
  79. {
  80. $m = new BytesValue();
  81. $m->mergeFromJsonString("\"YQ==\"");
  82. $this->assertSame("a", $m->getValue());
  83. }
  84. public function testEncode()
  85. {
  86. $from = new TestMessage();
  87. $this->expectEmptyFields($from);
  88. $this->setFields($from);
  89. $this->expectFields($from);
  90. $data = $from->serializeToString();
  91. $this->assertSame(bin2hex(TestUtil::getGoldenTestMessage()),
  92. bin2hex($data));
  93. }
  94. public function testDecode()
  95. {
  96. $to = new TestMessage();
  97. $to->mergeFromString(TestUtil::getGoldenTestMessage());
  98. $this->expectFields($to);
  99. }
  100. public function testEncodeDecode()
  101. {
  102. $from = new TestMessage();
  103. $this->expectEmptyFields($from);
  104. $this->setFields($from);
  105. $this->expectFields($from);
  106. $data = $from->serializeToString();
  107. $to = new TestMessage();
  108. $to->mergeFromString($data);
  109. $this->expectFields($to);
  110. }
  111. public function testEncodeDecodeEmpty()
  112. {
  113. $from = new TestMessage();
  114. $this->expectEmptyFields($from);
  115. $data = $from->serializeToString();
  116. $to = new TestMessage();
  117. $to->mergeFromString($data);
  118. $this->expectEmptyFields($to);
  119. }
  120. public function testEncodeDecodeOneof()
  121. {
  122. $m = new TestMessage();
  123. $m->setOneofInt32(1);
  124. $data = $m->serializeToString();
  125. $n = new TestMessage();
  126. $n->mergeFromString($data);
  127. $this->assertSame(1, $n->getOneofInt32());
  128. $m->setOneofFloat(2.0);
  129. $data = $m->serializeToString();
  130. $n = new TestMessage();
  131. $n->mergeFromString($data);
  132. $this->assertSame(2.0, $n->getOneofFloat());
  133. $m->setOneofString('abc');
  134. $data = $m->serializeToString();
  135. $n = new TestMessage();
  136. $n->mergeFromString($data);
  137. $this->assertSame('abc', $n->getOneofString());
  138. $sub_m = new Sub();
  139. $sub_m->setA(1);
  140. $m->setOneofMessage($sub_m);
  141. $data = $m->serializeToString();
  142. $n = new TestMessage();
  143. $n->mergeFromString($data);
  144. $this->assertSame(1, $n->getOneofMessage()->getA());
  145. // Encode default value
  146. $m->setOneofEnum(TestEnum::ZERO);
  147. $data = $m->serializeToString();
  148. $n = new TestMessage();
  149. $n->mergeFromString($data);
  150. $this->assertSame("oneof_enum", $n->getMyOneof());
  151. $this->assertSame(TestEnum::ZERO, $n->getOneofEnum());
  152. $m->setOneofString("");
  153. $data = $m->serializeToString();
  154. $n = new TestMessage();
  155. $n->mergeFromString($data);
  156. $this->assertSame("oneof_string", $n->getMyOneof());
  157. $this->assertSame("", $n->getOneofString());
  158. $sub_m = new Sub();
  159. $m->setOneofMessage($sub_m);
  160. $data = $m->serializeToString();
  161. $n = new TestMessage();
  162. $n->mergeFromString($data);
  163. $this->assertSame("oneof_message", $n->getMyOneof());
  164. $this->assertFalse(is_null($n->getOneofMessage()));
  165. }
  166. public function testPackedEncode()
  167. {
  168. $from = new TestPackedMessage();
  169. TestUtil::setTestPackedMessage($from);
  170. $this->assertSame(TestUtil::getGoldenTestPackedMessage(),
  171. $from->serializeToString());
  172. }
  173. public function testPackedDecodePacked()
  174. {
  175. $to = new TestPackedMessage();
  176. $to->mergeFromString(TestUtil::getGoldenTestPackedMessage());
  177. TestUtil::assertTestPackedMessage($to);
  178. }
  179. public function testPackedDecodeUnpacked()
  180. {
  181. $to = new TestPackedMessage();
  182. $to->mergeFromString(TestUtil::getGoldenTestUnpackedMessage());
  183. TestUtil::assertTestPackedMessage($to);
  184. }
  185. public function testUnpackedEncode()
  186. {
  187. $from = new TestUnpackedMessage();
  188. TestUtil::setTestPackedMessage($from);
  189. $this->assertSame(TestUtil::getGoldenTestUnpackedMessage(),
  190. $from->serializeToString());
  191. }
  192. public function testUnpackedDecodePacked()
  193. {
  194. $to = new TestUnpackedMessage();
  195. $to->mergeFromString(TestUtil::getGoldenTestPackedMessage());
  196. TestUtil::assertTestPackedMessage($to);
  197. }
  198. public function testUnpackedDecodeUnpacked()
  199. {
  200. $to = new TestUnpackedMessage();
  201. $to->mergeFromString(TestUtil::getGoldenTestUnpackedMessage());
  202. TestUtil::assertTestPackedMessage($to);
  203. }
  204. public function testDecodeInt64()
  205. {
  206. // Read 64 testing
  207. $testVals = array(
  208. '10' => '100a',
  209. '100' => '1064',
  210. '800' => '10a006',
  211. '6400' => '108032',
  212. '70400' => '1080a604',
  213. '774400' => '1080a22f',
  214. '9292800' => '108098b704',
  215. '74342400' => '1080c0b923',
  216. '743424000' => '108080bfe202',
  217. '8177664000' => '108080b5bb1e',
  218. '65421312000' => '108080a8dbf301',
  219. '785055744000' => '108080e0c7ec16',
  220. '9420668928000' => '10808080dd969202',
  221. '103627358208000' => '10808080fff9c717',
  222. '1139900940288000' => '10808080f5bd978302',
  223. '13678811283456000' => '10808080fce699a618',
  224. '109430490267648000' => '10808080e0b7ceb1c201',
  225. '984874412408832000' => '10808080e0f5c1bed50d',
  226. );
  227. $msg = new TestMessage();
  228. foreach ($testVals as $original => $encoded) {
  229. $msg->setOptionalInt64($original);
  230. $data = $msg->serializeToString();
  231. $this->assertSame($encoded, bin2hex($data));
  232. $msg->setOptionalInt64(0);
  233. $msg->mergeFromString($data);
  234. $this->assertEquals($original, $msg->getOptionalInt64());
  235. }
  236. }
  237. public function testDecodeToExistingMessage()
  238. {
  239. $m1 = new TestMessage();
  240. $this->setFields($m1);
  241. $this->expectFields($m1);
  242. $m2 = new TestMessage();
  243. $this->setFields2($m2);
  244. $data = $m2->serializeToString();
  245. $m1->mergeFromString($data);
  246. $this->expectFieldsMerged($m1);
  247. }
  248. public function testDecodeFieldNonExist()
  249. {
  250. $data = hex2bin('c80501');
  251. $m = new TestMessage();
  252. $m->mergeFromString($data);
  253. }
  254. public function testEncodeNegativeInt32()
  255. {
  256. $m = new TestMessage();
  257. $m->setOptionalInt32(-1);
  258. $data = $m->serializeToString();
  259. $this->assertSame("08ffffffffffffffffff01", bin2hex($data));
  260. }
  261. public function testDecodeNegativeInt32()
  262. {
  263. $m = new TestMessage();
  264. $this->assertEquals(0, $m->getOptionalInt32());
  265. $m->mergeFromString(hex2bin("08ffffffffffffffffff01"));
  266. $this->assertEquals(-1, $m->getOptionalInt32());
  267. $m = new TestMessage();
  268. $this->assertEquals(0, $m->getOptionalInt32());
  269. $m->mergeFromString(hex2bin("08ffffffff0f"));
  270. $this->assertEquals(-1, $m->getOptionalInt32());
  271. }
  272. public function testRandomFieldOrder()
  273. {
  274. $m = new TestRandomFieldOrder();
  275. $data = $m->serializeToString();
  276. $this->assertSame("", $data);
  277. }
  278. /**
  279. * @expectedException Exception
  280. */
  281. public function testDecodeInvalidInt32()
  282. {
  283. $m = new TestMessage();
  284. $m->mergeFromString(hex2bin('08'));
  285. }
  286. /**
  287. * @expectedException Exception
  288. */
  289. public function testDecodeInvalidSubMessage()
  290. {
  291. $m = new TestMessage();
  292. $m->mergeFromString(hex2bin('9A010108'));
  293. }
  294. /**
  295. * @expectedException Exception
  296. */
  297. public function testDecodeInvalidInt64()
  298. {
  299. $m = new TestMessage();
  300. $m->mergeFromString(hex2bin('10'));
  301. }
  302. /**
  303. * @expectedException Exception
  304. */
  305. public function testDecodeInvalidUInt32()
  306. {
  307. $m = new TestMessage();
  308. $m->mergeFromString(hex2bin('18'));
  309. }
  310. /**
  311. * @expectedException Exception
  312. */
  313. public function testDecodeInvalidUInt64()
  314. {
  315. $m = new TestMessage();
  316. $m->mergeFromString(hex2bin('20'));
  317. }
  318. /**
  319. * @expectedException Exception
  320. */
  321. public function testDecodeInvalidSInt32()
  322. {
  323. $m = new TestMessage();
  324. $m->mergeFromString(hex2bin('28'));
  325. }
  326. /**
  327. * @expectedException Exception
  328. */
  329. public function testDecodeInvalidSInt64()
  330. {
  331. $m = new TestMessage();
  332. $m->mergeFromString(hex2bin('30'));
  333. }
  334. /**
  335. * @expectedException Exception
  336. */
  337. public function testDecodeInvalidFixed32()
  338. {
  339. $m = new TestMessage();
  340. $m->mergeFromString(hex2bin('3D'));
  341. }
  342. /**
  343. * @expectedException Exception
  344. */
  345. public function testDecodeInvalidFixed64()
  346. {
  347. $m = new TestMessage();
  348. $m->mergeFromString(hex2bin('41'));
  349. }
  350. /**
  351. * @expectedException Exception
  352. */
  353. public function testDecodeInvalidSFixed32()
  354. {
  355. $m = new TestMessage();
  356. $m->mergeFromString(hex2bin('4D'));
  357. }
  358. /**
  359. * @expectedException Exception
  360. */
  361. public function testDecodeInvalidSFixed64()
  362. {
  363. $m = new TestMessage();
  364. $m->mergeFromString(hex2bin('51'));
  365. }
  366. /**
  367. * @expectedException Exception
  368. */
  369. public function testDecodeInvalidFloat()
  370. {
  371. $m = new TestMessage();
  372. $m->mergeFromString(hex2bin('5D'));
  373. }
  374. /**
  375. * @expectedException Exception
  376. */
  377. public function testDecodeInvalidDouble()
  378. {
  379. $m = new TestMessage();
  380. $m->mergeFromString(hex2bin('61'));
  381. }
  382. /**
  383. * @expectedException Exception
  384. */
  385. public function testDecodeInvalidBool()
  386. {
  387. $m = new TestMessage();
  388. $m->mergeFromString(hex2bin('68'));
  389. }
  390. /**
  391. * @expectedException Exception
  392. */
  393. public function testDecodeInvalidStringLengthMiss()
  394. {
  395. $m = new TestMessage();
  396. $m->mergeFromString(hex2bin('72'));
  397. }
  398. /**
  399. * @expectedException Exception
  400. */
  401. public function testDecodeInvalidStringDataMiss()
  402. {
  403. $m = new TestMessage();
  404. $m->mergeFromString(hex2bin('7201'));
  405. }
  406. /**
  407. * @expectedException Exception
  408. */
  409. public function testDecodeInvalidBytesLengthMiss()
  410. {
  411. $m = new TestMessage();
  412. $m->mergeFromString(hex2bin('7A'));
  413. }
  414. /**
  415. * @expectedException Exception
  416. */
  417. public function testDecodeInvalidBytesDataMiss()
  418. {
  419. $m = new TestMessage();
  420. $m->mergeFromString(hex2bin('7A01'));
  421. }
  422. /**
  423. * @expectedException Exception
  424. */
  425. public function testDecodeInvalidEnum()
  426. {
  427. $m = new TestMessage();
  428. $m->mergeFromString(hex2bin('8001'));
  429. }
  430. /**
  431. * @expectedException Exception
  432. */
  433. public function testDecodeInvalidMessageLengthMiss()
  434. {
  435. $m = new TestMessage();
  436. $m->mergeFromString(hex2bin('8A01'));
  437. }
  438. /**
  439. * @expectedException Exception
  440. */
  441. public function testDecodeInvalidMessageDataMiss()
  442. {
  443. $m = new TestMessage();
  444. $m->mergeFromString(hex2bin('8A0101'));
  445. }
  446. /**
  447. * @expectedException Exception
  448. */
  449. public function testDecodeInvalidPackedMessageLength()
  450. {
  451. $m = new TestPackedMessage();
  452. $m->mergeFromString(hex2bin('D205'));
  453. }
  454. public function testUnknown()
  455. {
  456. // Test preserve unknown for varint.
  457. $m = new TestMessage();
  458. $from = hex2bin('F80601'); // TODO(teboring): Add a util to encode
  459. // varint for better readability
  460. $m->mergeFromString($from);
  461. $to = $m->serializeToString();
  462. $this->assertSame(bin2hex($from), bin2hex($to));
  463. // Test preserve unknown for 64-bit.
  464. $m = new TestMessage();
  465. $from = hex2bin('F9060000000000000000');
  466. $m->mergeFromString($from);
  467. $to = $m->serializeToString();
  468. $this->assertSame(bin2hex($from), bin2hex($to));
  469. // Test preserve unknown for length delimited.
  470. $m = new TestMessage();
  471. $from = hex2bin('FA0600');
  472. $m->mergeFromString($from);
  473. $to = $m->serializeToString();
  474. $this->assertSame(bin2hex($from), bin2hex($to));
  475. // Test preserve unknown for 32-bit.
  476. $m = new TestMessage();
  477. $from = hex2bin('FD0600000000');
  478. $m->mergeFromString($from);
  479. $to = $m->serializeToString();
  480. $this->assertSame(bin2hex($from), bin2hex($to));
  481. // Test discard unknown in message.
  482. $m = new TestMessage();
  483. $from = hex2bin('F80601');
  484. $m->mergeFromString($from);
  485. $m->discardUnknownFields();
  486. $to = $m->serializeToString();
  487. $this->assertSame("", bin2hex($to));
  488. // Test discard unknown for singular message field.
  489. $m = new TestMessage();
  490. $from = hex2bin('8A0103F80601');
  491. $m->mergeFromString($from);
  492. $m->discardUnknownFields();
  493. $to = $m->serializeToString();
  494. $this->assertSame("8a0100", bin2hex($to));
  495. // Test discard unknown for repeated message field.
  496. $m = new TestMessage();
  497. $from = hex2bin('FA0203F80601');
  498. $m->mergeFromString($from);
  499. $m->discardUnknownFields();
  500. $to = $m->serializeToString();
  501. $this->assertSame("fa0200", bin2hex($to));
  502. // Test discard unknown for map message value field.
  503. $m = new TestMessage();
  504. $from = hex2bin("BA050708011203F80601");
  505. $m->mergeFromString($from);
  506. $m->discardUnknownFields();
  507. $to = $m->serializeToString();
  508. $this->assertSame("ba050408011200", bin2hex($to));
  509. // Test discard unknown for singular message field.
  510. $m = new TestMessage();
  511. $from = hex2bin('9A0403F80601');
  512. $m->mergeFromString($from);
  513. $m->discardUnknownFields();
  514. $to = $m->serializeToString();
  515. $this->assertSame("9a0400", bin2hex($to));
  516. }
  517. public function testJsonEncode()
  518. {
  519. $from = new TestMessage();
  520. $this->setFields($from);
  521. $data = $from->serializeToJsonString();
  522. $to = new TestMessage();
  523. $to->mergeFromJsonString($data);
  524. $this->expectFields($to);
  525. }
  526. }