xref: /aosp_15_r20/external/protobuf/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1*1b3f573fSAndroid Build Coastguard Worker #region Copyright notice and license
2*1b3f573fSAndroid Build Coastguard Worker // Protocol Buffers - Google's data interchange format
3*1b3f573fSAndroid Build Coastguard Worker // Copyright 2015 Google Inc.  All rights reserved.
4*1b3f573fSAndroid Build Coastguard Worker // https://developers.google.com/protocol-buffers/
5*1b3f573fSAndroid Build Coastguard Worker //
6*1b3f573fSAndroid Build Coastguard Worker // Redistribution and use in source and binary forms, with or without
7*1b3f573fSAndroid Build Coastguard Worker // modification, are permitted provided that the following conditions are
8*1b3f573fSAndroid Build Coastguard Worker // met:
9*1b3f573fSAndroid Build Coastguard Worker //
10*1b3f573fSAndroid Build Coastguard Worker //     * Redistributions of source code must retain the above copyright
11*1b3f573fSAndroid Build Coastguard Worker // notice, this list of conditions and the following disclaimer.
12*1b3f573fSAndroid Build Coastguard Worker //     * Redistributions in binary form must reproduce the above
13*1b3f573fSAndroid Build Coastguard Worker // copyright notice, this list of conditions and the following disclaimer
14*1b3f573fSAndroid Build Coastguard Worker // in the documentation and/or other materials provided with the
15*1b3f573fSAndroid Build Coastguard Worker // distribution.
16*1b3f573fSAndroid Build Coastguard Worker //     * Neither the name of Google Inc. nor the names of its
17*1b3f573fSAndroid Build Coastguard Worker // contributors may be used to endorse or promote products derived from
18*1b3f573fSAndroid Build Coastguard Worker // this software without specific prior written permission.
19*1b3f573fSAndroid Build Coastguard Worker //
20*1b3f573fSAndroid Build Coastguard Worker // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*1b3f573fSAndroid Build Coastguard Worker // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23*1b3f573fSAndroid Build Coastguard Worker // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24*1b3f573fSAndroid Build Coastguard Worker // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25*1b3f573fSAndroid Build Coastguard Worker // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27*1b3f573fSAndroid Build Coastguard Worker // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28*1b3f573fSAndroid Build Coastguard Worker // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29*1b3f573fSAndroid Build Coastguard Worker // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30*1b3f573fSAndroid Build Coastguard Worker // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*1b3f573fSAndroid Build Coastguard Worker #endregion
32*1b3f573fSAndroid Build Coastguard Worker 
33*1b3f573fSAndroid Build Coastguard Worker using System;
34*1b3f573fSAndroid Build Coastguard Worker using System.Collections;
35*1b3f573fSAndroid Build Coastguard Worker using System.Collections.Generic;
36*1b3f573fSAndroid Build Coastguard Worker using System.Collections.ObjectModel;
37*1b3f573fSAndroid Build Coastguard Worker using System.IO;
38*1b3f573fSAndroid Build Coastguard Worker using System.Linq;
39*1b3f573fSAndroid Build Coastguard Worker using System.Text;
40*1b3f573fSAndroid Build Coastguard Worker using Google.Protobuf.TestProtos;
41*1b3f573fSAndroid Build Coastguard Worker using Google.Protobuf.WellKnownTypes;
42*1b3f573fSAndroid Build Coastguard Worker using NUnit.Framework;
43*1b3f573fSAndroid Build Coastguard Worker 
44*1b3f573fSAndroid Build Coastguard Worker namespace Google.Protobuf.Collections
45*1b3f573fSAndroid Build Coastguard Worker {
46*1b3f573fSAndroid Build Coastguard Worker     public class RepeatedFieldTest
47*1b3f573fSAndroid Build Coastguard Worker     {
48*1b3f573fSAndroid Build Coastguard Worker         [Test]
NullValuesRejected()49*1b3f573fSAndroid Build Coastguard Worker         public void NullValuesRejected()
50*1b3f573fSAndroid Build Coastguard Worker         {
51*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string>();
52*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => list.Add((string)null));
53*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => list.Add((IEnumerable<string>)null));
54*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => list.Add((RepeatedField<string>)null));
55*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => list.Contains(null));
56*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => list.IndexOf(null));
57*1b3f573fSAndroid Build Coastguard Worker         }
58*1b3f573fSAndroid Build Coastguard Worker 
59*1b3f573fSAndroid Build Coastguard Worker         [Test]
Add_SingleItem()60*1b3f573fSAndroid Build Coastguard Worker         public void Add_SingleItem()
61*1b3f573fSAndroid Build Coastguard Worker         {
62*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string>();
63*1b3f573fSAndroid Build Coastguard Worker             list.Add("foo");
64*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1, list.Count);
65*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("foo", list[0]);
66*1b3f573fSAndroid Build Coastguard Worker         }
67*1b3f573fSAndroid Build Coastguard Worker 
68*1b3f573fSAndroid Build Coastguard Worker         [Test]
Add_Sequence()69*1b3f573fSAndroid Build Coastguard Worker         public void Add_Sequence()
70*1b3f573fSAndroid Build Coastguard Worker         {
71*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string>();
72*1b3f573fSAndroid Build Coastguard Worker             list.Add(new[] { "foo", "bar" });
73*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(2, list.Count);
74*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("foo", list[0]);
75*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("bar", list[1]);
76*1b3f573fSAndroid Build Coastguard Worker         }
77*1b3f573fSAndroid Build Coastguard Worker 
78*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddRange_SlowPath()79*1b3f573fSAndroid Build Coastguard Worker         public void AddRange_SlowPath()
80*1b3f573fSAndroid Build Coastguard Worker         {
81*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string>();
82*1b3f573fSAndroid Build Coastguard Worker             list.AddRange(new[] { "foo", "bar" }.Select(x => x));
83*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(2, list.Count);
84*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("foo", list[0]);
85*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("bar", list[1]);
86*1b3f573fSAndroid Build Coastguard Worker         }
87*1b3f573fSAndroid Build Coastguard Worker 
88*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddRange_SlowPath_NullsProhibited_ReferenceType()89*1b3f573fSAndroid Build Coastguard Worker         public void AddRange_SlowPath_NullsProhibited_ReferenceType()
90*1b3f573fSAndroid Build Coastguard Worker         {
91*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string>();
92*1b3f573fSAndroid Build Coastguard Worker             // It's okay for this to throw ArgumentNullException if necessary.
93*1b3f573fSAndroid Build Coastguard Worker             // It's not ideal, but not awful.
94*1b3f573fSAndroid Build Coastguard Worker             Assert.Catch<ArgumentException>(() => list.AddRange(new[] { "foo", null }.Select(x => x)));
95*1b3f573fSAndroid Build Coastguard Worker         }
96*1b3f573fSAndroid Build Coastguard Worker 
97*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddRange_SlowPath_NullsProhibited_NullableValueType()98*1b3f573fSAndroid Build Coastguard Worker         public void AddRange_SlowPath_NullsProhibited_NullableValueType()
99*1b3f573fSAndroid Build Coastguard Worker         {
100*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int?>();
101*1b3f573fSAndroid Build Coastguard Worker             // It's okay for this to throw ArgumentNullException if necessary.
102*1b3f573fSAndroid Build Coastguard Worker             // It's not ideal, but not awful.
103*1b3f573fSAndroid Build Coastguard Worker             Assert.Catch<ArgumentException>(() => list.AddRange(new[] { 20, (int?)null }.Select(x => x)));
104*1b3f573fSAndroid Build Coastguard Worker         }
105*1b3f573fSAndroid Build Coastguard Worker 
106*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddRange_Optimized_NonNullableValueType()107*1b3f573fSAndroid Build Coastguard Worker         public void AddRange_Optimized_NonNullableValueType()
108*1b3f573fSAndroid Build Coastguard Worker         {
109*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int>();
110*1b3f573fSAndroid Build Coastguard Worker             list.AddRange(new List<int> { 20, 30 });
111*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(2, list.Count);
112*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(20, list[0]);
113*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(30, list[1]);
114*1b3f573fSAndroid Build Coastguard Worker         }
115*1b3f573fSAndroid Build Coastguard Worker 
116*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddRange_Optimized_ReferenceType()117*1b3f573fSAndroid Build Coastguard Worker         public void AddRange_Optimized_ReferenceType()
118*1b3f573fSAndroid Build Coastguard Worker         {
119*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string>();
120*1b3f573fSAndroid Build Coastguard Worker             list.AddRange(new List<string> { "foo", "bar" });
121*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(2, list.Count);
122*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("foo", list[0]);
123*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("bar", list[1]);
124*1b3f573fSAndroid Build Coastguard Worker         }
125*1b3f573fSAndroid Build Coastguard Worker 
126*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddRange_Optimized_NullableValueType()127*1b3f573fSAndroid Build Coastguard Worker         public void AddRange_Optimized_NullableValueType()
128*1b3f573fSAndroid Build Coastguard Worker         {
129*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int?>();
130*1b3f573fSAndroid Build Coastguard Worker             list.AddRange(new List<int?> { 20, 30 });
131*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(2, list.Count);
132*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual((int?) 20, list[0]);
133*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual((int?) 30, list[1]);
134*1b3f573fSAndroid Build Coastguard Worker         }
135*1b3f573fSAndroid Build Coastguard Worker 
136*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddRange_Optimized_NullsProhibited_ReferenceType()137*1b3f573fSAndroid Build Coastguard Worker         public void AddRange_Optimized_NullsProhibited_ReferenceType()
138*1b3f573fSAndroid Build Coastguard Worker         {
139*1b3f573fSAndroid Build Coastguard Worker             // We don't just trust that a collection with a nullable element type doesn't contain nulls
140*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string>();
141*1b3f573fSAndroid Build Coastguard Worker             // It's okay for this to throw ArgumentNullException if necessary.
142*1b3f573fSAndroid Build Coastguard Worker             // It's not ideal, but not awful.
143*1b3f573fSAndroid Build Coastguard Worker             Assert.Catch<ArgumentException>(() => list.AddRange(new List<string> { "foo", null }));
144*1b3f573fSAndroid Build Coastguard Worker         }
145*1b3f573fSAndroid Build Coastguard Worker 
146*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddRange_Optimized_NullsProhibited_NullableValueType()147*1b3f573fSAndroid Build Coastguard Worker         public void AddRange_Optimized_NullsProhibited_NullableValueType()
148*1b3f573fSAndroid Build Coastguard Worker         {
149*1b3f573fSAndroid Build Coastguard Worker             // We don't just trust that a collection with a nullable element type doesn't contain nulls
150*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int?>();
151*1b3f573fSAndroid Build Coastguard Worker             // It's okay for this to throw ArgumentNullException if necessary.
152*1b3f573fSAndroid Build Coastguard Worker             // It's not ideal, but not awful.
153*1b3f573fSAndroid Build Coastguard Worker             Assert.Catch<ArgumentException>(() => list.AddRange(new List<int?> { 20, null }));
154*1b3f573fSAndroid Build Coastguard Worker         }
155*1b3f573fSAndroid Build Coastguard Worker 
156*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddRange_AlreadyNotEmpty()157*1b3f573fSAndroid Build Coastguard Worker         public void AddRange_AlreadyNotEmpty()
158*1b3f573fSAndroid Build Coastguard Worker         {
159*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int> { 1, 2, 3 };
160*1b3f573fSAndroid Build Coastguard Worker             list.AddRange(new List<int> { 4, 5, 6 });
161*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { 1, 2, 3, 4, 5, 6 }, list);
162*1b3f573fSAndroid Build Coastguard Worker         }
163*1b3f573fSAndroid Build Coastguard Worker 
164*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddRange_RepeatedField()165*1b3f573fSAndroid Build Coastguard Worker         public void AddRange_RepeatedField()
166*1b3f573fSAndroid Build Coastguard Worker         {
167*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string> { "original" };
168*1b3f573fSAndroid Build Coastguard Worker             list.AddRange(new RepeatedField<string> { "foo", "bar" });
169*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(3, list.Count);
170*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("original", list[0]);
171*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("foo", list[1]);
172*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("bar", list[2]);
173*1b3f573fSAndroid Build Coastguard Worker         }
174*1b3f573fSAndroid Build Coastguard Worker 
175*1b3f573fSAndroid Build Coastguard Worker         [Test]
RemoveAt_Valid()176*1b3f573fSAndroid Build Coastguard Worker         public void RemoveAt_Valid()
177*1b3f573fSAndroid Build Coastguard Worker         {
178*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string> { "first", "second", "third" };
179*1b3f573fSAndroid Build Coastguard Worker             list.RemoveAt(1);
180*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "first", "third" }, list);
181*1b3f573fSAndroid Build Coastguard Worker             // Just check that these don't throw...
182*1b3f573fSAndroid Build Coastguard Worker             list.RemoveAt(list.Count - 1); // Now the count will be 1...
183*1b3f573fSAndroid Build Coastguard Worker             list.RemoveAt(0);
184*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(0, list.Count);
185*1b3f573fSAndroid Build Coastguard Worker         }
186*1b3f573fSAndroid Build Coastguard Worker 
187*1b3f573fSAndroid Build Coastguard Worker         [Test]
RemoveAt_Invalid()188*1b3f573fSAndroid Build Coastguard Worker         public void RemoveAt_Invalid()
189*1b3f573fSAndroid Build Coastguard Worker         {
190*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string> { "first", "second", "third" };
191*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => list.RemoveAt(-1));
192*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => list.RemoveAt(3));
193*1b3f573fSAndroid Build Coastguard Worker         }
194*1b3f573fSAndroid Build Coastguard Worker 
195*1b3f573fSAndroid Build Coastguard Worker         [Test]
Insert_Valid()196*1b3f573fSAndroid Build Coastguard Worker         public void Insert_Valid()
197*1b3f573fSAndroid Build Coastguard Worker         {
198*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string> { "first", "second" };
199*1b3f573fSAndroid Build Coastguard Worker             list.Insert(1, "middle");
200*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "first", "middle", "second" }, list);
201*1b3f573fSAndroid Build Coastguard Worker             list.Insert(3, "end");
202*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "first", "middle", "second", "end" }, list);
203*1b3f573fSAndroid Build Coastguard Worker             list.Insert(0, "start");
204*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "start", "first", "middle", "second", "end" }, list);
205*1b3f573fSAndroid Build Coastguard Worker         }
206*1b3f573fSAndroid Build Coastguard Worker 
207*1b3f573fSAndroid Build Coastguard Worker         [Test]
Insert_Invalid()208*1b3f573fSAndroid Build Coastguard Worker         public void Insert_Invalid()
209*1b3f573fSAndroid Build Coastguard Worker         {
210*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string> { "first", "second" };
211*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(-1, "foo"));
212*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(3, "foo"));
213*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => list.Insert(0, null));
214*1b3f573fSAndroid Build Coastguard Worker         }
215*1b3f573fSAndroid Build Coastguard Worker 
216*1b3f573fSAndroid Build Coastguard Worker         [Test]
Equals_RepeatedField()217*1b3f573fSAndroid Build Coastguard Worker         public void Equals_RepeatedField()
218*1b3f573fSAndroid Build Coastguard Worker         {
219*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string> { "first", "second" };
220*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(list.Equals((RepeatedField<string>) null));
221*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(list.Equals(list));
222*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(list.Equals(new RepeatedField<string> { "first", "third" }));
223*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(list.Equals(new RepeatedField<string> { "first" }));
224*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(list.Equals(new RepeatedField<string> { "first", "second" }));
225*1b3f573fSAndroid Build Coastguard Worker         }
226*1b3f573fSAndroid Build Coastguard Worker 
227*1b3f573fSAndroid Build Coastguard Worker         [Test]
Equals_Object()228*1b3f573fSAndroid Build Coastguard Worker         public void Equals_Object()
229*1b3f573fSAndroid Build Coastguard Worker         {
230*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string> { "first", "second" };
231*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(list.Equals((object) null));
232*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(list.Equals((object) list));
233*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(list.Equals((object) new RepeatedField<string> { "first", "third" }));
234*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(list.Equals((object) new RepeatedField<string> { "first" }));
235*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(list.Equals((object) new RepeatedField<string> { "first", "second" }));
236*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(list.Equals(new object()));
237*1b3f573fSAndroid Build Coastguard Worker         }
238*1b3f573fSAndroid Build Coastguard Worker 
239*1b3f573fSAndroid Build Coastguard Worker         [Test]
GetEnumerator_GenericInterface()240*1b3f573fSAndroid Build Coastguard Worker         public void GetEnumerator_GenericInterface()
241*1b3f573fSAndroid Build Coastguard Worker         {
242*1b3f573fSAndroid Build Coastguard Worker             IEnumerable<string> list = new RepeatedField<string> { "first", "second" };
243*1b3f573fSAndroid Build Coastguard Worker             // Select gets rid of the optimizations in ToList...
244*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "first", "second" }, list.Select(x => x).ToList());
245*1b3f573fSAndroid Build Coastguard Worker         }
246*1b3f573fSAndroid Build Coastguard Worker 
247*1b3f573fSAndroid Build Coastguard Worker         [Test]
GetEnumerator_NonGenericInterface()248*1b3f573fSAndroid Build Coastguard Worker         public void GetEnumerator_NonGenericInterface()
249*1b3f573fSAndroid Build Coastguard Worker         {
250*1b3f573fSAndroid Build Coastguard Worker             IEnumerable list = new RepeatedField<string> { "first", "second" };
251*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "first", "second" }, list.Cast<object>().ToList());
252*1b3f573fSAndroid Build Coastguard Worker         }
253*1b3f573fSAndroid Build Coastguard Worker 
254*1b3f573fSAndroid Build Coastguard Worker         [Test]
CopyTo()255*1b3f573fSAndroid Build Coastguard Worker         public void CopyTo()
256*1b3f573fSAndroid Build Coastguard Worker         {
257*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string> { "first", "second" };
258*1b3f573fSAndroid Build Coastguard Worker             string[] stringArray = new string[4];
259*1b3f573fSAndroid Build Coastguard Worker             list.CopyTo(stringArray, 1);
260*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { null, "first", "second", null }, stringArray);
261*1b3f573fSAndroid Build Coastguard Worker         }
262*1b3f573fSAndroid Build Coastguard Worker 
263*1b3f573fSAndroid Build Coastguard Worker         [Test]
Indexer_Get()264*1b3f573fSAndroid Build Coastguard Worker         public void Indexer_Get()
265*1b3f573fSAndroid Build Coastguard Worker         {
266*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string> { "first", "second" };
267*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("first", list[0]);
268*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("second", list[1]);
269*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => list[-1].GetHashCode());
270*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => list[2].GetHashCode());
271*1b3f573fSAndroid Build Coastguard Worker         }
272*1b3f573fSAndroid Build Coastguard Worker 
273*1b3f573fSAndroid Build Coastguard Worker         [Test]
Indexer_Set()274*1b3f573fSAndroid Build Coastguard Worker         public void Indexer_Set()
275*1b3f573fSAndroid Build Coastguard Worker         {
276*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string> { "first", "second" };
277*1b3f573fSAndroid Build Coastguard Worker             list[0] = "changed";
278*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("changed", list[0]);
279*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => list[0] = null);
280*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => list[-1] = "bad");
281*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => list[2] = "bad");
282*1b3f573fSAndroid Build Coastguard Worker         }
283*1b3f573fSAndroid Build Coastguard Worker 
284*1b3f573fSAndroid Build Coastguard Worker         [Test]
Clone_ReturnsMutable()285*1b3f573fSAndroid Build Coastguard Worker         public void Clone_ReturnsMutable()
286*1b3f573fSAndroid Build Coastguard Worker         {
287*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int> { 0 };
288*1b3f573fSAndroid Build Coastguard Worker             var clone = list.Clone();
289*1b3f573fSAndroid Build Coastguard Worker             clone[0] = 1;
290*1b3f573fSAndroid Build Coastguard Worker         }
291*1b3f573fSAndroid Build Coastguard Worker 
292*1b3f573fSAndroid Build Coastguard Worker         [Test]
Enumerator()293*1b3f573fSAndroid Build Coastguard Worker         public void Enumerator()
294*1b3f573fSAndroid Build Coastguard Worker         {
295*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string> { "first", "second" };
296*1b3f573fSAndroid Build Coastguard Worker             using (var enumerator = list.GetEnumerator())
297*1b3f573fSAndroid Build Coastguard Worker             {
298*1b3f573fSAndroid Build Coastguard Worker                 Assert.IsTrue(enumerator.MoveNext());
299*1b3f573fSAndroid Build Coastguard Worker                 Assert.AreEqual("first", enumerator.Current);
300*1b3f573fSAndroid Build Coastguard Worker                 Assert.IsTrue(enumerator.MoveNext());
301*1b3f573fSAndroid Build Coastguard Worker                 Assert.AreEqual("second", enumerator.Current);
302*1b3f573fSAndroid Build Coastguard Worker                 Assert.IsFalse(enumerator.MoveNext());
303*1b3f573fSAndroid Build Coastguard Worker                 Assert.IsFalse(enumerator.MoveNext());
304*1b3f573fSAndroid Build Coastguard Worker             }
305*1b3f573fSAndroid Build Coastguard Worker         }
306*1b3f573fSAndroid Build Coastguard Worker 
307*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddEntriesFrom_PackedInt32()308*1b3f573fSAndroid Build Coastguard Worker         public void AddEntriesFrom_PackedInt32()
309*1b3f573fSAndroid Build Coastguard Worker         {
310*1b3f573fSAndroid Build Coastguard Worker             uint packedTag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
311*1b3f573fSAndroid Build Coastguard Worker             var stream = new MemoryStream();
312*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(stream);
313*1b3f573fSAndroid Build Coastguard Worker             var length = CodedOutputStream.ComputeInt32Size(10)
314*1b3f573fSAndroid Build Coastguard Worker                 + CodedOutputStream.ComputeInt32Size(999)
315*1b3f573fSAndroid Build Coastguard Worker                 + CodedOutputStream.ComputeInt32Size(-1000);
316*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(packedTag);
317*1b3f573fSAndroid Build Coastguard Worker             output.WriteRawVarint32((uint) length);
318*1b3f573fSAndroid Build Coastguard Worker             output.WriteInt32(10);
319*1b3f573fSAndroid Build Coastguard Worker             output.WriteInt32(999);
320*1b3f573fSAndroid Build Coastguard Worker             output.WriteInt32(-1000);
321*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
322*1b3f573fSAndroid Build Coastguard Worker             stream.Position = 0;
323*1b3f573fSAndroid Build Coastguard Worker 
324*1b3f573fSAndroid Build Coastguard Worker             // Deliberately "expecting" a non-packed tag, but we detect that the data is
325*1b3f573fSAndroid Build Coastguard Worker             // actually packed.
326*1b3f573fSAndroid Build Coastguard Worker             uint nonPackedTag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
327*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<int>();
328*1b3f573fSAndroid Build Coastguard Worker             var input = new CodedInputStream(stream);
329*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(packedTag);
330*1b3f573fSAndroid Build Coastguard Worker             field.AddEntriesFrom(input, FieldCodec.ForInt32(nonPackedTag));
331*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { 10, 999, -1000 }, field);
332*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(input.IsAtEnd);
333*1b3f573fSAndroid Build Coastguard Worker         }
334*1b3f573fSAndroid Build Coastguard Worker 
335*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddEntriesFrom_NonPackedInt32()336*1b3f573fSAndroid Build Coastguard Worker         public void AddEntriesFrom_NonPackedInt32()
337*1b3f573fSAndroid Build Coastguard Worker         {
338*1b3f573fSAndroid Build Coastguard Worker             uint nonPackedTag = WireFormat.MakeTag(10, WireFormat.WireType.Varint);
339*1b3f573fSAndroid Build Coastguard Worker             var stream = new MemoryStream();
340*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(stream);
341*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(nonPackedTag);
342*1b3f573fSAndroid Build Coastguard Worker             output.WriteInt32(10);
343*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(nonPackedTag);
344*1b3f573fSAndroid Build Coastguard Worker             output.WriteInt32(999);
345*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(nonPackedTag);
346*1b3f573fSAndroid Build Coastguard Worker             output.WriteInt32(-1000); // Just for variety...
347*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
348*1b3f573fSAndroid Build Coastguard Worker             stream.Position = 0;
349*1b3f573fSAndroid Build Coastguard Worker 
350*1b3f573fSAndroid Build Coastguard Worker             // Deliberately "expecting" a packed tag, but we detect that the data is
351*1b3f573fSAndroid Build Coastguard Worker             // actually not packed.
352*1b3f573fSAndroid Build Coastguard Worker             uint packedTag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
353*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<int>();
354*1b3f573fSAndroid Build Coastguard Worker             var input = new CodedInputStream(stream);
355*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(nonPackedTag);
356*1b3f573fSAndroid Build Coastguard Worker             field.AddEntriesFrom(input, FieldCodec.ForInt32(packedTag));
357*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { 10, 999, -1000 }, field);
358*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(input.IsAtEnd);
359*1b3f573fSAndroid Build Coastguard Worker         }
360*1b3f573fSAndroid Build Coastguard Worker 
361*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddEntriesFrom_String()362*1b3f573fSAndroid Build Coastguard Worker         public void AddEntriesFrom_String()
363*1b3f573fSAndroid Build Coastguard Worker         {
364*1b3f573fSAndroid Build Coastguard Worker             uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
365*1b3f573fSAndroid Build Coastguard Worker             var stream = new MemoryStream();
366*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(stream);
367*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(tag);
368*1b3f573fSAndroid Build Coastguard Worker             output.WriteString("Foo");
369*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(tag);
370*1b3f573fSAndroid Build Coastguard Worker             output.WriteString("");
371*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(tag);
372*1b3f573fSAndroid Build Coastguard Worker             output.WriteString("Bar");
373*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
374*1b3f573fSAndroid Build Coastguard Worker             stream.Position = 0;
375*1b3f573fSAndroid Build Coastguard Worker 
376*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<string>();
377*1b3f573fSAndroid Build Coastguard Worker             var input = new CodedInputStream(stream);
378*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(tag);
379*1b3f573fSAndroid Build Coastguard Worker             field.AddEntriesFrom(input, FieldCodec.ForString(tag));
380*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "Foo", "", "Bar" }, field);
381*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(input.IsAtEnd);
382*1b3f573fSAndroid Build Coastguard Worker         }
383*1b3f573fSAndroid Build Coastguard Worker 
384*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddEntriesFrom_Message()385*1b3f573fSAndroid Build Coastguard Worker         public void AddEntriesFrom_Message()
386*1b3f573fSAndroid Build Coastguard Worker         {
387*1b3f573fSAndroid Build Coastguard Worker             var message1 = new ForeignMessage { C = 2000 };
388*1b3f573fSAndroid Build Coastguard Worker             var message2 = new ForeignMessage { C = -250 };
389*1b3f573fSAndroid Build Coastguard Worker 
390*1b3f573fSAndroid Build Coastguard Worker             uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
391*1b3f573fSAndroid Build Coastguard Worker             var stream = new MemoryStream();
392*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(stream);
393*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(tag);
394*1b3f573fSAndroid Build Coastguard Worker             output.WriteMessage(message1);
395*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(tag);
396*1b3f573fSAndroid Build Coastguard Worker             output.WriteMessage(message2);
397*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
398*1b3f573fSAndroid Build Coastguard Worker             stream.Position = 0;
399*1b3f573fSAndroid Build Coastguard Worker 
400*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<ForeignMessage>();
401*1b3f573fSAndroid Build Coastguard Worker             var input = new CodedInputStream(stream);
402*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(tag);
403*1b3f573fSAndroid Build Coastguard Worker             field.AddEntriesFrom(input, FieldCodec.ForMessage(tag, ForeignMessage.Parser));
404*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { message1, message2}, field);
405*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(input.IsAtEnd);
406*1b3f573fSAndroid Build Coastguard Worker         }
407*1b3f573fSAndroid Build Coastguard Worker 
408*1b3f573fSAndroid Build Coastguard Worker         [Test]
WriteTo_PackedInt32()409*1b3f573fSAndroid Build Coastguard Worker         public void WriteTo_PackedInt32()
410*1b3f573fSAndroid Build Coastguard Worker         {
411*1b3f573fSAndroid Build Coastguard Worker             uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
412*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<int> { 10, 1000, 1000000 };
413*1b3f573fSAndroid Build Coastguard Worker             var stream = new MemoryStream();
414*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(stream);
415*1b3f573fSAndroid Build Coastguard Worker             field.WriteTo(output, FieldCodec.ForInt32(tag));
416*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
417*1b3f573fSAndroid Build Coastguard Worker             stream.Position = 0;
418*1b3f573fSAndroid Build Coastguard Worker 
419*1b3f573fSAndroid Build Coastguard Worker             var input = new CodedInputStream(stream);
420*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(tag);
421*1b3f573fSAndroid Build Coastguard Worker             var length = input.ReadLength();
422*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(10, input.ReadInt32());
423*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1000, input.ReadInt32());
424*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1000000, input.ReadInt32());
425*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(input.IsAtEnd);
426*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1 + CodedOutputStream.ComputeLengthSize(length) + length, stream.Length);
427*1b3f573fSAndroid Build Coastguard Worker         }
428*1b3f573fSAndroid Build Coastguard Worker 
429*1b3f573fSAndroid Build Coastguard Worker         [Test]
WriteTo_NonPackedInt32()430*1b3f573fSAndroid Build Coastguard Worker         public void WriteTo_NonPackedInt32()
431*1b3f573fSAndroid Build Coastguard Worker         {
432*1b3f573fSAndroid Build Coastguard Worker             uint tag = WireFormat.MakeTag(10, WireFormat.WireType.Varint);
433*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<int> { 10, 1000, 1000000};
434*1b3f573fSAndroid Build Coastguard Worker             var stream = new MemoryStream();
435*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(stream);
436*1b3f573fSAndroid Build Coastguard Worker             field.WriteTo(output, FieldCodec.ForInt32(tag));
437*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
438*1b3f573fSAndroid Build Coastguard Worker             stream.Position = 0;
439*1b3f573fSAndroid Build Coastguard Worker 
440*1b3f573fSAndroid Build Coastguard Worker             var input = new CodedInputStream(stream);
441*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(tag);
442*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(10, input.ReadInt32());
443*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(tag);
444*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1000, input.ReadInt32());
445*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(tag);
446*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1000000, input.ReadInt32());
447*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(input.IsAtEnd);
448*1b3f573fSAndroid Build Coastguard Worker         }
449*1b3f573fSAndroid Build Coastguard Worker 
450*1b3f573fSAndroid Build Coastguard Worker         [Test]
WriteTo_String()451*1b3f573fSAndroid Build Coastguard Worker         public void WriteTo_String()
452*1b3f573fSAndroid Build Coastguard Worker         {
453*1b3f573fSAndroid Build Coastguard Worker             uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
454*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<string> { "Foo", "", "Bar" };
455*1b3f573fSAndroid Build Coastguard Worker             var stream = new MemoryStream();
456*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(stream);
457*1b3f573fSAndroid Build Coastguard Worker             field.WriteTo(output, FieldCodec.ForString(tag));
458*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
459*1b3f573fSAndroid Build Coastguard Worker             stream.Position = 0;
460*1b3f573fSAndroid Build Coastguard Worker 
461*1b3f573fSAndroid Build Coastguard Worker             var input = new CodedInputStream(stream);
462*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(tag);
463*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("Foo", input.ReadString());
464*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(tag);
465*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("", input.ReadString());
466*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(tag);
467*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("Bar", input.ReadString());
468*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(input.IsAtEnd);
469*1b3f573fSAndroid Build Coastguard Worker         }
470*1b3f573fSAndroid Build Coastguard Worker 
471*1b3f573fSAndroid Build Coastguard Worker         [Test]
WriteTo_Message()472*1b3f573fSAndroid Build Coastguard Worker         public void WriteTo_Message()
473*1b3f573fSAndroid Build Coastguard Worker         {
474*1b3f573fSAndroid Build Coastguard Worker             var message1 = new ForeignMessage { C = 20 };
475*1b3f573fSAndroid Build Coastguard Worker             var message2 = new ForeignMessage { C = 25 };
476*1b3f573fSAndroid Build Coastguard Worker             uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
477*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<ForeignMessage> { message1, message2 };
478*1b3f573fSAndroid Build Coastguard Worker             var stream = new MemoryStream();
479*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(stream);
480*1b3f573fSAndroid Build Coastguard Worker             field.WriteTo(output, FieldCodec.ForMessage(tag, ForeignMessage.Parser));
481*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
482*1b3f573fSAndroid Build Coastguard Worker             stream.Position = 0;
483*1b3f573fSAndroid Build Coastguard Worker 
484*1b3f573fSAndroid Build Coastguard Worker             var input = new CodedInputStream(stream);
485*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(tag);
486*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(message1, input.ReadMessage(ForeignMessage.Parser));
487*1b3f573fSAndroid Build Coastguard Worker             input.AssertNextTag(tag);
488*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(message2, input.ReadMessage(ForeignMessage.Parser));
489*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(input.IsAtEnd);
490*1b3f573fSAndroid Build Coastguard Worker         }
491*1b3f573fSAndroid Build Coastguard Worker 
492*1b3f573fSAndroid Build Coastguard Worker         [Test]
CalculateSize_VariableSizeNonPacked()493*1b3f573fSAndroid Build Coastguard Worker         public void CalculateSize_VariableSizeNonPacked()
494*1b3f573fSAndroid Build Coastguard Worker         {
495*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int> { 1, 500, 1 };
496*1b3f573fSAndroid Build Coastguard Worker             var tag = WireFormat.MakeTag(1, WireFormat.WireType.Varint);
497*1b3f573fSAndroid Build Coastguard Worker             // 2 bytes for the first entry, 3 bytes for the second, 2 bytes for the third
498*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(7, list.CalculateSize(FieldCodec.ForInt32(tag)));
499*1b3f573fSAndroid Build Coastguard Worker         }
500*1b3f573fSAndroid Build Coastguard Worker 
501*1b3f573fSAndroid Build Coastguard Worker         [Test]
CalculateSize_FixedSizeNonPacked()502*1b3f573fSAndroid Build Coastguard Worker         public void CalculateSize_FixedSizeNonPacked()
503*1b3f573fSAndroid Build Coastguard Worker         {
504*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int> { 1, 500, 1 };
505*1b3f573fSAndroid Build Coastguard Worker             var tag = WireFormat.MakeTag(1, WireFormat.WireType.Fixed32);
506*1b3f573fSAndroid Build Coastguard Worker             // 5 bytes for the each entry
507*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(15, list.CalculateSize(FieldCodec.ForSFixed32(tag)));
508*1b3f573fSAndroid Build Coastguard Worker         }
509*1b3f573fSAndroid Build Coastguard Worker 
510*1b3f573fSAndroid Build Coastguard Worker         [Test]
CalculateSize_VariableSizePacked()511*1b3f573fSAndroid Build Coastguard Worker         public void CalculateSize_VariableSizePacked()
512*1b3f573fSAndroid Build Coastguard Worker         {
513*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int> { 1, 500, 1};
514*1b3f573fSAndroid Build Coastguard Worker             var tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
515*1b3f573fSAndroid Build Coastguard Worker             // 1 byte for the tag, 1 byte for the length,
516*1b3f573fSAndroid Build Coastguard Worker             // 1 byte for the first entry, 2 bytes for the second, 1 byte for the third
517*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(6, list.CalculateSize(FieldCodec.ForInt32(tag)));
518*1b3f573fSAndroid Build Coastguard Worker         }
519*1b3f573fSAndroid Build Coastguard Worker 
520*1b3f573fSAndroid Build Coastguard Worker         [Test]
CalculateSize_FixedSizePacked()521*1b3f573fSAndroid Build Coastguard Worker         public void CalculateSize_FixedSizePacked()
522*1b3f573fSAndroid Build Coastguard Worker         {
523*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int> { 1, 500, 1 };
524*1b3f573fSAndroid Build Coastguard Worker             var tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
525*1b3f573fSAndroid Build Coastguard Worker             // 1 byte for the tag, 1 byte for the length, 4 bytes per entry
526*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(14, list.CalculateSize(FieldCodec.ForSFixed32(tag)));
527*1b3f573fSAndroid Build Coastguard Worker         }
528*1b3f573fSAndroid Build Coastguard Worker 
529*1b3f573fSAndroid Build Coastguard Worker         [Test]
TestNegativeEnumArray()530*1b3f573fSAndroid Build Coastguard Worker         public void TestNegativeEnumArray()
531*1b3f573fSAndroid Build Coastguard Worker         {
532*1b3f573fSAndroid Build Coastguard Worker             int arraySize = 1 + 1 + (11 * 5);
533*1b3f573fSAndroid Build Coastguard Worker             int msgSize = arraySize;
534*1b3f573fSAndroid Build Coastguard Worker             byte[] bytes = new byte[msgSize];
535*1b3f573fSAndroid Build Coastguard Worker             CodedOutputStream output = new CodedOutputStream(bytes);
536*1b3f573fSAndroid Build Coastguard Worker             uint tag = WireFormat.MakeTag(8, WireFormat.WireType.Varint);
537*1b3f573fSAndroid Build Coastguard Worker             for (int i = 0; i >= -5; i--)
538*1b3f573fSAndroid Build Coastguard Worker             {
539*1b3f573fSAndroid Build Coastguard Worker                 output.WriteTag(tag);
540*1b3f573fSAndroid Build Coastguard Worker                 output.WriteEnum(i);
541*1b3f573fSAndroid Build Coastguard Worker             }
542*1b3f573fSAndroid Build Coastguard Worker 
543*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(0, output.SpaceLeft);
544*1b3f573fSAndroid Build Coastguard Worker 
545*1b3f573fSAndroid Build Coastguard Worker             CodedInputStream input = new CodedInputStream(bytes);
546*1b3f573fSAndroid Build Coastguard Worker             tag = input.ReadTag();
547*1b3f573fSAndroid Build Coastguard Worker 
548*1b3f573fSAndroid Build Coastguard Worker             RepeatedField<SampleEnum> values = new RepeatedField<SampleEnum>();
549*1b3f573fSAndroid Build Coastguard Worker             values.AddEntriesFrom(input, FieldCodec.ForEnum(tag, x => (int)x, x => (SampleEnum)x));
550*1b3f573fSAndroid Build Coastguard Worker 
551*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(6, values.Count);
552*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(SampleEnum.None, values[0]);
553*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(((SampleEnum)(-1)), values[1]);
554*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(SampleEnum.NegativeValue, values[2]);
555*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(((SampleEnum)(-3)), values[3]);
556*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(((SampleEnum)(-4)), values[4]);
557*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(((SampleEnum)(-5)), values[5]);
558*1b3f573fSAndroid Build Coastguard Worker         }
559*1b3f573fSAndroid Build Coastguard Worker 
560*1b3f573fSAndroid Build Coastguard Worker 
561*1b3f573fSAndroid Build Coastguard Worker         [Test]
TestNegativeEnumPackedArray()562*1b3f573fSAndroid Build Coastguard Worker         public void TestNegativeEnumPackedArray()
563*1b3f573fSAndroid Build Coastguard Worker         {
564*1b3f573fSAndroid Build Coastguard Worker             int arraySize = 1 + (10 * 5);
565*1b3f573fSAndroid Build Coastguard Worker             int msgSize = 1 + 1 + arraySize;
566*1b3f573fSAndroid Build Coastguard Worker             byte[] bytes = new byte[msgSize];
567*1b3f573fSAndroid Build Coastguard Worker             CodedOutputStream output = new CodedOutputStream(bytes);
568*1b3f573fSAndroid Build Coastguard Worker             // Length-delimited to show we want the packed representation
569*1b3f573fSAndroid Build Coastguard Worker             uint tag = WireFormat.MakeTag(8, WireFormat.WireType.LengthDelimited);
570*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(tag);
571*1b3f573fSAndroid Build Coastguard Worker             int size = 0;
572*1b3f573fSAndroid Build Coastguard Worker             for (int i = 0; i >= -5; i--)
573*1b3f573fSAndroid Build Coastguard Worker             {
574*1b3f573fSAndroid Build Coastguard Worker                 size += CodedOutputStream.ComputeEnumSize(i);
575*1b3f573fSAndroid Build Coastguard Worker             }
576*1b3f573fSAndroid Build Coastguard Worker             output.WriteRawVarint32((uint)size);
577*1b3f573fSAndroid Build Coastguard Worker             for (int i = 0; i >= -5; i--)
578*1b3f573fSAndroid Build Coastguard Worker             {
579*1b3f573fSAndroid Build Coastguard Worker                 output.WriteEnum(i);
580*1b3f573fSAndroid Build Coastguard Worker             }
581*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(0, output.SpaceLeft);
582*1b3f573fSAndroid Build Coastguard Worker 
583*1b3f573fSAndroid Build Coastguard Worker             CodedInputStream input = new CodedInputStream(bytes);
584*1b3f573fSAndroid Build Coastguard Worker             tag = input.ReadTag();
585*1b3f573fSAndroid Build Coastguard Worker 
586*1b3f573fSAndroid Build Coastguard Worker             RepeatedField<SampleEnum> values = new RepeatedField<SampleEnum>();
587*1b3f573fSAndroid Build Coastguard Worker             values.AddEntriesFrom(input, FieldCodec.ForEnum(tag, x => (int)x, x => (SampleEnum)x));
588*1b3f573fSAndroid Build Coastguard Worker 
589*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(6, values.Count);
590*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(SampleEnum.None, values[0]);
591*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(((SampleEnum)(-1)), values[1]);
592*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(SampleEnum.NegativeValue, values[2]);
593*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(((SampleEnum)(-3)), values[3]);
594*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(((SampleEnum)(-4)), values[4]);
595*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(((SampleEnum)(-5)), values[5]);
596*1b3f573fSAndroid Build Coastguard Worker         }
597*1b3f573fSAndroid Build Coastguard Worker 
598*1b3f573fSAndroid Build Coastguard Worker         [Test]
TestPackedRepeatedFieldCollectionNonDivisibleLength()599*1b3f573fSAndroid Build Coastguard Worker         public void TestPackedRepeatedFieldCollectionNonDivisibleLength()
600*1b3f573fSAndroid Build Coastguard Worker         {
601*1b3f573fSAndroid Build Coastguard Worker             uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
602*1b3f573fSAndroid Build Coastguard Worker             var codec = FieldCodec.ForFixed32(tag);
603*1b3f573fSAndroid Build Coastguard Worker             var stream = new MemoryStream();
604*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(stream);
605*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(tag);
606*1b3f573fSAndroid Build Coastguard Worker             output.WriteString("A long string");
607*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(codec.Tag);
608*1b3f573fSAndroid Build Coastguard Worker             output.WriteRawVarint32((uint)codec.FixedSize - 1); // Length not divisible by FixedSize
609*1b3f573fSAndroid Build Coastguard Worker             output.WriteFixed32(uint.MaxValue);
610*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
611*1b3f573fSAndroid Build Coastguard Worker             stream.Position = 0;
612*1b3f573fSAndroid Build Coastguard Worker 
613*1b3f573fSAndroid Build Coastguard Worker             var input = new CodedInputStream(stream);
614*1b3f573fSAndroid Build Coastguard Worker             input.ReadTag();
615*1b3f573fSAndroid Build Coastguard Worker             input.ReadString();
616*1b3f573fSAndroid Build Coastguard Worker             input.ReadTag();
617*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<uint>();
618*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<InvalidProtocolBufferException>(() => field.AddEntriesFrom(input, codec));
619*1b3f573fSAndroid Build Coastguard Worker 
620*1b3f573fSAndroid Build Coastguard Worker             // Collection was not pre-initialized
621*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(0, field.Count);
622*1b3f573fSAndroid Build Coastguard Worker         }
623*1b3f573fSAndroid Build Coastguard Worker 
624*1b3f573fSAndroid Build Coastguard Worker         [Test]
TestPackedRepeatedFieldCollectionNotAllocatedWhenLengthExceedsBuffer()625*1b3f573fSAndroid Build Coastguard Worker         public void TestPackedRepeatedFieldCollectionNotAllocatedWhenLengthExceedsBuffer()
626*1b3f573fSAndroid Build Coastguard Worker         {
627*1b3f573fSAndroid Build Coastguard Worker             uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
628*1b3f573fSAndroid Build Coastguard Worker             var codec = FieldCodec.ForFixed32(tag);
629*1b3f573fSAndroid Build Coastguard Worker             var stream = new MemoryStream();
630*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(stream);
631*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(tag);
632*1b3f573fSAndroid Build Coastguard Worker             output.WriteString("A long string");
633*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(codec.Tag);
634*1b3f573fSAndroid Build Coastguard Worker             output.WriteRawVarint32((uint)codec.FixedSize);
635*1b3f573fSAndroid Build Coastguard Worker             // Note that there is no content for the packed field.
636*1b3f573fSAndroid Build Coastguard Worker             // The field length exceeds the remaining length of content.
637*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
638*1b3f573fSAndroid Build Coastguard Worker             stream.Position = 0;
639*1b3f573fSAndroid Build Coastguard Worker 
640*1b3f573fSAndroid Build Coastguard Worker             var input = new CodedInputStream(stream);
641*1b3f573fSAndroid Build Coastguard Worker             input.ReadTag();
642*1b3f573fSAndroid Build Coastguard Worker             input.ReadString();
643*1b3f573fSAndroid Build Coastguard Worker             input.ReadTag();
644*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<uint>();
645*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<InvalidProtocolBufferException>(() => field.AddEntriesFrom(input, codec));
646*1b3f573fSAndroid Build Coastguard Worker 
647*1b3f573fSAndroid Build Coastguard Worker             // Collection was not pre-initialized
648*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(0, field.Count);
649*1b3f573fSAndroid Build Coastguard Worker         }
650*1b3f573fSAndroid Build Coastguard Worker 
651*1b3f573fSAndroid Build Coastguard Worker         [Test]
TestPackedRepeatedFieldCollectionNotAllocatedWhenLengthExceedsRemainingData()652*1b3f573fSAndroid Build Coastguard Worker         public void TestPackedRepeatedFieldCollectionNotAllocatedWhenLengthExceedsRemainingData()
653*1b3f573fSAndroid Build Coastguard Worker         {
654*1b3f573fSAndroid Build Coastguard Worker             uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited);
655*1b3f573fSAndroid Build Coastguard Worker             var codec = FieldCodec.ForFixed32(tag);
656*1b3f573fSAndroid Build Coastguard Worker             var stream = new MemoryStream();
657*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(stream);
658*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(tag);
659*1b3f573fSAndroid Build Coastguard Worker             output.WriteString("A long string");
660*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(codec.Tag);
661*1b3f573fSAndroid Build Coastguard Worker             output.WriteRawVarint32((uint)codec.FixedSize);
662*1b3f573fSAndroid Build Coastguard Worker             // Note that there is no content for the packed field.
663*1b3f573fSAndroid Build Coastguard Worker             // The field length exceeds the remaining length of the buffer.
664*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
665*1b3f573fSAndroid Build Coastguard Worker             stream.Position = 0;
666*1b3f573fSAndroid Build Coastguard Worker 
667*1b3f573fSAndroid Build Coastguard Worker             var sequence = ReadOnlySequenceFactory.CreateWithContent(stream.ToArray());
668*1b3f573fSAndroid Build Coastguard Worker             ParseContext.Initialize(sequence, out ParseContext ctx);
669*1b3f573fSAndroid Build Coastguard Worker 
670*1b3f573fSAndroid Build Coastguard Worker             ctx.ReadTag();
671*1b3f573fSAndroid Build Coastguard Worker             ctx.ReadString();
672*1b3f573fSAndroid Build Coastguard Worker             ctx.ReadTag();
673*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<uint>();
674*1b3f573fSAndroid Build Coastguard Worker             try
675*1b3f573fSAndroid Build Coastguard Worker             {
676*1b3f573fSAndroid Build Coastguard Worker                 field.AddEntriesFrom(ref ctx, codec);
677*1b3f573fSAndroid Build Coastguard Worker                 Assert.Fail();
678*1b3f573fSAndroid Build Coastguard Worker             }
679*1b3f573fSAndroid Build Coastguard Worker             catch (InvalidProtocolBufferException)
680*1b3f573fSAndroid Build Coastguard Worker             {
681*1b3f573fSAndroid Build Coastguard Worker             }
682*1b3f573fSAndroid Build Coastguard Worker 
683*1b3f573fSAndroid Build Coastguard Worker             // Collection was not pre-initialized
684*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(0, field.Count);
685*1b3f573fSAndroid Build Coastguard Worker         }
686*1b3f573fSAndroid Build Coastguard Worker 
687*1b3f573fSAndroid Build Coastguard Worker         // Fairly perfunctory tests for the non-generic IList implementation
688*1b3f573fSAndroid Build Coastguard Worker         [Test]
IList_Indexer()689*1b3f573fSAndroid Build Coastguard Worker         public void IList_Indexer()
690*1b3f573fSAndroid Build Coastguard Worker         {
691*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<string> { "first", "second" };
692*1b3f573fSAndroid Build Coastguard Worker             IList list = field;
693*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("first", list[0]);
694*1b3f573fSAndroid Build Coastguard Worker             list[1] = "changed";
695*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("changed", field[1]);
696*1b3f573fSAndroid Build Coastguard Worker         }
697*1b3f573fSAndroid Build Coastguard Worker 
698*1b3f573fSAndroid Build Coastguard Worker         [Test]
IList_Contains()699*1b3f573fSAndroid Build Coastguard Worker         public void IList_Contains()
700*1b3f573fSAndroid Build Coastguard Worker         {
701*1b3f573fSAndroid Build Coastguard Worker             IList list = new RepeatedField<string> { "first", "second" };
702*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(list.Contains("second"));
703*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(list.Contains("third"));
704*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(list.Contains(new object()));
705*1b3f573fSAndroid Build Coastguard Worker         }
706*1b3f573fSAndroid Build Coastguard Worker 
707*1b3f573fSAndroid Build Coastguard Worker         [Test]
IList_Add()708*1b3f573fSAndroid Build Coastguard Worker         public void IList_Add()
709*1b3f573fSAndroid Build Coastguard Worker         {
710*1b3f573fSAndroid Build Coastguard Worker             IList list = new RepeatedField<string> { "first", "second" };
711*1b3f573fSAndroid Build Coastguard Worker             list.Add("third");
712*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "first", "second", "third" }, list);
713*1b3f573fSAndroid Build Coastguard Worker         }
714*1b3f573fSAndroid Build Coastguard Worker 
715*1b3f573fSAndroid Build Coastguard Worker         [Test]
IList_Remove()716*1b3f573fSAndroid Build Coastguard Worker         public void IList_Remove()
717*1b3f573fSAndroid Build Coastguard Worker         {
718*1b3f573fSAndroid Build Coastguard Worker             IList list = new RepeatedField<string> { "first", "second" };
719*1b3f573fSAndroid Build Coastguard Worker             list.Remove("third"); // No-op, no exception
720*1b3f573fSAndroid Build Coastguard Worker             list.Remove(new object()); // No-op, no exception
721*1b3f573fSAndroid Build Coastguard Worker             list.Remove("first");
722*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "second" }, list);
723*1b3f573fSAndroid Build Coastguard Worker         }
724*1b3f573fSAndroid Build Coastguard Worker 
725*1b3f573fSAndroid Build Coastguard Worker         [Test]
IList_IsFixedSize()726*1b3f573fSAndroid Build Coastguard Worker         public void IList_IsFixedSize()
727*1b3f573fSAndroid Build Coastguard Worker         {
728*1b3f573fSAndroid Build Coastguard Worker             var field = new RepeatedField<string> { "first", "second" };
729*1b3f573fSAndroid Build Coastguard Worker             IList list = field;
730*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(list.IsFixedSize);
731*1b3f573fSAndroid Build Coastguard Worker         }
732*1b3f573fSAndroid Build Coastguard Worker 
733*1b3f573fSAndroid Build Coastguard Worker         [Test]
IList_IndexOf()734*1b3f573fSAndroid Build Coastguard Worker         public void IList_IndexOf()
735*1b3f573fSAndroid Build Coastguard Worker         {
736*1b3f573fSAndroid Build Coastguard Worker             IList list = new RepeatedField<string> { "first", "second" };
737*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1, list.IndexOf("second"));
738*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(-1, list.IndexOf("third"));
739*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(-1, list.IndexOf(new object()));
740*1b3f573fSAndroid Build Coastguard Worker         }
741*1b3f573fSAndroid Build Coastguard Worker 
742*1b3f573fSAndroid Build Coastguard Worker         [Test]
IList_SyncRoot()743*1b3f573fSAndroid Build Coastguard Worker         public void IList_SyncRoot()
744*1b3f573fSAndroid Build Coastguard Worker         {
745*1b3f573fSAndroid Build Coastguard Worker             IList list = new RepeatedField<string> { "first", "second" };
746*1b3f573fSAndroid Build Coastguard Worker             Assert.AreSame(list, list.SyncRoot);
747*1b3f573fSAndroid Build Coastguard Worker         }
748*1b3f573fSAndroid Build Coastguard Worker 
749*1b3f573fSAndroid Build Coastguard Worker         [Test]
IList_CopyTo()750*1b3f573fSAndroid Build Coastguard Worker         public void IList_CopyTo()
751*1b3f573fSAndroid Build Coastguard Worker         {
752*1b3f573fSAndroid Build Coastguard Worker             IList list = new RepeatedField<string> { "first", "second" };
753*1b3f573fSAndroid Build Coastguard Worker             string[] stringArray = new string[4];
754*1b3f573fSAndroid Build Coastguard Worker             list.CopyTo(stringArray, 1);
755*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { null, "first",  "second", null }, stringArray);
756*1b3f573fSAndroid Build Coastguard Worker 
757*1b3f573fSAndroid Build Coastguard Worker             object[] objectArray = new object[4];
758*1b3f573fSAndroid Build Coastguard Worker             list.CopyTo(objectArray, 1);
759*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { null, "first", "second", null }, objectArray);
760*1b3f573fSAndroid Build Coastguard Worker 
761*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArrayTypeMismatchException>(() => list.CopyTo(new StringBuilder[4], 1));
762*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArrayTypeMismatchException>(() => list.CopyTo(new int[4], 1));
763*1b3f573fSAndroid Build Coastguard Worker         }
764*1b3f573fSAndroid Build Coastguard Worker 
765*1b3f573fSAndroid Build Coastguard Worker         [Test]
IList_IsSynchronized()766*1b3f573fSAndroid Build Coastguard Worker         public void IList_IsSynchronized()
767*1b3f573fSAndroid Build Coastguard Worker         {
768*1b3f573fSAndroid Build Coastguard Worker             IList list = new RepeatedField<string> { "first", "second" };
769*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(list.IsSynchronized);
770*1b3f573fSAndroid Build Coastguard Worker         }
771*1b3f573fSAndroid Build Coastguard Worker 
772*1b3f573fSAndroid Build Coastguard Worker         [Test]
IList_Insert()773*1b3f573fSAndroid Build Coastguard Worker         public void IList_Insert()
774*1b3f573fSAndroid Build Coastguard Worker         {
775*1b3f573fSAndroid Build Coastguard Worker             IList list = new RepeatedField<string> { "first", "second" };
776*1b3f573fSAndroid Build Coastguard Worker             list.Insert(1, "middle");
777*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "first", "middle", "second" }, list);
778*1b3f573fSAndroid Build Coastguard Worker         }
779*1b3f573fSAndroid Build Coastguard Worker 
780*1b3f573fSAndroid Build Coastguard Worker         [Test]
ToString_Integers()781*1b3f573fSAndroid Build Coastguard Worker         public void ToString_Integers()
782*1b3f573fSAndroid Build Coastguard Worker         {
783*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int> { 5, 10, 20 };
784*1b3f573fSAndroid Build Coastguard Worker             var text = list.ToString();
785*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("[ 5, 10, 20 ]", text);
786*1b3f573fSAndroid Build Coastguard Worker         }
787*1b3f573fSAndroid Build Coastguard Worker 
788*1b3f573fSAndroid Build Coastguard Worker         [Test]
ToString_Strings()789*1b3f573fSAndroid Build Coastguard Worker         public void ToString_Strings()
790*1b3f573fSAndroid Build Coastguard Worker         {
791*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<string> { "x", "y", "z" };
792*1b3f573fSAndroid Build Coastguard Worker             var text = list.ToString();
793*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("[ \"x\", \"y\", \"z\" ]", text);
794*1b3f573fSAndroid Build Coastguard Worker         }
795*1b3f573fSAndroid Build Coastguard Worker 
796*1b3f573fSAndroid Build Coastguard Worker         [Test]
ToString_Messages()797*1b3f573fSAndroid Build Coastguard Worker         public void ToString_Messages()
798*1b3f573fSAndroid Build Coastguard Worker         {
799*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<TestAllTypes> { new TestAllTypes { SingleDouble = 1.5 }, new TestAllTypes { SingleInt32 = 10 } };
800*1b3f573fSAndroid Build Coastguard Worker             var text = list.ToString();
801*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("[ { \"singleDouble\": 1.5 }, { \"singleInt32\": 10 } ]", text);
802*1b3f573fSAndroid Build Coastguard Worker         }
803*1b3f573fSAndroid Build Coastguard Worker 
804*1b3f573fSAndroid Build Coastguard Worker         [Test]
ToString_Empty()805*1b3f573fSAndroid Build Coastguard Worker         public void ToString_Empty()
806*1b3f573fSAndroid Build Coastguard Worker         {
807*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<TestAllTypes> { };
808*1b3f573fSAndroid Build Coastguard Worker             var text = list.ToString();
809*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("[ ]", text);
810*1b3f573fSAndroid Build Coastguard Worker         }
811*1b3f573fSAndroid Build Coastguard Worker 
812*1b3f573fSAndroid Build Coastguard Worker         [Test]
ToString_InvalidElementType()813*1b3f573fSAndroid Build Coastguard Worker         public void ToString_InvalidElementType()
814*1b3f573fSAndroid Build Coastguard Worker         {
815*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<decimal> { 15m };
816*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentException>(() => list.ToString());
817*1b3f573fSAndroid Build Coastguard Worker         }
818*1b3f573fSAndroid Build Coastguard Worker 
819*1b3f573fSAndroid Build Coastguard Worker         [Test]
ToString_Timestamp()820*1b3f573fSAndroid Build Coastguard Worker         public void ToString_Timestamp()
821*1b3f573fSAndroid Build Coastguard Worker         {
822*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<Timestamp> { Timestamp.FromDateTime(new DateTime(2015, 10, 1, 12, 34, 56, DateTimeKind.Utc)) };
823*1b3f573fSAndroid Build Coastguard Worker             var text = list.ToString();
824*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("[ \"2015-10-01T12:34:56Z\" ]", text);
825*1b3f573fSAndroid Build Coastguard Worker         }
826*1b3f573fSAndroid Build Coastguard Worker 
827*1b3f573fSAndroid Build Coastguard Worker         [Test]
ToString_Struct()828*1b3f573fSAndroid Build Coastguard Worker         public void ToString_Struct()
829*1b3f573fSAndroid Build Coastguard Worker         {
830*1b3f573fSAndroid Build Coastguard Worker             var message = new Struct { Fields = { { "foo", new Value { NumberValue = 20 } } } };
831*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<Struct> { message };
832*1b3f573fSAndroid Build Coastguard Worker             var text = list.ToString();
833*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(text, "[ { \"foo\": 20 } ]", message.ToString());
834*1b3f573fSAndroid Build Coastguard Worker         }
835*1b3f573fSAndroid Build Coastguard Worker 
836*1b3f573fSAndroid Build Coastguard Worker         [Test]
NaNValuesComparedBitwise()837*1b3f573fSAndroid Build Coastguard Worker         public void NaNValuesComparedBitwise()
838*1b3f573fSAndroid Build Coastguard Worker         {
839*1b3f573fSAndroid Build Coastguard Worker             var list1 = new RepeatedField<double> { SampleNaNs.Regular, SampleNaNs.SignallingFlipped };
840*1b3f573fSAndroid Build Coastguard Worker             var list2 = new RepeatedField<double> { SampleNaNs.Regular, SampleNaNs.PayloadFlipped };
841*1b3f573fSAndroid Build Coastguard Worker             var list3 = new RepeatedField<double> { SampleNaNs.Regular, SampleNaNs.SignallingFlipped };
842*1b3f573fSAndroid Build Coastguard Worker 
843*1b3f573fSAndroid Build Coastguard Worker             // All SampleNaNs have the same hashcode under certain targets (e.g. netcoreapp3.1)
844*1b3f573fSAndroid Build Coastguard Worker             EqualityTester.AssertInequality(list1, list2, checkHashcode: false);
845*1b3f573fSAndroid Build Coastguard Worker             EqualityTester.AssertEquality(list1, list3);
846*1b3f573fSAndroid Build Coastguard Worker             Assert.True(list1.Contains(SampleNaNs.SignallingFlipped));
847*1b3f573fSAndroid Build Coastguard Worker             Assert.False(list2.Contains(SampleNaNs.SignallingFlipped));
848*1b3f573fSAndroid Build Coastguard Worker         }
849*1b3f573fSAndroid Build Coastguard Worker 
850*1b3f573fSAndroid Build Coastguard Worker         [Test]
Capacity_Increase()851*1b3f573fSAndroid Build Coastguard Worker         public void Capacity_Increase()
852*1b3f573fSAndroid Build Coastguard Worker         {
853*1b3f573fSAndroid Build Coastguard Worker             // Unfortunately this case tests implementation details of RepeatedField.  This is necessary
854*1b3f573fSAndroid Build Coastguard Worker 
855*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int>() { 1, 2, 3 };
856*1b3f573fSAndroid Build Coastguard Worker 
857*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(8, list.Capacity);
858*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(3, list.Count);
859*1b3f573fSAndroid Build Coastguard Worker 
860*1b3f573fSAndroid Build Coastguard Worker             list.Capacity = 10; // Set capacity to a larger value to trigger growth
861*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(10, list.Capacity, "Capacity increased");
862*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(3, list.Count);
863*1b3f573fSAndroid Build Coastguard Worker 
864*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new int[] {1, 2, 3}, list.ToArray(), "We didn't lose our data in the resize");
865*1b3f573fSAndroid Build Coastguard Worker         }
866*1b3f573fSAndroid Build Coastguard Worker 
867*1b3f573fSAndroid Build Coastguard Worker         [Test]
Capacity_Decrease()868*1b3f573fSAndroid Build Coastguard Worker         public void Capacity_Decrease()
869*1b3f573fSAndroid Build Coastguard Worker         {
870*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int>() { 1, 2, 3 };
871*1b3f573fSAndroid Build Coastguard Worker 
872*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(8, list.Capacity);
873*1b3f573fSAndroid Build Coastguard Worker             Assert.DoesNotThrow(() => list.Capacity = 5, "Can decrease capacity if new capacity is greater than list.Count");
874*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(5, list.Capacity);
875*1b3f573fSAndroid Build Coastguard Worker 
876*1b3f573fSAndroid Build Coastguard Worker             Assert.DoesNotThrow(() => list.Capacity = 3, "Can set capacity exactly to list.Count" );
877*1b3f573fSAndroid Build Coastguard Worker 
878*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => list.Capacity = 2, "Can't set the capacity smaller than list.Count" );
879*1b3f573fSAndroid Build Coastguard Worker 
880*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => list.Capacity = 0, "Can't set the capacity to zero" );
881*1b3f573fSAndroid Build Coastguard Worker 
882*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => list.Capacity = -1, "Can't set the capacity to negative" );
883*1b3f573fSAndroid Build Coastguard Worker         }
884*1b3f573fSAndroid Build Coastguard Worker 
885*1b3f573fSAndroid Build Coastguard Worker         [Test]
Capacity_Zero()886*1b3f573fSAndroid Build Coastguard Worker         public void Capacity_Zero()
887*1b3f573fSAndroid Build Coastguard Worker         {
888*1b3f573fSAndroid Build Coastguard Worker             var list = new RepeatedField<int>() { 1 };
889*1b3f573fSAndroid Build Coastguard Worker             list.RemoveAt(0);
890*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(0, list.Count);
891*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(8, list.Capacity);
892*1b3f573fSAndroid Build Coastguard Worker 
893*1b3f573fSAndroid Build Coastguard Worker             Assert.DoesNotThrow(() => list.Capacity = 0, "Can set Capacity to 0");
894*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(0, list.Capacity);
895*1b3f573fSAndroid Build Coastguard Worker         }
896*1b3f573fSAndroid Build Coastguard Worker     }
897*1b3f573fSAndroid Build Coastguard Worker }
898