| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573 |
- //
- // HashSetTest.cs
- //
- // Authors:
- // Jb Evain <[email protected]>
- //
- // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using NUnit.Framework;
- namespace MonoTests.System.Collections.Generic {
- [TestFixture]
- public class HashSetTest {
- [Test]
- public void TestAdd ()
- {
- var set = new HashSet<int> ();
- Assert.IsTrue (set.Add (1));
- Assert.IsTrue (set.Add (2));
- Assert.IsTrue (set.Add (3));
- Assert.IsTrue (set.Add (4));
- Assert.IsFalse (set.Add (4));
- Assert.IsFalse (set.Add (3));
- Assert.IsFalse (set.Add (2));
- Assert.IsFalse (set.Add (1));
- Assert.IsTrue (set.Add (0));
- Assert.IsFalse (set.Add (0));
- }
- [Test]
- public void TestRemove ()
- {
- var set = new HashSet<int> ();
- Assert.IsTrue (set.Add (1));
- Assert.IsTrue (set.Add (2));
- Assert.IsTrue (set.Add (3));
- Assert.IsTrue (set.Add (4));
- Assert.IsTrue (set.Remove (2));
- Assert.IsTrue (set.Remove (3));
- AssertContainsOnly (new int [] {1, 4}, set);
- }
- [Test]
- public void TestMassiveAdd ()
- {
- var set = new HashSet<int> ();
- var massive = Enumerable.Range (0, 10000).ToArray ();
- foreach (var item in massive)
- Assert.IsTrue (set.Add (item));
- AssertContainsOnly (massive, set);
- }
- [Test]
- public void TestMassiveRemove ()
- {
- var massive = Enumerable.Range (0, 10000).ToArray ();
- var set = new HashSet<int> (massive);
- foreach (var item in massive)
- Assert.IsTrue (set.Remove (item));
- AssertIsEmpty (set);
- }
- [Test]
- public void TestCopyTo ()
- {
- var data = new [] {1, 2, 3, 4, 5};
- var set = new HashSet<int> (data);
- var array = new int [set.Count];
- set.CopyTo (array, 0);
- AssertContainsOnly (data, array);
- }
- [Test]
- public void TestClear ()
- {
- var data = new [] {1, 2, 3, 4, 5, 6};
- var set = new HashSet<int> (data);
- Assert.AreEqual (data.Length, set.Count);
- set.Clear ();
- AssertIsEmpty (set);
- }
- [Test]
- public void TestContains ()
- {
- var data = new [] {1, 2, 3, 4, 5, 6};
- var set = new HashSet<int> (data);
- foreach (var item in data)
- Assert.IsTrue (set.Contains (item));
- }
- [Test, ExpectedException (typeof (InvalidOperationException))]
- public void TestModifySetWhileForeach ()
- {
- var set = new HashSet<int> (new [] {1, 2, 3, 4});
- foreach (var item in set)
- set.Add (item + 2);
- }
- [Test]
- public void TestRemoveWhere ()
- {
- var data = new [] {1, 2, 3, 4, 5, 6, 7, 8, 9};
- var result = new [] {2, 4, 6, 8};
- var set = new HashSet<int> (data);
- int removed = set.RemoveWhere (i => (i % 2) != 0);
- Assert.AreEqual (data.Length - result.Length, removed);
- AssertContainsOnly (result, set);
- }
- [Test]
- public void TestOverlaps ()
- {
- var set = new HashSet<int> (new [] {1, 2, 3, 4, 5});
- Assert.IsTrue (set.Overlaps (new [] {0, 2}));
- }
- [Test]
- public void TestIntersectWith ()
- {
- var data = new [] {1, 2, 3, 4};
- var other = new [] {2, 4, 5, 6};
- var result = new [] {2, 4};
- var set = new HashSet<int> (data);
- set.IntersectWith (other);
- AssertContainsOnly (result, set);
- }
- [Test]
- public void TestIntersectWithComparer ()
- {
- var data = new[] {"a", "b", "C", "d", "E"};
- var other = new[] {"a", "B", "e"};
- var result = new[] {"a", "b", "E"};
- var set = new HashSet<string> (data, StringComparer.OrdinalIgnoreCase);
- set.IntersectWith (other);
- AssertContainsOnly (result, set);
- }
- [Test]
- public void TestExceptWith ()
- {
- var data = new [] {1, 2, 3, 4, 5, 6};
- var other = new [] {2, 4, 6};
- var result = new [] {1, 3, 5};
- var set = new HashSet<int> (data);
- set.ExceptWith (other);
- AssertContainsOnly (result, set);
- }
- [Test]
- public void TestUnionWith ()
- {
- var data = new [] {1, 2, 3, 4, 5, 6};
- var other = new [] {4, 5, 6, 7, 8, 9};
- var result = new [] {1, 2, 3, 4, 5, 6, 7, 8, 9};
- var set = new HashSet<int> (data);
- set.UnionWith (other);
- AssertContainsOnly (result, set);
- }
- [Test]
- public void TestSymmetricExceptWith ()
- {
- var data = new [] {1, 2, 3, 4, 5};
- var other = new [] {4, 5, 6, 7, 8, 9, 9};
- var result = new [] {1, 2, 3, 6, 7, 8, 9};
- var set = new HashSet<int> (data);
- set.SymmetricExceptWith (other);
- AssertContainsOnly (result, set);
- }
- [Test]
- public void TestEmptyHashSubsetOf ()
- {
- var set = new HashSet<int> ();
- Assert.IsTrue (set.IsSubsetOf (new int [0]));
- Assert.IsTrue (set.IsSubsetOf (new [] {1, 2}));
- }
- [Test]
- public void TestSubsetOf ()
- {
- var data = new [] {1, 2, 3};
- var other = new [] {1, 2, 3, 4, 5};
- var other2 = new [] {1, 2, 3};
- var other3 = new [] {0, 1, 2};
- var set = new HashSet<int> (data);
- Assert.IsTrue (set.IsSubsetOf (other));
- Assert.IsTrue (set.IsSubsetOf (other2));
- Assert.IsFalse (set.IsSubsetOf (other3));
- }
- [Test]
- public void TestSubsetOfComparer ()
- {
- var data = new[] { "abc", "DF", "gHIl" };
- var other1 = new[] { "pqR", "ABC", "ghil", "dF", "lmn" };
- var set = new HashSet<string> (data, StringComparer.OrdinalIgnoreCase);
- Assert.IsTrue (set.IsSubsetOf (other1));
- }
- [Test]
- public void TestProperSubsetOf ()
- {
- var data = new [] {1, 2, 3};
- var other = new [] {1, 2, 3, 4, 5};
- var other2 = new [] {1, 2, 3};
- var other3 = new [] {0, 1, 2};
- var set = new HashSet<int> (data);
- Assert.IsTrue (set.IsProperSubsetOf (other));
- Assert.IsFalse (set.IsProperSubsetOf (other2));
- Assert.IsFalse (set.IsProperSubsetOf (other3));
- }
- [Test]
- public void TestProperSubsetOfComparer ()
- {
- var data = new[] { "abc", "DF", "gHIl" };
- var other1 = new[] { "pqR", "ABC", "ghil", "dF", "lmn" };
- var set = new HashSet<string> (data, StringComparer.OrdinalIgnoreCase);
- Assert.IsTrue (set.IsProperSubsetOf (other1));
- }
- [Test]
- public void TestSupersetOf ()
- {
- var data = new [] {1, 2, 3, 4, 5};
- var other = new [] {2, 3, 4};
- var other2 = new [] {1, 2, 3, 4, 5};
- var other3 = new [] {4, 5, 6};
- var set = new HashSet<int> (data);
- Assert.IsTrue (set.IsSupersetOf (other));
- Assert.IsTrue (set.IsSupersetOf (other2));
- Assert.IsFalse (set.IsSupersetOf (other3));
- }
- [Test]
- public void TestSupersetOfComparer ()
- {
- var data = new[] {"a", "B", "c", "D"};
- var other1 = new[] {"A", "a", "C", "c"};
- var other2 = new[] {"A", "a", "B", "D", "C", "c"};
- var set = new HashSet<string> (data, StringComparer.OrdinalIgnoreCase);
- Assert.IsTrue (set.IsSupersetOf (other1));
- Assert.IsTrue (set.IsSupersetOf (other2));
- }
- [Test]
- public void TestProperSupersetOf ()
- {
- var data = new [] {1, 2, 3, 4, 5};
- var other = new [] {2, 3, 4};
- var other2 = new [] {1, 2, 3, 4, 5};
- var other3 = new [] {4, 5, 6};
- var set = new HashSet<int> (data);
- Assert.IsTrue (set.IsProperSupersetOf (other));
- Assert.IsFalse (set.IsProperSupersetOf (other2));
- Assert.IsFalse (set.IsProperSupersetOf (other3));
- }
- [Test]
- public void TestProperSupersetOfComparer ()
- {
- var data = new[] { "a", "B", "c", "D" };
- var other1 = new[] { "A", "a", "d", "D" };
- var other2 = new[] { "A", "a", "B", "D", "C", "c" };
- var set = new HashSet<string> (data, StringComparer.OrdinalIgnoreCase);
- Assert.IsTrue (set.IsProperSupersetOf (other1));
- Assert.IsFalse (set.IsProperSupersetOf (other2));
- }
- [Test]
- public void TestSetEquals ()
- {
- var data = new [] {1, 2, 3, 4};
- var other = new [] {1, 2, 3, 4};
- var other2 = new [] {1, 2, 2, 4};
- var other3 = new [] {1, 2};
- var other4 = new [] {1, 2, 3, 4, 5};
- var other5 = new [] {1, 1, 1, 1};
- var set = new HashSet<int> (data);
- Assert.IsTrue (set.SetEquals (other));
- Assert.IsFalse (set.SetEquals (other2));
- Assert.IsFalse (set.SetEquals (other3));
- Assert.IsFalse (set.SetEquals (other4));
- Assert.IsFalse (set.SetEquals (other5));
- }
- [Test]
- public void TestSetEqualsComparer ()
- {
- var data = new[] { "abc", "DF", "gHIl" };
- var other1 = new[] { "ABC", "DF", "GHIL" };
- var other2 = new[] { "ABC", "aBc", "DF", "GHIL", "ghil" };
- var set = new HashSet<string>(data, StringComparer.OrdinalIgnoreCase);
- Assert.IsTrue (set.SetEquals (other1));
- Assert.IsTrue (set.SetEquals (other2));
- }
- [Test]
- public void TestCopyToFull ()
- {
- var data = new [] {1, 2, 3, 4};
- var set = new HashSet<int> (data);
- var res = new int [set.Count];
- set.CopyTo (res, 0);
- AssertContainsOnly (res, data);
- }
- [Test]
- public void TestCopyToEmpty ()
- {
- var set = new HashSet<int> ();
- var res = new int [0];
- set.CopyTo (res, 0);
- }
- [Test]
- public void TestCopyToPrecise ()
- {
- var set = new HashSet<int> ();
- set.Add (42);
- var dest = new int [12];
- set.CopyTo (dest, 6, 1);
- Assert.AreEqual (42, dest [6]);
- }
- [Test]
- public void TestICollection ()
- {
- var set = new HashSet<int> () as ICollection<int>;
- set.Add (42);
- set.Add (42);
- Assert.AreEqual (1, set.Count);
- }
- [Test]
- public void TestHashSetEqualityComparer ()
- {
- var data = new string[] { "foo", "bar", "foobar" };
- var set1 = new HashSet<string> (data, StringComparer.Ordinal);
- var set2 = new HashSet<string> (data, StringComparer.OrdinalIgnoreCase);
- var comparer = HashSet<string>.CreateSetComparer ();
- Assert.IsTrue (comparer.Equals (set1, set1));
- Assert.IsTrue (comparer.Equals (set1, set2));
- Assert.AreEqual (comparer.GetHashCode (set1), comparer.GetHashCode (set2));
- var set3 = new HashSet<string> (new [] { "foobar", "foo", "bar" });
- Assert.IsTrue (comparer.Equals (set1, set3));
- Assert.AreEqual (comparer.GetHashCode (set1), comparer.GetHashCode (set3));
- var set4 = new HashSet<string> (new [] { "oh", "hai", "folks" });
- Assert.IsFalse (comparer.Equals (set2, set4));
- Assert.AreNotEqual (comparer.GetHashCode (set2), comparer.GetHashCode (set4));
- Assert.IsTrue (comparer.Equals (null, null));
- Assert.AreEqual (0, comparer.GetHashCode (null));
- Assert.IsFalse (comparer.Equals (set1, null));
- }
- static void AssertContainsOnly<T> (IEnumerable<T> result, IEnumerable<T> data)
- {
- Assert.AreEqual (result.Count (), data.Count ());
- var store = new List<T> (result);
- foreach (var element in data) {
- Assert.IsTrue (store.Contains (element));
- store.Remove (element);
- }
- AssertIsEmpty (store);
- }
- static void AssertIsEmpty<T> (IEnumerable<T> source)
- {
- Assert.AreEqual (0, source.Count ());
- }
- delegate void D ();
- bool Throws (D d)
- {
- try {
- d ();
- return false;
- } catch {
- return true;
- }
- }
- [Test]
- // based on #491858, #517415
- public void Enumerator_Current ()
- {
- #pragma warning disable 0168
- var e1 = new HashSet<int>.Enumerator ();
- Assert.IsFalse (Throws (delegate { var x = e1.Current; }));
- var d = new HashSet<int> ();
- var e2 = d.GetEnumerator ();
- Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
- e2.MoveNext ();
- Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
- e2.Dispose ();
- Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
- var e3 = ((IEnumerable<int>) d).GetEnumerator ();
- Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
- e3.MoveNext ();
- Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
- e3.Dispose ();
- Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
- var e4 = ((IEnumerable) d).GetEnumerator ();
- Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
- e4.MoveNext ();
- Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
- ((IDisposable) e4).Dispose ();
- Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
- #pragma warning restore 0168
- }
- [Test]
- public void TestNullsWithComparerThrowingException ()
- {
- // NOTE: We should get the same errors when using StringComparer.Ordinal on Mono 2.6.1, but the look-alike gives us more control over this test case
- var set = new HashSet<string> (new StringComparerOrdinalLookAlike ());
- Assert.IsTrue (set.Add (string.Empty), "#1a");
- Assert.IsFalse (set.Contains (null), "#2a");
- Assert.IsTrue (set.Add (null), "#2b");
- Assert.IsTrue (set.Contains (null), "#2c");
- Assert.AreEqual (2, set.Count, "#3");
- Assert.IsTrue (set.Add ("a"), "#4");
- AssertContainsOnly (new string [] { string.Empty, null, "a" }, set);
- Assert.IsFalse (set.Add (null), "#5");
- Assert.IsTrue (set.Add ("b"), "#6");
- Assert.IsFalse (set.Add ("b"), "#7");
- Assert.IsFalse (set.Add (string.Empty), "#8");
- Assert.IsFalse (set.Add ("a"), "#9");
- Assert.IsFalse (set.Add (null), "#10");
- Assert.IsTrue (set.Add ("c"), "#11");
- Assert.IsFalse (set.Add ("c"), "#12");
- Assert.AreEqual (5, set.Count, "#13");
- Assert.IsTrue (set.Remove (null), "#14");
- Assert.IsTrue (set.Remove ("b"), "#15");
- Assert.IsFalse (set.Remove (null), "#16");
- Assert.AreEqual (3, set.Count, "#17");
- AssertContainsOnly (new string [] { string.Empty, "a", "c" }, set);
- }
- private class StringComparerOrdinalLookAlike : IEqualityComparer<string>
- {
- public bool Equals(string x, string y)
- {
- return string.CompareOrdinal(x, y) == 0;
- }
- public int GetHashCode(string str)
- {
- if (str != null)
- return str.GetHashCode();
- throw new ArgumentNullException (); // Important aspect for test (same as what StringComparer.Ordinal does, and different from GenericEqualityComparer<string>)
- }
- }
- [Test]
- public void TrimWithoutChange ()
- {
- var lookup = new HashSet<string> ();
- for (int i = 0; i < 10000; i++) {
- lookup.Add (i.ToString ());
- }
- lookup.Remove (3.ToString ());
- for (int i = 0; i < 1000; i++) {
- lookup.TrimExcess ();
- }
- }
- }
- }
|