xref: /aosp_15_r20/external/protobuf/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.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.IO;
35*1b3f573fSAndroid Build Coastguard Worker using System.Collections.Generic;
36*1b3f573fSAndroid Build Coastguard Worker using Google.Protobuf.TestProtos;
37*1b3f573fSAndroid Build Coastguard Worker using NUnit.Framework;
38*1b3f573fSAndroid Build Coastguard Worker using System.Collections;
39*1b3f573fSAndroid Build Coastguard Worker using System.Linq;
40*1b3f573fSAndroid Build Coastguard Worker 
41*1b3f573fSAndroid Build Coastguard Worker namespace Google.Protobuf.Collections
42*1b3f573fSAndroid Build Coastguard Worker {
43*1b3f573fSAndroid Build Coastguard Worker     /// <summary>
44*1b3f573fSAndroid Build Coastguard Worker     /// Tests for MapField which aren't reliant on the encoded format -
45*1b3f573fSAndroid Build Coastguard Worker     /// tests for serialization/deserialization are part of GeneratedMessageTest.
46*1b3f573fSAndroid Build Coastguard Worker     /// </summary>
47*1b3f573fSAndroid Build Coastguard Worker     public class MapFieldTest
48*1b3f573fSAndroid Build Coastguard Worker     {
49*1b3f573fSAndroid Build Coastguard Worker         [Test]
Clone_ClonesMessages()50*1b3f573fSAndroid Build Coastguard Worker         public void Clone_ClonesMessages()
51*1b3f573fSAndroid Build Coastguard Worker         {
52*1b3f573fSAndroid Build Coastguard Worker             var message = new ForeignMessage { C = 20 };
53*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, ForeignMessage> { { "x", message } };
54*1b3f573fSAndroid Build Coastguard Worker             var clone = map.Clone();
55*1b3f573fSAndroid Build Coastguard Worker             map["x"].C = 30;
56*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(20, clone["x"].C);
57*1b3f573fSAndroid Build Coastguard Worker         }
58*1b3f573fSAndroid Build Coastguard Worker 
59*1b3f573fSAndroid Build Coastguard Worker         [Test]
NullValuesProhibited()60*1b3f573fSAndroid Build Coastguard Worker         public void NullValuesProhibited()
61*1b3f573fSAndroid Build Coastguard Worker         {
62*1b3f573fSAndroid Build Coastguard Worker             TestNullValues<int?>(0);
63*1b3f573fSAndroid Build Coastguard Worker             TestNullValues("");
64*1b3f573fSAndroid Build Coastguard Worker             TestNullValues(new TestAllTypes());
65*1b3f573fSAndroid Build Coastguard Worker         }
66*1b3f573fSAndroid Build Coastguard Worker 
TestNullValues(T nonNullValue)67*1b3f573fSAndroid Build Coastguard Worker         private void TestNullValues<T>(T nonNullValue)
68*1b3f573fSAndroid Build Coastguard Worker         {
69*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<int, T>();
70*1b3f573fSAndroid Build Coastguard Worker             var nullValue = (T) (object) null;
71*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => map.Add(0, nullValue));
72*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => map[0] = nullValue);
73*1b3f573fSAndroid Build Coastguard Worker             map.Add(1, nonNullValue);
74*1b3f573fSAndroid Build Coastguard Worker             map[1] = nonNullValue;
75*1b3f573fSAndroid Build Coastguard Worker         }
76*1b3f573fSAndroid Build Coastguard Worker 
77*1b3f573fSAndroid Build Coastguard Worker         [Test]
Add_ForbidsNullKeys()78*1b3f573fSAndroid Build Coastguard Worker         public void Add_ForbidsNullKeys()
79*1b3f573fSAndroid Build Coastguard Worker         {
80*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, ForeignMessage>();
81*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => map.Add(null, new ForeignMessage()));
82*1b3f573fSAndroid Build Coastguard Worker         }
83*1b3f573fSAndroid Build Coastguard Worker 
84*1b3f573fSAndroid Build Coastguard Worker         [Test]
Indexer_ForbidsNullKeys()85*1b3f573fSAndroid Build Coastguard Worker         public void Indexer_ForbidsNullKeys()
86*1b3f573fSAndroid Build Coastguard Worker         {
87*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, ForeignMessage>();
88*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => map[null] = new ForeignMessage());
89*1b3f573fSAndroid Build Coastguard Worker         }
90*1b3f573fSAndroid Build Coastguard Worker 
91*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddPreservesInsertionOrder()92*1b3f573fSAndroid Build Coastguard Worker         public void AddPreservesInsertionOrder()
93*1b3f573fSAndroid Build Coastguard Worker         {
94*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string>();
95*1b3f573fSAndroid Build Coastguard Worker             map.Add("a", "v1");
96*1b3f573fSAndroid Build Coastguard Worker             map.Add("b", "v2");
97*1b3f573fSAndroid Build Coastguard Worker             map.Add("c", "v3");
98*1b3f573fSAndroid Build Coastguard Worker             map.Remove("b");
99*1b3f573fSAndroid Build Coastguard Worker             map.Add("d", "v4");
100*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "a", "c", "d" }, map.Keys);
101*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "v1", "v3", "v4" }, map.Values);
102*1b3f573fSAndroid Build Coastguard Worker         }
103*1b3f573fSAndroid Build Coastguard Worker 
104*1b3f573fSAndroid Build Coastguard Worker         [Test]
EqualityIsOrderInsensitive()105*1b3f573fSAndroid Build Coastguard Worker         public void EqualityIsOrderInsensitive()
106*1b3f573fSAndroid Build Coastguard Worker         {
107*1b3f573fSAndroid Build Coastguard Worker             var map1 = new MapField<string, string>();
108*1b3f573fSAndroid Build Coastguard Worker             map1.Add("a", "v1");
109*1b3f573fSAndroid Build Coastguard Worker             map1.Add("b", "v2");
110*1b3f573fSAndroid Build Coastguard Worker 
111*1b3f573fSAndroid Build Coastguard Worker             var map2 = new MapField<string, string>();
112*1b3f573fSAndroid Build Coastguard Worker             map2.Add("b", "v2");
113*1b3f573fSAndroid Build Coastguard Worker             map2.Add("a", "v1");
114*1b3f573fSAndroid Build Coastguard Worker 
115*1b3f573fSAndroid Build Coastguard Worker             EqualityTester.AssertEquality(map1, map2);
116*1b3f573fSAndroid Build Coastguard Worker         }
117*1b3f573fSAndroid Build Coastguard Worker 
118*1b3f573fSAndroid Build Coastguard Worker         [Test]
EqualityIsKeySensitive()119*1b3f573fSAndroid Build Coastguard Worker         public void EqualityIsKeySensitive()
120*1b3f573fSAndroid Build Coastguard Worker         {
121*1b3f573fSAndroid Build Coastguard Worker             var map1 = new MapField<string, string>();
122*1b3f573fSAndroid Build Coastguard Worker             map1.Add("first key", "v1");
123*1b3f573fSAndroid Build Coastguard Worker             map1.Add("second key", "v2");
124*1b3f573fSAndroid Build Coastguard Worker 
125*1b3f573fSAndroid Build Coastguard Worker             var map2 = new MapField<string, string>();
126*1b3f573fSAndroid Build Coastguard Worker             map2.Add("third key", "v1");
127*1b3f573fSAndroid Build Coastguard Worker             map2.Add("fourth key", "v2");
128*1b3f573fSAndroid Build Coastguard Worker 
129*1b3f573fSAndroid Build Coastguard Worker             EqualityTester.AssertInequality(map1, map2);
130*1b3f573fSAndroid Build Coastguard Worker         }
131*1b3f573fSAndroid Build Coastguard Worker 
132*1b3f573fSAndroid Build Coastguard Worker         [Test]
Equality_Simple()133*1b3f573fSAndroid Build Coastguard Worker         public void Equality_Simple()
134*1b3f573fSAndroid Build Coastguard Worker         {
135*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string>();
136*1b3f573fSAndroid Build Coastguard Worker             EqualityTester.AssertEquality(map, map);
137*1b3f573fSAndroid Build Coastguard Worker             EqualityTester.AssertInequality(map, null);
138*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(map.Equals(new object()));
139*1b3f573fSAndroid Build Coastguard Worker         }
140*1b3f573fSAndroid Build Coastguard Worker 
141*1b3f573fSAndroid Build Coastguard Worker         [Test]
EqualityIsValueSensitive()142*1b3f573fSAndroid Build Coastguard Worker         public void EqualityIsValueSensitive()
143*1b3f573fSAndroid Build Coastguard Worker         {
144*1b3f573fSAndroid Build Coastguard Worker             // Note: Without some care, it's a little easier than one might
145*1b3f573fSAndroid Build Coastguard Worker             // hope to see hash collisions, but only in some environments...
146*1b3f573fSAndroid Build Coastguard Worker             var map1 = new MapField<string, string>();
147*1b3f573fSAndroid Build Coastguard Worker             map1.Add("a", "first value");
148*1b3f573fSAndroid Build Coastguard Worker             map1.Add("b", "second value");
149*1b3f573fSAndroid Build Coastguard Worker 
150*1b3f573fSAndroid Build Coastguard Worker             var map2 = new MapField<string, string>();
151*1b3f573fSAndroid Build Coastguard Worker             map2.Add("a", "third value");
152*1b3f573fSAndroid Build Coastguard Worker             map2.Add("b", "fourth value");
153*1b3f573fSAndroid Build Coastguard Worker 
154*1b3f573fSAndroid Build Coastguard Worker             EqualityTester.AssertInequality(map1, map2);
155*1b3f573fSAndroid Build Coastguard Worker         }
156*1b3f573fSAndroid Build Coastguard Worker 
157*1b3f573fSAndroid Build Coastguard Worker         [Test]
Add_Dictionary()158*1b3f573fSAndroid Build Coastguard Worker         public void Add_Dictionary()
159*1b3f573fSAndroid Build Coastguard Worker         {
160*1b3f573fSAndroid Build Coastguard Worker             var map1 = new MapField<string, string>
161*1b3f573fSAndroid Build Coastguard Worker             {
162*1b3f573fSAndroid Build Coastguard Worker                 { "x", "y" },
163*1b3f573fSAndroid Build Coastguard Worker                 { "a", "b" }
164*1b3f573fSAndroid Build Coastguard Worker             };
165*1b3f573fSAndroid Build Coastguard Worker             var map2 = new MapField<string, string>
166*1b3f573fSAndroid Build Coastguard Worker             {
167*1b3f573fSAndroid Build Coastguard Worker                 { "before", "" },
168*1b3f573fSAndroid Build Coastguard Worker                 map1,
169*1b3f573fSAndroid Build Coastguard Worker                 { "after", "" }
170*1b3f573fSAndroid Build Coastguard Worker             };
171*1b3f573fSAndroid Build Coastguard Worker             var expected = new MapField<string, string>
172*1b3f573fSAndroid Build Coastguard Worker             {
173*1b3f573fSAndroid Build Coastguard Worker                 { "before", "" },
174*1b3f573fSAndroid Build Coastguard Worker                 { "x", "y" },
175*1b3f573fSAndroid Build Coastguard Worker                 { "a", "b" },
176*1b3f573fSAndroid Build Coastguard Worker                 { "after", "" }
177*1b3f573fSAndroid Build Coastguard Worker             };
178*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(expected, map2);
179*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "before", "x", "a", "after" }, map2.Keys);
180*1b3f573fSAndroid Build Coastguard Worker         }
181*1b3f573fSAndroid Build Coastguard Worker 
182*1b3f573fSAndroid Build Coastguard Worker         // General IDictionary<TKey, TValue> behavior tests
183*1b3f573fSAndroid Build Coastguard Worker         [Test]
Add_KeyAlreadyExists()184*1b3f573fSAndroid Build Coastguard Worker         public void Add_KeyAlreadyExists()
185*1b3f573fSAndroid Build Coastguard Worker         {
186*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string>();
187*1b3f573fSAndroid Build Coastguard Worker             map.Add("foo", "bar");
188*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentException>(() => map.Add("foo", "baz"));
189*1b3f573fSAndroid Build Coastguard Worker         }
190*1b3f573fSAndroid Build Coastguard Worker 
191*1b3f573fSAndroid Build Coastguard Worker         [Test]
Add_Pair()192*1b3f573fSAndroid Build Coastguard Worker         public void Add_Pair()
193*1b3f573fSAndroid Build Coastguard Worker         {
194*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string>();
195*1b3f573fSAndroid Build Coastguard Worker             ICollection<KeyValuePair<string, string>> collection = map;
196*1b3f573fSAndroid Build Coastguard Worker             collection.Add(NewKeyValuePair("x", "y"));
197*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("y", map["x"]);
198*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentException>(() => collection.Add(NewKeyValuePair("x", "z")));
199*1b3f573fSAndroid Build Coastguard Worker         }
200*1b3f573fSAndroid Build Coastguard Worker 
201*1b3f573fSAndroid Build Coastguard Worker         [Test]
Contains_Pair()202*1b3f573fSAndroid Build Coastguard Worker         public void Contains_Pair()
203*1b3f573fSAndroid Build Coastguard Worker         {
204*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "x", "y" } };
205*1b3f573fSAndroid Build Coastguard Worker             ICollection<KeyValuePair<string, string>> collection = map;
206*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(collection.Contains(NewKeyValuePair("x", "y")));
207*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(collection.Contains(NewKeyValuePair("x", "z")));
208*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(collection.Contains(NewKeyValuePair("z", "y")));
209*1b3f573fSAndroid Build Coastguard Worker         }
210*1b3f573fSAndroid Build Coastguard Worker 
211*1b3f573fSAndroid Build Coastguard Worker         [Test]
Remove_Key()212*1b3f573fSAndroid Build Coastguard Worker         public void Remove_Key()
213*1b3f573fSAndroid Build Coastguard Worker         {
214*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string>();
215*1b3f573fSAndroid Build Coastguard Worker             map.Add("foo", "bar");
216*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1, map.Count);
217*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(map.Remove("missing"));
218*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1, map.Count);
219*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(map.Remove("foo"));
220*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(0, map.Count);
221*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => map.Remove(null));
222*1b3f573fSAndroid Build Coastguard Worker         }
223*1b3f573fSAndroid Build Coastguard Worker 
224*1b3f573fSAndroid Build Coastguard Worker         [Test]
Remove_Pair()225*1b3f573fSAndroid Build Coastguard Worker         public void Remove_Pair()
226*1b3f573fSAndroid Build Coastguard Worker         {
227*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string>();
228*1b3f573fSAndroid Build Coastguard Worker             map.Add("foo", "bar");
229*1b3f573fSAndroid Build Coastguard Worker             ICollection<KeyValuePair<string, string>> collection = map;
230*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1, map.Count);
231*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(collection.Remove(NewKeyValuePair("wrong key", "bar")));
232*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1, map.Count);
233*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(collection.Remove(NewKeyValuePair("foo", "wrong value")));
234*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1, map.Count);
235*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(collection.Remove(NewKeyValuePair("foo", "bar")));
236*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(0, map.Count);
237*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentException>(() => collection.Remove(new KeyValuePair<string, string>(null, "")));
238*1b3f573fSAndroid Build Coastguard Worker         }
239*1b3f573fSAndroid Build Coastguard Worker 
240*1b3f573fSAndroid Build Coastguard Worker         [Test]
CopyTo_Pair()241*1b3f573fSAndroid Build Coastguard Worker         public void CopyTo_Pair()
242*1b3f573fSAndroid Build Coastguard Worker         {
243*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string>();
244*1b3f573fSAndroid Build Coastguard Worker             map.Add("foo", "bar");
245*1b3f573fSAndroid Build Coastguard Worker             ICollection<KeyValuePair<string, string>> collection = map;
246*1b3f573fSAndroid Build Coastguard Worker             KeyValuePair<string, string>[] array = new KeyValuePair<string, string>[3];
247*1b3f573fSAndroid Build Coastguard Worker             collection.CopyTo(array, 1);
248*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(NewKeyValuePair("foo", "bar"), array[1]);
249*1b3f573fSAndroid Build Coastguard Worker         }
250*1b3f573fSAndroid Build Coastguard Worker 
251*1b3f573fSAndroid Build Coastguard Worker         [Test]
Clear()252*1b3f573fSAndroid Build Coastguard Worker         public void Clear()
253*1b3f573fSAndroid Build Coastguard Worker         {
254*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "x", "y" } };
255*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1, map.Count);
256*1b3f573fSAndroid Build Coastguard Worker             map.Clear();
257*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(0, map.Count);
258*1b3f573fSAndroid Build Coastguard Worker             map.Add("x", "y");
259*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1, map.Count);
260*1b3f573fSAndroid Build Coastguard Worker         }
261*1b3f573fSAndroid Build Coastguard Worker 
262*1b3f573fSAndroid Build Coastguard Worker         [Test]
Indexer_Get()263*1b3f573fSAndroid Build Coastguard Worker         public void Indexer_Get()
264*1b3f573fSAndroid Build Coastguard Worker         {
265*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "x", "y" } };
266*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("y", map["x"]);
267*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<KeyNotFoundException>(() => { var ignored = map["z"]; });
268*1b3f573fSAndroid Build Coastguard Worker         }
269*1b3f573fSAndroid Build Coastguard Worker 
270*1b3f573fSAndroid Build Coastguard Worker         [Test]
Indexer_Set()271*1b3f573fSAndroid Build Coastguard Worker         public void Indexer_Set()
272*1b3f573fSAndroid Build Coastguard Worker         {
273*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string>();
274*1b3f573fSAndroid Build Coastguard Worker             map["x"] = "y";
275*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("y", map["x"]);
276*1b3f573fSAndroid Build Coastguard Worker             map["x"] = "z"; // This won't throw, unlike Add.
277*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("z", map["x"]);
278*1b3f573fSAndroid Build Coastguard Worker         }
279*1b3f573fSAndroid Build Coastguard Worker 
280*1b3f573fSAndroid Build Coastguard Worker         [Test]
GetEnumerator_NonGeneric()281*1b3f573fSAndroid Build Coastguard Worker         public void GetEnumerator_NonGeneric()
282*1b3f573fSAndroid Build Coastguard Worker         {
283*1b3f573fSAndroid Build Coastguard Worker             IEnumerable map = new MapField<string, string> { { "x", "y" } };
284*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { new KeyValuePair<string, string>("x", "y") },
285*1b3f573fSAndroid Build Coastguard Worker                 map.Cast<object>().ToList());
286*1b3f573fSAndroid Build Coastguard Worker         }
287*1b3f573fSAndroid Build Coastguard Worker 
288*1b3f573fSAndroid Build Coastguard Worker         // Test for the explicitly-implemented non-generic IDictionary interface
289*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionary_GetEnumerator()290*1b3f573fSAndroid Build Coastguard Worker         public void IDictionary_GetEnumerator()
291*1b3f573fSAndroid Build Coastguard Worker         {
292*1b3f573fSAndroid Build Coastguard Worker             IDictionary map = new MapField<string, string> { { "x", "y" } };
293*1b3f573fSAndroid Build Coastguard Worker             var enumerator = map.GetEnumerator();
294*1b3f573fSAndroid Build Coastguard Worker 
295*1b3f573fSAndroid Build Coastguard Worker             // Commented assertions show an ideal situation - it looks like
296*1b3f573fSAndroid Build Coastguard Worker             // the LinkedList enumerator doesn't throw when you ask for the current entry
297*1b3f573fSAndroid Build Coastguard Worker             // at an inappropriate time; fixing this would be more work than it's worth.
298*1b3f573fSAndroid Build Coastguard Worker             // Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
299*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(enumerator.MoveNext());
300*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("x", enumerator.Key);
301*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("y", enumerator.Value);
302*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(new DictionaryEntry("x", "y"), enumerator.Current);
303*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(new DictionaryEntry("x", "y"), enumerator.Entry);
304*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(enumerator.MoveNext());
305*1b3f573fSAndroid Build Coastguard Worker             // Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
306*1b3f573fSAndroid Build Coastguard Worker             enumerator.Reset();
307*1b3f573fSAndroid Build Coastguard Worker             // Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
308*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(enumerator.MoveNext());
309*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("x", enumerator.Key); // Assume the rest are okay
310*1b3f573fSAndroid Build Coastguard Worker         }
311*1b3f573fSAndroid Build Coastguard Worker 
312*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionary_Add()313*1b3f573fSAndroid Build Coastguard Worker         public void IDictionary_Add()
314*1b3f573fSAndroid Build Coastguard Worker         {
315*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "x", "y" } };
316*1b3f573fSAndroid Build Coastguard Worker             IDictionary dictionary = map;
317*1b3f573fSAndroid Build Coastguard Worker             dictionary.Add("a", "b");
318*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("b", map["a"]);
319*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentException>(() => dictionary.Add("a", "duplicate"));
320*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<InvalidCastException>(() => dictionary.Add(new object(), "key is bad"));
321*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<InvalidCastException>(() => dictionary.Add("value is bad", new object()));
322*1b3f573fSAndroid Build Coastguard Worker         }
323*1b3f573fSAndroid Build Coastguard Worker 
324*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionary_Contains()325*1b3f573fSAndroid Build Coastguard Worker         public void IDictionary_Contains()
326*1b3f573fSAndroid Build Coastguard Worker         {
327*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "x", "y" } };
328*1b3f573fSAndroid Build Coastguard Worker             IDictionary dictionary = map;
329*1b3f573fSAndroid Build Coastguard Worker 
330*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(dictionary.Contains("a"));
331*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(dictionary.Contains(5));
332*1b3f573fSAndroid Build Coastguard Worker             // Surprising, but IDictionary.Contains is only about keys.
333*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(dictionary.Contains(new DictionaryEntry("x", "y")));
334*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(dictionary.Contains("x"));
335*1b3f573fSAndroid Build Coastguard Worker         }
336*1b3f573fSAndroid Build Coastguard Worker 
337*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionary_Remove()338*1b3f573fSAndroid Build Coastguard Worker         public void IDictionary_Remove()
339*1b3f573fSAndroid Build Coastguard Worker         {
340*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "x", "y" } };
341*1b3f573fSAndroid Build Coastguard Worker             IDictionary dictionary = map;
342*1b3f573fSAndroid Build Coastguard Worker             dictionary.Remove("a");
343*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1, dictionary.Count);
344*1b3f573fSAndroid Build Coastguard Worker             dictionary.Remove(5);
345*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1, dictionary.Count);
346*1b3f573fSAndroid Build Coastguard Worker             dictionary.Remove(new DictionaryEntry("x", "y"));
347*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(1, dictionary.Count);
348*1b3f573fSAndroid Build Coastguard Worker             dictionary.Remove("x");
349*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual(0, dictionary.Count);
350*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => dictionary.Remove(null));
351*1b3f573fSAndroid Build Coastguard Worker         }
352*1b3f573fSAndroid Build Coastguard Worker 
353*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionary_CopyTo()354*1b3f573fSAndroid Build Coastguard Worker         public void IDictionary_CopyTo()
355*1b3f573fSAndroid Build Coastguard Worker         {
356*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "x", "y" } };
357*1b3f573fSAndroid Build Coastguard Worker             IDictionary dictionary = map;
358*1b3f573fSAndroid Build Coastguard Worker             var array = new DictionaryEntry[3];
359*1b3f573fSAndroid Build Coastguard Worker             dictionary.CopyTo(array, 1);
360*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { default(DictionaryEntry), new DictionaryEntry("x", "y"), default(DictionaryEntry) },
361*1b3f573fSAndroid Build Coastguard Worker                 array);
362*1b3f573fSAndroid Build Coastguard Worker             var objectArray = new object[3];
363*1b3f573fSAndroid Build Coastguard Worker             dictionary.CopyTo(objectArray, 1);
364*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new object[] { null, new DictionaryEntry("x", "y"), null },
365*1b3f573fSAndroid Build Coastguard Worker                 objectArray);
366*1b3f573fSAndroid Build Coastguard Worker         }
367*1b3f573fSAndroid Build Coastguard Worker 
368*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionary_IsFixedSize()369*1b3f573fSAndroid Build Coastguard Worker         public void IDictionary_IsFixedSize()
370*1b3f573fSAndroid Build Coastguard Worker         {
371*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "x", "y" } };
372*1b3f573fSAndroid Build Coastguard Worker             IDictionary dictionary = map;
373*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(dictionary.IsFixedSize);
374*1b3f573fSAndroid Build Coastguard Worker         }
375*1b3f573fSAndroid Build Coastguard Worker 
376*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionary_Keys()377*1b3f573fSAndroid Build Coastguard Worker         public void IDictionary_Keys()
378*1b3f573fSAndroid Build Coastguard Worker         {
379*1b3f573fSAndroid Build Coastguard Worker             IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
380*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "x" }, dictionary.Keys);
381*1b3f573fSAndroid Build Coastguard Worker         }
382*1b3f573fSAndroid Build Coastguard Worker 
383*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionary_Values()384*1b3f573fSAndroid Build Coastguard Worker         public void IDictionary_Values()
385*1b3f573fSAndroid Build Coastguard Worker         {
386*1b3f573fSAndroid Build Coastguard Worker             IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
387*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "y" }, dictionary.Values);
388*1b3f573fSAndroid Build Coastguard Worker         }
389*1b3f573fSAndroid Build Coastguard Worker 
390*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionary_IsSynchronized()391*1b3f573fSAndroid Build Coastguard Worker         public void IDictionary_IsSynchronized()
392*1b3f573fSAndroid Build Coastguard Worker         {
393*1b3f573fSAndroid Build Coastguard Worker             IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
394*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(dictionary.IsSynchronized);
395*1b3f573fSAndroid Build Coastguard Worker         }
396*1b3f573fSAndroid Build Coastguard Worker 
397*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionary_SyncRoot()398*1b3f573fSAndroid Build Coastguard Worker         public void IDictionary_SyncRoot()
399*1b3f573fSAndroid Build Coastguard Worker         {
400*1b3f573fSAndroid Build Coastguard Worker             IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
401*1b3f573fSAndroid Build Coastguard Worker             Assert.AreSame(dictionary, dictionary.SyncRoot);
402*1b3f573fSAndroid Build Coastguard Worker         }
403*1b3f573fSAndroid Build Coastguard Worker 
404*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionary_Indexer_Get()405*1b3f573fSAndroid Build Coastguard Worker         public void IDictionary_Indexer_Get()
406*1b3f573fSAndroid Build Coastguard Worker         {
407*1b3f573fSAndroid Build Coastguard Worker             IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
408*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("y", dictionary["x"]);
409*1b3f573fSAndroid Build Coastguard Worker             Assert.IsNull(dictionary["a"]);
410*1b3f573fSAndroid Build Coastguard Worker             Assert.IsNull(dictionary[5]);
411*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => dictionary[null].GetHashCode());
412*1b3f573fSAndroid Build Coastguard Worker         }
413*1b3f573fSAndroid Build Coastguard Worker 
414*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionary_Indexer_Set()415*1b3f573fSAndroid Build Coastguard Worker         public void IDictionary_Indexer_Set()
416*1b3f573fSAndroid Build Coastguard Worker         {
417*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "x", "y" } };
418*1b3f573fSAndroid Build Coastguard Worker             IDictionary dictionary = map;
419*1b3f573fSAndroid Build Coastguard Worker             map["a"] = "b";
420*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("b", map["a"]);
421*1b3f573fSAndroid Build Coastguard Worker             map["a"] = "c";
422*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("c", map["a"]);
423*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<InvalidCastException>(() => dictionary[5] = "x");
424*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<InvalidCastException>(() => dictionary["x"] = 5);
425*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => dictionary[null] = "z");
426*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => dictionary["x"] = null);
427*1b3f573fSAndroid Build Coastguard Worker         }
428*1b3f573fSAndroid Build Coastguard Worker 
429*1b3f573fSAndroid Build Coastguard Worker         [Test]
KeysReturnsLiveView()430*1b3f573fSAndroid Build Coastguard Worker         public void KeysReturnsLiveView()
431*1b3f573fSAndroid Build Coastguard Worker         {
432*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string>();
433*1b3f573fSAndroid Build Coastguard Worker             var keys = map.Keys;
434*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new string[0], keys);
435*1b3f573fSAndroid Build Coastguard Worker             map["foo"] = "bar";
436*1b3f573fSAndroid Build Coastguard Worker             map["x"] = "y";
437*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "foo", "x" }, keys);
438*1b3f573fSAndroid Build Coastguard Worker         }
439*1b3f573fSAndroid Build Coastguard Worker 
440*1b3f573fSAndroid Build Coastguard Worker         [Test]
ValuesReturnsLiveView()441*1b3f573fSAndroid Build Coastguard Worker         public void ValuesReturnsLiveView()
442*1b3f573fSAndroid Build Coastguard Worker         {
443*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string>();
444*1b3f573fSAndroid Build Coastguard Worker             var values = map.Values;
445*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new string[0], values);
446*1b3f573fSAndroid Build Coastguard Worker             map["foo"] = "bar";
447*1b3f573fSAndroid Build Coastguard Worker             map["x"] = "y";
448*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { "bar", "y" }, values);
449*1b3f573fSAndroid Build Coastguard Worker         }
450*1b3f573fSAndroid Build Coastguard Worker 
451*1b3f573fSAndroid Build Coastguard Worker         // Just test keys - we know the implementation is the same for values
452*1b3f573fSAndroid Build Coastguard Worker         [Test]
ViewsAreReadOnly()453*1b3f573fSAndroid Build Coastguard Worker         public void ViewsAreReadOnly()
454*1b3f573fSAndroid Build Coastguard Worker         {
455*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string>();
456*1b3f573fSAndroid Build Coastguard Worker             var keys = map.Keys;
457*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(keys.IsReadOnly);
458*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<NotSupportedException>(() => keys.Clear());
459*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<NotSupportedException>(() => keys.Remove("a"));
460*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<NotSupportedException>(() => keys.Add("a"));
461*1b3f573fSAndroid Build Coastguard Worker         }
462*1b3f573fSAndroid Build Coastguard Worker 
463*1b3f573fSAndroid Build Coastguard Worker         // Just test keys - we know the implementation is the same for values
464*1b3f573fSAndroid Build Coastguard Worker         [Test]
ViewCopyTo()465*1b3f573fSAndroid Build Coastguard Worker         public void ViewCopyTo()
466*1b3f573fSAndroid Build Coastguard Worker         {
467*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
468*1b3f573fSAndroid Build Coastguard Worker             var keys = map.Keys;
469*1b3f573fSAndroid Build Coastguard Worker             var array = new string[4];
470*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentException>(() => keys.CopyTo(array, 3));
471*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => keys.CopyTo(array, -1));
472*1b3f573fSAndroid Build Coastguard Worker             keys.CopyTo(array, 1);
473*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array);
474*1b3f573fSAndroid Build Coastguard Worker         }
475*1b3f573fSAndroid Build Coastguard Worker 
476*1b3f573fSAndroid Build Coastguard Worker         // Just test keys - we know the implementation is the same for values
477*1b3f573fSAndroid Build Coastguard Worker         [Test]
NonGenericViewCopyTo()478*1b3f573fSAndroid Build Coastguard Worker         public void NonGenericViewCopyTo()
479*1b3f573fSAndroid Build Coastguard Worker         {
480*1b3f573fSAndroid Build Coastguard Worker             IDictionary map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
481*1b3f573fSAndroid Build Coastguard Worker             ICollection keys = map.Keys;
482*1b3f573fSAndroid Build Coastguard Worker             // Note the use of the Array type here rather than string[]
483*1b3f573fSAndroid Build Coastguard Worker             Array array = new string[4];
484*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentException>(() => keys.CopyTo(array, 3));
485*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentOutOfRangeException>(() => keys.CopyTo(array, -1));
486*1b3f573fSAndroid Build Coastguard Worker             keys.CopyTo(array, 1);
487*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array);
488*1b3f573fSAndroid Build Coastguard Worker         }
489*1b3f573fSAndroid Build Coastguard Worker 
490*1b3f573fSAndroid Build Coastguard Worker         [Test]
KeysContains()491*1b3f573fSAndroid Build Coastguard Worker         public void KeysContains()
492*1b3f573fSAndroid Build Coastguard Worker         {
493*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
494*1b3f573fSAndroid Build Coastguard Worker             var keys = map.Keys;
495*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(keys.Contains("foo"));
496*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(keys.Contains("bar")); // It's a value!
497*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(keys.Contains("1"));
498*1b3f573fSAndroid Build Coastguard Worker             // Keys can't be null, so we should prevent contains check
499*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentNullException>(() => keys.Contains(null));
500*1b3f573fSAndroid Build Coastguard Worker         }
501*1b3f573fSAndroid Build Coastguard Worker 
502*1b3f573fSAndroid Build Coastguard Worker         [Test]
KeysCopyTo()503*1b3f573fSAndroid Build Coastguard Worker         public void KeysCopyTo()
504*1b3f573fSAndroid Build Coastguard Worker         {
505*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
506*1b3f573fSAndroid Build Coastguard Worker             var keys = map.Keys.ToArray(); // Uses CopyTo internally
507*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEquivalent(new[] { "foo", "x" }, keys);
508*1b3f573fSAndroid Build Coastguard Worker         }
509*1b3f573fSAndroid Build Coastguard Worker 
510*1b3f573fSAndroid Build Coastguard Worker         [Test]
ValuesContains()511*1b3f573fSAndroid Build Coastguard Worker         public void ValuesContains()
512*1b3f573fSAndroid Build Coastguard Worker         {
513*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
514*1b3f573fSAndroid Build Coastguard Worker             var values = map.Values;
515*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(values.Contains("bar"));
516*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(values.Contains("foo")); // It's a key!
517*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(values.Contains("1"));
518*1b3f573fSAndroid Build Coastguard Worker             // Values can be null, so this makes sense
519*1b3f573fSAndroid Build Coastguard Worker             Assert.IsFalse(values.Contains(null));
520*1b3f573fSAndroid Build Coastguard Worker         }
521*1b3f573fSAndroid Build Coastguard Worker 
522*1b3f573fSAndroid Build Coastguard Worker         [Test]
ValuesCopyTo()523*1b3f573fSAndroid Build Coastguard Worker         public void ValuesCopyTo()
524*1b3f573fSAndroid Build Coastguard Worker         {
525*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
526*1b3f573fSAndroid Build Coastguard Worker             var values = map.Values.ToArray(); // Uses CopyTo internally
527*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEquivalent(new[] { "bar", "y" }, values);
528*1b3f573fSAndroid Build Coastguard Worker         }
529*1b3f573fSAndroid Build Coastguard Worker 
530*1b3f573fSAndroid Build Coastguard Worker         [Test]
ToString_StringToString()531*1b3f573fSAndroid Build Coastguard Worker         public void ToString_StringToString()
532*1b3f573fSAndroid Build Coastguard Worker         {
533*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
534*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("{ \"foo\": \"bar\", \"x\": \"y\" }", map.ToString());
535*1b3f573fSAndroid Build Coastguard Worker         }
536*1b3f573fSAndroid Build Coastguard Worker 
537*1b3f573fSAndroid Build Coastguard Worker         [Test]
ToString_UnsupportedKeyType()538*1b3f573fSAndroid Build Coastguard Worker         public void ToString_UnsupportedKeyType()
539*1b3f573fSAndroid Build Coastguard Worker         {
540*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<byte, string> { { 10, "foo" } };
541*1b3f573fSAndroid Build Coastguard Worker             Assert.Throws<ArgumentException>(() => map.ToString());
542*1b3f573fSAndroid Build Coastguard Worker         }
543*1b3f573fSAndroid Build Coastguard Worker 
544*1b3f573fSAndroid Build Coastguard Worker         [Test]
NaNValuesComparedBitwise()545*1b3f573fSAndroid Build Coastguard Worker         public void NaNValuesComparedBitwise()
546*1b3f573fSAndroid Build Coastguard Worker         {
547*1b3f573fSAndroid Build Coastguard Worker             var map1 = new MapField<string, double>
548*1b3f573fSAndroid Build Coastguard Worker             {
549*1b3f573fSAndroid Build Coastguard Worker                 { "x", SampleNaNs.Regular },
550*1b3f573fSAndroid Build Coastguard Worker                 { "y", SampleNaNs.SignallingFlipped }
551*1b3f573fSAndroid Build Coastguard Worker             };
552*1b3f573fSAndroid Build Coastguard Worker 
553*1b3f573fSAndroid Build Coastguard Worker             var map2 = new MapField<string, double>
554*1b3f573fSAndroid Build Coastguard Worker             {
555*1b3f573fSAndroid Build Coastguard Worker                 { "x", SampleNaNs.Regular },
556*1b3f573fSAndroid Build Coastguard Worker                 { "y", SampleNaNs.PayloadFlipped }
557*1b3f573fSAndroid Build Coastguard Worker             };
558*1b3f573fSAndroid Build Coastguard Worker 
559*1b3f573fSAndroid Build Coastguard Worker             var map3 = new MapField<string, double>
560*1b3f573fSAndroid Build Coastguard Worker             {
561*1b3f573fSAndroid Build Coastguard Worker                 { "x", SampleNaNs.Regular },
562*1b3f573fSAndroid Build Coastguard Worker                 { "y", SampleNaNs.SignallingFlipped }
563*1b3f573fSAndroid Build Coastguard Worker             };
564*1b3f573fSAndroid Build Coastguard Worker 
565*1b3f573fSAndroid Build Coastguard Worker             EqualityTester.AssertInequality(map1, map2);
566*1b3f573fSAndroid Build Coastguard Worker             EqualityTester.AssertEquality(map1, map3);
567*1b3f573fSAndroid Build Coastguard Worker             Assert.True(map1.Values.Contains(SampleNaNs.SignallingFlipped));
568*1b3f573fSAndroid Build Coastguard Worker             Assert.False(map2.Values.Contains(SampleNaNs.SignallingFlipped));
569*1b3f573fSAndroid Build Coastguard Worker         }
570*1b3f573fSAndroid Build Coastguard Worker 
571*1b3f573fSAndroid Build Coastguard Worker         // This wouldn't usually happen, as protos can't use doubles as map keys,
572*1b3f573fSAndroid Build Coastguard Worker         // but let's be consistent.
573*1b3f573fSAndroid Build Coastguard Worker         [Test]
NaNKeysComparedBitwise()574*1b3f573fSAndroid Build Coastguard Worker         public void NaNKeysComparedBitwise()
575*1b3f573fSAndroid Build Coastguard Worker         {
576*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<double, string>
577*1b3f573fSAndroid Build Coastguard Worker             {
578*1b3f573fSAndroid Build Coastguard Worker                 { SampleNaNs.Regular, "x" },
579*1b3f573fSAndroid Build Coastguard Worker                 { SampleNaNs.SignallingFlipped, "y" }
580*1b3f573fSAndroid Build Coastguard Worker             };
581*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("x", map[SampleNaNs.Regular]);
582*1b3f573fSAndroid Build Coastguard Worker             Assert.AreEqual("y", map[SampleNaNs.SignallingFlipped]);
583*1b3f573fSAndroid Build Coastguard Worker             string ignored;
584*1b3f573fSAndroid Build Coastguard Worker             Assert.False(map.TryGetValue(SampleNaNs.PayloadFlipped, out ignored));
585*1b3f573fSAndroid Build Coastguard Worker         }
586*1b3f573fSAndroid Build Coastguard Worker 
587*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddEntriesFrom_CodedInputStream()588*1b3f573fSAndroid Build Coastguard Worker         public void AddEntriesFrom_CodedInputStream()
589*1b3f573fSAndroid Build Coastguard Worker         {
590*1b3f573fSAndroid Build Coastguard Worker             // map will have string key and string value
591*1b3f573fSAndroid Build Coastguard Worker             var keyTag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
592*1b3f573fSAndroid Build Coastguard Worker             var valueTag = WireFormat.MakeTag(2, WireFormat.WireType.LengthDelimited);
593*1b3f573fSAndroid Build Coastguard Worker 
594*1b3f573fSAndroid Build Coastguard Worker             var memoryStream = new MemoryStream();
595*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(memoryStream);
596*1b3f573fSAndroid Build Coastguard Worker             output.WriteLength(20);  // total of keyTag + key + valueTag + value
597*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(keyTag);
598*1b3f573fSAndroid Build Coastguard Worker             output.WriteString("the_key");
599*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(valueTag);
600*1b3f573fSAndroid Build Coastguard Worker             output.WriteString("the_value");
601*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
602*1b3f573fSAndroid Build Coastguard Worker 
603*1b3f573fSAndroid Build Coastguard Worker             var field = new MapField<string,string>();
604*1b3f573fSAndroid Build Coastguard Worker             var mapCodec = new MapField<string,string>.Codec(FieldCodec.ForString(keyTag, ""), FieldCodec.ForString(valueTag, ""), 10);
605*1b3f573fSAndroid Build Coastguard Worker             var input = new CodedInputStream(memoryStream.ToArray());
606*1b3f573fSAndroid Build Coastguard Worker 
607*1b3f573fSAndroid Build Coastguard Worker             // test the legacy overload of AddEntriesFrom that takes a CodedInputStream
608*1b3f573fSAndroid Build Coastguard Worker             field.AddEntriesFrom(input, mapCodec);
609*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEquivalent(new[] { "the_key" }, field.Keys);
610*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEquivalent(new[] { "the_value" }, field.Values);
611*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(input.IsAtEnd);
612*1b3f573fSAndroid Build Coastguard Worker         }
613*1b3f573fSAndroid Build Coastguard Worker 
614*1b3f573fSAndroid Build Coastguard Worker         [Test]
AddEntriesFrom_CodedInputStream_MissingKey()615*1b3f573fSAndroid Build Coastguard Worker         public void AddEntriesFrom_CodedInputStream_MissingKey()
616*1b3f573fSAndroid Build Coastguard Worker         {
617*1b3f573fSAndroid Build Coastguard Worker             // map will have string key and string value
618*1b3f573fSAndroid Build Coastguard Worker             var keyTag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
619*1b3f573fSAndroid Build Coastguard Worker             var valueTag = WireFormat.MakeTag(2, WireFormat.WireType.LengthDelimited);
620*1b3f573fSAndroid Build Coastguard Worker 
621*1b3f573fSAndroid Build Coastguard Worker             var memoryStream = new MemoryStream();
622*1b3f573fSAndroid Build Coastguard Worker             var output = new CodedOutputStream(memoryStream);
623*1b3f573fSAndroid Build Coastguard Worker             output.WriteLength(11);  // total of valueTag + value
624*1b3f573fSAndroid Build Coastguard Worker             output.WriteTag(valueTag);
625*1b3f573fSAndroid Build Coastguard Worker             output.WriteString("the_value");
626*1b3f573fSAndroid Build Coastguard Worker             output.Flush();
627*1b3f573fSAndroid Build Coastguard Worker 
628*1b3f573fSAndroid Build Coastguard Worker             var field = new MapField<string, string>();
629*1b3f573fSAndroid Build Coastguard Worker             var mapCodec = new MapField<string, string>.Codec(FieldCodec.ForString(keyTag, ""), FieldCodec.ForString(valueTag, ""), 10);
630*1b3f573fSAndroid Build Coastguard Worker             var input = new CodedInputStream(memoryStream.ToArray());
631*1b3f573fSAndroid Build Coastguard Worker 
632*1b3f573fSAndroid Build Coastguard Worker             field.AddEntriesFrom(input, mapCodec);
633*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEquivalent(new[] { "" }, field.Keys);
634*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEquivalent(new[] { "the_value" }, field.Values);
635*1b3f573fSAndroid Build Coastguard Worker             Assert.IsTrue(input.IsAtEnd);
636*1b3f573fSAndroid Build Coastguard Worker         }
637*1b3f573fSAndroid Build Coastguard Worker 
638*1b3f573fSAndroid Build Coastguard Worker #if !NET35
639*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionaryKeys_Equals_IReadOnlyDictionaryKeys()640*1b3f573fSAndroid Build Coastguard Worker         public void IDictionaryKeys_Equals_IReadOnlyDictionaryKeys()
641*1b3f573fSAndroid Build Coastguard Worker         {
642*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
643*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEquivalent(((IDictionary<string, string>)map).Keys, ((IReadOnlyDictionary<string, string>)map).Keys);
644*1b3f573fSAndroid Build Coastguard Worker         }
645*1b3f573fSAndroid Build Coastguard Worker 
646*1b3f573fSAndroid Build Coastguard Worker         [Test]
IDictionaryValues_Equals_IReadOnlyDictionaryValues()647*1b3f573fSAndroid Build Coastguard Worker         public void IDictionaryValues_Equals_IReadOnlyDictionaryValues()
648*1b3f573fSAndroid Build Coastguard Worker         {
649*1b3f573fSAndroid Build Coastguard Worker             var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
650*1b3f573fSAndroid Build Coastguard Worker             CollectionAssert.AreEquivalent(((IDictionary<string, string>)map).Values, ((IReadOnlyDictionary<string, string>)map).Values);
651*1b3f573fSAndroid Build Coastguard Worker         }
652*1b3f573fSAndroid Build Coastguard Worker #endif
653*1b3f573fSAndroid Build Coastguard Worker 
NewKeyValuePair(TKey key, TValue value)654*1b3f573fSAndroid Build Coastguard Worker         private static KeyValuePair<TKey, TValue> NewKeyValuePair<TKey, TValue>(TKey key, TValue value)
655*1b3f573fSAndroid Build Coastguard Worker         {
656*1b3f573fSAndroid Build Coastguard Worker             return new KeyValuePair<TKey, TValue>(key, value);
657*1b3f573fSAndroid Build Coastguard Worker         }
658*1b3f573fSAndroid Build Coastguard Worker     }
659*1b3f573fSAndroid Build Coastguard Worker }
660