Skip to content

Commit

Permalink
Continuation of fixes identified when fixing issue #16
Browse files Browse the repository at this point in the history
Added INotifyCollectionChanged unit tests for the following classes:
- ConcurrentObservableCollection
- ConcurrentObservableDictionary
- ConcurrentObservableHashSet
- ConcurrentObservableSortedCollection
- ConcurrentObservableSortedDictionary
- ConcurrentObservableSortedSet

Fixed a few issues that were identified by the tests.
  • Loading branch information
stewienj committed Jan 27, 2021
1 parent 7cb2994 commit 784981e
Show file tree
Hide file tree
Showing 9 changed files with 885 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Swordfish.NET.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
Expand All @@ -20,7 +21,7 @@ namespace Swordfish.NET.UnitTestV3
/// Test the following collection classes:
///
/// - ConcurrentObservableCollection - done (this class)
/// - ConcurrentObservableDictionary
/// - ConcurrentObservableDictionary - done (other class)
/// - ConcurrentObservableHashSet
/// - ConcurrentObservableSortedCollection
/// - ConcurrentObservableSortedDictionary
Expand All @@ -30,7 +31,7 @@ namespace Swordfish.NET.UnitTestV3
public class ConcurrentObservableCollection_INotifyCollectionChangedTests
{
[TestMethod]
public void Test_ConcurrentObservableCollection_AddRange()
public void Test_ConcurrentObservableCollection_AddRange_IList()
{
var toAdd = Enumerable.Range(0, 100).ToList();
var collection = new ConcurrentObservableCollection<int>();
Expand All @@ -50,8 +51,7 @@ public void Test_ConcurrentObservableCollection_AddRange()
Assert.IsNotNull(returnedArgs.NewItems);
Assert.IsNull(returnedArgs.OldItems);
Assert.AreEqual(toAdd.Count(), returnedArgs.NewItems.Count);
Assert.IsTrue(toAdd.Zip(returnedArgs.NewItems.OfType<int>(), (a, b) => a == b).All(c => c));

Assert.IsTrue(CollectionsAreEqual(toAdd, returnedArgs.NewItems));
}

[TestMethod]
Expand Down Expand Up @@ -80,11 +80,11 @@ public void Test_ConcurrentObservableCollection_InsertRange()
Assert.IsNotNull(returnedArgs.NewItems);
Assert.IsNull(returnedArgs.OldItems);
Assert.AreEqual(toAdd.Count(), returnedArgs.NewItems.Count);
Assert.IsTrue(toAdd.Zip(returnedArgs.NewItems.OfType<int>(), (a, b) => a == b).All(c => c));
Assert.IsTrue(CollectionsAreEqual(toAdd, returnedArgs.NewItems));
}

[TestMethod]
public void Test_ConcurrentObservableCollection_RemoveRange()
public void Test_ConcurrentObservableCollection_RemoveRange_ByIndex()
{
var initial = Enumerable.Range(0, 100).ToList();
var startIndex = 50;
Expand Down Expand Up @@ -112,6 +112,42 @@ public void Test_ConcurrentObservableCollection_RemoveRange()
Assert.IsNull(returnedArgs.NewItems);
Assert.IsNotNull(returnedArgs.OldItems);
Assert.AreEqual(removeCount, returnedArgs.OldItems.Count);
var toRemove = initial.Skip(startIndex).Take(removeCount).ToList();
Assert.IsTrue(CollectionsAreEqual(toRemove, returnedArgs.OldItems));
}

[TestMethod]
public void Test_ConcurrentObservableCollection_RemoveRange_ByList()
{
var initial = Enumerable.Range(0, 100).ToList();
var startIndex = 50;
var removeCount = 40;
var toRemove = initial.Skip(startIndex).Take(removeCount).ToList();
var collection = new ConcurrentObservableCollection<int>();
collection.AddRange(initial);
Assert.AreEqual(100, collection.Count);

// Record all the collection changed events
List<(object, NotifyCollectionChangedEventArgs)> returnedList = new List<(object, NotifyCollectionChangedEventArgs)>();
collection.CollectionChanged += (s, e) => returnedList.Add((s, e));

collection.RemoveRange(toRemove);

// Check just one collection changed event was fired
Assert.AreEqual(1, returnedList.Count);
(var returnedObject, var returnedArgs) = returnedList[0];

Assert.IsNotNull(returnedObject);
Assert.IsNotNull(returnedArgs);

Assert.AreEqual(returnedObject, collection);
Assert.AreEqual(NotifyCollectionChangedAction.Remove, returnedArgs.Action);
// Removed by values so index not relevant, should be -1
Assert.AreEqual(-1, returnedArgs.OldStartingIndex);
Assert.IsNull(returnedArgs.NewItems);
Assert.IsNotNull(returnedArgs.OldItems);
Assert.AreEqual(removeCount, returnedArgs.OldItems.Count);
Assert.IsTrue(CollectionsAreEqual(toRemove, returnedArgs.OldItems));
}

