1 #region Copyright notice and license 2 // Protocol Buffers - Google's data interchange format 3 // Copyright 2015 Google Inc. All rights reserved. 4 // 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file or at 7 // https://developers.google.com/open-source/licenses/bsd 8 #endregion 9 10 using Google.Protobuf.TestProtos; 11 using NUnit.Framework; 12 using System; 13 using System.Collections; 14 using System.Collections.Generic; 15 16 namespace Google.Protobuf.Reflection 17 { 18 public class FieldAccessTest 19 { 20 [Test] GetValue()21 public void GetValue() 22 { 23 var message = SampleMessages.CreateFullTestAllTypes(); 24 var fields = TestAllTypes.Descriptor.Fields; 25 Assert.AreEqual(message.SingleBool, fields[TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(message)); 26 Assert.AreEqual(message.SingleBytes, fields[TestAllTypes.SingleBytesFieldNumber].Accessor.GetValue(message)); 27 Assert.AreEqual(message.SingleDouble, fields[TestAllTypes.SingleDoubleFieldNumber].Accessor.GetValue(message)); 28 Assert.AreEqual(message.SingleFixed32, fields[TestAllTypes.SingleFixed32FieldNumber].Accessor.GetValue(message)); 29 Assert.AreEqual(message.SingleFixed64, fields[TestAllTypes.SingleFixed64FieldNumber].Accessor.GetValue(message)); 30 Assert.AreEqual(message.SingleFloat, fields[TestAllTypes.SingleFloatFieldNumber].Accessor.GetValue(message)); 31 Assert.AreEqual(message.SingleForeignEnum, fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.GetValue(message)); 32 Assert.AreEqual(message.SingleForeignMessage, fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.GetValue(message)); 33 Assert.AreEqual(message.SingleImportEnum, fields[TestAllTypes.SingleImportEnumFieldNumber].Accessor.GetValue(message)); 34 Assert.AreEqual(message.SingleImportMessage, fields[TestAllTypes.SingleImportMessageFieldNumber].Accessor.GetValue(message)); 35 Assert.AreEqual(message.SingleInt32, fields[TestAllTypes.SingleInt32FieldNumber].Accessor.GetValue(message)); 36 Assert.AreEqual(message.SingleInt64, fields[TestAllTypes.SingleInt64FieldNumber].Accessor.GetValue(message)); 37 Assert.AreEqual(message.SingleNestedEnum, fields[TestAllTypes.SingleNestedEnumFieldNumber].Accessor.GetValue(message)); 38 Assert.AreEqual(message.SingleNestedMessage, fields[TestAllTypes.SingleNestedMessageFieldNumber].Accessor.GetValue(message)); 39 Assert.AreEqual(message.SinglePublicImportMessage, fields[TestAllTypes.SinglePublicImportMessageFieldNumber].Accessor.GetValue(message)); 40 Assert.AreEqual(message.SingleSint32, fields[TestAllTypes.SingleSint32FieldNumber].Accessor.GetValue(message)); 41 Assert.AreEqual(message.SingleSint64, fields[TestAllTypes.SingleSint64FieldNumber].Accessor.GetValue(message)); 42 Assert.AreEqual(message.SingleString, fields[TestAllTypes.SingleStringFieldNumber].Accessor.GetValue(message)); 43 Assert.AreEqual(message.SingleSfixed32, fields[TestAllTypes.SingleSfixed32FieldNumber].Accessor.GetValue(message)); 44 Assert.AreEqual(message.SingleSfixed64, fields[TestAllTypes.SingleSfixed64FieldNumber].Accessor.GetValue(message)); 45 Assert.AreEqual(message.SingleUint32, fields[TestAllTypes.SingleUint32FieldNumber].Accessor.GetValue(message)); 46 Assert.AreEqual(message.SingleUint64, fields[TestAllTypes.SingleUint64FieldNumber].Accessor.GetValue(message)); 47 Assert.AreEqual(message.OneofBytes, fields[TestAllTypes.OneofBytesFieldNumber].Accessor.GetValue(message)); 48 Assert.AreEqual(message.OneofString, fields[TestAllTypes.OneofStringFieldNumber].Accessor.GetValue(message)); 49 Assert.AreEqual(message.OneofNestedMessage, fields[TestAllTypes.OneofNestedMessageFieldNumber].Accessor.GetValue(message)); 50 Assert.AreEqual(message.OneofUint32, fields[TestAllTypes.OneofUint32FieldNumber].Accessor.GetValue(message)); 51 52 // Just one example for repeated fields - they're all just returning the list 53 var list = (IList) fields[TestAllTypes.RepeatedInt32FieldNumber].Accessor.GetValue(message); 54 Assert.AreEqual(message.RepeatedInt32, list); 55 Assert.AreEqual(message.RepeatedInt32[0], list[0]); // Just in case there was any doubt... 56 57 // Just a single map field, for the same reason 58 var mapMessage = new TestMap { MapStringString = { { "key1", "value1" }, { "key2", "value2" } } }; 59 fields = TestMap.Descriptor.Fields; 60 var dictionary = (IDictionary) fields[TestMap.MapStringStringFieldNumber].Accessor.GetValue(mapMessage); 61 Assert.AreEqual(mapMessage.MapStringString, dictionary); 62 Assert.AreEqual("value1", dictionary["key1"]); 63 } 64 65 [Test] Clear()66 public void Clear() 67 { 68 var message = SampleMessages.CreateFullTestAllTypes(); 69 var fields = TestAllTypes.Descriptor.Fields; 70 fields[TestAllTypes.SingleBoolFieldNumber].Accessor.Clear(message); 71 fields[TestAllTypes.SingleInt32FieldNumber].Accessor.Clear(message); 72 fields[TestAllTypes.SingleStringFieldNumber].Accessor.Clear(message); 73 fields[TestAllTypes.SingleBytesFieldNumber].Accessor.Clear(message); 74 fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.Clear(message); 75 fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.Clear(message); 76 fields[TestAllTypes.RepeatedDoubleFieldNumber].Accessor.Clear(message); 77 78 var expected = new TestAllTypes(SampleMessages.CreateFullTestAllTypes()) 79 { 80 SingleBool = false, 81 SingleInt32 = 0, 82 SingleString = "", 83 SingleBytes = ByteString.Empty, 84 SingleForeignEnum = 0, 85 SingleForeignMessage = null, 86 }; 87 expected.RepeatedDouble.Clear(); 88 89 Assert.AreEqual(expected, message); 90 91 // Separately, maps. 92 var mapMessage = new TestMap { MapStringString = { { "key1", "value1" }, { "key2", "value2" } } }; 93 fields = TestMap.Descriptor.Fields; 94 fields[TestMap.MapStringStringFieldNumber].Accessor.Clear(mapMessage); 95 Assert.AreEqual(0, mapMessage.MapStringString.Count); 96 } 97 98 [Test] SetValue_SingleFields()99 public void SetValue_SingleFields() 100 { 101 // Just a sample (primitives, messages, enums, strings, byte strings) 102 var message = SampleMessages.CreateFullTestAllTypes(); 103 var fields = TestAllTypes.Descriptor.Fields; 104 fields[TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, false); 105 fields[TestAllTypes.SingleInt32FieldNumber].Accessor.SetValue(message, 500); 106 fields[TestAllTypes.SingleStringFieldNumber].Accessor.SetValue(message, "It's a string"); 107 fields[TestAllTypes.SingleBytesFieldNumber].Accessor.SetValue(message, ByteString.CopyFrom(99, 98, 97)); 108 fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.SetValue(message, ForeignEnum.ForeignFoo); 109 fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.SetValue(message, new ForeignMessage { C = 12345 }); 110 fields[TestAllTypes.SingleDoubleFieldNumber].Accessor.SetValue(message, 20150701.5); 111 112 var expected = new TestAllTypes(SampleMessages.CreateFullTestAllTypes()) 113 { 114 SingleBool = false, 115 SingleInt32 = 500, 116 SingleString = "It's a string", 117 SingleBytes = ByteString.CopyFrom(99, 98, 97), 118 SingleForeignEnum = ForeignEnum.ForeignFoo, 119 SingleForeignMessage = new ForeignMessage { C = 12345 }, 120 SingleDouble = 20150701.5 121 }; 122 123 Assert.AreEqual(expected, message); 124 } 125 126 [Test] SetValue_SingleFields_WrongType()127 public void SetValue_SingleFields_WrongType() 128 { 129 IMessage message = SampleMessages.CreateFullTestAllTypes(); 130 var fields = message.Descriptor.Fields; 131 Assert.Throws<InvalidCastException>(() => fields[TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, "This isn't a bool")); 132 } 133 134 [Test] SetValue_MapFields()135 public void SetValue_MapFields() 136 { 137 IMessage message = new TestMap(); 138 var fields = message.Descriptor.Fields; 139 Assert.Throws<InvalidOperationException>(() => fields[TestMap.MapStringStringFieldNumber].Accessor.SetValue(message, new Dictionary<string, string>())); 140 } 141 142 [Test] SetValue_RepeatedFields()143 public void SetValue_RepeatedFields() 144 { 145 IMessage message = SampleMessages.CreateFullTestAllTypes(); 146 var fields = message.Descriptor.Fields; 147 Assert.Throws<InvalidOperationException>(() => fields[TestAllTypes.RepeatedDoubleFieldNumber].Accessor.SetValue(message, new double[10])); 148 } 149 150 [Test] GetValue_IncorrectType()151 public void GetValue_IncorrectType() 152 { 153 IMessage message = SampleMessages.CreateFullTestAllTypes(); 154 var fields = message.Descriptor.Fields; 155 Assert.Throws<InvalidCastException>(() => fields[TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(new TestMap())); 156 } 157 158 [Test] Oneof()159 public void Oneof() 160 { 161 var message = new TestAllTypes(); 162 var descriptor = TestAllTypes.Descriptor; 163 Assert.AreEqual(1, descriptor.Oneofs.Count); 164 var oneof = descriptor.Oneofs[0]; 165 Assert.AreEqual("oneof_field", oneof.Name); 166 Assert.IsNull(oneof.Accessor.GetCaseFieldDescriptor(message)); 167 168 message.OneofString = "foo"; 169 Assert.AreSame(descriptor.Fields[TestAllTypes.OneofStringFieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message)); 170 171 message.OneofUint32 = 10; 172 Assert.AreSame(descriptor.Fields[TestAllTypes.OneofUint32FieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message)); 173 174 oneof.Accessor.Clear(message); 175 Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase); 176 } 177 178 [Test] FieldDescriptor_ByName()179 public void FieldDescriptor_ByName() 180 { 181 var descriptor = TestAllTypes.Descriptor; 182 Assert.AreSame( 183 descriptor.Fields[TestAllTypes.SingleBoolFieldNumber], 184 descriptor.Fields["single_bool"]); 185 } 186 187 [Test] FieldDescriptor_NotFound()188 public void FieldDescriptor_NotFound() 189 { 190 var descriptor = TestAllTypes.Descriptor; 191 Assert.Throws<KeyNotFoundException>(() => descriptor.Fields[999999].ToString()); 192 Assert.Throws<KeyNotFoundException>(() => descriptor.Fields["not found"].ToString()); 193 } 194 } 195 } 196