From 3f45d7c11e200184cfc09fb92efe25a63df1eef1 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Sat, 8 Aug 2015 07:17:58 +0100 Subject: Implement Keys and Values as views --- .../Collections/MapFieldTest.cs | 71 ++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'csharp/src/Google.Protobuf.Test') diff --git a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs index c62ac046..08f1a19c 100644 --- a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs +++ b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs @@ -477,6 +477,77 @@ namespace Google.Protobuf.Collections Assert.IsTrue(new MapField(true).AllowsNullValues); } + [Test] + public void KeysReturnsLiveView() + { + var map = new MapField(); + var keys = map.Keys; + CollectionAssert.AreEqual(new string[0], keys); + map["foo"] = "bar"; + map["x"] = "y"; + CollectionAssert.AreEqual(new[] { "foo", "x" }, keys); + } + + [Test] + public void ValuesReturnsLiveView() + { + var map = new MapField(); + var values = map.Values; + CollectionAssert.AreEqual(new string[0], values); + map["foo"] = "bar"; + map["x"] = "y"; + CollectionAssert.AreEqual(new[] { "bar", "y" }, values); + } + + // Just test keys - we know the implementation is the same for values + [Test] + public void ViewsAreReadOnly() + { + var map = new MapField(); + var keys = map.Keys; + Assert.IsTrue(keys.IsReadOnly); + Assert.Throws(() => keys.Clear()); + Assert.Throws(() => keys.Remove("a")); + Assert.Throws(() => keys.Add("a")); + } + + // Just test keys - we know the implementation is the same for values + [Test] + public void ViewCopyTo() + { + var map = new MapField { { "foo", "bar" }, { "x", "y" } }; + var keys = map.Keys; + var array = new string[4]; + Assert.Throws(() => keys.CopyTo(array, 3)); + Assert.Throws(() => keys.CopyTo(array, -1)); + keys.CopyTo(array, 1); + CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array); + } + + [Test] + public void KeysContains() + { + var map = new MapField { { "foo", "bar" }, { "x", "y" } }; + var keys = map.Keys; + Assert.IsTrue(keys.Contains("foo")); + Assert.IsFalse(keys.Contains("bar")); // It's a value! + Assert.IsFalse(keys.Contains("1")); + // Keys can't be null, so we should prevent contains check + Assert.Throws(() => keys.Contains(null)); + } + + [Test] + public void ValuesContains() + { + var map = new MapField { { "foo", "bar" }, { "x", "y" } }; + var values = map.Values; + Assert.IsTrue(values.Contains("bar")); + Assert.IsFalse(values.Contains("foo")); // It's a key! + Assert.IsFalse(values.Contains("1")); + // Values can be null, so this makes sense + Assert.IsFalse(values.Contains(null)); + } + private static KeyValuePair NewKeyValuePair(TKey key, TValue value) { return new KeyValuePair(key, value); -- cgit v1.2.3 From 5be01ee65b987ef17e6418fbff5f161ed0f5cc87 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Mon, 10 Aug 2015 08:47:07 +0100 Subject: Implement ICollection.CopyTo (using Array) for MapField views. --- .../src/Google.Protobuf.Test/Collections/MapFieldTest.cs | 14 ++++++++++++++ csharp/src/Google.Protobuf/Collections/MapField.cs | 13 ++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'csharp/src/Google.Protobuf.Test') diff --git a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs index 08f1a19c..29c4c2a9 100644 --- a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs +++ b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs @@ -523,6 +523,20 @@ namespace Google.Protobuf.Collections keys.CopyTo(array, 1); CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array); } + + // Just test keys - we know the implementation is the same for values + [Test] + public void NonGenericViewCopyTo() + { + IDictionary map = new MapField { { "foo", "bar" }, { "x", "y" } }; + ICollection keys = map.Keys; + // Note the use of the Array type here rather than string[] + Array array = new string[4]; + Assert.Throws(() => keys.CopyTo(array, 3)); + Assert.Throws(() => keys.CopyTo(array, -1)); + keys.CopyTo(array, 1); + CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array); + } [Test] public void KeysContains() diff --git a/csharp/src/Google.Protobuf/Collections/MapField.cs b/csharp/src/Google.Protobuf/Collections/MapField.cs index 6dcdc100..004ff54b 100644 --- a/csharp/src/Google.Protobuf/Collections/MapField.cs +++ b/csharp/src/Google.Protobuf/Collections/MapField.cs @@ -735,7 +735,18 @@ namespace Google.Protobuf.Collections public void CopyTo(Array array, int index) { - throw new NotImplementedException(); + if (index < 0) + { + throw new ArgumentOutOfRangeException("arrayIndex"); + } + if (index + Count >= array.Length) + { + throw new ArgumentException("Not enough space in the array", "array"); + } + foreach (var item in this) + { + array.SetValue(item, index++); + } } } } -- cgit v1.2.3