Index: Ringtoets/Common/src/Ringtoets.Common.Data/UpdateDataStrategies/UpdateDataStrategyBase.cs
===================================================================
diff -u -rc6b6a1a125535151416a5426d75472d045943d1a -r4e8fa8a9a88207029ec813bcf15f1eff9e0ab118
--- Ringtoets/Common/src/Ringtoets.Common.Data/UpdateDataStrategies/UpdateDataStrategyBase.cs (.../UpdateDataStrategyBase.cs) (revision c6b6a1a125535151416a5426d75472d045943d1a)
+++ Ringtoets/Common/src/Ringtoets.Common.Data/UpdateDataStrategies/UpdateDataStrategyBase.cs (.../UpdateDataStrategyBase.cs) (revision 4e8fa8a9a88207029ec813bcf15f1eff9e0ab118)
@@ -95,6 +95,8 @@
/// The source file path.
/// A of affected objects.
/// Thrown when an error occurred while updating the data.
+ /// Thrown when contains
+ /// null elements.
protected IEnumerable UpdateTargetCollectionData(ObservableUniqueItemCollectionWithSourcePath targetDataCollection,
IEnumerable importedDataCollection,
string sourceFilePath)
@@ -122,7 +124,7 @@
///
/// The target data collection which needs to be updated.
/// The imported data collection which is used to update
- /// the
+ /// the .
/// The source file path.
/// A with affected objects.
/// Thrown when:
@@ -131,13 +133,17 @@
/// - duplicate items are found in the .
///
///
+ /// Thrown when either
+ /// or is null.
+ /// Thrown when contains
+ /// null elements.
private IEnumerable ModifyDataCollection(ObservableUniqueItemCollectionWithSourcePath targetDataCollection,
IEnumerable importedDataCollection,
string sourceFilePath)
{
TTargetData[] importedObjects = importedDataCollection.ToArray();
- var modification = new Modification(targetDataCollection, importedObjects, equalityComparer);
+ var modification = new CollectionModification(targetDataCollection, importedObjects, equalityComparer);
var affectedObjects = new List();
if (modification.HasUpdates())
@@ -209,20 +215,45 @@
///
/// Inner class for obtaining the modifications of an update action.
///
- private class Modification
+ private class CollectionModification
{
///
- /// Creates a new instance of .
+ /// Creates a new instance of .
///
/// The current collection of objects.
- /// The collection of objects that were imported.
+ /// The collection containing objects that were imported
+ /// and thus could contain updates for the existing objects.
/// The comparer to test whether elements in
/// have a matching element in
/// .
- public Modification(IEnumerable existingObjects,
+ /// Thrown if any parameter is null.
+ /// Thrown when
+ /// or contains a null element.
+ public CollectionModification(IEnumerable existingObjects,
IEnumerable updatedObjects,
IEqualityComparer equalityComparer)
{
+ if (existingObjects == null)
+ {
+ throw new ArgumentNullException(nameof(existingObjects));
+ }
+ if (updatedObjects == null)
+ {
+ throw new ArgumentNullException(nameof(updatedObjects));
+ }
+ if (equalityComparer == null)
+ {
+ throw new ArgumentNullException(nameof(equalityComparer));
+ }
+ if (existingObjects.Contains(null))
+ {
+ throw new ArgumentException(@"Cannot determine modifications from a collection which contain null.", nameof(existingObjects));
+ }
+ if (updatedObjects.Contains(null))
+ {
+ throw new ArgumentException(@"Cannot determine modifications with a collection which contain null.", nameof(updatedObjects));
+ }
+
TTargetData[] existingArray = existingObjects.ToArray();
var index = 0;
@@ -256,68 +287,38 @@
///
/// Gets a collection of updated objects from the existing object collection and the
- /// added objects from the imported object collection, in the same order that was
+ /// added objects from the imported object collection in the same order that was
/// found in the imported object collection.
///
/// An ordered collection of updated and added elements.
public IEnumerable GetModifiedCollection()
{
- TTargetData[] remainingObjects = ObjectsToBeUpdated.Values.Union(ObjectsToBeAdded.Values).ToArray();
- int[] indices = GetElementOrder();
+ KeyValuePair[] remainingObjects = ObjectsToBeUpdated.Union(ObjectsToBeAdded).ToArray();
- foreach (int i in Enumerable.Range(0, remainingObjects.Length))
+ var orderedObjects = new TTargetData[remainingObjects.Length];
+
+ foreach (KeyValuePair remainingObject in remainingObjects)
{
- TTargetData x = remainingObjects[i];
- int j = i;
- while (true)
- {
- int k = indices[j];
- indices[j] = j;
- if (k == i)
- {
- break;
- }
- remainingObjects[j] = remainingObjects[k];
- j = k;
- }
- remainingObjects[j] = x;
+ orderedObjects[remainingObject.Key] = remainingObject.Value;
}
- return remainingObjects;
+ return orderedObjects;
}
///
/// Finds out whether there was a difference between the existing and the imported
/// object collections.
///
- ///
+ /// true if there were any updates, false otherwise.
public bool HasUpdates()
{
return ObjectsToBeRemoved.Any() || ObjectsToBeAdded.Any() || ObjectsToBeUpdated.Any();
}
private Dictionary ObjectsToBeAdded { get; } = new Dictionary();
-
- private int[] GetElementOrder()
- {
- int[] keys = ObjectsToBeUpdated.Keys.Union(ObjectsToBeAdded.Keys).ToArray();
-
- int orderLength = keys.Length;
- var order = new int[orderLength];
- for (var valueToInsert = 0; valueToInsert < orderLength; valueToInsert++)
- {
- order[keys[valueToInsert]] = valueToInsert;
- }
-
- return order;
- }
-
+
private static int FindIndex(TTargetData[] collectionToLookIn, TTargetData objectToFind, IEqualityComparer equalityComparer)
{
- if (objectToFind == null)
- {
- throw new ArgumentNullException(nameof(objectToFind));
- }
for (var i = 0; i < collectionToLookIn.Length; i++)
{
TTargetData targetData = collectionToLookIn[i];
Index: Ringtoets/Common/test/Ringtoets.Common.Data.Test/UpdateDataStrategies/UpdateDataStrategyBaseTest.cs
===================================================================
diff -u -rc6b6a1a125535151416a5426d75472d045943d1a -r4e8fa8a9a88207029ec813bcf15f1eff9e0ab118
--- Ringtoets/Common/test/Ringtoets.Common.Data.Test/UpdateDataStrategies/UpdateDataStrategyBaseTest.cs (.../UpdateDataStrategyBaseTest.cs) (revision c6b6a1a125535151416a5426d75472d045943d1a)
+++ Ringtoets/Common/test/Ringtoets.Common.Data.Test/UpdateDataStrategies/UpdateDataStrategyBaseTest.cs (.../UpdateDataStrategyBaseTest.cs) (revision 4e8fa8a9a88207029ec813bcf15f1eff9e0ab118)
@@ -86,17 +86,33 @@
{
// Setup
var strategy = new TestUpdateDataStrategy(new TestFailureMechanism());
- var collection = new TestUniqueItemCollection();
// Call
- TestDelegate call = () => strategy.ConcreteUpdateData(collection, null, string.Empty);
+ TestDelegate call = () => strategy.ConcreteUpdateData(new TestUniqueItemCollection(), null, string.Empty);
// Assert
string paramName = Assert.Throws(call).ParamName;
Assert.AreEqual("importedDataCollection", paramName);
}
[Test]
+ public void UpdateTargetCollectionData_ImportedDataCollectionContainsNullElement_ThrowsArgumentException()
+ {
+ // Setup
+ var strategy = new TestUpdateDataStrategy(new TestFailureMechanism());
+
+ // Call
+ TestDelegate call = () => strategy.ConcreteUpdateData(new TestUniqueItemCollection(), new TestItem[]
+ {
+ null
+ }, string.Empty);
+
+ // Assert
+ string paramName = Assert.Throws(call).ParamName;
+ Assert.AreEqual("updatedObjects", paramName);
+ }
+
+ [Test]
public void UpdateTargetCollectionData_SourceFilePathNull_ThrowsArgumentNullException()
{
// Setup
@@ -475,6 +491,36 @@
}
[Test]
+ public void UpdateTargetCollectionData_CollectionOrderChangedAndElementRemoved_UpdatesCollectionInCorrectOrder()
+ {
+ // Setup
+ var currentCollection = new[]
+ {
+ new TestItem("Item one"),
+ new TestItem("Item two"),
+ new TestItem("Item three")
+ };
+ var collection = new TestUniqueItemCollection();
+ collection.AddRange(currentCollection, sourceFilePath);
+
+ var importedItems = new[]
+ {
+ new TestItem("Item three"),
+ new TestItem("Item one")
+ };
+
+ var strategy = new TestUpdateDataStrategy(new TestFailureMechanism());
+
+ // Call
+ strategy.ConcreteUpdateData(collection,
+ importedItems,
+ sourceFilePath);
+
+ // Assert
+ CollectionAssert.AreEqual(importedItems, collection);
+ }
+
+ [Test]
public void UpdateTargetCollectionData_CollectionNotEmptyAndImportedDataHasDuplicateDefinitions_ThrowsUpdateDataException()
{
// Setup