MessageTest.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Google.ProtocolBuffers.Descriptors;
  5. using Google.ProtocolBuffers.TestProtos;
  6. using NUnit.Framework;
  7. namespace Google.ProtocolBuffers {
  8. /// <summary>
  9. /// Miscellaneous tests for message operations that apply to both
  10. /// generated and dynamic messages.
  11. /// </summary>
  12. [TestFixture]
  13. public class MessageTest {
  14. // =================================================================
  15. // Message-merging tests.
  16. private static readonly TestAllTypes MergeSource = new TestAllTypes.Builder {
  17. OptionalInt32 = 1,
  18. OptionalString = "foo",
  19. OptionalForeignMessage = ForeignMessage.DefaultInstance,
  20. }.AddRepeatedString("bar").Build();
  21. private static readonly TestAllTypes MergeDest = new TestAllTypes.Builder {
  22. OptionalInt64 = 2,
  23. OptionalString = "baz",
  24. OptionalForeignMessage = new ForeignMessage.Builder { C=3 }.Build(),
  25. }.AddRepeatedString("qux").Build();
  26. private const string MergeResultText =
  27. "optional_int32: 1\n" +
  28. "optional_int64: 2\n" +
  29. "optional_string: \"foo\"\n" +
  30. "optional_foreign_message {\n" +
  31. " c: 3\n" +
  32. "}\n" +
  33. "repeated_string: \"qux\"\n" +
  34. "repeated_string: \"bar\"\n";
  35. [Test]
  36. public void MergeFrom() {
  37. TestAllTypes result = TestAllTypes.CreateBuilder(MergeDest).MergeFrom(MergeSource).Build();
  38. Assert.AreEqual(MergeResultText, result.ToString());
  39. }
  40. /// <summary>
  41. /// Test merging a DynamicMessage into a GeneratedMessage.
  42. /// As long as they have the same descriptor, this should work, but it is an
  43. /// entirely different code path.
  44. /// </summary>
  45. [Test]
  46. public void MergeFromDynamic() {
  47. TestAllTypes result = (TestAllTypes) TestAllTypes.CreateBuilder(MergeDest)
  48. .MergeFrom(DynamicMessage.CreateBuilder(MergeSource).Build())
  49. .Build();
  50. Assert.AreEqual(MergeResultText, result.ToString());
  51. }
  52. /** Test merging two DynamicMessages. */
  53. public void testDynamicMergeFrom() {
  54. DynamicMessage result = (DynamicMessage) DynamicMessage.CreateBuilder(MergeDest)
  55. .MergeFrom((DynamicMessage) DynamicMessage.CreateBuilder(MergeSource).Build())
  56. .Build();
  57. Assert.AreEqual(MergeResultText, result.ToString());
  58. }
  59. // =================================================================
  60. // Required-field-related tests.
  61. private static readonly TestRequired TestRequiredUninitialized = TestRequired.DefaultInstance;
  62. private static readonly TestRequired TestRequiredInitialized = new TestRequired.Builder {
  63. A = 1, B = 2, C = 3
  64. }.Build();
  65. [Test]
  66. public void Initialization() {
  67. TestRequired.Builder builder = TestRequired.CreateBuilder();
  68. Assert.IsFalse(builder.IsInitialized);
  69. builder.A = 1;
  70. Assert.IsFalse(builder.IsInitialized);
  71. builder.B = 1;
  72. Assert.IsFalse(builder.IsInitialized);
  73. builder.C = 1;
  74. Assert.IsTrue(builder.IsInitialized);
  75. }
  76. [Test]
  77. public void RequiredForeign() {
  78. TestRequiredForeign.Builder builder = TestRequiredForeign.CreateBuilder();
  79. Assert.IsTrue(builder.IsInitialized);
  80. builder.SetOptionalMessage(TestRequiredUninitialized);
  81. Assert.IsFalse(builder.IsInitialized);
  82. builder.SetOptionalMessage(TestRequiredInitialized);
  83. Assert.IsTrue(builder.IsInitialized);
  84. builder.AddRepeatedMessage(TestRequiredUninitialized);
  85. Assert.IsFalse(builder.IsInitialized);
  86. builder.SetRepeatedMessage(0, TestRequiredInitialized);
  87. Assert.IsTrue(builder.IsInitialized);
  88. }
  89. [Test]
  90. public void RequiredExtension() {
  91. TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();
  92. Assert.IsTrue(builder.IsInitialized);
  93. builder.SetExtension(TestRequired.Types.Single, TestRequiredUninitialized);
  94. Assert.IsFalse(builder.IsInitialized);
  95. builder.SetExtension(TestRequired.Types.Single, TestRequiredInitialized);
  96. Assert.IsTrue(builder.IsInitialized);
  97. builder.AddExtension(TestRequired.Types.Multi, TestRequiredUninitialized);
  98. Assert.IsFalse(builder.IsInitialized);
  99. builder.SetExtension(TestRequired.Types.Multi, 0, TestRequiredInitialized);
  100. Assert.IsTrue(builder.IsInitialized);
  101. }
  102. [Test]
  103. public void RequiredDynamic() {
  104. MessageDescriptor descriptor = TestRequired.Descriptor;
  105. DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(descriptor);
  106. Assert.IsFalse(builder.IsInitialized);
  107. builder[descriptor.FindDescriptor<FieldDescriptor>("a")] = 1;
  108. Assert.IsFalse(builder.IsInitialized);
  109. builder[descriptor.FindDescriptor<FieldDescriptor>("b")] = 1;
  110. Assert.IsFalse(builder.IsInitialized);
  111. builder[descriptor.FindDescriptor<FieldDescriptor>("c")] = 1;
  112. Assert.IsTrue(builder.IsInitialized);
  113. }
  114. [Test]
  115. public void RequiredDynamicForeign() {
  116. MessageDescriptor descriptor = TestRequiredForeign.Descriptor;
  117. DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(descriptor);
  118. Assert.IsTrue(builder.IsInitialized);
  119. builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredUninitialized;
  120. Assert.IsFalse(builder.IsInitialized);
  121. builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredInitialized;
  122. Assert.IsTrue(builder.IsInitialized);
  123. // TODO(jonskeet): Remove this nastiness by making IBuilder always generic.
  124. ((IBuilder) builder).AddRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), TestRequiredUninitialized);
  125. Assert.IsFalse(builder.IsInitialized);
  126. builder.SetRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), 0, TestRequiredInitialized);
  127. Assert.IsTrue(builder.IsInitialized);
  128. }
  129. [Test]
  130. public void UninitializedException() {
  131. try {
  132. TestRequired.CreateBuilder().Build();
  133. Assert.Fail("Should have thrown an exception.");
  134. } catch (UninitializedMessageException e) {
  135. Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
  136. }
  137. }
  138. [Test]
  139. public void BuildPartial() {
  140. // We're mostly testing that no exception is thrown.
  141. TestRequired message = TestRequired.CreateBuilder().BuildPartial();
  142. Assert.IsFalse(message.IsInitialized);
  143. }
  144. [Test]
  145. public void NestedUninitializedException() {
  146. try {
  147. TestRequiredForeign.CreateBuilder()
  148. .SetOptionalMessage(TestRequiredUninitialized)
  149. .AddRepeatedMessage(TestRequiredUninitialized)
  150. .AddRepeatedMessage(TestRequiredUninitialized)
  151. .Build();
  152. Assert.Fail("Should have thrown an exception.");
  153. } catch (UninitializedMessageException e) {
  154. Assert.AreEqual(
  155. "Message missing required fields: " +
  156. "optional_message.a, " +
  157. "optional_message.b, " +
  158. "optional_message.c, " +
  159. "repeated_message[0].a, " +
  160. "repeated_message[0].b, " +
  161. "repeated_message[0].c, " +
  162. "repeated_message[1].a, " +
  163. "repeated_message[1].b, " +
  164. "repeated_message[1].c",
  165. e.Message);
  166. }
  167. }
  168. [Test]
  169. public void BuildNestedPartial() {
  170. // We're mostly testing that no exception is thrown.
  171. TestRequiredForeign message =
  172. TestRequiredForeign.CreateBuilder()
  173. .SetOptionalMessage(TestRequiredUninitialized)
  174. .AddRepeatedMessage(TestRequiredUninitialized)
  175. .AddRepeatedMessage(TestRequiredUninitialized)
  176. .BuildPartial();
  177. Assert.IsFalse(message.IsInitialized);
  178. }
  179. [Test]
  180. public void ParseUnititialized() {
  181. try {
  182. TestRequired.ParseFrom(ByteString.Empty);
  183. Assert.Fail("Should have thrown an exception.");
  184. } catch (InvalidProtocolBufferException e) {
  185. Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
  186. }
  187. }
  188. [Test]
  189. public void ParseNestedUnititialized() {
  190. ByteString data =
  191. TestRequiredForeign.CreateBuilder()
  192. .SetOptionalMessage(TestRequiredUninitialized)
  193. .AddRepeatedMessage(TestRequiredUninitialized)
  194. .AddRepeatedMessage(TestRequiredUninitialized)
  195. .BuildPartial().ToByteString();
  196. try {
  197. TestRequiredForeign.ParseFrom(data);
  198. Assert.Fail("Should have thrown an exception.");
  199. } catch (InvalidProtocolBufferException e) {
  200. Assert.AreEqual(
  201. "Message missing required fields: " +
  202. "optional_message.a, " +
  203. "optional_message.b, " +
  204. "optional_message.c, " +
  205. "repeated_message[0].a, " +
  206. "repeated_message[0].b, " +
  207. "repeated_message[0].c, " +
  208. "repeated_message[1].a, " +
  209. "repeated_message[1].b, " +
  210. "repeated_message[1].c",
  211. e.Message);
  212. }
  213. }
  214. [Test]
  215. public void DynamicUninitializedException() {
  216. try {
  217. DynamicMessage.CreateBuilder(TestRequired.Descriptor).Build();
  218. Assert.Fail("Should have thrown an exception.");
  219. } catch (UninitializedMessageException e) {
  220. Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
  221. }
  222. }
  223. [Test]
  224. public void DynamicBuildPartial() {
  225. // We're mostly testing that no exception is thrown.
  226. // TODO(jonskeet): Fix this ghastly casting mess
  227. DynamicMessage message = (DynamicMessage) ((IBuilder) DynamicMessage.CreateBuilder(TestRequired.Descriptor)).BuildPartial();
  228. Assert.IsFalse(message.Initialized);
  229. }
  230. [Test]
  231. public void DynamicParseUnititialized() {
  232. try {
  233. MessageDescriptor descriptor = TestRequired.Descriptor;
  234. DynamicMessage.ParseFrom(descriptor, ByteString.Empty);
  235. Assert.Fail("Should have thrown an exception.");
  236. } catch (InvalidProtocolBufferException e) {
  237. Assert.AreEqual("Message missing required fields: a, b, c", e.Message);
  238. }
  239. }
  240. }
  241. }