Skip to content

Commit

Permalink
Fixed a major bug in ConcurrentObservableDictionary where an internal…
Browse files Browse the repository at this point in the history
… object was being returned instead of the desired value in an indexed accessor
  • Loading branch information
stewienj committed Jan 28, 2021
1 parent 784981e commit 9e38958
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 70 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.Linq;

Expand Down Expand Up @@ -39,7 +40,6 @@ IEnumerable<KeyValuePair<string,string>> GetIEnumerable()
[TestMethod]
public void AddTest()
{

int testCollectionCount = 10;
int itemsPerCollection = 200_000;
var sourceCollections = new List<List<int>>();
Expand Down Expand Up @@ -101,7 +101,6 @@ public void AddTest()
Assert.IsTrue(allItemsPresent, "All items present");
}


[TestMethod]
public void TestManyOperations()
{
Expand Down Expand Up @@ -232,5 +231,68 @@ public void TestManyOperations()

Assert.IsTrue(allEqualAfterRemoveAt, "Items correct order after removing at index");
}

[TestMethod]
public void TestIndexOfInViews()
{
var initial = Enumerable.Range(0, 100).Select(x => new KeyValuePair<int, string>(x, x.ToString())).ToList();
var other = Enumerable.Range(100, 100).Select(x => new KeyValuePair<int, string>(x, x.ToString())).ToList();
var testCollection = new ConcurrentObservableDictionary<int, string>();
testCollection.AddRange(initial);
var collectionView = testCollection.CollectionView;
var keysView = testCollection.Keys;
var valuesView = testCollection.Values;

// Test the IList implementation because it had a bug

IList collectionList = (IList)testCollection.CollectionView;
IList keysList = (IList)testCollection.Keys;
IList valuesList = (IList)testCollection.Values;

foreach (var item in initial)
{
Assert.IsTrue(testCollection.Contains(item));

Assert.IsTrue(collectionView.Contains(item));
Assert.IsTrue(keysView.Contains(item.Key));
Assert.IsTrue(valuesView.Contains(item.Value));

Assert.IsTrue(collectionList.Contains(item));
Assert.IsTrue(keysList.Contains(item.Key));
Assert.IsTrue(valuesList.Contains(item.Value));
}

foreach (var item in other)
{
Assert.IsFalse(testCollection.Contains(item));

Assert.IsFalse(collectionView.Contains(item));
Assert.IsFalse(keysView.Contains(item.Key));
Assert.IsFalse(valuesView.Contains(item.Value));

Assert.IsFalse(collectionList.Contains(item));
Assert.IsFalse(keysList.Contains(item.Key));
Assert.IsFalse(valuesList.Contains(item.Value));
}

for (int i=0; i<initial.Count; ++i)
{
Assert.AreEqual(initial[i], collectionView[i]);
Assert.AreEqual(initial[i].Key, keysView[i]);
Assert.AreEqual(initial[i].Value, valuesView[i]);

Assert.AreEqual(initial[i], collectionList[i]);
Assert.AreEqual(initial[i].Key, keysList[i]);
Assert.AreEqual(initial[i].Value, valuesList[i]);

Assert.AreEqual(i, collectionView.IndexOf(initial[i]));
Assert.AreEqual(i, keysView.IndexOf(initial[i].Key));
Assert.AreEqual(i, valuesView.IndexOf(initial[i].Value));

Assert.AreEqual(i, collectionList.IndexOf(initial[i]));
Assert.AreEqual(i, keysList.IndexOf(initial[i].Key));
Assert.AreEqual(i, valuesList.IndexOf(initial[i].Value));
}
}
}
}
88 changes: 20 additions & 68 deletions Swordfish.NET.CollectionsV3/ListSelect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,11 @@ public ListSelect(IList<TSource> sourceList, Func<TSource, TResult> select)

TResult IList<TResult>.this[int index]
{
get
{
return _select(_sourceList[index]);
}

set
{
throw new NotImplementedException();
}
get => _select(_sourceList[index]);
set => throw new NotImplementedException();
}

int ICollection<TResult>.Count
{
get
{
return _sourceList.Count;
}
}
int ICollection<TResult>.Count => _sourceList.Count;

bool ICollection<TResult>.IsReadOnly => true;

Expand All @@ -63,22 +50,17 @@ int ICollection<TResult>.Count

object ICollection.SyncRoot => null;

object IList.this[int index] { get => _sourceList[index]; set => throw new NotImplementedException(); }

public void Add(TResult item)
object IList.this[int index]
{
throw new NotImplementedException();
get => _select(_sourceList[index]);
set => throw new NotImplementedException();
}

public void Clear()
{
throw new NotImplementedException();
}
public void Add(TResult item) => throw new NotImplementedException();

public bool Contains(TResult item)
{
return _sourceList.Select(x => _select(x)).Where(x => x.Equals(item)).Any();
}
public void Clear() => throw new NotImplementedException();

public bool Contains(TResult item) => _sourceList.Select(x => _select(x)).Where(x => x.Equals(item)).Any();

public void CopyTo(TResult[] array, int arrayIndex)
{
Expand All @@ -90,15 +72,9 @@ public void CopyTo(TResult[] array, int arrayIndex)
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return _sourceList.Select(x => _select(x)).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => _sourceList.Select(x => _select(x)).GetEnumerator();

public IEnumerator<TResult> GetEnumerator()
{
return _sourceList.Select(x => _select(x)).GetEnumerator();
}
public IEnumerator<TResult> GetEnumerator() => _sourceList.Select(x => _select(x)).GetEnumerator();

public int IndexOf(TResult item)
{
Expand All @@ -114,48 +90,24 @@ public int IndexOf(TResult item)
return -1;
}

void IList<TResult>.Insert(int index, TResult item)
{
throw new NotImplementedException();
}
void IList<TResult>.Insert(int index, TResult item) => throw new NotImplementedException();

bool ICollection<TResult>.Remove(TResult item)
{
throw new NotImplementedException();
}
bool ICollection<TResult>.Remove(TResult item) => throw new NotImplementedException();

void IList<TResult>.RemoveAt(int index)
{
throw new NotImplementedException();
}
void IList<TResult>.RemoveAt(int index) => throw new NotImplementedException();

int IList.Add(object value)
{
throw new NotImplementedException();
}
int IList.Add(object value) => throw new NotImplementedException();

bool IList.Contains(object value) => Contains((TResult)value);

int IList.IndexOf(object value) => IndexOf((TResult)value);

void IList.Insert(int index, object value)
{
throw new NotImplementedException();
}
void IList.Insert(int index, object value) => throw new NotImplementedException();

void IList.Remove(object value)
{
throw new NotImplementedException();
}
void IList.Remove(object value) => throw new NotImplementedException();

void IList.RemoveAt(int index)
{
throw new NotImplementedException();
}
void IList.RemoveAt(int index) => throw new NotImplementedException();

void ICollection.CopyTo(Array array, int index)
{
throw new NotImplementedException();
}
void ICollection.CopyTo(Array array, int index) => throw new NotImplementedException();
}
}

0 comments on commit 9e38958

Please sign in to comment.