/thirdparty/breakpad/third_party/protobuf/protobuf/java/src/test/java/com/google/protobuf/TextFormatTest.java

http://github.com/tomahawk-player/tomahawk · Java · 752 lines · 583 code · 81 blank · 88 comment · 1 complexity · 02346b7399543b84042764b6b8bd02dc MD5 · raw file

  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // http://code.google.com/p/protobuf/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. package com.google.protobuf;
  31. import com.google.protobuf.Descriptors.FieldDescriptor;
  32. import protobuf_unittest.UnittestMset.TestMessageSet;
  33. import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
  34. import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
  35. import protobuf_unittest.UnittestProto.OneString;
  36. import protobuf_unittest.UnittestProto.TestAllExtensions;
  37. import protobuf_unittest.UnittestProto.TestAllTypes;
  38. import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
  39. import protobuf_unittest.UnittestProto.TestEmptyMessage;
  40. import junit.framework.TestCase;
  41. import java.io.StringReader;
  42. /**
  43. * Test case for {@link TextFormat}.
  44. *
  45. * TODO(wenboz): ExtensionTest and rest of text_format_unittest.cc.
  46. *
  47. * @author wenboz@google.com (Wenbo Zhu)
  48. */
  49. public class TextFormatTest extends TestCase {
  50. // A basic string with different escapable characters for testing.
  51. private final static String kEscapeTestString =
  52. "\"A string with ' characters \n and \r newlines and \t tabs and \001 "
  53. + "slashes \\";
  54. // A representation of the above string with all the characters escaped.
  55. private final static String kEscapeTestStringEscaped =
  56. "\\\"A string with \\' characters \\n and \\r newlines "
  57. + "and \\t tabs and \\001 slashes \\\\";
  58. private static String allFieldsSetText = TestUtil.readTextFromFile(
  59. "text_format_unittest_data.txt");
  60. private static String allExtensionsSetText = TestUtil.readTextFromFile(
  61. "text_format_unittest_extensions_data.txt");
  62. private static String exoticText =
  63. "repeated_int32: -1\n" +
  64. "repeated_int32: -2147483648\n" +
  65. "repeated_int64: -1\n" +
  66. "repeated_int64: -9223372036854775808\n" +
  67. "repeated_uint32: 4294967295\n" +
  68. "repeated_uint32: 2147483648\n" +
  69. "repeated_uint64: 18446744073709551615\n" +
  70. "repeated_uint64: 9223372036854775808\n" +
  71. "repeated_double: 123.0\n" +
  72. "repeated_double: 123.5\n" +
  73. "repeated_double: 0.125\n" +
  74. "repeated_double: .125\n" +
  75. "repeated_double: -.125\n" +
  76. "repeated_double: 1.23E17\n" +
  77. "repeated_double: 1.23E+17\n" +
  78. "repeated_double: -1.23e-17\n" +
  79. "repeated_double: .23e+17\n" +
  80. "repeated_double: -.23E17\n" +
  81. "repeated_double: 1.235E22\n" +
  82. "repeated_double: 1.235E-18\n" +
  83. "repeated_double: 123.456789\n" +
  84. "repeated_double: Infinity\n" +
  85. "repeated_double: -Infinity\n" +
  86. "repeated_double: NaN\n" +
  87. "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"" +
  88. "\\341\\210\\264\"\n" +
  89. "repeated_bytes: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\376\"\n";
  90. private static String canonicalExoticText =
  91. exoticText.replace(": .", ": 0.").replace(": -.", ": -0.") // short-form double
  92. .replace("23e", "23E").replace("E+", "E").replace("0.23E17", "2.3E16");
  93. private String messageSetText =
  94. "[protobuf_unittest.TestMessageSetExtension1] {\n" +
  95. " i: 123\n" +
  96. "}\n" +
  97. "[protobuf_unittest.TestMessageSetExtension2] {\n" +
  98. " str: \"foo\"\n" +
  99. "}\n";
  100. /** Print TestAllTypes and compare with golden file. */
  101. public void testPrintMessage() throws Exception {
  102. String javaText = TextFormat.printToString(TestUtil.getAllSet());
  103. // Java likes to add a trailing ".0" to floats and doubles. C printf
  104. // (with %g format) does not. Our golden files are used for both
  105. // C++ and Java TextFormat classes, so we need to conform.
  106. javaText = javaText.replace(".0\n", "\n");
  107. assertEquals(allFieldsSetText, javaText);
  108. }
  109. /** Print TestAllExtensions and compare with golden file. */
  110. public void testPrintExtensions() throws Exception {
  111. String javaText = TextFormat.printToString(TestUtil.getAllExtensionsSet());
  112. // Java likes to add a trailing ".0" to floats and doubles. C printf
  113. // (with %g format) does not. Our golden files are used for both
  114. // C++ and Java TextFormat classes, so we need to conform.
  115. javaText = javaText.replace(".0\n", "\n");
  116. assertEquals(allExtensionsSetText, javaText);
  117. }
  118. // Creates an example unknown field set.
  119. private UnknownFieldSet makeUnknownFieldSet() {
  120. return UnknownFieldSet.newBuilder()
  121. .addField(5,
  122. UnknownFieldSet.Field.newBuilder()
  123. .addVarint(1)
  124. .addFixed32(2)
  125. .addFixed64(3)
  126. .addLengthDelimited(ByteString.copyFromUtf8("4"))
  127. .addGroup(
  128. UnknownFieldSet.newBuilder()
  129. .addField(10,
  130. UnknownFieldSet.Field.newBuilder()
  131. .addVarint(5)
  132. .build())
  133. .build())
  134. .build())
  135. .addField(8,
  136. UnknownFieldSet.Field.newBuilder()
  137. .addVarint(1)
  138. .addVarint(2)
  139. .addVarint(3)
  140. .build())
  141. .addField(15,
  142. UnknownFieldSet.Field.newBuilder()
  143. .addVarint(0xABCDEF1234567890L)
  144. .addFixed32(0xABCD1234)
  145. .addFixed64(0xABCDEF1234567890L)
  146. .build())
  147. .build();
  148. }
  149. public void testPrintUnknownFields() throws Exception {
  150. // Test printing of unknown fields in a message.
  151. TestEmptyMessage message =
  152. TestEmptyMessage.newBuilder()
  153. .setUnknownFields(makeUnknownFieldSet())
  154. .build();
  155. assertEquals(
  156. "5: 1\n" +
  157. "5: 0x00000002\n" +
  158. "5: 0x0000000000000003\n" +
  159. "5: \"4\"\n" +
  160. "5 {\n" +
  161. " 10: 5\n" +
  162. "}\n" +
  163. "8: 1\n" +
  164. "8: 2\n" +
  165. "8: 3\n" +
  166. "15: 12379813812177893520\n" +
  167. "15: 0xabcd1234\n" +
  168. "15: 0xabcdef1234567890\n",
  169. TextFormat.printToString(message));
  170. }
  171. public void testPrintField() throws Exception {
  172. final FieldDescriptor dataField =
  173. OneString.getDescriptor().findFieldByName("data");
  174. assertEquals(
  175. "data: \"test data\"\n",
  176. TextFormat.printFieldToString(dataField, "test data"));
  177. final FieldDescriptor optionalField =
  178. TestAllTypes.getDescriptor().findFieldByName("optional_nested_message");
  179. final Object value = NestedMessage.newBuilder().setBb(42).build();
  180. assertEquals(
  181. "optional_nested_message {\n bb: 42\n}\n",
  182. TextFormat.printFieldToString(optionalField, value));
  183. }
  184. /**
  185. * Helper to construct a ByteString from a String containing only 8-bit
  186. * characters. The characters are converted directly to bytes, *not*
  187. * encoded using UTF-8.
  188. */
  189. private ByteString bytes(String str) throws Exception {
  190. return ByteString.copyFrom(str.getBytes("ISO-8859-1"));
  191. }
  192. /**
  193. * Helper to construct a ByteString from a bunch of bytes. The inputs are
  194. * actually ints so that I can use hex notation and not get stupid errors
  195. * about precision.
  196. */
  197. private ByteString bytes(int... bytesAsInts) {
  198. byte[] bytes = new byte[bytesAsInts.length];
  199. for (int i = 0; i < bytesAsInts.length; i++) {
  200. bytes[i] = (byte) bytesAsInts[i];
  201. }
  202. return ByteString.copyFrom(bytes);
  203. }
  204. public void testPrintExotic() throws Exception {
  205. Message message = TestAllTypes.newBuilder()
  206. // Signed vs. unsigned numbers.
  207. .addRepeatedInt32 (-1)
  208. .addRepeatedUint32(-1)
  209. .addRepeatedInt64 (-1)
  210. .addRepeatedUint64(-1)
  211. .addRepeatedInt32 (1 << 31)
  212. .addRepeatedUint32(1 << 31)
  213. .addRepeatedInt64 (1l << 63)
  214. .addRepeatedUint64(1l << 63)
  215. // Floats of various precisions and exponents.
  216. .addRepeatedDouble(123)
  217. .addRepeatedDouble(123.5)
  218. .addRepeatedDouble(0.125)
  219. .addRepeatedDouble(.125)
  220. .addRepeatedDouble(-.125)
  221. .addRepeatedDouble(123e15)
  222. .addRepeatedDouble(123e15)
  223. .addRepeatedDouble(-1.23e-17)
  224. .addRepeatedDouble(.23e17)
  225. .addRepeatedDouble(-23e15)
  226. .addRepeatedDouble(123.5e20)
  227. .addRepeatedDouble(123.5e-20)
  228. .addRepeatedDouble(123.456789)
  229. .addRepeatedDouble(Double.POSITIVE_INFINITY)
  230. .addRepeatedDouble(Double.NEGATIVE_INFINITY)
  231. .addRepeatedDouble(Double.NaN)
  232. // Strings and bytes that needing escaping.
  233. .addRepeatedString("\0\001\007\b\f\n\r\t\013\\\'\"\u1234")
  234. .addRepeatedBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"\u00fe"))
  235. .build();
  236. assertEquals(canonicalExoticText, message.toString());
  237. }
  238. public void testPrintMessageSet() throws Exception {
  239. TestMessageSet messageSet =
  240. TestMessageSet.newBuilder()
  241. .setExtension(
  242. TestMessageSetExtension1.messageSetExtension,
  243. TestMessageSetExtension1.newBuilder().setI(123).build())
  244. .setExtension(
  245. TestMessageSetExtension2.messageSetExtension,
  246. TestMessageSetExtension2.newBuilder().setStr("foo").build())
  247. .build();
  248. assertEquals(messageSetText, messageSet.toString());
  249. }
  250. // =================================================================
  251. public void testParse() throws Exception {
  252. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  253. TextFormat.merge(allFieldsSetText, builder);
  254. TestUtil.assertAllFieldsSet(builder.build());
  255. }
  256. public void testParseReader() throws Exception {
  257. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  258. TextFormat.merge(new StringReader(allFieldsSetText), builder);
  259. TestUtil.assertAllFieldsSet(builder.build());
  260. }
  261. public void testParseExtensions() throws Exception {
  262. TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
  263. TextFormat.merge(allExtensionsSetText,
  264. TestUtil.getExtensionRegistry(),
  265. builder);
  266. TestUtil.assertAllExtensionsSet(builder.build());
  267. }
  268. public void testParseCompatibility() throws Exception {
  269. String original = "repeated_float: inf\n" +
  270. "repeated_float: -inf\n" +
  271. "repeated_float: nan\n" +
  272. "repeated_float: inff\n" +
  273. "repeated_float: -inff\n" +
  274. "repeated_float: nanf\n" +
  275. "repeated_float: 1.0f\n" +
  276. "repeated_float: infinityf\n" +
  277. "repeated_float: -Infinityf\n" +
  278. "repeated_double: infinity\n" +
  279. "repeated_double: -infinity\n" +
  280. "repeated_double: nan\n";
  281. String canonical = "repeated_float: Infinity\n" +
  282. "repeated_float: -Infinity\n" +
  283. "repeated_float: NaN\n" +
  284. "repeated_float: Infinity\n" +
  285. "repeated_float: -Infinity\n" +
  286. "repeated_float: NaN\n" +
  287. "repeated_float: 1.0\n" +
  288. "repeated_float: Infinity\n" +
  289. "repeated_float: -Infinity\n" +
  290. "repeated_double: Infinity\n" +
  291. "repeated_double: -Infinity\n" +
  292. "repeated_double: NaN\n";
  293. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  294. TextFormat.merge(original, builder);
  295. assertEquals(canonical, builder.build().toString());
  296. }
  297. public void testParseExotic() throws Exception {
  298. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  299. TextFormat.merge(exoticText, builder);
  300. // Too lazy to check things individually. Don't try to debug this
  301. // if testPrintExotic() is failing.
  302. assertEquals(canonicalExoticText, builder.build().toString());
  303. }
  304. public void testParseMessageSet() throws Exception {
  305. ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
  306. extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
  307. extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
  308. TestMessageSet.Builder builder = TestMessageSet.newBuilder();
  309. TextFormat.merge(messageSetText, extensionRegistry, builder);
  310. TestMessageSet messageSet = builder.build();
  311. assertTrue(messageSet.hasExtension(
  312. TestMessageSetExtension1.messageSetExtension));
  313. assertEquals(123, messageSet.getExtension(
  314. TestMessageSetExtension1.messageSetExtension).getI());
  315. assertTrue(messageSet.hasExtension(
  316. TestMessageSetExtension2.messageSetExtension));
  317. assertEquals("foo", messageSet.getExtension(
  318. TestMessageSetExtension2.messageSetExtension).getStr());
  319. }
  320. public void testParseNumericEnum() throws Exception {
  321. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  322. TextFormat.merge("optional_nested_enum: 2", builder);
  323. assertEquals(TestAllTypes.NestedEnum.BAR, builder.getOptionalNestedEnum());
  324. }
  325. public void testParseAngleBrackets() throws Exception {
  326. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  327. TextFormat.merge("OptionalGroup: < a: 1 >", builder);
  328. assertTrue(builder.hasOptionalGroup());
  329. assertEquals(1, builder.getOptionalGroup().getA());
  330. }
  331. public void testParseComment() throws Exception {
  332. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  333. TextFormat.merge(
  334. "# this is a comment\n" +
  335. "optional_int32: 1 # another comment\n" +
  336. "optional_int64: 2\n" +
  337. "# EOF comment", builder);
  338. assertEquals(1, builder.getOptionalInt32());
  339. assertEquals(2, builder.getOptionalInt64());
  340. }
  341. private void assertParseError(String error, String text) {
  342. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  343. try {
  344. TextFormat.merge(text, TestUtil.getExtensionRegistry(), builder);
  345. fail("Expected parse exception.");
  346. } catch (TextFormat.ParseException e) {
  347. assertEquals(error, e.getMessage());
  348. }
  349. }
  350. public void testParseErrors() throws Exception {
  351. assertParseError(
  352. "1:16: Expected \":\".",
  353. "optional_int32 123");
  354. assertParseError(
  355. "1:23: Expected identifier.",
  356. "optional_nested_enum: ?");
  357. assertParseError(
  358. "1:18: Couldn't parse integer: Number must be positive: -1",
  359. "optional_uint32: -1");
  360. assertParseError(
  361. "1:17: Couldn't parse integer: Number out of range for 32-bit signed " +
  362. "integer: 82301481290849012385230157",
  363. "optional_int32: 82301481290849012385230157");
  364. assertParseError(
  365. "1:16: Expected \"true\" or \"false\".",
  366. "optional_bool: maybe");
  367. assertParseError(
  368. "1:16: Expected \"true\" or \"false\".",
  369. "optional_bool: 2");
  370. assertParseError(
  371. "1:18: Expected string.",
  372. "optional_string: 123");
  373. assertParseError(
  374. "1:18: String missing ending quote.",
  375. "optional_string: \"ueoauaoe");
  376. assertParseError(
  377. "1:18: String missing ending quote.",
  378. "optional_string: \"ueoauaoe\n" +
  379. "optional_int32: 123");
  380. assertParseError(
  381. "1:18: Invalid escape sequence: '\\z'",
  382. "optional_string: \"\\z\"");
  383. assertParseError(
  384. "1:18: String missing ending quote.",
  385. "optional_string: \"ueoauaoe\n" +
  386. "optional_int32: 123");
  387. assertParseError(
  388. "1:2: Extension \"nosuchext\" not found in the ExtensionRegistry.",
  389. "[nosuchext]: 123");
  390. assertParseError(
  391. "1:20: Extension \"protobuf_unittest.optional_int32_extension\" does " +
  392. "not extend message type \"protobuf_unittest.TestAllTypes\".",
  393. "[protobuf_unittest.optional_int32_extension]: 123");
  394. assertParseError(
  395. "1:1: Message type \"protobuf_unittest.TestAllTypes\" has no field " +
  396. "named \"nosuchfield\".",
  397. "nosuchfield: 123");
  398. assertParseError(
  399. "1:21: Expected \">\".",
  400. "OptionalGroup < a: 1");
  401. assertParseError(
  402. "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
  403. "value named \"NO_SUCH_VALUE\".",
  404. "optional_nested_enum: NO_SUCH_VALUE");
  405. assertParseError(
  406. "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
  407. "value with number 123.",
  408. "optional_nested_enum: 123");
  409. // Delimiters must match.
  410. assertParseError(
  411. "1:22: Expected identifier.",
  412. "OptionalGroup < a: 1 }");
  413. assertParseError(
  414. "1:22: Expected identifier.",
  415. "OptionalGroup { a: 1 >");
  416. }
  417. // =================================================================
  418. public void testEscape() throws Exception {
  419. // Escape sequences.
  420. assertEquals("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
  421. TextFormat.escapeBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"")));
  422. assertEquals("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
  423. TextFormat.escapeText("\0\001\007\b\f\n\r\t\013\\\'\""));
  424. assertEquals(bytes("\0\001\007\b\f\n\r\t\013\\\'\""),
  425. TextFormat.unescapeBytes("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
  426. assertEquals("\0\001\007\b\f\n\r\t\013\\\'\"",
  427. TextFormat.unescapeText("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
  428. assertEquals(kEscapeTestStringEscaped,
  429. TextFormat.escapeText(kEscapeTestString));
  430. assertEquals(kEscapeTestString,
  431. TextFormat.unescapeText(kEscapeTestStringEscaped));
  432. // Unicode handling.
  433. assertEquals("\\341\\210\\264", TextFormat.escapeText("\u1234"));
  434. assertEquals("\\341\\210\\264",
  435. TextFormat.escapeBytes(bytes(0xe1, 0x88, 0xb4)));
  436. assertEquals("\u1234", TextFormat.unescapeText("\\341\\210\\264"));
  437. assertEquals(bytes(0xe1, 0x88, 0xb4),
  438. TextFormat.unescapeBytes("\\341\\210\\264"));
  439. assertEquals("\u1234", TextFormat.unescapeText("\\xe1\\x88\\xb4"));
  440. assertEquals(bytes(0xe1, 0x88, 0xb4),
  441. TextFormat.unescapeBytes("\\xe1\\x88\\xb4"));
  442. // Handling of strings with unescaped Unicode characters > 255.
  443. final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c";
  444. ByteString zhByteString = ByteString.copyFromUtf8(zh);
  445. assertEquals(zhByteString, TextFormat.unescapeBytes(zh));
  446. // Errors.
  447. try {
  448. TextFormat.unescapeText("\\x");
  449. fail("Should have thrown an exception.");
  450. } catch (TextFormat.InvalidEscapeSequenceException e) {
  451. // success
  452. }
  453. try {
  454. TextFormat.unescapeText("\\z");
  455. fail("Should have thrown an exception.");
  456. } catch (TextFormat.InvalidEscapeSequenceException e) {
  457. // success
  458. }
  459. try {
  460. TextFormat.unescapeText("\\");
  461. fail("Should have thrown an exception.");
  462. } catch (TextFormat.InvalidEscapeSequenceException e) {
  463. // success
  464. }
  465. }
  466. public void testParseInteger() throws Exception {
  467. assertEquals( 0, TextFormat.parseInt32( "0"));
  468. assertEquals( 1, TextFormat.parseInt32( "1"));
  469. assertEquals( -1, TextFormat.parseInt32( "-1"));
  470. assertEquals( 12345, TextFormat.parseInt32( "12345"));
  471. assertEquals( -12345, TextFormat.parseInt32( "-12345"));
  472. assertEquals( 2147483647, TextFormat.parseInt32( "2147483647"));
  473. assertEquals(-2147483648, TextFormat.parseInt32("-2147483648"));
  474. assertEquals( 0, TextFormat.parseUInt32( "0"));
  475. assertEquals( 1, TextFormat.parseUInt32( "1"));
  476. assertEquals( 12345, TextFormat.parseUInt32( "12345"));
  477. assertEquals( 2147483647, TextFormat.parseUInt32("2147483647"));
  478. assertEquals((int) 2147483648L, TextFormat.parseUInt32("2147483648"));
  479. assertEquals((int) 4294967295L, TextFormat.parseUInt32("4294967295"));
  480. assertEquals( 0L, TextFormat.parseInt64( "0"));
  481. assertEquals( 1L, TextFormat.parseInt64( "1"));
  482. assertEquals( -1L, TextFormat.parseInt64( "-1"));
  483. assertEquals( 12345L, TextFormat.parseInt64( "12345"));
  484. assertEquals( -12345L, TextFormat.parseInt64( "-12345"));
  485. assertEquals( 2147483647L, TextFormat.parseInt64( "2147483647"));
  486. assertEquals(-2147483648L, TextFormat.parseInt64("-2147483648"));
  487. assertEquals( 4294967295L, TextFormat.parseInt64( "4294967295"));
  488. assertEquals( 4294967296L, TextFormat.parseInt64( "4294967296"));
  489. assertEquals(9223372036854775807L,
  490. TextFormat.parseInt64("9223372036854775807"));
  491. assertEquals(-9223372036854775808L,
  492. TextFormat.parseInt64("-9223372036854775808"));
  493. assertEquals( 0L, TextFormat.parseUInt64( "0"));
  494. assertEquals( 1L, TextFormat.parseUInt64( "1"));
  495. assertEquals( 12345L, TextFormat.parseUInt64( "12345"));
  496. assertEquals( 2147483647L, TextFormat.parseUInt64( "2147483647"));
  497. assertEquals( 4294967295L, TextFormat.parseUInt64( "4294967295"));
  498. assertEquals( 4294967296L, TextFormat.parseUInt64( "4294967296"));
  499. assertEquals(9223372036854775807L,
  500. TextFormat.parseUInt64("9223372036854775807"));
  501. assertEquals(-9223372036854775808L,
  502. TextFormat.parseUInt64("9223372036854775808"));
  503. assertEquals(-1L, TextFormat.parseUInt64("18446744073709551615"));
  504. // Hex
  505. assertEquals(0x1234abcd, TextFormat.parseInt32("0x1234abcd"));
  506. assertEquals(-0x1234abcd, TextFormat.parseInt32("-0x1234abcd"));
  507. assertEquals(-1, TextFormat.parseUInt64("0xffffffffffffffff"));
  508. assertEquals(0x7fffffffffffffffL,
  509. TextFormat.parseInt64("0x7fffffffffffffff"));
  510. // Octal
  511. assertEquals(01234567, TextFormat.parseInt32("01234567"));
  512. // Out-of-range
  513. try {
  514. TextFormat.parseInt32("2147483648");
  515. fail("Should have thrown an exception.");
  516. } catch (NumberFormatException e) {
  517. // success
  518. }
  519. try {
  520. TextFormat.parseInt32("-2147483649");
  521. fail("Should have thrown an exception.");
  522. } catch (NumberFormatException e) {
  523. // success
  524. }
  525. try {
  526. TextFormat.parseUInt32("4294967296");
  527. fail("Should have thrown an exception.");
  528. } catch (NumberFormatException e) {
  529. // success
  530. }
  531. try {
  532. TextFormat.parseUInt32("-1");
  533. fail("Should have thrown an exception.");
  534. } catch (NumberFormatException e) {
  535. // success
  536. }
  537. try {
  538. TextFormat.parseInt64("9223372036854775808");
  539. fail("Should have thrown an exception.");
  540. } catch (NumberFormatException e) {
  541. // success
  542. }
  543. try {
  544. TextFormat.parseInt64("-9223372036854775809");
  545. fail("Should have thrown an exception.");
  546. } catch (NumberFormatException e) {
  547. // success
  548. }
  549. try {
  550. TextFormat.parseUInt64("18446744073709551616");
  551. fail("Should have thrown an exception.");
  552. } catch (NumberFormatException e) {
  553. // success
  554. }
  555. try {
  556. TextFormat.parseUInt64("-1");
  557. fail("Should have thrown an exception.");
  558. } catch (NumberFormatException e) {
  559. // success
  560. }
  561. // Not a number.
  562. try {
  563. TextFormat.parseInt32("abcd");
  564. fail("Should have thrown an exception.");
  565. } catch (NumberFormatException e) {
  566. // success
  567. }
  568. }
  569. public void testParseString() throws Exception {
  570. final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c";
  571. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  572. TextFormat.merge("optional_string: \"" + zh + "\"", builder);
  573. assertEquals(zh, builder.getOptionalString());
  574. }
  575. public void testParseLongString() throws Exception {
  576. String longText =
  577. "123456789012345678901234567890123456789012345678901234567890" +
  578. "123456789012345678901234567890123456789012345678901234567890" +
  579. "123456789012345678901234567890123456789012345678901234567890" +
  580. "123456789012345678901234567890123456789012345678901234567890" +
  581. "123456789012345678901234567890123456789012345678901234567890" +
  582. "123456789012345678901234567890123456789012345678901234567890" +
  583. "123456789012345678901234567890123456789012345678901234567890" +
  584. "123456789012345678901234567890123456789012345678901234567890" +
  585. "123456789012345678901234567890123456789012345678901234567890" +
  586. "123456789012345678901234567890123456789012345678901234567890" +
  587. "123456789012345678901234567890123456789012345678901234567890" +
  588. "123456789012345678901234567890123456789012345678901234567890" +
  589. "123456789012345678901234567890123456789012345678901234567890" +
  590. "123456789012345678901234567890123456789012345678901234567890" +
  591. "123456789012345678901234567890123456789012345678901234567890" +
  592. "123456789012345678901234567890123456789012345678901234567890" +
  593. "123456789012345678901234567890123456789012345678901234567890" +
  594. "123456789012345678901234567890123456789012345678901234567890" +
  595. "123456789012345678901234567890123456789012345678901234567890" +
  596. "123456789012345678901234567890123456789012345678901234567890";
  597. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  598. TextFormat.merge("optional_string: \"" + longText + "\"", builder);
  599. assertEquals(longText, builder.getOptionalString());
  600. }
  601. public void testParseBoolean() throws Exception {
  602. String goodText =
  603. "repeated_bool: t repeated_bool : 0\n" +
  604. "repeated_bool :f repeated_bool:1";
  605. String goodTextCanonical =
  606. "repeated_bool: true\n" +
  607. "repeated_bool: false\n" +
  608. "repeated_bool: false\n" +
  609. "repeated_bool: true\n";
  610. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  611. TextFormat.merge(goodText, builder);
  612. assertEquals(goodTextCanonical, builder.build().toString());
  613. try {
  614. TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder();
  615. TextFormat.merge("optional_bool:2", badBuilder);
  616. fail("Should have thrown an exception.");
  617. } catch (TextFormat.ParseException e) {
  618. // success
  619. }
  620. try {
  621. TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder();
  622. TextFormat.merge("optional_bool: foo", badBuilder);
  623. fail("Should have thrown an exception.");
  624. } catch (TextFormat.ParseException e) {
  625. // success
  626. }
  627. }
  628. public void testParseAdjacentStringLiterals() throws Exception {
  629. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  630. TextFormat.merge("optional_string: \"foo\" 'corge' \"grault\"", builder);
  631. assertEquals("foocorgegrault", builder.getOptionalString());
  632. }
  633. public void testPrintFieldValue() throws Exception {
  634. assertPrintFieldValue("\"Hello\"", "Hello", "repeated_string");
  635. assertPrintFieldValue("123.0", 123f, "repeated_float");
  636. assertPrintFieldValue("123.0", 123d, "repeated_double");
  637. assertPrintFieldValue("123", 123, "repeated_int32");
  638. assertPrintFieldValue("123", 123L, "repeated_int64");
  639. assertPrintFieldValue("true", true, "repeated_bool");
  640. assertPrintFieldValue("4294967295", 0xFFFFFFFF, "repeated_uint32");
  641. assertPrintFieldValue("18446744073709551615", 0xFFFFFFFFFFFFFFFFL,
  642. "repeated_uint64");
  643. assertPrintFieldValue("\"\\001\\002\\003\"",
  644. ByteString.copyFrom(new byte[] {1, 2, 3}), "repeated_bytes");
  645. }
  646. private void assertPrintFieldValue(String expect, Object value,
  647. String fieldName) throws Exception {
  648. TestAllTypes.Builder builder = TestAllTypes.newBuilder();
  649. StringBuilder sb = new StringBuilder();
  650. TextFormat.printFieldValue(
  651. TestAllTypes.getDescriptor().findFieldByName(fieldName),
  652. value, sb);
  653. assertEquals(expect, sb.toString());
  654. }
  655. public void testShortDebugString() {
  656. assertEquals("optional_nested_message { bb: 42 } repeated_int32: 1"
  657. + " repeated_uint32: 2",
  658. TextFormat.shortDebugString(TestAllTypes.newBuilder()
  659. .addRepeatedInt32(1)
  660. .addRepeatedUint32(2)
  661. .setOptionalNestedMessage(
  662. NestedMessage.newBuilder().setBb(42).build())
  663. .build()));
  664. }
  665. public void testShortDebugString_unknown() {
  666. assertEquals("5: 1 5: 0x00000002 5: 0x0000000000000003 5: \"4\" 5 { 10: 5 }"
  667. + " 8: 1 8: 2 8: 3 15: 12379813812177893520 15: 0xabcd1234 15:"
  668. + " 0xabcdef1234567890",
  669. TextFormat.shortDebugString(makeUnknownFieldSet()));
  670. }
  671. }