// Copyright (C) Stichting Deltares 2016. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Linq; using Core.Common.TestUtil; using NUnit.Framework; using Rhino.Mocks; namespace Core.Common.Base.Test { [TestFixture] public class ObservableCollectionWithSourcePathTest { [Test] public void DefaultConstructor_ReturnObservableCollectionWithSourcePath() { // Call var collection = new ObservableCollectionWithSourcePath(); // Assert Assert.IsInstanceOf(collection); Assert.IsNull(collection.SourcePath); Assert.AreEqual(0, collection.Count); CollectionAssert.IsEmpty(collection); } [Test] public void AddRange_ItemsNull_ThrowArgumentNullException() { // Setup var collection = new ObservableCollectionWithSourcePath(); // Call TestDelegate call = () => collection.AddRange(null, "path"); // Assert string paramName = Assert.Throws(call).ParamName; Assert.AreEqual("items", paramName); } [Test] public void AddRange_ItemsHasNullElement_ThrowArgumentException() { // Setup var collection = new ObservableCollectionWithSourcePath(); var models = new[] { new object(), null, new object() }; // Call TestDelegate call = () => collection.AddRange(models, "path"); // Assert string message = "Collection cannot contain null."; string paramName = TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, message).ParamName; Assert.AreEqual("items", paramName); } [Test] public void AddRange_FilePathNull_ThrowArgumentNullException() { // Setup var collection = new ObservableCollectionWithSourcePath(); // Call TestDelegate call = () => collection.AddRange(Enumerable.Empty(), null); // Assert string paramName = Assert.Throws(call).ParamName; Assert.AreEqual("filePath", paramName); } [Test] public void AddRange_NotAnActualFilePath_ThrowArgumentNull() { // Setup var collection = new ObservableCollectionWithSourcePath(); const string invalidFilePath = @" "; // Call TestDelegate call = () => collection.AddRange(Enumerable.Empty(), invalidFilePath); // Assert string message = $"'{invalidFilePath}' is not a valid filepath."; string paramName = TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, message).ParamName; Assert.AreEqual("filePath", paramName); } [Test] public void AddRange_AddNewStochasticSoilModel_CollectionContainsModel() { // Setup var collection = new ObservableCollectionWithSourcePath(); var item = new object(); // Call const string filePath = "some/file/path"; collection.AddRange(new[] { item }, filePath); // Assert CollectionAssert.Contains(collection, item); Assert.AreEqual(filePath, collection.SourcePath); } [Test] public void AddRange_AddingNewModels_CollectionContainsExpectedElements() { // Setup var collection = new ObservableCollectionWithSourcePath(); var expectedCollection = new[] { new object(), new object(), new object(), new object() }; const string filePath = "some/file/path"; // Call collection.AddRange(expectedCollection, filePath); // Assert CollectionAssert.AreEqual(expectedCollection, collection); Assert.AreEqual(filePath, collection.SourcePath); } [Test] public void Count_CollectionFilledWithElements_ReturnsExpectedNumberOfElements() { // Setup var collection = new ObservableCollectionWithSourcePath(); collection.AddRange(new[] { new object(), new object(), new object(), new object() }, "path"); // 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 ObservableCollectionWithSourcePath(); // Call TestDelegate call = () => { object item = collection[invalidIndex]; }; // Assert Assert.Throws(call); } [Test] public void Indexer_GetElementAtIndex_ReturnsExpectedElement() { // Setup var elementToRetrieve = new object(); var collection = new ObservableCollectionWithSourcePath(); collection.AddRange(new[] { new object(), new object(), new object(), new object(), elementToRetrieve }, "path"); // Call object retrievedElement = collection[4]; // Assert Assert.AreSame(elementToRetrieve, retrievedElement); } [Test] public void Remove_ElementNotInList_ReturnsFalse() { // Setup var element = new object(); var collection = new ObservableCollectionWithSourcePath(); var expectedCollection = new[] { new object(), new object(), new object(), new object() }; collection.AddRange(expectedCollection, "path"); // Call bool removeSuccessful = collection.Remove(element); // Assert Assert.IsFalse(removeSuccessful); CollectionAssert.AreEqual(expectedCollection, collection); } [Test] public void Remove_ElementInCollection_ReturnsTrue() { // Setup var elementToBeRemoved = new object(); var collection = new ObservableCollectionWithSourcePath(); var expectedCollections = new[] { new object(), new object(), new object(), new object() }; collection.AddRange(expectedCollections.Concat(new[] { elementToBeRemoved }), "path"); // Call bool removeSuccessful = collection.Remove(elementToBeRemoved); // Assert Assert.IsTrue(removeSuccessful); CollectionAssert.AreEqual(expectedCollections, collection); } [Test] public void Remove_ElementToRemoveMultiplesInCollection_ReturnsTrueAndRemovesFirstOccurence() { // Setup var elementToBeRemoved = new object(); var collection = new ObservableCollectionWithSourcePath(); var removeElementCollection = new[] { elementToBeRemoved }; var expectedCollection = new[] { new object(), new object(), new object(), new object(), elementToBeRemoved }; collection.AddRange(removeElementCollection.Concat(expectedCollection), "path"); // Call bool removeSuccessful = collection.Remove(elementToBeRemoved); // Assert Assert.IsTrue(removeSuccessful); CollectionAssert.AreEqual(expectedCollection, collection); } [Test] public void Remove_RemoveLastElement_ReturnsTrueAndClearSourcePath() { // Setup var elementToBeRemoved = new object(); var collection = new ObservableCollectionWithSourcePath(); collection.AddRange(new[] { elementToBeRemoved }, "path"); // Precondition Assert.IsNotNull(collection.SourcePath); // Call bool removeSuccesful = collection.Remove(elementToBeRemoved); // Assert Assert.IsTrue(removeSuccesful); Assert.IsNull(collection.SourcePath); } [Test] public void Clear_CollectionFullyDefined_ClearsSourcePathAndCollection() { // Setup var collection = new ObservableCollectionWithSourcePath(); var expectedObjectCollection = new[] { new object(), new object(), new object(), new object() }; collection.AddRange(expectedObjectCollection, "path"); // 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 observableCollection = new ObservableCollectionWithSourcePath(); observableCollection.Attach(observer); // Call observableCollection.NotifyObservers(); // Assert mocks.VerifyAll(); } [Test] public void NotifyObserver_AttachedObserverDetachedAgain_ObserverNoLongerNotified() { // Setup var mocks = new MockRepository(); var observer = mocks.StrictMock(); mocks.ReplayAll(); var observableCollection = new ObservableCollectionWithSourcePath(); observableCollection.Attach(observer); observableCollection.Detach(observer); // Call observableCollection.NotifyObservers(); // Assert mocks.VerifyAll(); // Expect no calls on 'observer' } [Test] public void NotifyObservers_MultipleObserversDetachingOrAttachingOthers_NoUpdatesForAttachedAndDetachedObservers() { // Setup var mocks = new MockRepository(); var observableCollection = new ObservableCollectionWithSourcePath(); var observer1 = mocks.Stub(); var observer2 = mocks.Stub(); var observer3 = mocks.Stub(); var observer4 = mocks.Stub(); var observer5 = mocks.Stub(); var observer6 = mocks.Stub(); observableCollection.Attach(observer1); observableCollection.Attach(observer2); observableCollection.Attach(observer3); observableCollection.Attach(observer4); observableCollection.Attach(observer6); observer1.Expect(o => o.UpdateObserver()); observer2.Expect(o => o.UpdateObserver()).Do((Action) (() => observableCollection.Detach(observer3))); observer3.Expect(o => o.UpdateObserver()).Repeat.Never(); // A detached observer should no longer be updated observer4.Expect(o => o.UpdateObserver()).Do((Action) (() => observableCollection.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 observableCollection.NotifyObservers(); // Assert mocks.VerifyAll(); } } }