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