TestWriterFormatJson.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using Google.ProtocolBuffers.Serialization;
  5. using Microsoft.VisualStudio.TestTools.UnitTesting;
  6. using Google.ProtocolBuffers.TestProtos;
  7. namespace Google.ProtocolBuffers
  8. {
  9. [TestClass]
  10. public class TestWriterFormatJson
  11. {
  12. [TestMethod]
  13. public void Example_FromJson()
  14. {
  15. TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder();
  16. //3.5: builder.MergeFromJson(@"{""valid"":true}");
  17. Extensions.MergeFromJson(builder, @"{""valid"":true}");
  18. TestXmlMessage message = builder.Build();
  19. Assert.AreEqual(true, message.Valid);
  20. }
  21. [TestMethod]
  22. public void Example_ToJson()
  23. {
  24. TestXmlMessage message =
  25. TestXmlMessage.CreateBuilder()
  26. .SetValid(true)
  27. .Build();
  28. //3.5: string json = message.ToJson();
  29. string json = Extensions.ToJson(message);
  30. Assert.AreEqual(@"{""valid"":true}", json);
  31. }
  32. [TestMethod]
  33. public void Example_WriteJsonUsingICodedOutputStream()
  34. {
  35. TestXmlMessage message =
  36. TestXmlMessage.CreateBuilder()
  37. .SetValid(true)
  38. .Build();
  39. using (TextWriter output = new StringWriter())
  40. {
  41. ICodedOutputStream writer = JsonFormatWriter.CreateInstance(output);
  42. writer.WriteMessageStart(); //manually begin the message, output is '{'
  43. writer.Flush();
  44. Assert.AreEqual("{", output.ToString());
  45. ICodedOutputStream stream = writer;
  46. message.WriteTo(stream); //write the message normally
  47. writer.Flush();
  48. Assert.AreEqual(@"{""valid"":true", output.ToString());
  49. writer.WriteMessageEnd(); //manually write the end message '}'
  50. Assert.AreEqual(@"{""valid"":true}", output.ToString());
  51. }
  52. }
  53. [TestMethod]
  54. public void Example_ReadJsonUsingICodedInputStream()
  55. {
  56. TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder();
  57. ICodedInputStream reader = JsonFormatReader.CreateInstance(@"{""valid"":true}");
  58. reader.ReadMessageStart(); //manually read the begin the message '{'
  59. builder.MergeFrom(reader); //write the message normally
  60. reader.ReadMessageEnd(); //manually read the end message '}'
  61. }
  62. protected string Content;
  63. [System.Diagnostics.DebuggerNonUserCode]
  64. protected void FormatterAssert<TMessage>(TMessage message, params string[] expecting) where TMessage : IMessageLite
  65. {
  66. StringWriter sw = new StringWriter();
  67. JsonFormatWriter.CreateInstance(sw).WriteMessage(message);
  68. Content = sw.ToString();
  69. ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
  70. UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry);
  71. IMessageLite copy =
  72. JsonFormatReader.CreateInstance(Content)
  73. .Merge(message.WeakCreateBuilderForType(), registry).WeakBuild();
  74. Assert.AreEqual(typeof(TMessage), copy.GetType());
  75. Assert.AreEqual(message, copy);
  76. foreach (string expect in expecting)
  77. Assert.IsTrue(Content.IndexOf(expect) >= 0, "Expected to find content '{0}' in: \r\n{1}", expect, Content);
  78. }
  79. [TestMethod]
  80. public void TestToJsonParseFromJson()
  81. {
  82. TestAllTypes msg = new TestAllTypes.Builder().SetDefaultBool(true).Build();
  83. string json = Extensions.ToJson(msg);
  84. Assert.AreEqual("{\"default_bool\":true}", json);
  85. TestAllTypes copy = Extensions.MergeFromJson(new TestAllTypes.Builder(), json).Build();
  86. Assert.IsTrue(copy.HasDefaultBool && copy.DefaultBool);
  87. Assert.AreEqual(msg, copy);
  88. }
  89. [TestMethod]
  90. public void TestToJsonParseFromJsonReader()
  91. {
  92. TestAllTypes msg = new TestAllTypes.Builder().SetDefaultBool(true).Build();
  93. string json = Extensions.ToJson(msg);
  94. Assert.AreEqual("{\"default_bool\":true}", json);
  95. TestAllTypes copy = Extensions.MergeFromJson(new TestAllTypes.Builder(), new StringReader(json)).Build();
  96. Assert.IsTrue(copy.HasDefaultBool && copy.DefaultBool);
  97. Assert.AreEqual(msg, copy);
  98. }
  99. [TestMethod]
  100. public void TestJsonFormatted()
  101. {
  102. TestXmlMessage message = TestXmlMessage.CreateBuilder()
  103. .SetValid(true)
  104. .SetNumber(0x1010)
  105. .AddChildren(TestXmlMessage.Types.Children.CreateBuilder())
  106. .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.ONE))
  107. .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.ONE).AddOptions(EnumOptions.TWO))
  108. .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().SetBinary(ByteString.CopyFromUtf8("abc")))
  109. .Build();
  110. StringWriter sw = new StringWriter();
  111. JsonFormatWriter.CreateInstance(sw).Formatted()
  112. .WriteMessage(message);
  113. string json = sw.ToString();
  114. TestXmlMessage copy = JsonFormatReader.CreateInstance(json)
  115. .Merge(TestXmlMessage.CreateBuilder()).Build();
  116. Assert.AreEqual(message, copy);
  117. }
  118. [TestMethod]
  119. public void TestEmptyMessage()
  120. {
  121. FormatterAssert(
  122. TestXmlChild.CreateBuilder()
  123. .Build(),
  124. @"{}"
  125. );
  126. }
  127. [TestMethod]
  128. public void TestRepeatedField()
  129. {
  130. FormatterAssert(
  131. TestXmlChild.CreateBuilder()
  132. .AddOptions(EnumOptions.ONE)
  133. .AddOptions(EnumOptions.TWO)
  134. .Build(),
  135. @"{""options"":[""ONE"",""TWO""]}"
  136. );
  137. }
  138. [TestMethod]
  139. public void TestNestedEmptyMessage()
  140. {
  141. FormatterAssert(
  142. TestXmlMessage.CreateBuilder()
  143. .SetChild(TestXmlChild.CreateBuilder().Build())
  144. .Build(),
  145. @"{""child"":{}}"
  146. );
  147. }
  148. [TestMethod]
  149. public void TestNestedMessage()
  150. {
  151. FormatterAssert(
  152. TestXmlMessage.CreateBuilder()
  153. .SetChild(TestXmlChild.CreateBuilder().AddOptions(EnumOptions.TWO).Build())
  154. .Build(),
  155. @"{""child"":{""options"":[""TWO""]}}"
  156. );
  157. }
  158. [TestMethod]
  159. public void TestBooleanTypes()
  160. {
  161. FormatterAssert(
  162. TestXmlMessage.CreateBuilder()
  163. .SetValid(true)
  164. .Build(),
  165. @"{""valid"":true}"
  166. );
  167. }
  168. [TestMethod]
  169. public void TestFullMessage()
  170. {
  171. FormatterAssert(
  172. TestXmlMessage.CreateBuilder()
  173. .SetValid(true)
  174. .SetText("text")
  175. .AddTextlines("a")
  176. .AddTextlines("b")
  177. .AddTextlines("c")
  178. .SetNumber(0x1010101010)
  179. .AddNumbers(1)
  180. .AddNumbers(2)
  181. .AddNumbers(3)
  182. .SetChild(TestXmlChild.CreateBuilder().AddOptions(EnumOptions.ONE).SetBinary(ByteString.CopyFrom(new byte[1])))
  183. .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.TWO).SetBinary(ByteString.CopyFrom(new byte[2])))
  184. .AddChildren(TestXmlMessage.Types.Children.CreateBuilder().AddOptions(EnumOptions.THREE).SetBinary(ByteString.CopyFrom(new byte[3])))
  185. .Build(),
  186. @"""text"":""text""",
  187. @"[""a"",""b"",""c""]",
  188. @"[1,2,3]",
  189. @"""child"":{",
  190. @"""children"":[{",
  191. @"AA==",
  192. @"AAA=",
  193. @"AAAA",
  194. 0x1010101010L.ToString()
  195. );
  196. }
  197. [TestMethod]
  198. public void TestMessageWithXmlText()
  199. {
  200. FormatterAssert(
  201. TestXmlMessage.CreateBuilder()
  202. .SetText("<text></text>")
  203. .Build(),
  204. @"{""text"":""<text><\/text>""}"
  205. );
  206. }
  207. [TestMethod]
  208. public void TestWithEscapeChars()
  209. {
  210. FormatterAssert(
  211. TestXmlMessage.CreateBuilder()
  212. .SetText(" \t <- \"leading space and trailing\" -> \\ \xef54 \x0000 \xFF \xFFFF \b \f \r \n \t ")
  213. .Build(),
  214. "{\"text\":\" \\t <- \\\"leading space and trailing\\\" -> \\\\ \\uef54 \\u0000 \\u00ff \\uffff \\b \\f \\r \\n \\t \"}"
  215. );
  216. }
  217. [TestMethod]
  218. public void TestWithExtensionText()
  219. {
  220. FormatterAssert(
  221. TestXmlMessage.CreateBuilder()
  222. .SetValid(false)
  223. .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionText, " extension text value ! ")
  224. .Build(),
  225. @"{""valid"":false,""extension_text"":"" extension text value ! ""}"
  226. );
  227. }
  228. [TestMethod]
  229. public void TestWithExtensionNumber()
  230. {
  231. FormatterAssert(
  232. TestXmlMessage.CreateBuilder()
  233. .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionMessage,
  234. new TestXmlExtension.Builder().SetNumber(42).Build())
  235. .Build(),
  236. @"{""number"":42}"
  237. );
  238. }
  239. [TestMethod]
  240. public void TestWithExtensionArray()
  241. {
  242. FormatterAssert(
  243. TestXmlMessage.CreateBuilder()
  244. .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 100)
  245. .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 101)
  246. .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 102)
  247. .Build(),
  248. @"{""extension_number"":[100,101,102]}"
  249. );
  250. }
  251. [TestMethod]
  252. public void TestWithExtensionEnum()
  253. {
  254. FormatterAssert(
  255. TestXmlMessage.CreateBuilder()
  256. .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionEnum, EnumOptions.ONE)
  257. .Build(),
  258. @"{""extension_enum"":""ONE""}"
  259. );
  260. }
  261. [TestMethod]
  262. public void TestMessageWithExtensions()
  263. {
  264. FormatterAssert(
  265. TestXmlMessage.CreateBuilder()
  266. .SetValid(true)
  267. .SetText("text")
  268. .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionText, "extension text")
  269. .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionMessage, new TestXmlExtension.Builder().SetNumber(42).Build())
  270. .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 100)
  271. .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 101)
  272. .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 102)
  273. .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionEnum, EnumOptions.ONE)
  274. .Build(),
  275. @"""text"":""text""",
  276. @"""valid"":true",
  277. @"""extension_enum"":""ONE""",
  278. @"""extension_text"":""extension text""",
  279. @"""extension_number"":[100,101,102]",
  280. @"""extension_message"":{""number"":42}"
  281. );
  282. }
  283. [TestMethod]
  284. public void TestMessageMissingExtensions()
  285. {
  286. TestXmlMessage original = TestXmlMessage.CreateBuilder()
  287. .SetValid(true)
  288. .SetText("text")
  289. .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionText, " extension text value ! ")
  290. .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionMessage, new TestXmlExtension.Builder().SetNumber(42).Build())
  291. .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 100)
  292. .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 101)
  293. .AddExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber, 102)
  294. .SetExtension(UnitTestXmlSerializerTestProtoFile.ExtensionEnum, EnumOptions.ONE)
  295. .Build();
  296. TestXmlMessage message = original.ToBuilder()
  297. .ClearExtension(UnitTestXmlSerializerTestProtoFile.ExtensionText)
  298. .ClearExtension(UnitTestXmlSerializerTestProtoFile.ExtensionMessage)
  299. .ClearExtension(UnitTestXmlSerializerTestProtoFile.ExtensionNumber)
  300. .ClearExtension(UnitTestXmlSerializerTestProtoFile.ExtensionEnum)
  301. .Build();
  302. JsonFormatWriter writer = JsonFormatWriter.CreateInstance();
  303. writer.WriteMessage(original);
  304. Content = writer.ToString();
  305. IMessageLite copy = JsonFormatReader.CreateInstance(Content)
  306. .Merge(message.CreateBuilderForType()).Build();
  307. Assert.AreNotEqual(original, message);
  308. Assert.AreNotEqual(original, copy);
  309. Assert.AreEqual(message, copy);
  310. }
  311. [TestMethod]
  312. public void TestMergeFields()
  313. {
  314. TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder();
  315. builder.MergeFrom(JsonFormatReader.CreateInstance("\"valid\": true"));
  316. builder.MergeFrom(JsonFormatReader.CreateInstance("\"text\": \"text\", \"number\": \"411\""));
  317. Assert.AreEqual(true, builder.Valid);
  318. Assert.AreEqual("text", builder.Text);
  319. Assert.AreEqual(411, builder.Number);
  320. }
  321. [TestMethod]
  322. public void TestMessageArray()
  323. {
  324. JsonFormatWriter writer = JsonFormatWriter.CreateInstance().Formatted();
  325. using (writer.StartArray())
  326. {
  327. writer.WriteMessage(TestXmlMessage.CreateBuilder().SetNumber(1).AddTextlines("a").Build());
  328. writer.WriteMessage(TestXmlMessage.CreateBuilder().SetNumber(2).AddTextlines("b").Build());
  329. writer.WriteMessage(TestXmlMessage.CreateBuilder().SetNumber(3).AddTextlines("c").Build());
  330. }
  331. string json = writer.ToString();
  332. JsonFormatReader reader = JsonFormatReader.CreateInstance(json);
  333. TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder();
  334. int ordinal = 0;
  335. foreach (JsonFormatReader r in reader.EnumerateArray())
  336. {
  337. r.Merge(builder);
  338. Assert.AreEqual(++ordinal, builder.Number);
  339. }
  340. Assert.AreEqual(3, ordinal);
  341. Assert.AreEqual(3, builder.TextlinesCount);
  342. }
  343. [TestMethod]
  344. public void TestNestedMessageArray()
  345. {
  346. JsonFormatWriter writer = JsonFormatWriter.CreateInstance();
  347. using (writer.StartArray())
  348. {
  349. using (writer.StartArray())
  350. {
  351. writer.WriteMessage(TestXmlMessage.CreateBuilder().SetNumber(1).AddTextlines("a").Build());
  352. writer.WriteMessage(TestXmlMessage.CreateBuilder().SetNumber(2).AddTextlines("b").Build());
  353. }
  354. using (writer.StartArray())
  355. writer.WriteMessage(TestXmlMessage.CreateBuilder().SetNumber(3).AddTextlines("c").Build());
  356. }
  357. string json = writer.ToString();
  358. JsonFormatReader reader = JsonFormatReader.CreateInstance(json);
  359. TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder();
  360. int ordinal = 0;
  361. foreach (JsonFormatReader r in reader.EnumerateArray())
  362. foreach (JsonFormatReader r2 in r.EnumerateArray())
  363. {
  364. r2.Merge(builder);
  365. Assert.AreEqual(++ordinal, builder.Number);
  366. }
  367. Assert.AreEqual(3, ordinal);
  368. Assert.AreEqual(3, builder.TextlinesCount);
  369. }
  370. [TestMethod]
  371. public void TestReadWriteJsonWithoutRoot()
  372. {
  373. TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder();
  374. TestXmlMessage message = builder.SetText("abc").SetNumber(123).Build();
  375. string Json;
  376. using (StringWriter sw = new StringWriter())
  377. {
  378. ICodedOutputStream output = JsonFormatWriter.CreateInstance(sw);
  379. message.WriteTo(output);
  380. output.Flush();
  381. Json = sw.ToString();
  382. }
  383. Assert.AreEqual(@"""text"":""abc"",""number"":123", Json);
  384. ICodedInputStream input = JsonFormatReader.CreateInstance(Json);
  385. TestXmlMessage copy = TestXmlMessage.CreateBuilder().MergeFrom(input).Build();
  386. Assert.AreEqual(message, copy);
  387. }
  388. [TestMethod,ExpectedException(typeof(RecursionLimitExceededException))]
  389. public void TestRecursiveLimit()
  390. {
  391. StringBuilder sb = new StringBuilder(8192);
  392. for (int i = 0; i < 80; i++)
  393. sb.Append("{\"child\":");
  394. TestXmlRescursive msg = Extensions.MergeFromJson(new TestXmlRescursive.Builder(), sb.ToString()).Build();
  395. }
  396. [TestMethod, ExpectedException(typeof(FormatException))]
  397. public void FailWithEmptyText()
  398. {
  399. JsonFormatReader.CreateInstance("")
  400. .Merge(TestXmlMessage.CreateBuilder());
  401. }
  402. [TestMethod, ExpectedException(typeof(FormatException))]
  403. public void FailWithUnexpectedValue()
  404. {
  405. JsonFormatReader.CreateInstance("{{}}")
  406. .Merge(TestXmlMessage.CreateBuilder());
  407. }
  408. [TestMethod, ExpectedException(typeof(FormatException))]
  409. public void FailWithUnQuotedName()
  410. {
  411. JsonFormatReader.CreateInstance("{name:{}}")
  412. .Merge(TestXmlMessage.CreateBuilder());
  413. }
  414. [TestMethod, ExpectedException(typeof(FormatException))]
  415. public void FailWithUnexpectedType()
  416. {
  417. JsonFormatReader.CreateInstance("{\"valid\":{}}")
  418. .Merge(TestXmlMessage.CreateBuilder());
  419. }
  420. }
  421. }