MessageTest.cs 10 KB

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