Update mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs
[mono.git] / mcs / class / System.Core / Test / System.Collections.Generic / HashSetTest.cs
1 //
2 // HashSetTest.cs
3 //
4 // Authors:
5 //  Jb Evain  <jbevain@novell.com>
6 //
7 // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Collections;
31 using System.Collections.Generic;
32 using System.Linq;
33
34 using NUnit.Framework;
35
36 namespace MonoTests.System.Collections.Generic {
37
38         [TestFixture]
39         public class HashSetTest {
40
41                 [Test]
42                 public void TestAdd ()
43                 {
44                         var set = new HashSet<int> ();
45
46                         Assert.IsTrue (set.Add (1));
47                         Assert.IsTrue (set.Add (2));
48                         Assert.IsTrue (set.Add (3));
49                         Assert.IsTrue (set.Add (4));
50                         Assert.IsFalse (set.Add (4));
51                         Assert.IsFalse (set.Add (3));
52                         Assert.IsFalse (set.Add (2));
53                         Assert.IsFalse (set.Add (1));
54                         Assert.IsTrue (set.Add (0));
55                         Assert.IsFalse (set.Add (0));
56                 }
57
58                 [Test]
59                 public void TestRemove ()
60                 {
61                         var set = new HashSet<int> ();
62
63                         Assert.IsTrue (set.Add (1));
64                         Assert.IsTrue (set.Add (2));
65                         Assert.IsTrue (set.Add (3));
66                         Assert.IsTrue (set.Add (4));
67
68                         Assert.IsTrue (set.Remove (2));
69                         Assert.IsTrue (set.Remove (3));
70
71                         AssertContainsOnly (new int [] {1, 4}, set);
72                 }
73
74                 [Test]
75                 public void TestMassiveAdd ()
76                 {
77                         var set = new HashSet<int> ();
78
79                         var massive = Enumerable.Range (0, 10000).ToArray ();
80                         foreach (var item in massive)
81                                 Assert.IsTrue (set.Add (item));
82
83                         AssertContainsOnly (massive, set);
84                 }
85
86                 [Test]
87                 public void TestMassiveRemove ()
88                 {
89                         var massive = Enumerable.Range (0, 10000).ToArray ();
90                         var set = new HashSet<int> (massive);
91
92                         foreach (var item in massive)
93                                 Assert.IsTrue (set.Remove (item));
94
95                         AssertIsEmpty (set);
96                 }
97
98                 [Test]
99                 [Category("TargetJvmNotWorking")]
100                 public void TestCopyTo ()
101                 {
102                         var data = new [] {1, 2, 3, 4, 5};
103                         var set = new HashSet<int> (data);
104
105                         var array = new int [set.Count];
106                         set.CopyTo (array, 0);
107
108                         AssertContainsOnly (data, array);
109                 }
110
111                 [Test]
112                 public void TestClear ()
113                 {
114                         var data = new [] {1, 2, 3, 4, 5, 6};
115                         var set = new HashSet<int> (data);
116
117                         Assert.AreEqual (data.Length, set.Count);
118                         set.Clear ();
119                         AssertIsEmpty (set);
120                 }
121
122                 [Test]
123                 public void TestContains ()
124                 {
125                         var data = new [] {1, 2, 3, 4, 5, 6};
126                         var set = new HashSet<int> (data);
127
128                         foreach (var item in data)
129                                 Assert.IsTrue (set.Contains (item));
130                 }
131
132                 [Test, ExpectedException (typeof (InvalidOperationException))]
133                 public void TestModifySetWhileForeach ()
134                 {
135                         var set = new HashSet<int> (new [] {1, 2, 3, 4});
136                         foreach (var item in set)
137                                 set.Add (item + 2);
138                 }
139
140                 [Test]
141                 public void TestRemoveWhere ()
142                 {
143                         var data = new [] {1, 2, 3, 4, 5, 6, 7, 8, 9};
144                         var result = new [] {2, 4, 6, 8};
145
146                         var set = new HashSet<int> (data);
147                         int removed = set.RemoveWhere (i => (i % 2) != 0);
148
149                         Assert.AreEqual (data.Length - result.Length, removed);
150                         AssertContainsOnly (result, set);
151                 }
152
153                 [Test]
154                 public void TestOverlaps ()
155                 {
156                         var set = new HashSet<int> (new [] {1, 2, 3, 4, 5});
157
158                         Assert.IsTrue (set.Overlaps (new [] {0, 2}));
159                 }
160
161                 [Test]
162                 public void TestIntersectWith ()
163                 {
164                         var data = new [] {1, 2, 3, 4};
165                         var other = new [] {2, 4, 5, 6};
166                         var result = new [] {2, 4};
167
168                         var set = new HashSet<int> (data);
169
170                         set.IntersectWith (other);
171
172                         AssertContainsOnly (result, set);
173                 }
174
175                 [Test]
176                 public void TestExceptWith ()
177                 {
178                         var data = new [] {1, 2, 3, 4, 5, 6};
179                         var other = new [] {2, 4, 6};
180                         var result = new [] {1, 3, 5};
181                         var set = new HashSet<int> (data);
182
183                         set.ExceptWith (other);
184
185                         AssertContainsOnly (result, set);
186                 }
187
188                 [Test]
189                 public void TestUnionWith ()
190                 {
191                         var data = new [] {1, 2, 3, 4, 5, 6};
192                         var other = new [] {4, 5, 6, 7, 8, 9};
193                         var result = new [] {1, 2, 3, 4, 5, 6, 7, 8, 9};
194
195                         var set = new HashSet<int> (data);
196                         set.UnionWith (other);
197
198                         AssertContainsOnly (result, set);
199                 }
200
201                 [Test]
202                 public void TestSymmetricExceptWith ()
203                 {
204                         var data = new [] {1, 2, 3, 4, 5};
205                         var other = new [] {4, 5, 6, 7, 8, 9, 9};
206                         var result = new [] {1, 2, 3, 6, 7, 8, 9};
207
208                         var set = new HashSet<int> (data);
209                         set.SymmetricExceptWith (other);
210
211                         AssertContainsOnly (result, set);
212                 }
213
214                 [Test]
215                 public void TestEmptyHashSubsetOf ()
216                 {
217                         var set = new HashSet<int> ();
218
219                         Assert.IsTrue (set.IsSubsetOf (new int [0]));
220                         Assert.IsTrue (set.IsSubsetOf (new [] {1, 2}));
221                 }
222
223                 [Test]
224                 public void TestSubsetOf ()
225                 {
226                         var data = new [] {1, 2, 3};
227                         var other = new [] {1, 2, 3, 4, 5};
228                         var other2 = new [] {1, 2, 3};
229                         var other3 = new [] {0, 1, 2};
230
231                         var set = new HashSet<int> (data);
232
233                         Assert.IsTrue (set.IsSubsetOf (other));
234                         Assert.IsTrue (set.IsSubsetOf (other2));
235                         Assert.IsFalse (set.IsSubsetOf (other3));
236                 }
237
238                 [Test]
239                 public void TestProperSubsetOf ()
240                 {
241                         var data = new [] {1, 2, 3};
242                         var other = new [] {1, 2, 3, 4, 5};
243                         var other2 = new [] {1, 2, 3};
244                         var other3 = new [] {0, 1, 2};
245
246                         var set = new HashSet<int> (data);
247
248                         Assert.IsTrue (set.IsProperSubsetOf (other));
249                         Assert.IsFalse (set.IsProperSubsetOf (other2));
250                         Assert.IsFalse (set.IsProperSubsetOf (other3));
251                 }
252
253                 [Test]
254                 public void TestSupersetOf ()
255                 {
256                         var data = new [] {1, 2, 3, 4, 5};
257                         var other = new [] {2, 3, 4};
258                         var other2 = new [] {1, 2, 3, 4, 5};
259                         var other3 = new [] {4, 5, 6};
260
261                         var set = new HashSet<int> (data);
262
263                         Assert.IsTrue (set.IsSupersetOf (other));
264                         Assert.IsTrue (set.IsSupersetOf (other2));
265                         Assert.IsFalse (set.IsSupersetOf (other3));
266                 }
267
268                 [Test]
269                 public void TestProperSupersetOf ()
270                 {
271                         var data = new [] {1, 2, 3, 4, 5};
272                         var other = new [] {2, 3, 4};
273                         var other2 = new [] {1, 2, 3, 4, 5};
274                         var other3 = new [] {4, 5, 6};
275
276                         var set = new HashSet<int> (data);
277
278                         Assert.IsTrue (set.IsProperSupersetOf (other));
279                         Assert.IsFalse (set.IsProperSupersetOf (other2));
280                         Assert.IsFalse (set.IsProperSupersetOf (other3));
281                 }
282
283                 [Test]
284                 public void TestSetEquals ()
285                 {
286                         var data = new [] {1, 2, 3, 4};
287
288                         var other = new [] {1, 2, 3, 4};
289                         var other2 = new [] {1, 2, 2, 4};
290                         var other3 = new [] {1, 2};
291                         var other4 = new [] {1, 2, 3, 4, 5};
292                         var other5 = new [] {1, 1, 1, 1};
293
294                         var set = new HashSet<int> (data);
295
296                         Assert.IsTrue (set.SetEquals (other));
297                         Assert.IsFalse (set.SetEquals (other2));
298                         Assert.IsFalse (set.SetEquals (other3));
299                         Assert.IsFalse (set.SetEquals (other4));
300                         Assert.IsFalse (set.SetEquals (other5));
301                 }
302
303                 [Test]
304                 public void TestCopyToFull ()
305                 {
306                         var data = new [] {1, 2, 3, 4};
307
308                         var set = new HashSet<int> (data);
309
310                         var res = new int [set.Count];
311                         set.CopyTo (res, 0);
312
313                         AssertContainsOnly (res, data);
314                 }
315
316                 [Test]
317                 public void TestCopyToEmpty ()
318                 {
319                         var set = new HashSet<int> ();
320
321                         var res = new int [0];
322                         set.CopyTo (res, 0);
323                 }
324
325                 [Test]
326                 public void TestCopyToPrecise ()
327                 {
328                         var set = new HashSet<int> ();
329                         set.Add (42);
330
331                         var dest = new int [12];
332
333                         set.CopyTo (dest, 6, 1);
334
335                         Assert.AreEqual (42, dest [6]);
336                 }
337
338                 [Test]
339                 public void TestICollection ()
340                 {
341                         var set = new HashSet<int> () as ICollection<int>;
342                         set.Add (42);
343                         set.Add (42);
344
345                         Assert.AreEqual (1, set.Count);
346                 }
347
348                 [Test]
349                 public void TestHashSetEqualityComparer ()
350                 {
351                         var data = new string[] { "foo", "bar", "foobar" };
352                         var set1 = new HashSet<string> (data, StringComparer.Ordinal);
353                         var set2 = new HashSet<string> (data, StringComparer.OrdinalIgnoreCase);
354
355                         var comparer = HashSet<string>.CreateSetComparer ();
356                         Assert.IsTrue (comparer.Equals (set1, set1));
357                         Assert.IsTrue (comparer.Equals (set1, set2));
358                         Assert.AreEqual (comparer.GetHashCode (set1), comparer.GetHashCode (set2));
359
360                         var set3 = new HashSet<string> (new [] { "foobar", "foo", "bar" });
361                         Assert.IsTrue (comparer.Equals (set1, set3));
362                         Assert.AreEqual (comparer.GetHashCode (set1), comparer.GetHashCode (set3));
363
364                         var set4 = new HashSet<string> (new [] { "oh", "hai", "folks" });
365                         Assert.IsFalse (comparer.Equals (set2, set4));
366                         Assert.AreNotEqual (comparer.GetHashCode (set2), comparer.GetHashCode (set4));
367
368                         Assert.IsTrue (comparer.Equals (null, null));
369                         Assert.AreEqual (0, comparer.GetHashCode (null));
370                         Assert.IsFalse (comparer.Equals (set1, null));
371                 }
372
373                 static void AssertContainsOnly<T> (IEnumerable<T> result, IEnumerable<T> data)
374                 {
375                         Assert.AreEqual (result.Count (), data.Count ());
376
377                         var store = new List<T> (result);
378                         foreach (var element in data) {
379                                 Assert.IsTrue (store.Contains (element));
380                                 store.Remove (element);
381                         }
382
383                         AssertIsEmpty (store);
384                 }
385
386                 static void AssertIsEmpty<T> (IEnumerable<T> source)
387                 {
388                         Assert.AreEqual (0, source.Count ());
389                 }
390
391
392                 delegate void D ();
393                 bool Throws (D d)
394                 {
395                         try {
396                                 d ();
397                                 return false;
398                         } catch {
399                                 return true;
400                         }
401                 }
402
403                 [Test]
404                 // based on #491858, #517415
405                 public void Enumerator_Current ()
406                 {
407 #pragma warning disable 0168
408                         var e1 = new HashSet<int>.Enumerator ();
409                         Assert.IsFalse (Throws (delegate { var x = e1.Current; }));
410
411                         var d = new HashSet<int> ();
412                         var e2 = d.GetEnumerator ();
413                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
414                         e2.MoveNext ();
415                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
416                         e2.Dispose ();
417                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
418
419                         var e3 = ((IEnumerable<int>) d).GetEnumerator ();
420                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
421                         e3.MoveNext ();
422                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
423                         e3.Dispose ();
424                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
425
426                         var e4 = ((IEnumerable) d).GetEnumerator ();
427                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
428                         e4.MoveNext ();
429                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
430                         ((IDisposable) e4).Dispose ();
431                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
432 #pragma warning restore 0168
433                 }
434
435                 [Test]
436                 public void TestNullsWithComparerThrowingException ()
437                 {
438                         // 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
439                         var set = new HashSet<string> (new StringComparerOrdinalLookAlike ());
440                         Assert.IsTrue (set.Add (string.Empty), "#1a");
441                         Assert.IsFalse (set.Contains (null), "#2a");
442                         Assert.IsTrue (set.Add (null), "#2b");
443                         Assert.IsTrue (set.Contains (null), "#2c");
444                         Assert.AreEqual (2, set.Count, "#3");
445                         Assert.IsTrue (set.Add ("a"), "#4");
446                         AssertContainsOnly (new string [] { string.Empty, null, "a" }, set);
447                         Assert.IsFalse (set.Add (null), "#5");
448                         Assert.IsTrue (set.Add ("b"), "#6");
449                         Assert.IsFalse (set.Add ("b"), "#7");
450                         Assert.IsFalse (set.Add (string.Empty), "#8");
451                         Assert.IsFalse (set.Add ("a"), "#9");
452                         Assert.IsFalse (set.Add (null), "#10");
453                         Assert.IsTrue (set.Add ("c"), "#11");
454                         Assert.IsFalse (set.Add ("c"), "#12");
455                         Assert.AreEqual (5, set.Count, "#13");
456                         Assert.IsTrue (set.Remove (null), "#14");
457                         Assert.IsTrue (set.Remove ("b"), "#15");
458                         Assert.IsFalse (set.Remove (null), "#16");
459                         Assert.AreEqual (3, set.Count, "#17");
460                         AssertContainsOnly (new string [] { string.Empty, "a", "c" }, set);
461                 }
462
463                 private class StringComparerOrdinalLookAlike : IEqualityComparer<string>
464                 {
465                         public bool Equals(string x, string y)
466                         {
467                                 return string.CompareOrdinal(x, y) == 0;
468                         }
469
470                         public int GetHashCode(string str)
471                         {
472                                 if (str != null)
473                                         return str.GetHashCode();
474                                 throw new ArgumentNullException ();  // Important aspect for test (same as what StringComparer.Ordinal does, and different from GenericEqualityComparer<string>)
475                         }
476                 }
477         }
478 }