textformatserializer_test.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. // Copyright 2012 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Unit tests for goog.proto2.TextFormatSerializer.
  16. *
  17. */
  18. /** @suppress {extraProvide} */
  19. goog.provide('goog.proto2.TextFormatSerializerTest');
  20. goog.require('goog.proto2.ObjectSerializer');
  21. goog.require('goog.proto2.TextFormatSerializer');
  22. goog.require('goog.testing.jsunit');
  23. goog.require('proto2.TestAllTypes');
  24. goog.setTestOnly('goog.proto2.TextFormatSerializerTest');
  25. function testSerialization() {
  26. var message = new proto2.TestAllTypes();
  27. // Set the fields.
  28. // Singular.
  29. message.setOptionalInt32(101);
  30. message.setOptionalUint32(103);
  31. message.setOptionalSint32(105);
  32. message.setOptionalFixed32(107);
  33. message.setOptionalSfixed32(109);
  34. message.setOptionalInt64('102');
  35. message.setOptionalFloat(111.5);
  36. message.setOptionalDouble(112.5);
  37. message.setOptionalBool(true);
  38. message.setOptionalString('test');
  39. message.setOptionalBytes('abcd');
  40. var group = new proto2.TestAllTypes.OptionalGroup();
  41. group.setA(111);
  42. message.setOptionalgroup(group);
  43. var nestedMessage = new proto2.TestAllTypes.NestedMessage();
  44. nestedMessage.setB(112);
  45. message.setOptionalNestedMessage(nestedMessage);
  46. message.setOptionalNestedEnum(proto2.TestAllTypes.NestedEnum.FOO);
  47. // Repeated.
  48. message.addRepeatedInt32(201);
  49. message.addRepeatedInt32(202);
  50. // Serialize to a simplified text format.
  51. var simplified = new goog.proto2.TextFormatSerializer().serialize(message);
  52. var expected = 'optional_int32: 101\n' +
  53. 'optional_int64: 102\n' +
  54. 'optional_uint32: 103\n' +
  55. 'optional_sint32: 105\n' +
  56. 'optional_fixed32: 107\n' +
  57. 'optional_sfixed32: 109\n' +
  58. 'optional_float: 111.5\n' +
  59. 'optional_double: 112.5\n' +
  60. 'optional_bool: true\n' +
  61. 'optional_string: "test"\n' +
  62. 'optional_bytes: "abcd"\n' +
  63. 'optionalgroup {\n' +
  64. ' a: 111\n' +
  65. '}\n' +
  66. 'optional_nested_message {\n' +
  67. ' b: 112\n' +
  68. '}\n' +
  69. 'optional_nested_enum: FOO\n' +
  70. 'repeated_int32: 201\n' +
  71. 'repeated_int32: 202\n';
  72. assertEquals(expected, simplified);
  73. }
  74. function testSerializationOfUnknown() {
  75. var nestedUnknown = new proto2.TestAllTypes();
  76. var message = new proto2.TestAllTypes();
  77. // Set the fields.
  78. // Known.
  79. message.setOptionalInt32(101);
  80. message.addRepeatedInt32(201);
  81. message.addRepeatedInt32(202);
  82. nestedUnknown.addRepeatedInt32(301);
  83. nestedUnknown.addRepeatedInt32(302);
  84. // Unknown.
  85. message.setUnknown(1000, 301);
  86. message.setUnknown(1001, 302);
  87. message.setUnknown(1002, 'hello world');
  88. message.setUnknown(1002, nestedUnknown);
  89. nestedUnknown.setUnknown(2000, 401);
  90. // Serialize.
  91. var simplified = new goog.proto2.TextFormatSerializer().serialize(message);
  92. var expected = 'optional_int32: 101\n' +
  93. 'repeated_int32: 201\n' +
  94. 'repeated_int32: 202\n' +
  95. '1000: 301\n' +
  96. '1001: 302\n' +
  97. '1002 {\n' +
  98. ' repeated_int32: 301\n' +
  99. ' repeated_int32: 302\n' +
  100. ' 2000: 401\n' +
  101. '}\n';
  102. assertEquals(expected, simplified);
  103. }
  104. function testSerializationOfUnknownParsedFromObject() {
  105. // Construct the object-serialized representation of the message constructed
  106. // programmatically in the test above.
  107. var serialized = {
  108. 1: 101,
  109. 31: [201, 202],
  110. 1000: 301,
  111. 1001: 302,
  112. 1002: {31: [301, 302], 2000: 401}
  113. };
  114. // Deserialize that representation into a TestAllTypes message.
  115. var objectSerializer = new goog.proto2.ObjectSerializer();
  116. var message = new proto2.TestAllTypes();
  117. objectSerializer.deserializeTo(message, serialized);
  118. // Check that the text format matches what we expect.
  119. var simplified = new goog.proto2.TextFormatSerializer().serialize(message);
  120. var expected =
  121. ('optional_int32: 101\n' +
  122. 'repeated_int32: 201\n' +
  123. 'repeated_int32: 202\n' +
  124. '1000: 301\n' +
  125. '1001: 302\n' +
  126. '1002 {\n' +
  127. ' 31: 301\n' +
  128. ' 31: 302\n' +
  129. ' 2000: 401\n' +
  130. '}\n');
  131. assertEquals(expected, simplified);
  132. }
  133. /**
  134. * Asserts that the given string value parses into the given set of tokens.
  135. * @param {string} value The string value to parse.
  136. * @param {Array<Object> | Object} tokens The tokens to check against. If not
  137. * an array, a single token is expected.
  138. * @param {boolean=} opt_ignoreWhitespace Whether whitespace tokens should be
  139. * skipped by the tokenizer.
  140. */
  141. function assertTokens(value, tokens, opt_ignoreWhitespace) {
  142. var tokenizer = new goog.proto2.TextFormatSerializer.Tokenizer_(
  143. value, opt_ignoreWhitespace);
  144. var tokensFound = [];
  145. while (tokenizer.next()) {
  146. tokensFound.push(tokenizer.getCurrent());
  147. }
  148. if (goog.typeOf(tokens) != 'array') {
  149. tokens = [tokens];
  150. }
  151. assertEquals(tokens.length, tokensFound.length);
  152. for (var i = 0; i < tokens.length; ++i) {
  153. assertToken(tokens[i], tokensFound[i]);
  154. }
  155. }
  156. function assertToken(expected, found) {
  157. assertEquals(expected.type, found.type);
  158. if (expected.value) {
  159. assertEquals(expected.value, found.value);
  160. }
  161. }
  162. function testTokenizer() {
  163. var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes;
  164. assertTokens('{ 123 }', [
  165. {type: types.OPEN_BRACE}, {type: types.WHITESPACE, value: ' '},
  166. {type: types.NUMBER, value: '123'}, {type: types.WHITESPACE, value: ' '},
  167. {type: types.CLOSE_BRACE}
  168. ]);
  169. // The c++ proto serializer might represent a float in exponential
  170. // notation:
  171. assertTokens('{ 1.2345e+3 }', [
  172. {type: types.OPEN_BRACE}, {type: types.WHITESPACE, value: ' '},
  173. {type: types.NUMBER, value: '1.2345e+3'},
  174. {type: types.WHITESPACE, value: ' '}, {type: types.CLOSE_BRACE}
  175. ]);
  176. }
  177. function testTokenizerExponentialFloatProblem() {
  178. var input = 'merchant: { # blah blah\n' +
  179. ' total_price: 3.2186e+06 # 3_218_600; 3.07Mi\n' +
  180. ' taxes : 2.17199e+06\n' +
  181. '}';
  182. var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes;
  183. assertTokens(
  184. input,
  185. [
  186. {type: types.IDENTIFIER, value: 'merchant'},
  187. {type: types.COLON, value: ':'}, {type: types.OPEN_BRACE, value: '{'},
  188. {type: types.COMMENT, value: '# blah blah'},
  189. {type: types.IDENTIFIER, value: 'total_price'},
  190. {type: types.COLON, value: ':'},
  191. {type: types.NUMBER, value: '3.2186e+06'},
  192. {type: types.COMMENT, value: '# 3_218_600; 3.07Mi'},
  193. {type: types.IDENTIFIER, value: 'taxes'},
  194. {type: types.COLON, value: ':'},
  195. {type: types.NUMBER, value: '2.17199e+06'},
  196. {type: types.CLOSE_BRACE, value: '}'}
  197. ],
  198. true);
  199. }
  200. function testTokenizerNoWhitespace() {
  201. var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes;
  202. assertTokens(
  203. '{ "hello world" }',
  204. [
  205. {type: types.OPEN_BRACE}, {type: types.STRING, value: '"hello world"'},
  206. {type: types.CLOSE_BRACE}
  207. ],
  208. true);
  209. }
  210. function assertIdentifier(identifier) {
  211. var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes;
  212. assertTokens(identifier, {type: types.IDENTIFIER, value: identifier});
  213. }
  214. function assertComment(comment) {
  215. var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes;
  216. assertTokens(comment, {type: types.COMMENT, value: comment});
  217. }
  218. function assertString(str) {
  219. var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes;
  220. assertTokens(str, {type: types.STRING, value: str});
  221. }
  222. function assertNumber(num) {
  223. num = num.toString();
  224. var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes;
  225. assertTokens(num, {type: types.NUMBER, value: num});
  226. }
  227. function testTokenizerSingleTokens() {
  228. var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes;
  229. assertTokens('{', {type: types.OPEN_BRACE});
  230. assertTokens('}', {type: types.CLOSE_BRACE});
  231. assertTokens('<', {type: types.OPEN_TAG});
  232. assertTokens('>', {type: types.CLOSE_TAG});
  233. assertTokens(':', {type: types.COLON});
  234. assertTokens(',', {type: types.COMMA});
  235. assertTokens(';', {type: types.SEMI});
  236. assertIdentifier('abcd');
  237. assertIdentifier('Abcd');
  238. assertIdentifier('ABcd');
  239. assertIdentifier('ABcD');
  240. assertIdentifier('a123nc');
  241. assertIdentifier('a45_bC');
  242. assertIdentifier('A45_bC');
  243. assertIdentifier('inf');
  244. assertIdentifier('infinity');
  245. assertIdentifier('nan');
  246. assertNumber(0);
  247. assertNumber(10);
  248. assertNumber(123);
  249. assertNumber(1234);
  250. assertNumber(123.56);
  251. assertNumber(-124);
  252. assertNumber(-1234);
  253. assertNumber(-123.56);
  254. assertNumber('123f');
  255. assertNumber('123.6f');
  256. assertNumber('-123f');
  257. assertNumber('-123.8f');
  258. assertNumber('0x1234');
  259. assertNumber('0x12ac34');
  260. assertNumber('0x49e281db686fb');
  261. // Floating point numbers might be serialized in exponential
  262. // notation:
  263. assertNumber('1.2345e+3');
  264. assertNumber('1.2345e3');
  265. assertNumber('1.2345e-2');
  266. assertString('""');
  267. assertString('"hello world"');
  268. assertString('"hello # world"');
  269. assertString('"hello #\\" world"');
  270. assertString('"|"');
  271. assertString('"\\"\\""');
  272. assertString('"\\"foo\\""');
  273. assertString('"\\"foo\\" and \\"bar\\""');
  274. assertString('"foo \\"and\\" bar"');
  275. assertComment('# foo bar baz');
  276. assertComment('# foo ## bar baz');
  277. assertComment('# foo "bar" baz');
  278. }
  279. function testSerializationOfStringWithQuotes() {
  280. var nestedUnknown = new proto2.TestAllTypes();
  281. var message = new proto2.TestAllTypes();
  282. message.setOptionalString('hello "world"');
  283. // Serialize.
  284. var simplified = new goog.proto2.TextFormatSerializer().serialize(message);
  285. var expected = 'optional_string: "hello \\"world\\""\n';
  286. assertEquals(expected, simplified);
  287. }
  288. function testDeserialization() {
  289. var message = new proto2.TestAllTypes();
  290. var value = 'optional_int32: 101\n' +
  291. 'repeated_int32: 201\n' +
  292. 'repeated_int32: 202\n' +
  293. 'optional_float: 123.4';
  294. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  295. assertEquals(101, message.getOptionalInt32());
  296. assertEquals(201, message.getRepeatedInt32(0));
  297. assertEquals(202, message.getRepeatedInt32(1));
  298. assertEquals(123.4, message.getOptionalFloat());
  299. }
  300. function testDeserializationOfList() {
  301. var message = new proto2.TestAllTypes();
  302. var value = 'optional_int32: 101\n' +
  303. 'repeated_int32: [201, 202]\n' +
  304. 'optional_float: 123.4';
  305. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  306. assertEquals(101, message.getOptionalInt32());
  307. assertEquals(201, message.getRepeatedInt32(0));
  308. assertEquals(123.4, message.getOptionalFloat());
  309. }
  310. function testDeserializationOfIntegerAsHexadecimalString() {
  311. var message = new proto2.TestAllTypes();
  312. var value = 'optional_int32: 0x1\n' +
  313. 'optional_sint32: 0xf\n' +
  314. 'optional_uint32: 0xffffffff\n' +
  315. 'repeated_int32: [0x0, 0xff]\n';
  316. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  317. assertEquals(1, message.getOptionalInt32());
  318. assertEquals(15, message.getOptionalSint32());
  319. assertEquals(4294967295, message.getOptionalUint32());
  320. assertEquals(0, message.getRepeatedInt32(0));
  321. assertEquals(255, message.getRepeatedInt32(1));
  322. }
  323. function testDeserializationOfInt64AsHexadecimalString() {
  324. var message = new proto2.TestAllTypes();
  325. var value = 'optional_int64: 0xf';
  326. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  327. assertEquals('0xf', message.getOptionalInt64());
  328. }
  329. function testDeserializationOfZeroFalseAndEmptyString() {
  330. var message = new proto2.TestAllTypes();
  331. var value = 'optional_int32: 0\n' +
  332. 'optional_bool: false\n' +
  333. 'optional_string: ""';
  334. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  335. assertEquals(0, message.getOptionalInt32());
  336. assertEquals(false, message.getOptionalBool());
  337. assertEquals('', message.getOptionalString());
  338. }
  339. function testDeserializationOfConcatenatedString() {
  340. var message = new proto2.TestAllTypes();
  341. var value = 'optional_int32: 123\n' +
  342. 'optional_string:\n' +
  343. ' "FirstLine"\n' +
  344. ' "SecondLine"\n' +
  345. 'optional_float: 456.7';
  346. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  347. assertEquals(123, message.getOptionalInt32());
  348. assertEquals('FirstLineSecondLine', message.getOptionalString());
  349. assertEquals(456.7, message.getOptionalFloat());
  350. }
  351. function testDeserializationSkipComment() {
  352. var message = new proto2.TestAllTypes();
  353. var value = 'optional_int32: 101\n' +
  354. 'repeated_int32: 201\n' +
  355. '# Some comment.\n' +
  356. 'repeated_int32: 202\n' +
  357. 'optional_float: 123.4';
  358. var parser = new goog.proto2.TextFormatSerializer.Parser();
  359. assertTrue(parser.parse(message, value));
  360. assertEquals(101, message.getOptionalInt32());
  361. assertEquals(201, message.getRepeatedInt32(0));
  362. assertEquals(202, message.getRepeatedInt32(1));
  363. assertEquals(123.4, message.getOptionalFloat());
  364. }
  365. function testDeserializationSkipTrailingComment() {
  366. var message = new proto2.TestAllTypes();
  367. var value = 'optional_int32: 101\n' +
  368. 'repeated_int32: 201\n' +
  369. 'repeated_int32: 202 # Some trailing comment.\n' +
  370. 'optional_float: 123.4';
  371. var parser = new goog.proto2.TextFormatSerializer.Parser();
  372. assertTrue(parser.parse(message, value));
  373. assertEquals(101, message.getOptionalInt32());
  374. assertEquals(201, message.getRepeatedInt32(0));
  375. assertEquals(202, message.getRepeatedInt32(1));
  376. assertEquals(123.4, message.getOptionalFloat());
  377. }
  378. function testDeserializationSkipUnknown() {
  379. var message = new proto2.TestAllTypes();
  380. var value = 'optional_int32: 101\n' +
  381. 'repeated_int32: 201\n' +
  382. 'some_unknown: true\n' +
  383. 'repeated_int32: 202\n' +
  384. 'optional_float: 123.4';
  385. var parser = new goog.proto2.TextFormatSerializer.Parser();
  386. assertTrue(parser.parse(message, value, true));
  387. assertEquals(101, message.getOptionalInt32());
  388. assertEquals(201, message.getRepeatedInt32(0));
  389. assertEquals(202, message.getRepeatedInt32(1));
  390. assertEquals(123.4, message.getOptionalFloat());
  391. }
  392. function testDeserializationSkipUnknownList() {
  393. var message = new proto2.TestAllTypes();
  394. var value = 'optional_int32: 101\n' +
  395. 'repeated_int32: 201\n' +
  396. 'some_unknown: [true, 1, 201, "hello"]\n' +
  397. 'repeated_int32: 202\n' +
  398. 'optional_float: 123.4';
  399. var parser = new goog.proto2.TextFormatSerializer.Parser();
  400. assertTrue(parser.parse(message, value, true));
  401. assertEquals(101, message.getOptionalInt32());
  402. assertEquals(201, message.getRepeatedInt32(0));
  403. assertEquals(202, message.getRepeatedInt32(1));
  404. assertEquals(123.4, message.getOptionalFloat());
  405. }
  406. function testDeserializationSkipUnknownNested() {
  407. var message = new proto2.TestAllTypes();
  408. var value = 'optional_int32: 101\n' +
  409. 'repeated_int32: 201\n' +
  410. 'some_unknown: <\n' +
  411. ' a: 1\n' +
  412. ' b: 2\n' +
  413. '>\n' +
  414. 'repeated_int32: 202\n' +
  415. 'optional_float: 123.4';
  416. var parser = new goog.proto2.TextFormatSerializer.Parser();
  417. assertTrue(parser.parse(message, value, true));
  418. assertEquals(101, message.getOptionalInt32());
  419. assertEquals(201, message.getRepeatedInt32(0));
  420. assertEquals(202, message.getRepeatedInt32(1));
  421. assertEquals(123.4, message.getOptionalFloat());
  422. }
  423. function testDeserializationSkipUnknownNestedInvalid() {
  424. var message = new proto2.TestAllTypes();
  425. var value = 'optional_int32: 101\n' +
  426. 'repeated_int32: 201\n' +
  427. 'some_unknown: <\n' +
  428. ' a: \n' + // Missing value.
  429. ' b: 2\n' +
  430. '>\n' +
  431. 'repeated_int32: 202\n' +
  432. 'optional_float: 123.4';
  433. var parser = new goog.proto2.TextFormatSerializer.Parser();
  434. assertFalse(parser.parse(message, value, true));
  435. }
  436. function testDeserializationSkipUnknownNestedInvalid2() {
  437. var message = new proto2.TestAllTypes();
  438. var value = 'optional_int32: 101\n' +
  439. 'repeated_int32: 201\n' +
  440. 'some_unknown: <\n' +
  441. ' a: 2\n' +
  442. ' b: 2\n' +
  443. '}\n' + // Delimiter mismatch
  444. 'repeated_int32: 202\n' +
  445. 'optional_float: 123.4';
  446. var parser = new goog.proto2.TextFormatSerializer.Parser();
  447. assertFalse(parser.parse(message, value, true));
  448. }
  449. function testDeserializationLegacyFormat() {
  450. var message = new proto2.TestAllTypes();
  451. var value = 'optional_int32: 101,\n' +
  452. 'repeated_int32: 201,\n' +
  453. 'repeated_int32: 202;\n' +
  454. 'optional_float: 123.4';
  455. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  456. assertEquals(101, message.getOptionalInt32());
  457. assertEquals(201, message.getRepeatedInt32(0));
  458. assertEquals(202, message.getRepeatedInt32(1));
  459. assertEquals(123.4, message.getOptionalFloat());
  460. }
  461. function testDeserializationVariedNumbers() {
  462. var message = new proto2.TestAllTypes();
  463. var value =
  464. ('repeated_int32: 23\n' +
  465. 'repeated_int32: -3\n' +
  466. 'repeated_int32: 0xdeadbeef\n' +
  467. 'repeated_float: 123.0\n' +
  468. 'repeated_float: -3.27\n' +
  469. 'repeated_float: -35.5f\n');
  470. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  471. assertEquals(23, message.getRepeatedInt32(0));
  472. assertEquals(-3, message.getRepeatedInt32(1));
  473. assertEquals(3735928559, message.getRepeatedInt32(2));
  474. assertEquals(123.0, message.getRepeatedFloat(0));
  475. assertEquals(-3.27, message.getRepeatedFloat(1));
  476. assertEquals(-35.5, message.getRepeatedFloat(2));
  477. }
  478. function testDeserializationScientificNotation() {
  479. var message = new proto2.TestAllTypes();
  480. var value = 'repeated_float: 1.1e5\n' +
  481. 'repeated_float: 1.1e-5\n' +
  482. 'repeated_double: 1.1e5\n' +
  483. 'repeated_double: 1.1e-5\n';
  484. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  485. assertEquals(1.1e5, message.getRepeatedFloat(0));
  486. assertEquals(1.1e-5, message.getRepeatedFloat(1));
  487. assertEquals(1.1e5, message.getRepeatedDouble(0));
  488. assertEquals(1.1e-5, message.getRepeatedDouble(1));
  489. }
  490. function testParseNumericalConstant() {
  491. var parseNumericalConstant =
  492. goog.proto2.TextFormatSerializer.Parser.parseNumericalConstant_;
  493. assertEquals(Infinity, parseNumericalConstant('inf'));
  494. assertEquals(Infinity, parseNumericalConstant('inff'));
  495. assertEquals(Infinity, parseNumericalConstant('infinity'));
  496. assertEquals(Infinity, parseNumericalConstant('infinityf'));
  497. assertEquals(Infinity, parseNumericalConstant('Infinityf'));
  498. assertEquals(-Infinity, parseNumericalConstant('-inf'));
  499. assertEquals(-Infinity, parseNumericalConstant('-inff'));
  500. assertEquals(-Infinity, parseNumericalConstant('-infinity'));
  501. assertEquals(-Infinity, parseNumericalConstant('-infinityf'));
  502. assertEquals(-Infinity, parseNumericalConstant('-Infinity'));
  503. assertNull(parseNumericalConstant('-infin'));
  504. assertNull(parseNumericalConstant('infin'));
  505. assertNull(parseNumericalConstant('-infinite'));
  506. assertNull(parseNumericalConstant('-infin'));
  507. assertNull(parseNumericalConstant('infin'));
  508. assertNull(parseNumericalConstant('-infinite'));
  509. assertTrue(isNaN(parseNumericalConstant('Nan')));
  510. assertTrue(isNaN(parseNumericalConstant('NaN')));
  511. assertTrue(isNaN(parseNumericalConstant('NAN')));
  512. assertTrue(isNaN(parseNumericalConstant('nan')));
  513. assertTrue(isNaN(parseNumericalConstant('nanf')));
  514. assertTrue(isNaN(parseNumericalConstant('NaNf')));
  515. assertEquals(Number.POSITIVE_INFINITY, parseNumericalConstant('infinity'));
  516. assertEquals(Number.NEGATIVE_INFINITY, parseNumericalConstant('-inf'));
  517. assertEquals(Number.NEGATIVE_INFINITY, parseNumericalConstant('-infinity'));
  518. assertNull(parseNumericalConstant('na'));
  519. assertNull(parseNumericalConstant('-nan'));
  520. assertNull(parseNumericalConstant('none'));
  521. }
  522. function testDeserializationOfNumericalConstants() {
  523. var message = new proto2.TestAllTypes();
  524. var value =
  525. ('repeated_float: inf\n' +
  526. 'repeated_float: -inf\n' +
  527. 'repeated_float: nan\n' +
  528. 'repeated_float: 300.2\n');
  529. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  530. assertEquals(Infinity, message.getRepeatedFloat(0));
  531. assertEquals(-Infinity, message.getRepeatedFloat(1));
  532. assertTrue(isNaN(message.getRepeatedFloat(2)));
  533. assertEquals(300.2, message.getRepeatedFloat(3));
  534. }
  535. var floatFormatCases = [
  536. {given: '1.69e+06', expect: 1.69e+06}, {given: '1.69e6', expect: 1.69e+06},
  537. {given: '2.468e-2', expect: 0.02468}
  538. ];
  539. function testGetNumberFromStringExponentialNotation() {
  540. for (var i = 0; i < floatFormatCases.length; ++i) {
  541. var thistest = floatFormatCases[i];
  542. var result = goog.proto2.TextFormatSerializer.Parser.getNumberFromString_(
  543. thistest.given);
  544. assertEquals(thistest.expect, result);
  545. }
  546. }
  547. function testDeserializationExponentialFloat() {
  548. var parser = new goog.proto2.TextFormatSerializer.Parser();
  549. for (var i = 0; i < floatFormatCases.length; ++i) {
  550. var thistest = floatFormatCases[i];
  551. var message = new proto2.TestAllTypes();
  552. var value = 'optional_float: ' + thistest.given;
  553. assertTrue(parser.parse(message, value, true));
  554. assertEquals(thistest.expect, message.getOptionalFloat());
  555. }
  556. }
  557. function testGetNumberFromString() {
  558. var getNumberFromString =
  559. goog.proto2.TextFormatSerializer.Parser.getNumberFromString_;
  560. assertEquals(3735928559, getNumberFromString('0xdeadbeef'));
  561. assertEquals(4276215469, getNumberFromString('0xFEE1DEAD'));
  562. assertEquals(123.1, getNumberFromString('123.1'));
  563. assertEquals(123.0, getNumberFromString('123.0'));
  564. assertEquals(-29.3, getNumberFromString('-29.3f'));
  565. assertEquals(23, getNumberFromString('23'));
  566. assertEquals(-3, getNumberFromString('-3'));
  567. assertEquals(-3.27, getNumberFromString('-3.27'));
  568. assertThrows(goog.partial(getNumberFromString, 'cat'));
  569. assertThrows(goog.partial(getNumberFromString, 'NaN'));
  570. assertThrows(goog.partial(getNumberFromString, 'inf'));
  571. }
  572. function testDeserializationError() {
  573. var message = new proto2.TestAllTypes();
  574. var value = 'optional_int33: 101\n';
  575. var result =
  576. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  577. assertEquals(result, 'Unknown field: optional_int33');
  578. }
  579. function testNestedDeserialization() {
  580. var message = new proto2.TestAllTypes();
  581. var value = 'optional_int32: 101\n' +
  582. 'optional_nested_message: {\n' +
  583. ' b: 301\n' +
  584. '}';
  585. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  586. assertEquals(101, message.getOptionalInt32());
  587. assertEquals(301, message.getOptionalNestedMessage().getB());
  588. }
  589. function testNestedDeserializationLegacyFormat() {
  590. var message = new proto2.TestAllTypes();
  591. var value = 'optional_int32: 101\n' +
  592. 'optional_nested_message: <\n' +
  593. ' b: 301\n' +
  594. '>';
  595. new goog.proto2.TextFormatSerializer().deserializeTo(message, value);
  596. assertEquals(101, message.getOptionalInt32());
  597. assertEquals(301, message.getOptionalNestedMessage().getB());
  598. }
  599. function testBidirectional() {
  600. var message = new proto2.TestAllTypes();
  601. // Set the fields.
  602. // Singular.
  603. message.setOptionalInt32(101);
  604. message.setOptionalInt64('102');
  605. message.setOptionalUint32(103);
  606. message.setOptionalUint64('104');
  607. message.setOptionalSint32(105);
  608. message.setOptionalSint64('106');
  609. message.setOptionalFixed32(107);
  610. message.setOptionalFixed64('108');
  611. message.setOptionalSfixed32(109);
  612. message.setOptionalSfixed64('110');
  613. message.setOptionalFloat(111.5);
  614. message.setOptionalDouble(112.5);
  615. message.setOptionalBool(true);
  616. message.setOptionalString('test');
  617. message.setOptionalBytes('abcd');
  618. var group = new proto2.TestAllTypes.OptionalGroup();
  619. group.setA(111);
  620. message.setOptionalgroup(group);
  621. var nestedMessage = new proto2.TestAllTypes.NestedMessage();
  622. nestedMessage.setB(112);
  623. message.setOptionalNestedMessage(nestedMessage);
  624. message.setOptionalNestedEnum(proto2.TestAllTypes.NestedEnum.FOO);
  625. // Repeated.
  626. message.addRepeatedInt32(201);
  627. message.addRepeatedInt32(202);
  628. message.addRepeatedString('hello "world"');
  629. // Serialize the message to text form.
  630. var serializer = new goog.proto2.TextFormatSerializer();
  631. var textform = serializer.serialize(message);
  632. // Create a copy and deserialize into the copy.
  633. var copy = new proto2.TestAllTypes();
  634. serializer.deserializeTo(copy, textform);
  635. // Assert that the messages are structurally equivalent.
  636. assertTrue(copy.equals(message));
  637. }
  638. function testBidirectional64BitNumber() {
  639. var message = new proto2.TestAllTypes();
  640. message.setOptionalInt64Number(10000000);
  641. message.setOptionalInt64String('200000000000000000');
  642. // Serialize the message to text form.
  643. var serializer = new goog.proto2.TextFormatSerializer();
  644. var textform = serializer.serialize(message);
  645. // Create a copy and deserialize into the copy.
  646. var copy = new proto2.TestAllTypes();
  647. serializer.deserializeTo(copy, textform);
  648. // Assert that the messages are structurally equivalent.
  649. assertTrue(copy.equals(message));
  650. }
  651. function testUseEnumValues() {
  652. var message = new proto2.TestAllTypes();
  653. message.setOptionalNestedEnum(proto2.TestAllTypes.NestedEnum.FOO);
  654. var serializer = new goog.proto2.TextFormatSerializer(false, true);
  655. var textform = serializer.serialize(message);
  656. var expected = 'optional_nested_enum: 0\n';
  657. assertEquals(expected, textform);
  658. var deserializedMessage = new proto2.TestAllTypes();
  659. serializer.deserializeTo(deserializedMessage, textform);
  660. assertEquals(
  661. proto2.TestAllTypes.NestedEnum.FOO,
  662. deserializedMessage.getOptionalNestedEnum());
  663. }