[TestMethod]
Expand Down Expand Up @@ -147,12 +183,13 @@ public void Test_ConcurrentObservableCollection_Reset()
Assert.IsNull(returnedArgs0.NewItems);
Assert.IsNotNull(returnedArgs0.OldItems);
Assert.AreEqual(initial.Count(), returnedArgs0.OldItems.Count);
Assert.IsTrue(initial.Zip(returnedArgs0.OldItems.OfType<int>(), (a, b) => a == b).All(c => c));
Assert.IsTrue(CollectionsAreEqual(initial, returnedArgs0.OldItems));


Assert.IsNull(returnedArgs1.OldItems);
Assert.IsNotNull(returnedArgs1.NewItems);
Assert.AreEqual(toAdd.Count(), returnedArgs1.NewItems.Count);
Assert.IsTrue(toAdd.Zip(returnedArgs1.NewItems.OfType<int>(), (a, b) => a == b).All(c => c));
Assert.IsTrue(CollectionsAreEqual(toAdd, returnedArgs1.NewItems));
}

[TestMethod]
Expand Down Expand Up @@ -185,8 +222,10 @@ public void Test_ConcurrentObservableCollection_Clear()

Assert.IsNotNull(returnedArgs.OldItems);
Assert.AreEqual(initial.Count(), returnedArgs.OldItems.Count);
Assert.IsTrue(initial.Zip(returnedArgs.OldItems.OfType<int>(), (a, b) => a == b).All(c => c));
Assert.IsTrue(CollectionsAreEqual(initial, returnedArgs.OldItems));
}

bool CollectionsAreEqual(IEnumerable<int> collectionA, IList collectionB) =>
collectionA.Zip(collectionB.OfType<int>(), (a, b) => a == b).All(c => c);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Swordfish.NET.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
Expand All @@ -19,7 +20,7 @@ namespace Swordfish.NET.UnitTestV3
/// Test the following collection classes:
///
/// - ConcurrentObservableCollection - done (other class)
/// - ConcurrentObservableDictionary
/// - ConcurrentObservableDictionary - done (this class)
/// - ConcurrentObservableHashSet
/// - ConcurrentObservableSortedCollection
/// - ConcurrentObservableSortedDictionary
Expand Down Expand Up @@ -49,7 +50,7 @@ public void Test_ConcurrentObservableDictionary_AddRange_IEnumerable()
Assert.IsNotNull(returnedArgs.NewItems);
Assert.IsNull(returnedArgs.OldItems);
Assert.AreEqual(toAdd.Count(), returnedArgs.NewItems.Count);
Assert.IsTrue(toAdd.Zip(returnedArgs.NewItems.OfType<KeyValuePair<int, int>>(), (a, b) => a.Key == b.Key && a.Value == b.Value).All(c => c));
Assert.IsTrue(CollectionsAreEqual(toAdd, returnedArgs.NewItems));
}

[TestMethod]
Expand All @@ -73,7 +74,7 @@ public void Test_ConcurrentObservableDictionary_AddRange_List()
Assert.IsNotNull(returnedArgs.NewItems);
Assert.IsNull(returnedArgs.OldItems);
Assert.AreEqual(toAdd.Count(), returnedArgs.NewItems.Count);
Assert.IsTrue(toAdd.Zip(returnedArgs.NewItems.OfType<KeyValuePair<int, int>>(), (a, b) => a.Key == b.Key && a.Value == b.Value).All(c => c));
Assert.IsTrue(CollectionsAreEqual(toAdd, returnedArgs.NewItems));
}

[TestMethod]
Expand All @@ -97,7 +98,7 @@ public void Test_ConcurrentObservableDictionary_AddRange_Dictionary()
Assert.IsNotNull(returnedArgs.NewItems);
Assert.IsNull(returnedArgs.OldItems);
Assert.AreEqual(toAdd.Count(), returnedArgs.NewItems.Count);
Assert.IsTrue(toAdd.Zip(returnedArgs.NewItems.OfType<KeyValuePair<int, int>>(), (a, b) => a.Key == b.Key && a.Value == b.Value).All(c => c));
Assert.IsTrue(CollectionsAreEqual(toAdd, returnedArgs.NewItems));
}

