AbstractMessageTest.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  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 System;
  17. using System.Collections.Generic;
  18. using Google.ProtocolBuffers.Descriptors;
  19. using NUnit.Framework;
  20. using Google.ProtocolBuffers.TestProtos;
  21. namespace Google.ProtocolBuffers {
  22. [TestFixture]
  23. public class AbstractMessageTest {
  24. [Test]
  25. public void Clear() {
  26. AbstractMessageWrapper message = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder(TestUtil.GetAllSet())).Clear().Build();
  27. TestUtil.AssertClear((TestAllTypes) message.WrappedMessage);
  28. }
  29. [Test]
  30. public void Copy() {
  31. AbstractMessageWrapper message = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder()).MergeFrom(TestUtil.GetAllSet()).Build();
  32. TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage);
  33. }
  34. [Test]
  35. public void SerializedSize() {
  36. TestAllTypes message = TestUtil.GetAllSet();
  37. IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetAllSet());
  38. Assert.AreEqual(message.SerializedSize, abstractMessage.SerializedSize);
  39. }
  40. [Test]
  41. public void Serialization() {
  42. IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetAllSet());
  43. TestUtil.AssertAllFieldsSet(TestAllTypes.ParseFrom(abstractMessage.ToByteString()));
  44. Assert.AreEqual(TestUtil.GetAllSet().ToByteString(), abstractMessage.ToByteString());
  45. }
  46. [Test]
  47. public void Parsing() {
  48. IBuilder builder = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder());
  49. AbstractMessageWrapper message = (AbstractMessageWrapper) builder.WeakMergeFrom(TestUtil.GetAllSet().ToByteString()).WeakBuild();
  50. TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage);
  51. }
  52. [Test]
  53. public void OptimizedForSize() {
  54. // We're mostly only Checking that this class was compiled successfully.
  55. TestOptimizedForSize message = TestOptimizedForSize.CreateBuilder().SetI(1).Build();
  56. message = TestOptimizedForSize.ParseFrom(message.ToByteString());
  57. Assert.AreEqual(2, message.SerializedSize);
  58. }
  59. // -----------------------------------------------------------------
  60. // Tests for isInitialized().
  61. private static readonly TestRequired TestRequiredUninitialized = TestRequired.DefaultInstance;
  62. private static readonly TestRequired TestRequiredInitialized = TestRequired.CreateBuilder().SetA(1).SetB(2).SetC(3).Build();
  63. [Test]
  64. public void IsInitialized() {
  65. TestRequired.Builder builder = TestRequired.CreateBuilder();
  66. AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder);
  67. Assert.IsFalse(abstractBuilder.IsInitialized);
  68. builder.A = 1;
  69. Assert.IsFalse(abstractBuilder.IsInitialized);
  70. builder.B = 1;
  71. Assert.IsFalse(abstractBuilder.IsInitialized);
  72. builder.C = 1;
  73. Assert.IsTrue(abstractBuilder.IsInitialized);
  74. }
  75. [Test]
  76. public void ForeignIsInitialized() {
  77. TestRequiredForeign.Builder builder = TestRequiredForeign.CreateBuilder();
  78. AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder);
  79. Assert.IsTrue(abstractBuilder.IsInitialized);
  80. builder.SetOptionalMessage(TestRequiredUninitialized);
  81. Assert.IsFalse(abstractBuilder.IsInitialized);
  82. builder.SetOptionalMessage(TestRequiredInitialized);
  83. Assert.IsTrue(abstractBuilder.IsInitialized);
  84. builder.AddRepeatedMessage(TestRequiredUninitialized);
  85. Assert.IsFalse(abstractBuilder.IsInitialized);
  86. builder.SetRepeatedMessage(0, TestRequiredInitialized);
  87. Assert.IsTrue(abstractBuilder.IsInitialized);
  88. }
  89. // -----------------------------------------------------------------
  90. // Tests for mergeFrom
  91. static readonly TestAllTypes MergeSource = TestAllTypes.CreateBuilder()
  92. .SetOptionalInt32(1)
  93. .SetOptionalString("foo")
  94. .SetOptionalForeignMessage(ForeignMessage.DefaultInstance)
  95. .AddRepeatedString("bar")
  96. .Build();
  97. static readonly TestAllTypes MergeDest = TestAllTypes.CreateBuilder()
  98. .SetOptionalInt64(2)
  99. .SetOptionalString("baz")
  100. .SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(3).Build())
  101. .AddRepeatedString("qux")
  102. .Build();
  103. const string MergeResultText = "optional_int32: 1\n" +
  104. "optional_int64: 2\n" +
  105. "optional_string: \"foo\"\n" +
  106. "optional_foreign_message {\n" +
  107. " c: 3\n" +
  108. "}\n" +
  109. "repeated_string: \"qux\"\n" +
  110. "repeated_string: \"bar\"\n";
  111. [Test]
  112. public void MergeFrom() {
  113. AbstractMessageWrapper result = (AbstractMessageWrapper)
  114. new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder(MergeDest))
  115. .MergeFrom(MergeSource)
  116. .Build();
  117. Assert.AreEqual(MergeResultText, result.ToString());
  118. }
  119. // -----------------------------------------------------------------
  120. // Tests for equals and hashCode
  121. [Test]
  122. public void EqualsAndHashCode() {
  123. TestAllTypes a = TestUtil.GetAllSet();
  124. TestAllTypes b = TestAllTypes.CreateBuilder().Build();
  125. TestAllTypes c = TestAllTypes.CreateBuilder(b).AddRepeatedString("x").Build();
  126. TestAllTypes d = TestAllTypes.CreateBuilder(c).AddRepeatedString("y").Build();
  127. TestAllExtensions e = TestUtil.GetAllExtensionsSet();
  128. TestAllExtensions f = TestAllExtensions.CreateBuilder(e)
  129. .AddExtension(UnitTestProtoFile.RepeatedInt32Extension, 999).Build();
  130. CheckEqualsIsConsistent(a);
  131. CheckEqualsIsConsistent(b);
  132. CheckEqualsIsConsistent(c);
  133. CheckEqualsIsConsistent(d);
  134. CheckEqualsIsConsistent(e);
  135. CheckEqualsIsConsistent(f);
  136. CheckNotEqual(a, b);
  137. CheckNotEqual(a, c);
  138. CheckNotEqual(a, d);
  139. CheckNotEqual(a, e);
  140. CheckNotEqual(a, f);
  141. CheckNotEqual(b, c);
  142. CheckNotEqual(b, d);
  143. CheckNotEqual(b, e);
  144. CheckNotEqual(b, f);
  145. CheckNotEqual(c, d);
  146. CheckNotEqual(c, e);
  147. CheckNotEqual(c, f);
  148. CheckNotEqual(d, e);
  149. CheckNotEqual(d, f);
  150. CheckNotEqual(e, f);
  151. }
  152. /// <summary>
  153. /// Asserts that the given protos are equal and have the same hash code.
  154. /// </summary>
  155. private static void CheckEqualsIsConsistent(IMessage message) {
  156. // Object should be equal to itself.
  157. Assert.AreEqual(message, message);
  158. // Object should be equal to a dynamic copy of itself.
  159. DynamicMessage dynamic = DynamicMessage.CreateBuilder(message).Build();
  160. Assert.AreEqual(message, dynamic);
  161. Assert.AreEqual(dynamic, message);
  162. Assert.AreEqual(dynamic.GetHashCode(), message.GetHashCode());
  163. }
  164. /// <summary>
  165. /// Asserts that the given protos are not equal and have different hash codes.
  166. /// </summary>
  167. /// <remarks>
  168. /// It's valid for non-equal objects to have the same hash code, so
  169. /// this test is stricter than it needs to be. However, this should happen
  170. /// relatively rarely. (If this test fails, it's probably still due to a bug.)
  171. /// </remarks>
  172. private static void CheckNotEqual(IMessage m1, IMessage m2) {
  173. String equalsError = string.Format("{0} should not be equal to {1}", m1, m2);
  174. Assert.IsFalse(m1.Equals(m2), equalsError);
  175. Assert.IsFalse(m2.Equals(m1), equalsError);
  176. Assert.IsFalse(m1.GetHashCode() == m2.GetHashCode(),
  177. string.Format("{0} should have a different hash code from {1}", m1, m2));
  178. }
  179. /// <summary>
  180. /// Extends AbstractMessage and wraps some other message object. The methods
  181. /// of the Message interface which aren't explicitly implemented by
  182. /// AbstractMessage are forwarded to the wrapped object. This allows us to
  183. /// test that AbstractMessage's implementations work even if the wrapped
  184. /// object does not use them.
  185. /// </summary>
  186. private class AbstractMessageWrapper : AbstractMessage<AbstractMessageWrapper, AbstractMessageWrapper.Builder> {
  187. private readonly IMessage wrappedMessage;
  188. public IMessage WrappedMessage {
  189. get { return wrappedMessage; }
  190. }
  191. public AbstractMessageWrapper(IMessage wrappedMessage) {
  192. this.wrappedMessage = wrappedMessage;
  193. }
  194. public override MessageDescriptor DescriptorForType {
  195. get { return wrappedMessage.DescriptorForType; }
  196. }
  197. public override AbstractMessageWrapper DefaultInstanceForType {
  198. get { return new AbstractMessageWrapper(wrappedMessage.WeakDefaultInstanceForType); }
  199. }
  200. public override IDictionary<FieldDescriptor, object> AllFields {
  201. get { return wrappedMessage.AllFields; }
  202. }
  203. public override bool HasField(FieldDescriptor field) {
  204. return wrappedMessage.HasField(field);
  205. }
  206. public override object this[FieldDescriptor field] {
  207. get { return wrappedMessage[field]; }
  208. }
  209. public override object this[FieldDescriptor field, int index] {
  210. get { return wrappedMessage[field, index]; }
  211. }
  212. public override int GetRepeatedFieldCount(FieldDescriptor field) {
  213. return wrappedMessage.GetRepeatedFieldCount(field);
  214. }
  215. public override UnknownFieldSet UnknownFields {
  216. get { return wrappedMessage.UnknownFields; }
  217. }
  218. public override Builder CreateBuilderForType() {
  219. return new Builder(wrappedMessage.WeakCreateBuilderForType());
  220. }
  221. internal class Builder : AbstractBuilder<AbstractMessageWrapper, Builder> {
  222. private readonly IBuilder wrappedBuilder;
  223. protected override Builder ThisBuilder {
  224. get { return this; }
  225. }
  226. internal Builder(IBuilder wrappedBuilder) {
  227. this.wrappedBuilder = wrappedBuilder;
  228. }
  229. public override Builder MergeFrom(AbstractMessageWrapper other) {
  230. wrappedBuilder.WeakMergeFrom(other.wrappedMessage);
  231. return this;
  232. }
  233. public override bool IsInitialized {
  234. get { return wrappedBuilder.IsInitialized; }
  235. }
  236. public override IDictionary<FieldDescriptor, object> AllFields {
  237. get { return wrappedBuilder.AllFields; }
  238. }
  239. public override object this[FieldDescriptor field] {
  240. get { return wrappedBuilder[field]; }
  241. set { wrappedBuilder[field] = value; }
  242. }
  243. public override MessageDescriptor DescriptorForType {
  244. get { return wrappedBuilder.DescriptorForType; }
  245. }
  246. public override int GetRepeatedFieldCount(FieldDescriptor field) {
  247. return wrappedBuilder.GetRepeatedFieldCount(field);
  248. }
  249. public override object this[FieldDescriptor field, int index] {
  250. get { return wrappedBuilder[field, index]; }
  251. set { wrappedBuilder[field, index] = value; }
  252. }
  253. public override bool HasField(FieldDescriptor field) {
  254. return wrappedBuilder.HasField(field);
  255. }
  256. public override UnknownFieldSet UnknownFields {
  257. get { return wrappedBuilder.UnknownFields; }
  258. set { wrappedBuilder.UnknownFields = value; }
  259. }
  260. public override AbstractMessageWrapper Build() {
  261. return new AbstractMessageWrapper(wrappedBuilder.WeakBuild());
  262. }
  263. public override AbstractMessageWrapper BuildPartial() {
  264. return new AbstractMessageWrapper(wrappedBuilder.WeakBuildPartial());
  265. }
  266. public override Builder Clone() {
  267. return new Builder(wrappedBuilder.WeakClone());
  268. }
  269. public override AbstractMessageWrapper DefaultInstanceForType {
  270. get { return new AbstractMessageWrapper(wrappedBuilder.WeakDefaultInstanceForType); }
  271. }
  272. public override Builder ClearField(FieldDescriptor field) {
  273. wrappedBuilder.WeakClearField(field);
  274. return this;
  275. }
  276. public override Builder AddRepeatedField(FieldDescriptor field, object value) {
  277. wrappedBuilder.WeakAddRepeatedField(field, value);
  278. return this;
  279. }
  280. public override IBuilder CreateBuilderForField(FieldDescriptor field) {
  281. wrappedBuilder.CreateBuilderForField(field);
  282. return this;
  283. }
  284. public override Builder MergeFrom(IMessage other) {
  285. wrappedBuilder.WeakMergeFrom(other);
  286. return this;
  287. }
  288. public override Builder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) {
  289. wrappedBuilder.WeakMergeFrom(input, extensionRegistry);
  290. return this;
  291. }
  292. }
  293. }
  294. }
  295. }