blob: 936e41c68ab43816e1bbad7544554c2c859ffc20 [file] [log] [blame]
Jon Skeet20bf6a52015-07-22 15:14:38 +01001#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
33using Google.Protobuf.TestProtos;
34using NUnit.Framework;
35using System;
36using System.Collections;
37using System.Collections.Generic;
38
39namespace Google.Protobuf.Reflection
40{
41 public class FieldAccessTest
42 {
43 [Test]
44 public void GetValue()
45 {
46 var message = SampleMessages.CreateFullTestAllTypes();
Jon Skeetc1c6b2d2015-07-22 19:57:29 +010047 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));
Jon Skeet20bf6a52015-07-22 15:14:38 +010074
75 // Just one example for repeated fields - they're all just returning the list
Jon Skeetc1c6b2d2015-07-22 19:57:29 +010076 var list = (IList) fields[TestAllTypes.RepeatedInt32FieldNumber].Accessor.GetValue(message);
Jon Skeet20bf6a52015-07-22 15:14:38 +010077 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" } } };
Jon Skeetc1c6b2d2015-07-22 19:57:29 +010082 fields = TestMap.Descriptor.Fields;
83 var dictionary = (IDictionary) fields[TestMap.MapStringStringFieldNumber].Accessor.GetValue(mapMessage);
Jon Skeet20bf6a52015-07-22 15:14:38 +010084 Assert.AreEqual(mapMessage.MapStringString, dictionary);
85 Assert.AreEqual("value1", dictionary["key1"]);
86 }
87
88 [Test]
89 public void Clear()
90 {
91 var message = SampleMessages.CreateFullTestAllTypes();
Jon Skeetc1c6b2d2015-07-22 19:57:29 +010092 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);
Jon Skeet20bf6a52015-07-22 15:14:38 +0100100
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" } } };
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100116 fields = TestMap.Descriptor.Fields;
117 fields[TestMap.MapStringStringFieldNumber].Accessor.Clear(mapMessage);
Jon Skeet20bf6a52015-07-22 15:14:38 +0100118 Assert.AreEqual(0, mapMessage.MapStringString.Count);
119 }
120
121 [Test]
122 public void SetValue_SingleFields()
123 {
124 // Just a sample (primitives, messages, enums, strings, byte strings)
125 var message = SampleMessages.CreateFullTestAllTypes();
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100126 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.FOREIGN_FOO);
132 fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.SetValue(message, new ForeignMessage { C = 12345 });
133 fields[TestAllTypes.SingleDoubleFieldNumber].Accessor.SetValue(message, 20150701.5);
Jon Skeet20bf6a52015-07-22 15:14:38 +0100134
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.FOREIGN_FOO,
142 SingleForeignMessage = new ForeignMessage { C = 12345 },
143 SingleDouble = 20150701.5
144 };
145
146 Assert.AreEqual(expected, message);
147 }
148
149 [Test]
150 public void SetValue_SingleFields_WrongType()
151 {
152 IMessage message = SampleMessages.CreateFullTestAllTypes();
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100153 var fields = message.Descriptor.Fields;
154 Assert.Throws<InvalidCastException>(() => fields[TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, "This isn't a bool"));
Jon Skeet20bf6a52015-07-22 15:14:38 +0100155 }
156
157 [Test]
158 public void SetValue_MapFields()
159 {
160 IMessage message = new TestMap();
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100161 var fields = message.Descriptor.Fields;
162 Assert.Throws<InvalidOperationException>(() => fields[TestMap.MapStringStringFieldNumber].Accessor.SetValue(message, new Dictionary<string, string>()));
Jon Skeet20bf6a52015-07-22 15:14:38 +0100163 }
164
165 [Test]
166 public void SetValue_RepeatedFields()
167 {
168 IMessage message = SampleMessages.CreateFullTestAllTypes();
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100169 var fields = message.Descriptor.Fields;
170 Assert.Throws<InvalidOperationException>(() => fields[TestAllTypes.RepeatedDoubleFieldNumber].Accessor.SetValue(message, new double[10]));
Jon Skeet20bf6a52015-07-22 15:14:38 +0100171 }
172
173 [Test]
174 public void GetValue_IncorrectType()
175 {
176 IMessage message = SampleMessages.CreateFullTestAllTypes();
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100177 var fields = message.Descriptor.Fields;
178 Assert.Throws<InvalidCastException>(() => fields[TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(new TestMap()));
Jon Skeet20bf6a52015-07-22 15:14:38 +0100179 }
180
181 [Test]
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";
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100192 Assert.AreSame(descriptor.Fields[TestAllTypes.OneofStringFieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message));
Jon Skeet20bf6a52015-07-22 15:14:38 +0100193
194 message.OneofUint32 = 10;
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100195 Assert.AreSame(descriptor.Fields[TestAllTypes.OneofUint32FieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message));
Jon Skeet20bf6a52015-07-22 15:14:38 +0100196
197 oneof.Accessor.Clear(message);
198 Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
199 }
200
201 [Test]
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100202 public void FieldDescriptor_ByName()
Jon Skeet20bf6a52015-07-22 15:14:38 +0100203 {
204 var descriptor = TestAllTypes.Descriptor;
205 Assert.AreSame(
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100206 descriptor.Fields[TestAllTypes.SingleBoolFieldNumber],
207 descriptor.Fields["single_bool"]);
Jon Skeet20bf6a52015-07-22 15:14:38 +0100208 }
209
210 [Test]
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100211 public void FieldDescriptor_NotFound()
Jon Skeet20bf6a52015-07-22 15:14:38 +0100212 {
213 var descriptor = TestAllTypes.Descriptor;
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100214 Assert.Throws<KeyNotFoundException>(() => descriptor.Fields[999999].ToString());
215 Assert.Throws<KeyNotFoundException>(() => descriptor.Fields["not found"].ToString());
Jon Skeet547d8e82015-08-07 13:37:21 +0100216 }
Jon Skeet20bf6a52015-07-22 15:14:38 +0100217 }
218}