[TestMethod]
Expand Down Expand Up @@ -129,8 +130,72 @@ public void Test_ConcurrentObservableCollection_RemoveRange_ByIndex()
Assert.IsNull(returnedArgs.NewItems);
Assert.IsNotNull(returnedArgs.OldItems);
Assert.AreEqual(removeCount, returnedArgs.OldItems.Count);
Assert.IsTrue(CollectionsAreEqual(initial.Skip(startIndex).Take(removeCount), returnedArgs.OldItems));
}

[TestMethod]
public void Test_ConcurrentObservableCollection_RemoveRange_ByItems_IList()
{
var initial = Enumerable.Range(0, 100).Select(x => new KeyValuePair<int, int>(x, x));
var toRemove = Enumerable.Range(1, 40).Select(x => x * 2).ToList();
var collection = new ConcurrentObservableDictionary<int, int>();
collection.AddRange(initial);
Assert.AreEqual(100, collection.Count);

// Record all the collection changed events
List<(object, NotifyCollectionChangedEventArgs)> returnedList = new List<(object, NotifyCollectionChangedEventArgs)>();
collection.CollectionChanged += (s, e) => returnedList.Add((s, e));

collection.RemoveRange(toRemove);

// Check just one collection changed event was fired
Assert.AreEqual(1, returnedList.Count);
(var returnedObject, var returnedArgs) = returnedList[0];

Assert.IsNotNull(returnedObject);
Assert.IsNotNull(returnedArgs);

Assert.AreEqual(returnedObject, collection);
Assert.AreEqual(NotifyCollectionChangedAction.Remove, returnedArgs.Action);
Assert.AreEqual(-1, returnedArgs.OldStartingIndex);
Assert.IsNull(returnedArgs.NewItems);
Assert.IsNotNull(returnedArgs.OldItems);
Assert.AreEqual(toRemove.Count, returnedArgs.OldItems.Count);
Assert.IsTrue(CollectionsAreEqual(toRemove, returnedArgs.OldItems));
}

[TestMethod]
public void Test_ConcurrentObservableCollection_RemoveRange_ByItems_IEnumerable()
{
var initial = Enumerable.Range(0, 100).Select(x => new KeyValuePair<int, int>(x, x));
var toRemove = Enumerable.Range(1, 40).Select(x => x * 2);
var collection = new ConcurrentObservableDictionary<int, int>();
collection.AddRange(initial);
Assert.AreEqual(100, collection.Count);

// Record all the collection changed events
List<(object, NotifyCollectionChangedEventArgs)> returnedList = new List<(object, NotifyCollectionChangedEventArgs)>();
collection.CollectionChanged += (s, e) => returnedList.Add((s, e));

collection.RemoveRange(toRemove);

// Check just one collection changed event was fired
Assert.AreEqual(1, returnedList.Count);
(var returnedObject, var returnedArgs) = returnedList[0];

Assert.IsNotNull(returnedObject);
Assert.IsNotNull(returnedArgs);

Assert.AreEqual(returnedObject, collection);
Assert.AreEqual(NotifyCollectionChangedAction.Remove, returnedArgs.Action);
Assert.AreEqual(-1, returnedArgs.OldStartingIndex);
Assert.IsNull(returnedArgs.NewItems);
Assert.IsNotNull(returnedArgs.OldItems);
Assert.AreEqual(toRemove.Count(), returnedArgs.OldItems.Count);
Assert.IsTrue(CollectionsAreEqual(toRemove, returnedArgs.OldItems));
}


[TestMethod]
public void Test_ConcurrentObservableDictionary_Clear()
{
Expand Down Expand Up @@ -159,7 +224,12 @@ public void Test_ConcurrentObservableDictionary_Clear()
Assert.IsNotNull(returnedArgs.OldItems);
Assert.AreEqual(initial.Count(), returnedArgs.OldItems.Count);
Assert.IsTrue(initial.Zip(returnedArgs.OldItems.OfType<KeyValuePair<int, int>>(), (a, b) => a.Key == b.Key && a.Value == b.Value).All(c => c));

}

bool CollectionsAreEqual(IEnumerable<KeyValuePair<int, int>> collectionA, IList collectionB) =>
collectionA.Zip(collectionB.OfType<KeyValuePair<int, int>>(), (a, b) => a.Key == b.Key && a.Value == b.Value).All(c => c);

bool CollectionsAreEqual(IEnumerable<int> collectionA, IList collectionB) =>
collectionA.Zip(collectionB.OfType<int>(), (a, b) => a == b).All(c => c);
}
}
Loading

0 comments on commit 784981e

Please sign in to comment.