2010-01-20 Zoltan Varga <vargaz@gmail.com>
[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};
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                 static void AssertContainsOnly<T> (IEnumerable<T> result, IEnumerable<T> data)
349                 {
350                         Assert.AreEqual (result.Count (), data.Count ());
351
352                         var store = new List<T> (result);
353                         foreach (var element in data) {
354                                 Assert.IsTrue (store.Contains (element));
355                                 store.Remove (element);
356                         }
357
358                         AssertIsEmpty (store);
359                 }
360
361                 static void AssertIsEmpty<T> (IEnumerable<T> source)
362                 {
363                         Assert.AreEqual (0, source.Count ());
364                 }
365
366
367                 delegate void D ();
368                 bool Throws (D d)
369                 {
370                         try {
371                                 d ();
372                                 return false;
373                         } catch {
374                                 return true;
375                         }
376                 }
377
378                 [Test]
379                 // based on #491858, #517415
380                 public void Enumerator_Current ()
381                 {
382 #pragma warning disable 0168
383                         var e1 = new HashSet<int>.Enumerator ();
384                         Assert.IsFalse (Throws (delegate { var x = e1.Current; }));
385
386                         var d = new HashSet<int> ();
387                         var e2 = d.GetEnumerator ();
388                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
389                         e2.MoveNext ();
390                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
391                         e2.Dispose ();
392                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
393
394                         var e3 = ((IEnumerable<int>) d).GetEnumerator ();
395                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
396                         e3.MoveNext ();
397                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
398                         e3.Dispose ();
399                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
400
401                         var e4 = ((IEnumerable) d).GetEnumerator ();
402                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
403                         e4.MoveNext ();
404                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
405                         ((IDisposable) e4).Dispose ();
406                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
407 #pragma warning restore 0168
408                 }
409         }
410 }