Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/StochasticSoilModelCollection.cs
===================================================================
diff -u -r203d0f03d922b6dac20080dad8e82fe92c7bec86 -r5a453b9ac4ccaa5fc6f767036f0bcbf87ad05ff4
--- Ringtoets/Piping/src/Ringtoets.Piping.Data/StochasticSoilModelCollection.cs (.../StochasticSoilModelCollection.cs) (revision 203d0f03d922b6dac20080dad8e82fe92c7bec86)
+++ Ringtoets/Piping/src/Ringtoets.Piping.Data/StochasticSoilModelCollection.cs (.../StochasticSoilModelCollection.cs) (revision 5a453b9ac4ccaa5fc6f767036f0bcbf87ad05ff4)
@@ -19,19 +19,123 @@
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
using Core.Common.Base;
namespace Ringtoets.Piping.Data
{
///
- /// A collection of that was imported from a file.
+ /// A collection to store the and the source path
+ /// they were imported from.
///
- public class StochasticSoilModelCollection : ObservableList
+ public class StochasticSoilModelCollection : IObservable, IEnumerable
{
+ private readonly List stochasticSoilModels = new List();
+ private readonly ICollection observers = new Collection();
+
///
+ /// Gets or sets the element at index in the collection.
+ ///
+ /// The index.
+ /// The element at index in the collection.
+ /// Thrown when is not
+ /// between [0, )
+ public StochasticSoilModel this[int i]
+ {
+ get
+ {
+ return stochasticSoilModels[i];
+ }
+ set
+ {
+ stochasticSoilModels[i] = value;
+ }
+ }
+
+ ///
+ /// Removes the first occurence of in the collection.
+ ///
+ /// The to be removed.
+ /// True if the was successfully removed from the collection;
+ /// False if otherwise or if the was not found in the collection.
+ public bool Remove(StochasticSoilModel model)
+ {
+ return stochasticSoilModels.Remove(model);
+ }
+
+ ///
+ /// Clears the imported items in the collection and
+ /// the .
+ ///
+ public void Clear()
+ {
+ SourcePath = null;
+ stochasticSoilModels.Clear();
+ }
+
+ ///
+ /// Adds a item to the end of the collection.
+ ///
+ /// The to be added.
+ public void Add(StochasticSoilModel model)
+ {
+ stochasticSoilModels.Add(model);
+ }
+
+ ///
+ /// Gets the amount of items stored in the collection.
+ ///
+ public int Count
+ {
+ get
+ {
+ return stochasticSoilModels.Count;
+ }
+ }
+
+ ///
/// Gets or sets the last known file path from which the
/// elements were imported.
///
public string SourcePath { get; set; }
+
+ public void Attach(IObserver observer)
+ {
+ observers.Add(observer);
+ }
+
+ public void Detach(IObserver observer)
+ {
+ observers.Remove(observer);
+ }
+
+ public void NotifyObservers()
+ {
+ // Iterate through a copy of the list of observers; an update of one observer might result in detaching another observer (which will result in a "list modified" exception over here otherwise)
+ foreach (var observer in observers.ToArray())
+ {
+ // Ensure the observer is still part of the original list of observers
+ if (!observers.Contains(observer))
+ {
+ continue;
+ }
+
+ observer.UpdateObserver();
+ }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return stochasticSoilModels.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
}
}
\ No newline at end of file
Index: Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingFailureMechanismView.cs
===================================================================
diff -u -r2cafb330e0b90d1103bc9329eafbcba24836787f -r5a453b9ac4ccaa5fc6f767036f0bcbf87ad05ff4
--- Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingFailureMechanismView.cs (.../PipingFailureMechanismView.cs) (revision 2cafb330e0b90d1103bc9329eafbcba24836787f)
+++ Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingFailureMechanismView.cs (.../PipingFailureMechanismView.cs) (revision 5a453b9ac4ccaa5fc6f767036f0bcbf87ad05ff4)
@@ -195,7 +195,7 @@
{
ReferenceLine referenceLine = data.Parent.ReferenceLine;
IEnumerable failureMechanismSections = data.WrappedData.Sections;
- ObservableList stochasticSoilModels = data.WrappedData.StochasticSoilModels;
+ StochasticSoilModelCollection stochasticSoilModels = data.WrappedData.StochasticSoilModels;
ObservableList ringtoetsPipingSurfaceLines = data.WrappedData.SurfaceLines;
HydraulicBoundaryDatabase hydraulicBoundaryDatabase = data.Parent.HydraulicBoundaryDatabase;
IEnumerable calculations =
Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/StochasticSoilModelCollectionTest.cs
===================================================================
diff -u -r203d0f03d922b6dac20080dad8e82fe92c7bec86 -r5a453b9ac4ccaa5fc6f767036f0bcbf87ad05ff4
--- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/StochasticSoilModelCollectionTest.cs (.../StochasticSoilModelCollectionTest.cs) (revision 203d0f03d922b6dac20080dad8e82fe92c7bec86)
+++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/StochasticSoilModelCollectionTest.cs (.../StochasticSoilModelCollectionTest.cs) (revision 5a453b9ac4ccaa5fc6f767036f0bcbf87ad05ff4)
@@ -19,8 +19,11 @@
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
+using System;
+using System.Collections.Generic;
using Core.Common.Base;
using NUnit.Framework;
+using Rhino.Mocks;
namespace Ringtoets.Piping.Data.Test
{
@@ -34,8 +37,343 @@
var collection = new StochasticSoilModelCollection();
// Assert
- Assert.IsInstanceOf>(collection);
+ Assert.IsInstanceOf(collection);
Assert.IsNull(collection.SourcePath);
+ Assert.AreEqual(0, collection.Count);
+ CollectionAssert.IsEmpty(collection);
}
+
+ [Test]
+ public void Add_AddNewStochasticSoilModel_CollectionContainsModel()
+ {
+ // Setup
+ var collection = new StochasticSoilModelCollection();
+ var soilModel = new StochasticSoilModel(1, string.Empty, string.Empty);
+
+ // Call
+ collection.Add(soilModel);
+
+ // Assert
+ CollectionAssert.Contains(collection, soilModel);
+ }
+
+ [Test]
+ public void GivenCollection_WhenAddingNewModels_ThenCollectionContainsExpectedElements()
+ {
+ // Given
+ var collection = new StochasticSoilModelCollection();
+ var expectedSoilModelCollection = new[]
+ {
+ new StochasticSoilModel(1, string.Empty, string.Empty),
+ new StochasticSoilModel(2, string.Empty, string.Empty),
+ new StochasticSoilModel(3, string.Empty, string.Empty),
+ new StochasticSoilModel(4, string.Empty, string.Empty)
+ };
+
+ // When
+ foreach (var model in expectedSoilModelCollection)
+ {
+ collection.Add(model);
+ }
+
+ // Then
+ CollectionAssert.AreEqual(expectedSoilModelCollection, collection);
+ }
+
+ [Test]
+ public void Count_CollectionFilledWithElements_ReturnsExpectedNumberOfElements()
+ {
+ // Setup
+ var collection = new StochasticSoilModelCollection
+ {
+ new StochasticSoilModel(1, string.Empty, string.Empty),
+ new StochasticSoilModel(2, string.Empty, string.Empty),
+ new StochasticSoilModel(3, string.Empty, string.Empty),
+ new StochasticSoilModel(4, string.Empty, string.Empty)
+ };
+
+ // Call
+ int nrOfElements = collection.Count;
+
+ // Assert
+ Assert.AreEqual(4, nrOfElements);
+ }
+
+ [Test]
+ [TestCase(-1)]
+ [TestCase(0)]
+ public void Indexer_GetItemAtIndexOutOfRange_ThrowsArgumentOutOfRangeException(int invalidIndex)
+ {
+ // Setup
+ var collection = new StochasticSoilModelCollection();
+
+ // Call
+ TestDelegate call = () =>
+ {
+ StochasticSoilModel model = collection[invalidIndex];
+ };
+
+ // Assert
+ Assert.Throws(call);
+ }
+
+ [Test]
+ public void Indexer_GetElementAtIndex_ReturnsExpectedElement()
+ {
+ // Setup
+ var elementToRetrieve = new StochasticSoilModel(0, string.Empty, string.Empty);
+ var collection = new StochasticSoilModelCollection
+ {
+ new StochasticSoilModel(1, string.Empty, string.Empty),
+ new StochasticSoilModel(2, string.Empty, string.Empty),
+ new StochasticSoilModel(3, string.Empty, string.Empty),
+ new StochasticSoilModel(4, string.Empty, string.Empty),
+ elementToRetrieve
+ };
+
+ // Call
+ StochasticSoilModel retrievedElement = collection[4];
+
+ // Assert
+ Assert.AreSame(elementToRetrieve, retrievedElement);
+ }
+
+ [Test]
+ [TestCase(-1)]
+ [TestCase(0)]
+ public void Indexer_SetItemAtIndexOutOfRange_ThrowsArgumentOutOfRangeException(int invalidIndex)
+ {
+ // Setup
+ var collection = new StochasticSoilModelCollection();
+
+ // Call
+ TestDelegate call = () => { collection[invalidIndex] = new StochasticSoilModel(5, string.Empty, string.Empty); };
+
+ // Assert
+ Assert.Throws(call);
+ }
+
+ [Test]
+ public void Indexer_SetElementAtIndex_SetsExpectedElement()
+ {
+ // Setup
+ var elementToSet = new StochasticSoilModel(0, string.Empty, string.Empty);
+ var soilModel1 = new StochasticSoilModel(1, string.Empty, string.Empty);
+ var soilModel2 = new StochasticSoilModel(2, string.Empty, string.Empty);
+ var soilModel3 = new StochasticSoilModel(3, string.Empty, string.Empty);
+
+ var collection = new StochasticSoilModelCollection
+ {
+ soilModel1,
+ soilModel2,
+ soilModel3
+ };
+
+ // Call
+ collection[1] = elementToSet;
+
+ // Assert
+ IEnumerable expectedCollection = new[]
+ {
+ soilModel1,
+ elementToSet,
+ soilModel3
+ };
+ CollectionAssert.AreEqual(expectedCollection, collection);
+ }
+
+ [Test]
+ public void Remove_ElementNotInList_ReturnsFalse()
+ {
+ // Setup
+ var element = new StochasticSoilModel(0, string.Empty, string.Empty);
+
+ var collection = new StochasticSoilModelCollection();
+ var expectedSoilModelCollection = new[]
+ {
+ new StochasticSoilModel(1, string.Empty, string.Empty),
+ new StochasticSoilModel(2, string.Empty, string.Empty),
+ new StochasticSoilModel(3, string.Empty, string.Empty),
+ new StochasticSoilModel(4, string.Empty, string.Empty)
+ };
+
+ foreach (var model in expectedSoilModelCollection)
+ {
+ collection.Add(model);
+ }
+
+ // Call
+ bool removeSuccessful = collection.Remove(element);
+
+ // Assert
+ Assert.IsFalse(removeSuccessful);
+ CollectionAssert.AreEqual(expectedSoilModelCollection, collection);
+ }
+
+ [Test]
+ public void Remove_ElementInCollection_ReturnsTrue()
+ {
+ // Setup
+ var elementToBeRemoved = new StochasticSoilModel(0, string.Empty, string.Empty);
+
+ var collection = new StochasticSoilModelCollection();
+ var expectedSoilModelCollection = new[]
+ {
+ new StochasticSoilModel(1, string.Empty, string.Empty),
+ new StochasticSoilModel(2, string.Empty, string.Empty),
+ new StochasticSoilModel(3, string.Empty, string.Empty),
+ new StochasticSoilModel(4, string.Empty, string.Empty)
+ };
+
+ foreach (var model in expectedSoilModelCollection)
+ {
+ collection.Add(model);
+ }
+
+ collection.Add(elementToBeRemoved);
+
+ // Call
+ bool removeSuccessful = collection.Remove(elementToBeRemoved);
+
+ // Assert
+ Assert.IsTrue(removeSuccessful);
+ CollectionAssert.AreEqual(expectedSoilModelCollection, collection);
+ }
+
+ [Test]
+ public void Remove_ElementToRemoveMultiplesInCollection_ReturnsTrueAndRemovesFirstOccurence()
+ {
+ // Setup
+ var elementToBeRemoved = new StochasticSoilModel(0, string.Empty, string.Empty);
+
+ var collection = new StochasticSoilModelCollection
+ {
+ elementToBeRemoved
+ };
+ var expectedSoilModelCollection = new[]
+ {
+ new StochasticSoilModel(1, string.Empty, string.Empty),
+ new StochasticSoilModel(2, string.Empty, string.Empty),
+ new StochasticSoilModel(3, string.Empty, string.Empty),
+ new StochasticSoilModel(4, string.Empty, string.Empty),
+ elementToBeRemoved
+ };
+
+ foreach (var model in expectedSoilModelCollection)
+ {
+ collection.Add(model);
+ }
+
+ // Call
+ bool removeSuccessful = collection.Remove(elementToBeRemoved);
+
+ // Assert
+ Assert.IsTrue(removeSuccessful);
+ CollectionAssert.AreEqual(expectedSoilModelCollection, collection);
+ }
+
+ [Test]
+ public void Clear_CollectionFullyDefined_ClearsSourcePathAndCollection()
+ {
+ // Setup
+ var collection = new StochasticSoilModelCollection
+ {
+ SourcePath = "I am a source path for my models"
+ };
+ var expectedSoilModelCollection = new[]
+ {
+ new StochasticSoilModel(1, string.Empty, string.Empty),
+ new StochasticSoilModel(2, string.Empty, string.Empty),
+ new StochasticSoilModel(3, string.Empty, string.Empty),
+ new StochasticSoilModel(4, string.Empty, string.Empty)
+ };
+
+ foreach (var model in expectedSoilModelCollection)
+ {
+ collection.Add(model);
+ }
+
+ // Call
+ collection.Clear();
+
+ // Assert
+ Assert.IsNull(collection.SourcePath);
+ Assert.AreEqual(0, collection.Count);
+ CollectionAssert.IsEmpty(collection);
+ }
+
+ [Test]
+ public void NotifyObservers_WithObserverAttached_ObserverIsNotified()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var observer = mocks.StrictMock();
+ observer.Expect(o => o.UpdateObserver()); // Expect to be called once
+ mocks.ReplayAll();
+
+ var stochasticSoilModelCollection = new StochasticSoilModelCollection();
+ stochasticSoilModelCollection.Attach(observer);
+
+ // Call
+ stochasticSoilModelCollection.NotifyObservers();
+
+ // Assert
+ mocks.VerifyAll();
+ }
+
+ [Test]
+ public void NotifyObserver_AttachedObserverDetachedAgain_ObserverNoLongerNotified()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var observer = mocks.StrictMock();
+ mocks.ReplayAll();
+
+ var stochasticSoilModelCollection = new StochasticSoilModelCollection();
+ stochasticSoilModelCollection.Attach(observer);
+ stochasticSoilModelCollection.Detach(observer);
+
+ // Call
+ stochasticSoilModelCollection.NotifyObservers();
+
+ // Assert
+ mocks.VerifyAll(); // Expect no calls on 'observer'
+ }
+
+ [Test]
+ public void NotifyObservers_MultipleObserversDetachingOrAttachingOthers_NoUpdatesForAttachedAndDetachedObservers()
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var stochasticSoilModelCollection = new StochasticSoilModelCollection();
+
+ var observer1 = mocks.Stub();
+ var observer2 = mocks.Stub();
+ var observer3 = mocks.Stub();
+ var observer4 = mocks.Stub();
+ var observer5 = mocks.Stub();
+ var observer6 = mocks.Stub();
+
+ stochasticSoilModelCollection.Attach(observer1);
+ stochasticSoilModelCollection.Attach(observer2);
+ stochasticSoilModelCollection.Attach(observer3);
+ stochasticSoilModelCollection.Attach(observer4);
+ stochasticSoilModelCollection.Attach(observer6);
+
+ observer1.Expect(o => o.UpdateObserver());
+ observer2.Expect(o => o.UpdateObserver()).Do((Action) (() => stochasticSoilModelCollection.Detach(observer3)));
+ observer3.Expect(o => o.UpdateObserver()).Repeat.Never(); // A detached observer should no longer be updated
+ observer4.Expect(o => o.UpdateObserver()).Do((Action) (() => stochasticSoilModelCollection.Attach(observer5)));
+ observer5.Expect(o => o.UpdateObserver()).Repeat.Never(); // An attached observer should not be updated too
+ observer6.Expect(o => o.UpdateObserver());
+
+ mocks.ReplayAll();
+
+ // Call
+ stochasticSoilModelCollection.NotifyObservers();
+
+ // Assert
+ mocks.VerifyAll();
+ }
}
}
\ No newline at end of file