public void TestFieldPresence() { // Optional non-message fields set to their default value are treated the same // way as not set. // Serialization will ignore such fields. TestAllTypes.Builder builder = TestAllTypes.CreateBuilder(); builder.SetOptionalInt32(0); builder.SetOptionalString(""); builder.SetOptionalBytes(ByteString.Empty); builder.SetOptionalNestedEnum(TestAllTypes.Types.NestedEnum.FOO); TestAllTypes message = builder.Build(); Assert.AreEqual(0, message.SerializedSize); // Test merge TestAllTypes.Builder a = TestAllTypes.CreateBuilder(); a.SetOptionalInt32(1); a.SetOptionalString("x"); a.SetOptionalBytes(ByteString.CopyFromUtf8("y")); a.SetOptionalNestedEnum(TestAllTypes.Types.NestedEnum.BAR); a.MergeFrom(message); TestAllTypes messageA = a.Build(); Assert.AreEqual(1, messageA.OptionalInt32); Assert.AreEqual("x", messageA.OptionalString); Assert.AreEqual(ByteString.CopyFromUtf8("y"), messageA.OptionalBytes); Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR, messageA.OptionalNestedEnum); // equals/hashCode should produce the same results TestAllTypes empty = TestAllTypes.CreateBuilder().Build(); Assert.IsTrue(empty.Equals(message)); Assert.IsTrue(message.Equals(empty)); Assert.AreEqual(empty.GetHashCode(), message.GetHashCode()); }
private void TestManyChangesWithSnapshot(TestAllTypes root, TestAllTypes allTypes) { for (int i = 0; i < 10; i++) { var i1 = i; AssertEventsStableWithSnapshot(root, () => { SetSingular(allTypes, i1); }); AssertEventsStableWithSnapshot(root, () => { SetEnums(allTypes, i1); }); AssertEventsStableWithSnapshot(root, () => { SetNestedMessages(allTypes, i1); }); AssertEventsStableWithSnapshot(root, () => { UpdateNestedMessages(allTypes, i1); }); AssertEventsStableWithSnapshot(root, () => { ClearRepeated(allTypes); }); AssertEventsStableWithSnapshot(root, () => { AddRepeated(allTypes, i1); }); AssertEventsStableWithSnapshot(root, () => { RemoveRepeated(allTypes, i1); }); AssertEventsStableWithSnapshot(root, () => { AddRepeated(allTypes, i1); }); AssertEventsStableWithSnapshot(root, () => { RemoveAtRepeated(allTypes, 0); }); AssertEventsStableWithSnapshot(root, () => { AddRepeated(allTypes, i1); }); AssertEventsStableWithSnapshot(root, () => { ReplaceRepeated(allTypes, 0, i1); }, false); AssertEventsStableWithSnapshot(root, () => { ReplaceRepeated(allTypes, 0, i1 + 1); }); AssertEventsStableWithSnapshot(root, () => { InsertRepeated(allTypes, 0, i1 + 2); }); AssertEventsStableWithSnapshot(root, () => { ClearRepeated(allTypes); }); AssertEventsStableWithSnapshot(root, () => { AddRepeated(allTypes, i1); }); AssertEventsStableWithSnapshot(root, () => { UpdateRepeated(allTypes, 0, i1 + 1); }); AssertEventsStableWithSnapshot(root, () => { ClearMap(allTypes); }); AssertEventsStableWithSnapshot(root, () => { AddMap(allTypes, i1, i1); }); AssertEventsStableWithSnapshot(root, () => { RemoveMap(allTypes, i1); }); AssertEventsStableWithSnapshot(root, () => { AddMap(allTypes, i1, i1); }); AssertEventsStableWithSnapshot(root, () => { ReplaceMap(allTypes, i1, i1); }, false); AssertEventsStableWithSnapshot(root, () => { ReplaceMap(allTypes, i1, i1 + 1); }); AssertEventsStableWithSnapshot(root, () => { ClearMap(allTypes); }); AssertEventsStableWithSnapshot(root, () => { AddMap(allTypes, i1, i1); }); AssertEventsStableWithSnapshot(root, () => { UpdateMap(allTypes, i1, i1 + 1); }); AssertEventsStableWithSnapshot(root, () => { allTypes.OneofUint32 = UintValue(i1); }); AssertEventsStableWithSnapshot(root, () => { allTypes.OneofNestedMessage = NestedMessageValue(i1); }); AssertEventsStableWithSnapshot(root, () => { allTypes.OneofString = StringValue(i1); }); AssertEventsStableWithSnapshot(root, () => { allTypes.OneofBytes = ByteValue(i1); }); AssertEventsStableWithSnapshot(root, () => { allTypes.OneofForeignMessage = ForeignMessageValue(i1); }); AssertEventsStableWithSnapshot(root, () => { allTypes.OneofForeignMessageNoEvents = ForeignMessageNoEventsValue(i1); }); AssertEventsStableWithSnapshot(root, () => { allTypes.OneofAllTypes = TestAllTypesValue(i1); }); AssertEventsStableWithSnapshot(root, () => { allTypes.OneofAllTypesNoEvents = TestAllTypesNoEventsValue(i1); }); AssertEventsStableWithSnapshot(root, () => { allTypes.AllTypes = TestAllTypesValue(i1 * 2); }); AssertEventsStableWithSnapshot(root, () => { SetSingular(allTypes.AllTypes, i1 * 2 + 1); }); AssertEventsStableWithSnapshot(root, () => { allTypes.AllTypesNoEvents = TestAllTypesNoEventsValue(i1); }); } // list only changes for (int i = 0; i < 10; i++) { var i1 = i; AssertEventsStableWithClone(root, () => { AddRepeated(allTypes, i1); }); } for (int i = 0; i < 10; i++) { var i1 = i; AssertEventsStableWithClone(root, () => { UpdateRepeated(allTypes, i1, i1 + 1); }); } // map only changes for (int i = 0; i < 10; i++) { var i1 = i; AssertEventsStableWithClone(root, () => { ReplaceMap(allTypes, i1, i1); }); } for (int i = 0; i < 10; i++) { var i1 = i; AssertEventsStableWithClone(root, () => { UpdateMap(allTypes, i1, i1 + 1); }); } // just some basic sanity that these methods don't throw exceptions Assert.True(root.CalculateSize() > 0); Assert.True(root.GetHashCode() != 1); }