1 #region Copyright notice and license 2 // Protocol Buffers - Google's data interchange format 3 // Copyright 2015 Google Inc. All rights reserved. 4 // https://developers.google.com/protocol-buffers/ 5 // 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions are 8 // met: 9 // 10 // * Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // * Redistributions in binary form must reproduce the above 13 // copyright notice, this list of conditions and the following disclaimer 14 // in the documentation and/or other materials provided with the 15 // distribution. 16 // * Neither the name of Google Inc. nor the names of its 17 // contributors may be used to endorse or promote products derived from 18 // this software without specific prior written permission. 19 // 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 #endregion 32 33 using Google.Protobuf.TestProtos; 34 using NUnit.Framework; 35 using System; 36 using System.Collections; 37 using System.Collections.Generic; 38 39 namespace Google.Protobuf.Reflection 40 { 41 public class FieldAccessTest 42 { 43 [Test] GetValue()44 public void GetValue() 45 { 46 var message = SampleMessages.CreateFullTestAllTypes(); 47 var fields = TestAllTypes.Descriptor.Fields; 48 Assert.AreEqual(message.SingleBool, fields[TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(message)); 49 Assert.AreEqual(message.SingleBytes, fields[TestAllTypes.SingleBytesFieldNumber].Accessor.GetValue(message)); 50 Assert.AreEqual(message.SingleDouble, fields[TestAllTypes.SingleDoubleFieldNumber].Accessor.GetValue(message)); 51 Assert.AreEqual(message.SingleFixed32, fields[TestAllTypes.SingleFixed32FieldNumber].Accessor.GetValue(message)); 52 Assert.AreEqual(message.SingleFixed64, fields[TestAllTypes.SingleFixed64FieldNumber].Accessor.GetValue(message)); 53 Assert.AreEqual(message.SingleFloat, fields[TestAllTypes.SingleFloatFieldNumber].Accessor.GetValue(message)); 54 Assert.AreEqual(message.SingleForeignEnum, fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.GetValue(message)); 55 Assert.AreEqual(message.SingleForeignMessage, fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.GetValue(message)); 56 Assert.AreEqual(message.SingleImportEnum, fields[TestAllTypes.SingleImportEnumFieldNumber].Accessor.GetValue(message)); 57 Assert.AreEqual(message.SingleImportMessage, fields[TestAllTypes.SingleImportMessageFieldNumber].Accessor.GetValue(message)); 58 Assert.AreEqual(message.SingleInt32, fields[TestAllTypes.SingleInt32FieldNumber].Accessor.GetValue(message)); 59 Assert.AreEqual(message.SingleInt64, fields[TestAllTypes.SingleInt64FieldNumber].Accessor.GetValue(message)); 60 Assert.AreEqual(message.SingleNestedEnum, fields[TestAllTypes.SingleNestedEnumFieldNumber].Accessor.GetValue(message)); 61 Assert.AreEqual(message.SingleNestedMessage, fields[TestAllTypes.SingleNestedMessageFieldNumber].Accessor.GetValue(message)); 62 Assert.AreEqual(message.SinglePublicImportMessage, fields[TestAllTypes.SinglePublicImportMessageFieldNumber].Accessor.GetValue(message)); 63 Assert.AreEqual(message.SingleSint32, fields[TestAllTypes.SingleSint32FieldNumber].Accessor.GetValue(message)); 64 Assert.AreEqual(message.SingleSint64, fields[TestAllTypes.SingleSint64FieldNumber].Accessor.GetValue(message)); 65 Assert.AreEqual(message.SingleString, fields[TestAllTypes.SingleStringFieldNumber].Accessor.GetValue(message)); 66 Assert.AreEqual(message.SingleSfixed32, fields[TestAllTypes.SingleSfixed32FieldNumber].Accessor.GetValue(message)); 67 Assert.AreEqual(message.SingleSfixed64, fields[TestAllTypes.SingleSfixed64FieldNumber].Accessor.GetValue(message)); 68 Assert.AreEqual(message.SingleUint32, fields[TestAllTypes.SingleUint32FieldNumber].Accessor.GetValue(message)); 69 Assert.AreEqual(message.SingleUint64, fields[TestAllTypes.SingleUint64FieldNumber].Accessor.GetValue(message)); 70 Assert.AreEqual(message.OneofBytes, fields[TestAllTypes.OneofBytesFieldNumber].Accessor.GetValue(message)); 71 Assert.AreEqual(message.OneofString, fields[TestAllTypes.OneofStringFieldNumber].Accessor.GetValue(message)); 72 Assert.AreEqual(message.OneofNestedMessage, fields[TestAllTypes.OneofNestedMessageFieldNumber].Accessor.GetValue(message)); 73 Assert.AreEqual(message.OneofUint32, fields[TestAllTypes.OneofUint32FieldNumber].Accessor.GetValue(message)); 74 75 // Just one example for repeated fields - they're all just returning the list 76 var list = (IList) fields[TestAllTypes.RepeatedInt32FieldNumber].Accessor.GetValue(message); 77 Assert.AreEqual(message.RepeatedInt32, list); 78 Assert.AreEqual(message.RepeatedInt32[0], list[0]); // Just in case there was any doubt... 79 80 // Just a single map field, for the same reason 81 var mapMessage = new TestMap { MapStringString = { { "key1", "value1" }, { "key2", "value2" } } }; 82 fields = TestMap.Descriptor.Fields; 83 var dictionary = (IDictionary) fields[TestMap.MapStringStringFieldNumber].Accessor.GetValue(mapMessage); 84 Assert.AreEqual(mapMessage.MapStringString, dictionary); 85 Assert.AreEqual("value1", dictionary["key1"]); 86 } 87 88 [Test] Clear()89 public void Clear() 90 { 91 var message = SampleMessages.CreateFullTestAllTypes(); 92 var fields = TestAllTypes.Descriptor.Fields; 93 fields[TestAllTypes.SingleBoolFieldNumber].Accessor.Clear(message); 94 fields[TestAllTypes.SingleInt32FieldNumber].Accessor.Clear(message); 95 fields[TestAllTypes.SingleStringFieldNumber].Accessor.Clear(message); 96 fields[TestAllTypes.SingleBytesFieldNumber].Accessor.Clear(message); 97 fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.Clear(message); 98 fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.Clear(message); 99 fields[TestAllTypes.RepeatedDoubleFieldNumber].Accessor.Clear(message); 100 101 var expected = new TestAllTypes(SampleMessages.CreateFullTestAllTypes()) 102 { 103 SingleBool = false, 104 SingleInt32 = 0, 105 SingleString = "", 106 SingleBytes = ByteString.Empty, 107 SingleForeignEnum = 0, 108 SingleForeignMessage = null, 109 }; 110 expected.RepeatedDouble.Clear(); 111 112 Assert.AreEqual(expected, message); 113 114 // Separately, maps. 115 var mapMessage = new TestMap { MapStringString = { { "key1", "value1" }, { "key2", "value2" } } }; 116 fields = TestMap.Descriptor.Fields; 117 fields[TestMap.MapStringStringFieldNumber].Accessor.Clear(mapMessage); 118 Assert.AreEqual(0, mapMessage.MapStringString.Count); 119 } 120 121 [Test] SetValue_SingleFields()122 public void SetValue_SingleFields() 123 { 124 // Just a sample (primitives, messages, enums, strings, byte strings) 125 var message = SampleMessages.CreateFullTestAllTypes(); 126 var fields = TestAllTypes.Descriptor.Fields; 127 fields[TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, false); 128 fields[TestAllTypes.SingleInt32FieldNumber].Accessor.SetValue(message, 500); 129 fields[TestAllTypes.SingleStringFieldNumber].Accessor.SetValue(message, "It's a string"); 130 fields[TestAllTypes.SingleBytesFieldNumber].Accessor.SetValue(message, ByteString.CopyFrom(99, 98, 97)); 131 fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.SetValue(message, ForeignEnum.ForeignFoo); 132 fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.SetValue(message, new ForeignMessage { C = 12345 }); 133 fields[TestAllTypes.SingleDoubleFieldNumber].Accessor.SetValue(message, 20150701.5); 134 135 var expected = new TestAllTypes(SampleMessages.CreateFullTestAllTypes()) 136 { 137 SingleBool = false, 138 SingleInt32 = 500, 139 SingleString = "It's a string", 140 SingleBytes = ByteString.CopyFrom(99, 98, 97), 141 SingleForeignEnum = ForeignEnum.ForeignFoo, 142 SingleForeignMessage = new ForeignMessage { C = 12345 }, 143 SingleDouble = 20150701.5 144 }; 145 146 Assert.AreEqual(expected, message); 147 } 148 149 [Test] SetValue_SingleFields_WrongType()150 public void SetValue_SingleFields_WrongType() 151 { 152 IMessage message = SampleMessages.CreateFullTestAllTypes(); 153 var fields = message.Descriptor.Fields; 154 Assert.Throws<InvalidCastException>(() => fields[TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, "This isn't a bool")); 155 } 156 157 [Test] SetValue_MapFields()158 public void SetValue_MapFields() 159 { 160 IMessage message = new TestMap(); 161 var fields = message.Descriptor.Fields; 162 Assert.Throws<InvalidOperationException>(() => fields[TestMap.MapStringStringFieldNumber].Accessor.SetValue(message, new Dictionary<string, string>())); 163 } 164 165 [Test] SetValue_RepeatedFields()166 public void SetValue_RepeatedFields() 167 { 168 IMessage message = SampleMessages.CreateFullTestAllTypes(); 169 var fields = message.Descriptor.Fields; 170 Assert.Throws<InvalidOperationException>(() => fields[TestAllTypes.RepeatedDoubleFieldNumber].Accessor.SetValue(message, new double[10])); 171 } 172 173 [Test] GetValue_IncorrectType()174 public void GetValue_IncorrectType() 175 { 176 IMessage message = SampleMessages.CreateFullTestAllTypes(); 177 var fields = message.Descriptor.Fields; 178 Assert.Throws<InvalidCastException>(() => fields[TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(new TestMap())); 179 } 180 181 [Test] Oneof()182 public void Oneof() 183 { 184 var message = new TestAllTypes(); 185 var descriptor = TestAllTypes.Descriptor; 186 Assert.AreEqual(1, descriptor.Oneofs.Count); 187 var oneof = descriptor.Oneofs[0]; 188 Assert.AreEqual("oneof_field", oneof.Name); 189 Assert.IsNull(oneof.Accessor.GetCaseFieldDescriptor(message)); 190 191 message.OneofString = "foo"; 192 Assert.AreSame(descriptor.Fields[TestAllTypes.OneofStringFieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message)); 193 194 message.OneofUint32 = 10; 195 Assert.AreSame(descriptor.Fields[TestAllTypes.OneofUint32FieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message)); 196 197 oneof.Accessor.Clear(message); 198 Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase); 199 } 200 201 [Test] FieldDescriptor_ByName()202 public void FieldDescriptor_ByName() 203 { 204 var descriptor = TestAllTypes.Descriptor; 205 Assert.AreSame( 206 descriptor.Fields[TestAllTypes.SingleBoolFieldNumber], 207 descriptor.Fields["single_bool"]); 208 } 209 210 [Test] FieldDescriptor_NotFound()211 public void FieldDescriptor_NotFound() 212 { 213 var descriptor = TestAllTypes.Descriptor; 214 Assert.Throws<KeyNotFoundException>(() => descriptor.Fields[999999].ToString()); 215 Assert.Throws<KeyNotFoundException>(() => descriptor.Fields["not found"].ToString()); 216 } 217 } 218 } 219