Index: Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Forms/Views/ClosingStructuresFailureMechanismView.cs =================================================================== diff -u -rf1f94637a6b45b394493bf16a078b317c02d329b -re9d34986f2e90e63bbf6ebba579c24055c1c3853 --- Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Forms/Views/ClosingStructuresFailureMechanismView.cs (.../ClosingStructuresFailureMechanismView.cs) (revision f1f94637a6b45b394493bf16a078b317c02d329b) +++ Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Forms/Views/ClosingStructuresFailureMechanismView.cs (.../ClosingStructuresFailureMechanismView.cs) (revision e9d34986f2e90e63bbf6ebba579c24055c1c3853) @@ -52,6 +52,7 @@ private readonly RecursiveObserver calculationInputObserver; private readonly RecursiveObserver calculationGroupObserver; private readonly RecursiveObserver> calculationObserver; + private readonly RecursiveObserver foreshoreProfileObserver; private readonly MapDataCollection mapDataCollection; private readonly MapLineData referenceLineMapData; @@ -82,14 +83,15 @@ UpdateMapData(); }); - hydraulicBoundaryDatabaseObserver = new Observer(UpdateMapData); - foreshoreProfilesObserver = new Observer(UpdateMapData); - structuresObserver = new Observer(UpdateMapData); + hydraulicBoundaryDatabaseObserver = new Observer(UpdateHydraulicBoundaryLocationsMapData); + foreshoreProfilesObserver = new Observer(UpdateForeshoreProfilesMapData); + structuresObserver = new Observer(UpdateStructuresMapData); calculationInputObserver = new RecursiveObserver( - UpdateMapData, pcg => pcg.Children.Concat(pcg.Children.OfType>().Select(pc => pc.InputParameters))); - calculationGroupObserver = new RecursiveObserver(UpdateMapData, pcg => pcg.Children); - calculationObserver = new RecursiveObserver>(UpdateMapData, pcg => pcg.Children); + UpdateCalculationsMapData, pcg => pcg.Children.Concat(pcg.Children.OfType>().Select(pc => pc.InputParameters))); + calculationGroupObserver = new RecursiveObserver(UpdateCalculationsMapData, pcg => pcg.Children); + calculationObserver = new RecursiveObserver>(UpdateCalculationsMapData, pcg => pcg.Children); + foreshoreProfileObserver = new RecursiveObserver(UpdateForeshoreProfilesMapData, coll => coll); mapDataCollection = new MapDataCollection(ClosingStructuresDataResources.ClosingStructuresFailureMechanism_DisplayName); referenceLineMapData = RingtoetsMapDataFactory.CreateReferenceLineMapData(); @@ -127,6 +129,7 @@ assessmentSectionObserver.Observable = null; hydraulicBoundaryDatabaseObserver.Observable = null; foreshoreProfilesObserver.Observable = null; + foreshoreProfileObserver.Observable = null; structuresObserver.Observable = null; calculationInputObserver.Observable = null; calculationGroupObserver.Observable = null; @@ -140,12 +143,13 @@ assessmentSectionObserver.Observable = data.Parent; hydraulicBoundaryDatabaseObserver.Observable = data.Parent.HydraulicBoundaryDatabase; foreshoreProfilesObserver.Observable = data.WrappedData.ForeshoreProfiles; + foreshoreProfileObserver.Observable = data.WrappedData.ForeshoreProfiles; structuresObserver.Observable = data.WrappedData.ClosingStructures; calculationInputObserver.Observable = data.WrappedData.CalculationsGroup; calculationGroupObserver.Observable = data.WrappedData.CalculationsGroup; calculationObserver.Observable = data.WrappedData.CalculationsGroup; - SetMapDataFeatures(); + SetAllMapDataFeatures(); ringtoetsMapControl.SetAllData(mapDataCollection, data.Parent.BackgroundData); } @@ -166,6 +170,7 @@ assessmentSectionObserver.Dispose(); hydraulicBoundaryDatabaseObserver.Dispose(); foreshoreProfilesObserver.Dispose(); + foreshoreProfileObserver.Dispose(); calculationInputObserver.Dispose(); calculationGroupObserver.Dispose(); calculationObserver.Dispose(); @@ -180,36 +185,125 @@ private void UpdateMapData() { - SetMapDataFeatures(); + UpdateCalculationsMapData(); + UpdateHydraulicBoundaryLocationsMapData(); + UpdateReferenceLineMapData(); + UpdateSectionsMapData(); + UpdateForeshoreProfilesMapData(); + UpdateStructuresMapData(); + } + private void SetAllMapDataFeatures() + { + SetCalculationsMapData(); + SetHydraulicBoundaryLocationsMapData(); + SetReferenceLineMapData(); + SetSectionsMapData(); + SetForeshoreProfilesMapData(); + SetStructuresMapData(); + } + + #region Calculations MapData + + private void UpdateCalculationsMapData() + { + SetCalculationsMapData(); + calculationsMapData.NotifyObservers(); + } + + private void SetCalculationsMapData() + { + IEnumerable> calculations = + data.WrappedData.CalculationsGroup.GetCalculations().Cast>(); + calculationsMapData.Features = + RingtoetsMapDataFeaturesFactory.CreateStructureCalculationsFeatures(calculations); + } + + #endregion + + #region HydraulicBoundaryLocations MapData + + private void UpdateHydraulicBoundaryLocationsMapData() + { + SetHydraulicBoundaryLocationsMapData(); + hydraulicBoundaryLocationsMapData.NotifyObservers(); + } + + private void SetHydraulicBoundaryLocationsMapData() + { + HydraulicBoundaryDatabase hydraulicBoundaryDatabase = data.Parent.HydraulicBoundaryDatabase; + hydraulicBoundaryLocationsMapData.Features = + RingtoetsMapDataFeaturesFactory.CreateHydraulicBoundaryDatabaseFeatures(hydraulicBoundaryDatabase); + } + + #endregion + + #region ReferenceLine MapData + + private void UpdateReferenceLineMapData() + { + SetReferenceLineMapData(); referenceLineMapData.NotifyObservers(); + } + + private void SetReferenceLineMapData() + { + ReferenceLine referenceLine = data.Parent.ReferenceLine; + referenceLineMapData.Features = + RingtoetsMapDataFeaturesFactory.CreateReferenceLineFeatures(referenceLine, data.Parent.Id, data.Parent.Name); + } + #endregion + + #region Sections MapData + + private void UpdateSectionsMapData() + { + SetSectionsMapData(); sectionsMapData.NotifyObservers(); sectionsStartPointMapData.NotifyObservers(); sectionsEndPointMapData.NotifyObservers(); - hydraulicBoundaryLocationsMapData.NotifyObservers(); - foreshoreProfilesMapData.NotifyObservers(); - structuresMapData.NotifyObservers(); - calculationsMapData.NotifyObservers(); } - private void SetMapDataFeatures() + private void SetSectionsMapData() { - ReferenceLine referenceLine = data.Parent.ReferenceLine; IEnumerable failureMechanismSections = data.WrappedData.Sections; - HydraulicBoundaryDatabase hydraulicBoundaryDatabase = data.Parent.HydraulicBoundaryDatabase; - IEnumerable foreshoreProfiles = data.WrappedData.ForeshoreProfiles; - IEnumerable structures = data.WrappedData.ClosingStructures; - IEnumerable> calculations = - data.WrappedData.CalculationsGroup.GetCalculations().Cast>(); - - referenceLineMapData.Features = RingtoetsMapDataFeaturesFactory.CreateReferenceLineFeatures(referenceLine, data.Parent.Id, data.Parent.Name); + sectionsMapData.Features = RingtoetsMapDataFeaturesFactory.CreateFailureMechanismSectionFeatures(failureMechanismSections); sectionsStartPointMapData.Features = RingtoetsMapDataFeaturesFactory.CreateFailureMechanismSectionStartPointFeatures(failureMechanismSections); sectionsEndPointMapData.Features = RingtoetsMapDataFeaturesFactory.CreateFailureMechanismSectionEndPointFeatures(failureMechanismSections); - hydraulicBoundaryLocationsMapData.Features = RingtoetsMapDataFeaturesFactory.CreateHydraulicBoundaryDatabaseFeatures(hydraulicBoundaryDatabase); + } + + #endregion + + #region ForeshoreProfiles MapData + + private void UpdateForeshoreProfilesMapData() + { + SetForeshoreProfilesMapData(); + foreshoreProfilesMapData.NotifyObservers(); + } + + private void SetForeshoreProfilesMapData() + { + IEnumerable foreshoreProfiles = data.WrappedData.ForeshoreProfiles; foreshoreProfilesMapData.Features = RingtoetsMapDataFeaturesFactory.CreateForeshoreProfilesFeatures(foreshoreProfiles); + } + + #endregion + + #region Structures MapData + + private void UpdateStructuresMapData() + { + SetStructuresMapData(); + structuresMapData.NotifyObservers(); + } + + private void SetStructuresMapData() + { + IEnumerable structures = data.WrappedData.ClosingStructures; structuresMapData.Features = RingtoetsMapDataFeaturesFactory.CreateStructuresFeatures(structures); - calculationsMapData.Features = RingtoetsMapDataFeaturesFactory.CreateStructureCalculationsFeatures(calculations); } + #endregion } } \ No newline at end of file Index: Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Forms.Test/Views/ClosingStructuresFailureMechanismViewTest.cs =================================================================== diff -u -r6678115bc8c06dcc0b676429038e1839b128d6f2 -re9d34986f2e90e63bbf6ebba579c24055c1c3853 --- Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Forms.Test/Views/ClosingStructuresFailureMechanismViewTest.cs (.../ClosingStructuresFailureMechanismViewTest.cs) (revision 6678115bc8c06dcc0b676429038e1839b128d6f2) +++ Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Forms.Test/Views/ClosingStructuresFailureMechanismViewTest.cs (.../ClosingStructuresFailureMechanismViewTest.cs) (revision e9d34986f2e90e63bbf6ebba579c24055c1c3853) @@ -22,12 +22,14 @@ using System.Collections.Generic; using System.Linq; using System.Windows.Forms; +using Core.Common.Base; using Core.Common.Base.Geometry; using Core.Components.Gis.Data; using Core.Components.Gis.Features; using Core.Components.Gis.Forms; using Core.Components.Gis.Geometries; using NUnit.Framework; +using Rhino.Mocks; using Ringtoets.ClosingStructures.Data; using Ringtoets.ClosingStructures.Data.TestUtil; using Ringtoets.ClosingStructures.Forms.PresentationObjects; @@ -330,6 +332,18 @@ view.Data = failureMechanismContext; + var mocks = new MockRepository(); + IObserver[] observers = AttachMapDataObservers(mocks, map.Data.Collection); + observers[referenceLineIndex].Expect(obs => obs.UpdateObserver()); + observers[sectionsIndex].Expect(obs => obs.UpdateObserver()); + observers[sectionsStartPointIndex].Expect(obs => obs.UpdateObserver()); + observers[sectionsEndPointIndex].Expect(obs => obs.UpdateObserver()); + observers[hydraulicBoundaryLocationsIndex].Expect(obs => obs.UpdateObserver()); + observers[foreshoreProfilesIndex].Expect(obs => obs.UpdateObserver()); + observers[structuresIndex].Expect(obs => obs.UpdateObserver()); + observers[calculationsIndex].Expect(obs => obs.UpdateObserver()); + mocks.ReplayAll(); + MapData hydraulicBoundaryLocationsMapData = map.Data.Collection.ElementAt(hydraulicBoundaryLocationsIndex); // Precondition @@ -341,6 +355,7 @@ // Assert MapDataTestHelper.AssertHydraulicBoundaryLocationsMapData(hydraulicBoundaryDatabase2.Locations, hydraulicBoundaryLocationsMapData); + mocks.VerifyAll(); } } @@ -369,6 +384,11 @@ view.Data = failureMechanismContext; + var mocks = new MockRepository(); + IObserver[] observers = AttachMapDataObservers(mocks, map.Data.Collection); + observers[hydraulicBoundaryLocationsIndex].Expect(obs => obs.UpdateObserver()); + mocks.ReplayAll(); + MapData hydraulicBoundaryLocationsMapData = map.Data.Collection.ElementAt(hydraulicBoundaryLocationsIndex); // Precondition @@ -380,6 +400,7 @@ // Assert MapDataTestHelper.AssertHydraulicBoundaryLocationsMapData(hydraulicBoundaryDatabase.Locations, hydraulicBoundaryLocationsMapData); + mocks.VerifyAll(); } } @@ -413,6 +434,18 @@ view.Data = new ClosingStructuresFailureMechanismContext(new ClosingStructuresFailureMechanism(), assessmentSection); + var mocks = new MockRepository(); + IObserver[] observers = AttachMapDataObservers(mocks, map.Data.Collection); + observers[referenceLineIndex].Expect(obs => obs.UpdateObserver()); + observers[sectionsIndex].Expect(obs => obs.UpdateObserver()); + observers[sectionsStartPointIndex].Expect(obs => obs.UpdateObserver()); + observers[sectionsEndPointIndex].Expect(obs => obs.UpdateObserver()); + observers[hydraulicBoundaryLocationsIndex].Expect(obs => obs.UpdateObserver()).Repeat.Twice(); + observers[foreshoreProfilesIndex].Expect(obs => obs.UpdateObserver()); + observers[structuresIndex].Expect(obs => obs.UpdateObserver()); + observers[calculationsIndex].Expect(obs => obs.UpdateObserver()); + mocks.ReplayAll(); + MapData hydraulicBoundaryLocationsMapData = map.Data.Collection.ElementAt(hydraulicBoundaryLocationsIndex); // Precondition @@ -426,6 +459,7 @@ // Then MapDataTestHelper.AssertHydraulicBoundaryLocationsMapData(newHydraulicBoundaryDatabase.Locations, hydraulicBoundaryLocationsMapData); + mocks.VerifyAll(); } } @@ -459,6 +493,18 @@ view.Data = failureMechanismContext; + var mocks = new MockRepository(); + IObserver[] observers = AttachMapDataObservers(mocks, map.Data.Collection); + observers[referenceLineIndex].Expect(obs => obs.UpdateObserver()); + observers[sectionsIndex].Expect(obs => obs.UpdateObserver()); + observers[sectionsStartPointIndex].Expect(obs => obs.UpdateObserver()); + observers[sectionsEndPointIndex].Expect(obs => obs.UpdateObserver()); + observers[hydraulicBoundaryLocationsIndex].Expect(obs => obs.UpdateObserver()); + observers[foreshoreProfilesIndex].Expect(obs => obs.UpdateObserver()); + observers[structuresIndex].Expect(obs => obs.UpdateObserver()); + observers[calculationsIndex].Expect(obs => obs.UpdateObserver()); + mocks.ReplayAll(); + MapData referenceLineMapData = map.Data.Collection.ElementAt(referenceLineIndex); // Precondition @@ -470,6 +516,7 @@ // Assert MapDataTestHelper.AssertReferenceLineMapData(assessmentSection.ReferenceLine, referenceLineMapData); + mocks.VerifyAll(); } } @@ -490,6 +537,18 @@ var sectionStartsMapData = (MapPointData) map.Data.Collection.ElementAt(sectionsStartPointIndex); var sectionsEndsMapData = (MapPointData) map.Data.Collection.ElementAt(sectionsEndPointIndex); + var mocks = new MockRepository(); + IObserver[] observers = AttachMapDataObservers(mocks, map.Data.Collection); + observers[referenceLineIndex].Expect(obs => obs.UpdateObserver()); + observers[sectionsIndex].Expect(obs => obs.UpdateObserver()); + observers[sectionsStartPointIndex].Expect(obs => obs.UpdateObserver()); + observers[sectionsEndPointIndex].Expect(obs => obs.UpdateObserver()); + observers[hydraulicBoundaryLocationsIndex].Expect(obs => obs.UpdateObserver()); + observers[foreshoreProfilesIndex].Expect(obs => obs.UpdateObserver()); + observers[structuresIndex].Expect(obs => obs.UpdateObserver()); + observers[calculationsIndex].Expect(obs => obs.UpdateObserver()); + mocks.ReplayAll(); + // Call failureMechanism.AddSection(new FailureMechanismSection(string.Empty, new[] { @@ -502,10 +561,59 @@ MapDataTestHelper.AssertFailureMechanismSectionsMapData(failureMechanism.Sections, sectionMapData); MapDataTestHelper.AssertFailureMechanismSectionsStartPointMapData(failureMechanism.Sections, sectionStartsMapData); MapDataTestHelper.AssertFailureMechanismSectionsEndPointMapData(failureMechanism.Sections, sectionsEndsMapData); + mocks.VerifyAll(); } } [Test] + public void UpdateObserver_ForeshoreProfileUpdate_MapDataUpdated() + { + // Setup + using (var view = new ClosingStructuresFailureMechanismView()) + { + IMapControl map = ((RingtoetsMapControl) view.Controls[0]).MapControl; + + var failureMechanism = new ClosingStructuresFailureMechanism(); + var failureMechanismContext = new ClosingStructuresFailureMechanismContext(failureMechanism, new ObservableTestAssessmentSectionStub()); + + var foreshoreProfile = new TestForeshoreProfile("originalProfile ID", new[] + { + new Point2D(0, 0), + new Point2D(1, 1) + }); + failureMechanism.ForeshoreProfiles.AddRange(new[] + { + foreshoreProfile + }, "path"); + + view.Data = failureMechanismContext; + + var mocks = new MockRepository(); + IObserver[] observers = AttachMapDataObservers(mocks, map.Data.Collection); + observers[foreshoreProfilesIndex].Expect(obs => obs.UpdateObserver()); + mocks.ReplayAll(); + + MapData foreshoreProfileData = map.Data.Collection.ElementAt(foreshoreProfilesIndex); + + // Precondition + MapDataTestHelper.AssertForeshoreProfilesMapData(failureMechanism.ForeshoreProfiles, foreshoreProfileData); + + // Call + var foreshoreProfileToUpdateFrom = new TestForeshoreProfile("originalProfile ID", new[] + { + new Point2D(2, 2), + new Point2D(3, 3) + }); + foreshoreProfile.CopyProperties(foreshoreProfileToUpdateFrom); + foreshoreProfile.NotifyObservers(); + + // Assert + MapDataTestHelper.AssertForeshoreProfilesMapData(failureMechanism.ForeshoreProfiles, foreshoreProfileData); + mocks.ReplayAll(); + } + } + + [Test] public void UpdateObserver_ForeshoreProfilesUpdated_MapDataUpdated() { // Setup @@ -527,6 +635,11 @@ view.Data = failureMechanismContext; + var mocks = new MockRepository(); + IObserver[] observers = AttachMapDataObservers(mocks, map.Data.Collection); + observers[foreshoreProfilesIndex].Expect(obs => obs.UpdateObserver()); + mocks.ReplayAll(); + MapData foreshoreProfileData = map.Data.Collection.ElementAt(foreshoreProfilesIndex); // Precondition @@ -545,6 +658,7 @@ // Assert MapDataTestHelper.AssertForeshoreProfilesMapData(failureMechanism.ForeshoreProfiles, foreshoreProfileData); + mocks.VerifyAll(); } } @@ -568,6 +682,11 @@ MapData structuresData = map.Data.Collection.ElementAt(structuresIndex); + var mocks = new MockRepository(); + IObserver[] observers = AttachMapDataObservers(mocks, map.Data.Collection); + observers[structuresIndex].Expect(obs => obs.UpdateObserver()); + mocks.ReplayAll(); + // Precondition AssertStructures(failureMechanism.ClosingStructures, structuresData); @@ -580,6 +699,7 @@ // Assert AssertStructures(failureMechanism.ClosingStructures, structuresData); + mocks.VerifyAll(); } } @@ -626,11 +746,17 @@ failureMechanism.CalculationsGroup.Children.Add(calculationB); + var mocks = new MockRepository(); + IObserver[] observers = AttachMapDataObservers(mocks, map.Data.Collection); + observers[calculationsIndex].Expect(obs => obs.UpdateObserver()); + mocks.ReplayAll(); + // Call failureMechanism.CalculationsGroup.NotifyObservers(); // Assert AssertCalculationsMapData(failureMechanism.Calculations.Cast>(), calculationMapData); + mocks.VerifyAll(); } } @@ -663,13 +789,19 @@ var calculationMapData = (MapLineData) map.Data.Collection.ElementAt(calculationsIndex); + var mocks = new MockRepository(); + IObserver[] observers = AttachMapDataObservers(mocks, map.Data.Collection); + observers[calculationsIndex].Expect(obs => obs.UpdateObserver()); + mocks.ReplayAll(); + calculationA.InputParameters.Structure = new TestClosingStructure(calculationLocationB); // Call calculationA.InputParameters.NotifyObservers(); // Assert AssertCalculationsMapData(failureMechanism.Calculations.Cast>(), calculationMapData); + mocks.VerifyAll(); } } @@ -916,5 +1048,53 @@ Assert.AreEqual("Hydraulische randvoorwaarden", hydraulicBoundaryLocationsMapData.Name); Assert.AreEqual("Berekeningen", calculationsMapData.Name); } + + /// + /// Attaches mocked observers to all map data components. + /// + /// The . + /// The map data collection containing the + /// elements. + /// An array of mocked observers attached to the data in . + private static IObserver[] AttachMapDataObservers(MockRepository mocks, IEnumerable mapData) + { + MapData[] mapDataArray = mapData.ToArray(); + + var referenceLineMapDataObserver = mocks.StrictMock(); + mapDataArray[referenceLineIndex].Attach(referenceLineMapDataObserver); + + var sectionsMapDataObserver = mocks.StrictMock(); + mapDataArray[sectionsIndex].Attach(sectionsMapDataObserver); + + var sectionsStartPointMapDataObserver = mocks.StrictMock(); + mapDataArray[sectionsStartPointIndex].Attach(sectionsStartPointMapDataObserver); + + var sectionsEndPointMapDataObserver = mocks.StrictMock(); + mapDataArray[sectionsEndPointIndex].Attach(sectionsEndPointMapDataObserver); + + var hydraulicBoundaryLocationsMapDataObserver = mocks.StrictMock(); + mapDataArray[hydraulicBoundaryLocationsIndex].Attach(hydraulicBoundaryLocationsMapDataObserver); + + var foreshoreProfilesMapDataObserver = mocks.StrictMock(); + mapDataArray[foreshoreProfilesIndex].Attach(foreshoreProfilesMapDataObserver); + + var structuresMapDataObserver = mocks.StrictMock(); + mapDataArray[structuresIndex].Attach(structuresMapDataObserver); + + var calculationsMapDataObserver = mocks.StrictMock(); + mapDataArray[calculationsIndex].Attach(calculationsMapDataObserver); + + return new[] + { + referenceLineMapDataObserver, + sectionsMapDataObserver, + sectionsStartPointMapDataObserver, + sectionsEndPointMapDataObserver, + hydraulicBoundaryLocationsMapDataObserver, + foreshoreProfilesMapDataObserver, + structuresMapDataObserver, + calculationsMapDataObserver + }; + } } } \ No newline at end of file Index: Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/UpdateInfos/ForeshoreProfileContextUpdateInfoTest.cs =================================================================== diff -u -r6ea2281c03c04dfbfaa7742d533fc1f88b96f59c -re9d34986f2e90e63bbf6ebba579c24055c1c3853 --- Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/UpdateInfos/ForeshoreProfileContextUpdateInfoTest.cs (.../ForeshoreProfileContextUpdateInfoTest.cs) (revision 6ea2281c03c04dfbfaa7742d533fc1f88b96f59c) +++ Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/UpdateInfos/ForeshoreProfileContextUpdateInfoTest.cs (.../ForeshoreProfileContextUpdateInfoTest.cs) (revision e9d34986f2e90e63bbf6ebba579c24055c1c3853) @@ -187,7 +187,7 @@ } [Test] - public void CurrentPath_DikeProfileCollectionHasPathSet_ReturnsExpectedPath() + public void CurrentPath_ForeshoreProfileCollectionHasPathSet_ReturnsExpectedPath() { // Setup var mocks = new MockRepository();