MapFieldTest.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. #region Copyright notice and license
  2. // Protocol Buffers - Google's data interchange format
  3. // Copyright 2015 Google Inc. All rights reserved.
  4. // https://developers.google.com/protocol-buffers/
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are
  8. // met:
  9. //
  10. // * Redistributions of source code must retain the above copyright
  11. // notice, this list of conditions and the following disclaimer.
  12. // * Redistributions in binary form must reproduce the above
  13. // copyright notice, this list of conditions and the following disclaimer
  14. // in the documentation and/or other materials provided with the
  15. // distribution.
  16. // * Neither the name of Google Inc. nor the names of its
  17. // contributors may be used to endorse or promote products derived from
  18. // this software without specific prior written permission.
  19. //
  20. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. #endregion
  32. using System;
  33. using System.Collections.Generic;
  34. using Google.Protobuf.TestProtos;
  35. using NUnit.Framework;
  36. using System.Collections;
  37. using System.Linq;
  38. namespace Google.Protobuf.Collections
  39. {
  40. /// <summary>
  41. /// Tests for MapField which aren't reliant on the encoded format -
  42. /// tests for serialization/deserialization are part of GeneratedMessageTest.
  43. /// </summary>
  44. public class MapFieldTest
  45. {
  46. [Test]
  47. public void Clone_ClonesMessages()
  48. {
  49. var message = new ForeignMessage { C = 20 };
  50. var map = new MapField<string, ForeignMessage> { { "x", message } };
  51. var clone = map.Clone();
  52. map["x"].C = 30;
  53. Assert.AreEqual(20, clone["x"].C);
  54. }
  55. [Test]
  56. public void NullValuesProhibited()
  57. {
  58. TestNullValues<int?>(0);
  59. TestNullValues("");
  60. TestNullValues(new TestAllTypes());
  61. }
  62. private void TestNullValues<T>(T nonNullValue)
  63. {
  64. var map = new MapField<int, T>();
  65. var nullValue = (T) (object) null;
  66. Assert.Throws<ArgumentNullException>(() => map.Add(0, nullValue));
  67. Assert.Throws<ArgumentNullException>(() => map[0] = nullValue);
  68. map.Add(1, nonNullValue);
  69. map[1] = nonNullValue;
  70. }
  71. [Test]
  72. public void Add_ForbidsNullKeys()
  73. {
  74. var map = new MapField<string, ForeignMessage>();
  75. Assert.Throws<ArgumentNullException>(() => map.Add(null, new ForeignMessage()));
  76. }
  77. [Test]
  78. public void Indexer_ForbidsNullKeys()
  79. {
  80. var map = new MapField<string, ForeignMessage>();
  81. Assert.Throws<ArgumentNullException>(() => map[null] = new ForeignMessage());
  82. }
  83. [Test]
  84. public void AddPreservesInsertionOrder()
  85. {
  86. var map = new MapField<string, string>();
  87. map.Add("a", "v1");
  88. map.Add("b", "v2");
  89. map.Add("c", "v3");
  90. map.Remove("b");
  91. map.Add("d", "v4");
  92. CollectionAssert.AreEqual(new[] { "a", "c", "d" }, map.Keys);
  93. CollectionAssert.AreEqual(new[] { "v1", "v3", "v4" }, map.Values);
  94. }
  95. [Test]
  96. public void EqualityIsOrderInsensitive()
  97. {
  98. var map1 = new MapField<string, string>();
  99. map1.Add("a", "v1");
  100. map1.Add("b", "v2");
  101. var map2 = new MapField<string, string>();
  102. map2.Add("b", "v2");
  103. map2.Add("a", "v1");
  104. EqualityTester.AssertEquality(map1, map2);
  105. }
  106. [Test]
  107. public void EqualityIsKeySensitive()
  108. {
  109. var map1 = new MapField<string, string>();
  110. map1.Add("first key", "v1");
  111. map1.Add("second key", "v2");
  112. var map2 = new MapField<string, string>();
  113. map2.Add("third key", "v1");
  114. map2.Add("fourth key", "v2");
  115. EqualityTester.AssertInequality(map1, map2);
  116. }
  117. [Test]
  118. public void Equality_Simple()
  119. {
  120. var map = new MapField<string, string>();
  121. EqualityTester.AssertEquality(map, map);
  122. EqualityTester.AssertInequality(map, null);
  123. Assert.IsFalse(map.Equals(new object()));
  124. }
  125. [Test]
  126. public void EqualityIsValueSensitive()
  127. {
  128. // Note: Without some care, it's a little easier than one might
  129. // hope to see hash collisions, but only in some environments...
  130. var map1 = new MapField<string, string>();
  131. map1.Add("a", "first value");
  132. map1.Add("b", "second value");
  133. var map2 = new MapField<string, string>();
  134. map2.Add("a", "third value");
  135. map2.Add("b", "fourth value");
  136. EqualityTester.AssertInequality(map1, map2);
  137. }
  138. [Test]
  139. public void Add_Dictionary()
  140. {
  141. var map1 = new MapField<string, string>
  142. {
  143. { "x", "y" },
  144. { "a", "b" }
  145. };
  146. var map2 = new MapField<string, string>
  147. {
  148. { "before", "" },
  149. map1,
  150. { "after", "" }
  151. };
  152. var expected = new MapField<string, string>
  153. {
  154. { "before", "" },
  155. { "x", "y" },
  156. { "a", "b" },
  157. { "after", "" }
  158. };
  159. Assert.AreEqual(expected, map2);
  160. CollectionAssert.AreEqual(new[] { "before", "x", "a", "after" }, map2.Keys);
  161. }
  162. // General IDictionary<TKey, TValue> behavior tests
  163. [Test]
  164. public void Add_KeyAlreadyExists()
  165. {
  166. var map = new MapField<string, string>();
  167. map.Add("foo", "bar");
  168. Assert.Throws<ArgumentException>(() => map.Add("foo", "baz"));
  169. }
  170. [Test]
  171. public void Add_Pair()
  172. {
  173. var map = new MapField<string, string>();
  174. ICollection<KeyValuePair<string, string>> collection = map;
  175. collection.Add(NewKeyValuePair("x", "y"));
  176. Assert.AreEqual("y", map["x"]);
  177. Assert.Throws<ArgumentException>(() => collection.Add(NewKeyValuePair("x", "z")));
  178. }
  179. [Test]
  180. public void Contains_Pair()
  181. {
  182. var map = new MapField<string, string> { { "x", "y" } };
  183. ICollection<KeyValuePair<string, string>> collection = map;
  184. Assert.IsTrue(collection.Contains(NewKeyValuePair("x", "y")));
  185. Assert.IsFalse(collection.Contains(NewKeyValuePair("x", "z")));
  186. Assert.IsFalse(collection.Contains(NewKeyValuePair("z", "y")));
  187. }
  188. [Test]
  189. public void Remove_Key()
  190. {
  191. var map = new MapField<string, string>();
  192. map.Add("foo", "bar");
  193. Assert.AreEqual(1, map.Count);
  194. Assert.IsFalse(map.Remove("missing"));
  195. Assert.AreEqual(1, map.Count);
  196. Assert.IsTrue(map.Remove("foo"));
  197. Assert.AreEqual(0, map.Count);
  198. Assert.Throws<ArgumentNullException>(() => map.Remove(null));
  199. }
  200. [Test]
  201. public void Remove_Pair()
  202. {
  203. var map = new MapField<string, string>();
  204. map.Add("foo", "bar");
  205. ICollection<KeyValuePair<string, string>> collection = map;
  206. Assert.AreEqual(1, map.Count);
  207. Assert.IsFalse(collection.Remove(NewKeyValuePair("wrong key", "bar")));
  208. Assert.AreEqual(1, map.Count);
  209. Assert.IsFalse(collection.Remove(NewKeyValuePair("foo", "wrong value")));
  210. Assert.AreEqual(1, map.Count);
  211. Assert.IsTrue(collection.Remove(NewKeyValuePair("foo", "bar")));
  212. Assert.AreEqual(0, map.Count);
  213. Assert.Throws<ArgumentException>(() => collection.Remove(new KeyValuePair<string, string>(null, "")));
  214. }
  215. [Test]
  216. public void CopyTo_Pair()
  217. {
  218. var map = new MapField<string, string>();
  219. map.Add("foo", "bar");
  220. ICollection<KeyValuePair<string, string>> collection = map;
  221. KeyValuePair<string, string>[] array = new KeyValuePair<string, string>[3];
  222. collection.CopyTo(array, 1);
  223. Assert.AreEqual(NewKeyValuePair("foo", "bar"), array[1]);
  224. }
  225. [Test]
  226. public void Clear()
  227. {
  228. var map = new MapField<string, string> { { "x", "y" } };
  229. Assert.AreEqual(1, map.Count);
  230. map.Clear();
  231. Assert.AreEqual(0, map.Count);
  232. map.Add("x", "y");
  233. Assert.AreEqual(1, map.Count);
  234. }
  235. [Test]
  236. public void Indexer_Get()
  237. {
  238. var map = new MapField<string, string> { { "x", "y" } };
  239. Assert.AreEqual("y", map["x"]);
  240. Assert.Throws<KeyNotFoundException>(() => { var ignored = map["z"]; });
  241. }
  242. [Test]
  243. public void Indexer_Set()
  244. {
  245. var map = new MapField<string, string>();
  246. map["x"] = "y";
  247. Assert.AreEqual("y", map["x"]);
  248. map["x"] = "z"; // This won't throw, unlike Add.
  249. Assert.AreEqual("z", map["x"]);
  250. }
  251. [Test]
  252. public void GetEnumerator_NonGeneric()
  253. {
  254. IEnumerable map = new MapField<string, string> { { "x", "y" } };
  255. CollectionAssert.AreEqual(new[] { new KeyValuePair<string, string>("x", "y") },
  256. map.Cast<object>().ToList());
  257. }
  258. // Test for the explicitly-implemented non-generic IDictionary interface
  259. [Test]
  260. public void IDictionary_GetEnumerator()
  261. {
  262. IDictionary map = new MapField<string, string> { { "x", "y" } };
  263. var enumerator = map.GetEnumerator();
  264. // Commented assertions show an ideal situation - it looks like
  265. // the LinkedList enumerator doesn't throw when you ask for the current entry
  266. // at an inappropriate time; fixing this would be more work than it's worth.
  267. // Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
  268. Assert.IsTrue(enumerator.MoveNext());
  269. Assert.AreEqual("x", enumerator.Key);
  270. Assert.AreEqual("y", enumerator.Value);
  271. Assert.AreEqual(new DictionaryEntry("x", "y"), enumerator.Current);
  272. Assert.AreEqual(new DictionaryEntry("x", "y"), enumerator.Entry);
  273. Assert.IsFalse(enumerator.MoveNext());
  274. // Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
  275. enumerator.Reset();
  276. // Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
  277. Assert.IsTrue(enumerator.MoveNext());
  278. Assert.AreEqual("x", enumerator.Key); // Assume the rest are okay
  279. }
  280. [Test]
  281. public void IDictionary_Add()
  282. {
  283. var map = new MapField<string, string> { { "x", "y" } };
  284. IDictionary dictionary = map;
  285. dictionary.Add("a", "b");
  286. Assert.AreEqual("b", map["a"]);
  287. Assert.Throws<ArgumentException>(() => dictionary.Add("a", "duplicate"));
  288. Assert.Throws<InvalidCastException>(() => dictionary.Add(new object(), "key is bad"));
  289. Assert.Throws<InvalidCastException>(() => dictionary.Add("value is bad", new object()));
  290. }
  291. [Test]
  292. public void IDictionary_Contains()
  293. {
  294. var map = new MapField<string, string> { { "x", "y" } };
  295. IDictionary dictionary = map;
  296. Assert.IsFalse(dictionary.Contains("a"));
  297. Assert.IsFalse(dictionary.Contains(5));
  298. // Surprising, but IDictionary.Contains is only about keys.
  299. Assert.IsFalse(dictionary.Contains(new DictionaryEntry("x", "y")));
  300. Assert.IsTrue(dictionary.Contains("x"));
  301. }
  302. [Test]
  303. public void IDictionary_Remove()
  304. {
  305. var map = new MapField<string, string> { { "x", "y" } };
  306. IDictionary dictionary = map;
  307. dictionary.Remove("a");
  308. Assert.AreEqual(1, dictionary.Count);
  309. dictionary.Remove(5);
  310. Assert.AreEqual(1, dictionary.Count);
  311. dictionary.Remove(new DictionaryEntry("x", "y"));
  312. Assert.AreEqual(1, dictionary.Count);
  313. dictionary.Remove("x");
  314. Assert.AreEqual(0, dictionary.Count);
  315. Assert.Throws<ArgumentNullException>(() => dictionary.Remove(null));
  316. }
  317. [Test]
  318. public void IDictionary_CopyTo()
  319. {
  320. var map = new MapField<string, string> { { "x", "y" } };
  321. IDictionary dictionary = map;
  322. var array = new DictionaryEntry[3];
  323. dictionary.CopyTo(array, 1);
  324. CollectionAssert.AreEqual(new[] { default(DictionaryEntry), new DictionaryEntry("x", "y"), default(DictionaryEntry) },
  325. array);
  326. var objectArray = new object[3];
  327. dictionary.CopyTo(objectArray, 1);
  328. CollectionAssert.AreEqual(new object[] { null, new DictionaryEntry("x", "y"), null },
  329. objectArray);
  330. }
  331. [Test]
  332. public void IDictionary_IsFixedSize()
  333. {
  334. var map = new MapField<string, string> { { "x", "y" } };
  335. IDictionary dictionary = map;
  336. Assert.IsFalse(dictionary.IsFixedSize);
  337. }
  338. [Test]
  339. public void IDictionary_Keys()
  340. {
  341. IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
  342. CollectionAssert.AreEqual(new[] { "x" }, dictionary.Keys);
  343. }
  344. [Test]
  345. public void IDictionary_Values()
  346. {
  347. IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
  348. CollectionAssert.AreEqual(new[] { "y" }, dictionary.Values);
  349. }
  350. [Test]
  351. public void IDictionary_IsSynchronized()
  352. {
  353. IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
  354. Assert.IsFalse(dictionary.IsSynchronized);
  355. }
  356. [Test]
  357. public void IDictionary_SyncRoot()
  358. {
  359. IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
  360. Assert.AreSame(dictionary, dictionary.SyncRoot);
  361. }
  362. [Test]
  363. public void IDictionary_Indexer_Get()
  364. {
  365. IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
  366. Assert.AreEqual("y", dictionary["x"]);
  367. Assert.IsNull(dictionary["a"]);
  368. Assert.IsNull(dictionary[5]);
  369. Assert.Throws<ArgumentNullException>(() => dictionary[null].GetHashCode());
  370. }
  371. [Test]
  372. public void IDictionary_Indexer_Set()
  373. {
  374. var map = new MapField<string, string> { { "x", "y" } };
  375. IDictionary dictionary = map;
  376. map["a"] = "b";
  377. Assert.AreEqual("b", map["a"]);
  378. map["a"] = "c";
  379. Assert.AreEqual("c", map["a"]);
  380. Assert.Throws<InvalidCastException>(() => dictionary[5] = "x");
  381. Assert.Throws<InvalidCastException>(() => dictionary["x"] = 5);
  382. Assert.Throws<ArgumentNullException>(() => dictionary[null] = "z");
  383. Assert.Throws<ArgumentNullException>(() => dictionary["x"] = null);
  384. }
  385. [Test]
  386. public void KeysReturnsLiveView()
  387. {
  388. var map = new MapField<string, string>();
  389. var keys = map.Keys;
  390. CollectionAssert.AreEqual(new string[0], keys);
  391. map["foo"] = "bar";
  392. map["x"] = "y";
  393. CollectionAssert.AreEqual(new[] { "foo", "x" }, keys);
  394. }
  395. [Test]
  396. public void ValuesReturnsLiveView()
  397. {
  398. var map = new MapField<string, string>();
  399. var values = map.Values;
  400. CollectionAssert.AreEqual(new string[0], values);
  401. map["foo"] = "bar";
  402. map["x"] = "y";
  403. CollectionAssert.AreEqual(new[] { "bar", "y" }, values);
  404. }
  405. // Just test keys - we know the implementation is the same for values
  406. [Test]
  407. public void ViewsAreReadOnly()
  408. {
  409. var map = new MapField<string, string>();
  410. var keys = map.Keys;
  411. Assert.IsTrue(keys.IsReadOnly);
  412. Assert.Throws<NotSupportedException>(() => keys.Clear());
  413. Assert.Throws<NotSupportedException>(() => keys.Remove("a"));
  414. Assert.Throws<NotSupportedException>(() => keys.Add("a"));
  415. }
  416. // Just test keys - we know the implementation is the same for values
  417. [Test]
  418. public void ViewCopyTo()
  419. {
  420. var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
  421. var keys = map.Keys;
  422. var array = new string[4];
  423. Assert.Throws<ArgumentException>(() => keys.CopyTo(array, 3));
  424. Assert.Throws<ArgumentOutOfRangeException>(() => keys.CopyTo(array, -1));
  425. keys.CopyTo(array, 1);
  426. CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array);
  427. }
  428. // Just test keys - we know the implementation is the same for values
  429. [Test]
  430. public void NonGenericViewCopyTo()
  431. {
  432. IDictionary map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
  433. ICollection keys = map.Keys;
  434. // Note the use of the Array type here rather than string[]
  435. Array array = new string[4];
  436. Assert.Throws<ArgumentException>(() => keys.CopyTo(array, 3));
  437. Assert.Throws<ArgumentOutOfRangeException>(() => keys.CopyTo(array, -1));
  438. keys.CopyTo(array, 1);
  439. CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array);
  440. }
  441. [Test]
  442. public void KeysContains()
  443. {
  444. var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
  445. var keys = map.Keys;
  446. Assert.IsTrue(keys.Contains("foo"));
  447. Assert.IsFalse(keys.Contains("bar")); // It's a value!
  448. Assert.IsFalse(keys.Contains("1"));
  449. // Keys can't be null, so we should prevent contains check
  450. Assert.Throws<ArgumentNullException>(() => keys.Contains(null));
  451. }
  452. [Test]
  453. public void KeysCopyTo()
  454. {
  455. var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
  456. var keys = map.Keys.ToArray(); // Uses CopyTo internally
  457. CollectionAssert.AreEquivalent(new[] { "foo", "x" }, keys);
  458. }
  459. [Test]
  460. public void ValuesContains()
  461. {
  462. var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
  463. var values = map.Values;
  464. Assert.IsTrue(values.Contains("bar"));
  465. Assert.IsFalse(values.Contains("foo")); // It's a key!
  466. Assert.IsFalse(values.Contains("1"));
  467. // Values can be null, so this makes sense
  468. Assert.IsFalse(values.Contains(null));
  469. }
  470. [Test]
  471. public void ValuesCopyTo()
  472. {
  473. var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
  474. var values = map.Values.ToArray(); // Uses CopyTo internally
  475. CollectionAssert.AreEquivalent(new[] { "bar", "y" }, values);
  476. }
  477. [Test]
  478. public void ToString_StringToString()
  479. {
  480. var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
  481. Assert.AreEqual("{ \"foo\": \"bar\", \"x\": \"y\" }", map.ToString());
  482. }
  483. [Test]
  484. public void ToString_UnsupportedKeyType()
  485. {
  486. var map = new MapField<byte, string> { { 10, "foo" } };
  487. Assert.Throws<ArgumentException>(() => map.ToString());
  488. }
  489. [Test]
  490. public void NaNValuesComparedBitwise()
  491. {
  492. var map1 = new MapField<string, double>
  493. {
  494. { "x", SampleNaNs.Regular },
  495. { "y", SampleNaNs.SignallingFlipped }
  496. };
  497. var map2 = new MapField<string, double>
  498. {
  499. { "x", SampleNaNs.Regular },
  500. { "y", SampleNaNs.PayloadFlipped }
  501. };
  502. var map3 = new MapField<string, double>
  503. {
  504. { "x", SampleNaNs.Regular },
  505. { "y", SampleNaNs.SignallingFlipped }
  506. };
  507. EqualityTester.AssertInequality(map1, map2);
  508. EqualityTester.AssertEquality(map1, map3);
  509. Assert.True(map1.Values.Contains(SampleNaNs.SignallingFlipped));
  510. Assert.False(map2.Values.Contains(SampleNaNs.SignallingFlipped));
  511. }
  512. // This wouldn't usually happen, as protos can't use doubles as map keys,
  513. // but let's be consistent.
  514. [Test]
  515. public void NaNKeysComparedBitwise()
  516. {
  517. var map = new MapField<double, string>
  518. {
  519. { SampleNaNs.Regular, "x" },
  520. { SampleNaNs.SignallingFlipped, "y" }
  521. };
  522. Assert.AreEqual("x", map[SampleNaNs.Regular]);
  523. Assert.AreEqual("y", map[SampleNaNs.SignallingFlipped]);
  524. string ignored;
  525. Assert.False(map.TryGetValue(SampleNaNs.PayloadFlipped, out ignored));
  526. }
  527. #if !NET35
  528. [Test]
  529. public void IDictionaryKeys_Equals_IReadOnlyDictionaryKeys()
  530. {
  531. var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
  532. CollectionAssert.AreEquivalent(((IDictionary<string, string>)map).Keys, ((IReadOnlyDictionary<string, string>)map).Keys);
  533. }
  534. [Test]
  535. public void IDictionaryValues_Equals_IReadOnlyDictionaryValues()
  536. {
  537. var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
  538. CollectionAssert.AreEquivalent(((IDictionary<string, string>)map).Values, ((IReadOnlyDictionary<string, string>)map).Values);
  539. }
  540. #endif
  541. private static KeyValuePair<TKey, TValue> NewKeyValuePair<TKey, TValue>(TKey key, TValue value)
  542. {
  543. return new KeyValuePair<TKey, TValue>(key, value);
  544. }
  545. }
  546. }