Index: Core/Gui/test/Core.Gui.Test/Core.Gui.Test.csproj =================================================================== diff -u -rd8cc764febfb2ac4a533ed82ca12156c1a12b2de -raf6538ce2677998cbc514db20c2756c9dd2eac6f --- Core/Gui/test/Core.Gui.Test/Core.Gui.Test.csproj (.../Core.Gui.Test.csproj) (revision d8cc764febfb2ac4a533ed82ca12156c1a12b2de) +++ Core/Gui/test/Core.Gui.Test/Core.Gui.Test.csproj (.../Core.Gui.Test.csproj) (revision af6538ce2677998cbc514db20c2756c9dd2eac6f) @@ -17,6 +17,7 @@ + Index: Core/Gui/test/Core.Gui.Test/Forms/Map/FeatureBasedMapDataContextTreeNodeInfoTest.cs =================================================================== diff -u --- Core/Gui/test/Core.Gui.Test/Forms/Map/FeatureBasedMapDataContextTreeNodeInfoTest.cs (revision 0) +++ Core/Gui/test/Core.Gui.Test/Forms/Map/FeatureBasedMapDataContextTreeNodeInfoTest.cs (revision af6538ce2677998cbc514db20c2756c9dd2eac6f) @@ -0,0 +1,489 @@ +// Copyright (C) Stichting Deltares 2021. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer 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.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Windows.Forms; +using Core.Common.Base; +using Core.Common.Controls.TreeView; +using Core.Common.TestUtil; +using Core.Common.Util.Reflection; +using Core.Components.Gis.Data; +using Core.Components.Gis.Data.Removable; +using Core.Components.Gis.Features; +using Core.Components.Gis.Forms; +using Core.Components.Gis.Geometries; +using Core.Components.Gis.TestUtil; +using Core.Gui.ContextMenu; +using Core.Gui.Forms.Map; +using Core.Gui.PresentationObjects.Map; +using Core.Gui.Properties; +using Core.Gui.TestUtil.ContextMenu; +using NUnit.Framework; +using Rhino.Mocks; + +namespace Core.Gui.Test.Forms.Map +{ + [TestFixture] + public class FeatureBasedMapDataContextTreeNodeInfoTest + { + private const int mapDataContextMenuZoomToAllIndex = 0; + + private MapLegendView mapLegendView; + private TreeNodeInfo info; + private MockRepository mocks; + private IContextMenuBuilderProvider contextMenuBuilderProvider; + + private static IEnumerable MapDataLegendImages + { + get + { + yield return new TestCaseData(new MapPointData("test"), Resources.PointsIcon); + yield return new TestCaseData(new MapLineData("test"), Resources.LineIcon); + yield return new TestCaseData(new MapPolygonData("test"), Resources.AreaIcon); + } + } + + [SetUp] + public void SetUp() + { + mocks = new MockRepository(); + contextMenuBuilderProvider = mocks.StrictMock(); + mocks.ReplayAll(); + + mapLegendView = new MapLegendView(contextMenuBuilderProvider); + + var treeViewControl = TypeUtils.GetField(mapLegendView, "treeViewControl"); + var treeNodeInfoLookup = TypeUtils.GetField>(treeViewControl, "tagTypeTreeNodeInfoLookup"); + + info = treeNodeInfoLookup[typeof(FeatureBasedMapDataContext)]; + } + + [TearDown] + public void TearDown() + { + mapLegendView.Dispose(); + mocks.VerifyAll(); + } + + [Test] + public void Initialized_Always_ExpectedPropertiesSet() + { + // Assert + Assert.IsNotNull(info.Text); + Assert.IsNull(info.ForeColor); + Assert.IsNotNull(info.Image); + Assert.IsNotNull(info.ContextMenuStrip); + Assert.IsNull(info.EnsureVisibleOnCreate); + Assert.IsNull(info.ExpandOnCreate); + Assert.IsNull(info.ChildNodeObjects); + Assert.IsNull(info.CanRename); + Assert.IsNull(info.OnNodeRenamed); + Assert.IsNotNull(info.CanRemove); + Assert.IsNotNull(info.OnNodeRemoved); + Assert.IsNotNull(info.CanCheck); + Assert.IsNotNull(info.CheckedState); + Assert.IsNotNull(info.OnNodeChecked); + Assert.IsNotNull(info.CanDrag); + Assert.IsNull(info.CanDrop); + Assert.IsNull(info.CanInsert); + Assert.IsNull(info.OnDrop); + } + + [Test] + public void Text_WithContext_ReturnsNameFromWrappedMapData() + { + // Setup + FeatureBasedMapDataContext context = GetContext(new TestFeatureBasedMapData()); + + // Call + string text = info.Text(context); + + // Assert + Assert.AreEqual(context.WrappedData.Name, text); + } + + [Test] + [TestCaseSource(nameof(MapDataLegendImages))] + public void Image_WithContext_ReturnExpectedImage(FeatureBasedMapData mapData, Image expectedImage) + { + // Setup + FeatureBasedMapDataContext context = GetContext(mapData); + + // Call + Image image = info.Image(context); + + // Assert + TestHelper.AssertImagesAreEqual(expectedImage, image); + } + + [Test] + public void CanDrag_Always_ReturnsTrue() + { + // Call + bool canDrag = info.CanDrag(null, null); + + // Assert + Assert.IsTrue(canDrag); + } + + [Test] + public void CanCheck_Always_ReturnsTrue() + { + // Call + bool canCheck = info.CanCheck(null); + + // Assert + Assert.IsTrue(canCheck); + } + + [Test] + [TestCase(true)] + [TestCase(false)] + public void CheckedState_WithContext_ReturnsAccordingToVisibleStateOfMapData(bool isVisible) + { + // Setup + FeatureBasedMapDataContext context = GetContext(new TestFeatureBasedMapData()); + context.WrappedData.IsVisible = isVisible; + + // Call + TreeNodeCheckedState checkedState = info.CheckedState(context); + + // Assert + TreeNodeCheckedState expectedCheckedState = isVisible ? TreeNodeCheckedState.Checked : TreeNodeCheckedState.Unchecked; + Assert.AreEqual(expectedCheckedState, checkedState); + } + + [Test] + [TestCase(true)] + [TestCase(false)] + public void OnNodeChecked_WithContext_SetMapDataVisibilityAndNotifyObservers(bool initialVisibleState) + { + // Setup + var observer = mocks.StrictMock(); + observer.Expect(o => o.UpdateObserver()); + mocks.ReplayAll(); + + FeatureBasedMapDataContext context = GetContext(new TestFeatureBasedMapData()); + context.WrappedData.IsVisible = initialVisibleState; + + context.WrappedData.Attach(observer); + + // Call + info.OnNodeChecked(context, null); + + // Assert + Assert.AreEqual(!initialVisibleState, context.WrappedData.IsVisible); + mocks.VerifyAll(); + } + + [Test] + public void OnNodeChecked_WithContext_NotifyObserversOfParentMapDataCollections() + { + // Setup + var collectionObserver = mocks.StrictMock(); + collectionObserver.Expect(o => o.UpdateObserver()); + var parentCollectionObserver = mocks.StrictMock(); + parentCollectionObserver.Expect(o => o.UpdateObserver()); + mocks.ReplayAll(); + + var featureBasedMapData = new TestFeatureBasedMapData(); + var nestedMapDataCollection = new MapDataCollection("nested"); + nestedMapDataCollection.Add(featureBasedMapData); + var mapDataCollection = new MapDataCollection("test"); + mapDataCollection.Add(nestedMapDataCollection); + + MapDataCollectionContext rootCollectionContext = GetContext(mapDataCollection); + MapDataCollectionContext nestedCollectionContext = GetContext(nestedMapDataCollection, rootCollectionContext); + FeatureBasedMapDataContext featureBasedMapDataContext = GetContext((FeatureBasedMapData) featureBasedMapData, nestedCollectionContext); + + nestedMapDataCollection.Attach(collectionObserver); + mapDataCollection.Attach(parentCollectionObserver); + + // Call + info.OnNodeChecked(featureBasedMapDataContext, null); + + // Assert + mocks.VerifyAll(); + } + + [Test] + public void CanRemove_WithRemovableDataAndCollection_ReturnTrue() + { + // Setup + var removable = mocks.StrictMultiMock(new[] + { + typeof(IRemovable) + }, "name"); + mocks.ReplayAll(); + + FeatureBasedMapDataContext context = GetContext(removable); + + // Call + bool canRemove = info.CanRemove(context, context.ParentMapData); + + // Assert + Assert.IsTrue(canRemove); + } + + [Test] + public void CanRemove_WithoutCollection_ReturnFalse() + { + // Setup + var removable = mocks.StrictMultiMock(new[] + { + typeof(IRemovable) + }, "name"); + mocks.ReplayAll(); + + FeatureBasedMapDataContext context = GetContext(removable); + + // Call + bool canRemove = info.CanRemove(context, null); + + // Assert + Assert.IsFalse(canRemove); + } + + [Test] + public void CanRemove_WithNotRemovableData_ReturnFalse() + { + // Setup + var notRemovable = mocks.StrictMock("name"); + mocks.ReplayAll(); + + FeatureBasedMapDataContext context = GetContext(notRemovable); + + // Call + bool canRemove = info.CanRemove(context, context.ParentMapData); + + // Assert + Assert.IsFalse(canRemove); + } + + [Test] + public void OnNodeRemoved_WithRemovableDataToRemove_DataRemoved() + { + // Setup + var toRemove = mocks.StrictMultiMock(new[] + { + typeof(IRemovable) + }, "name"); + var otherData = mocks.Stub("name"); + mocks.ReplayAll(); + + var collection = new MapDataCollection("collection"); + collection.Add(toRemove); + collection.Add(otherData); + + FeatureBasedMapDataContext context = GetContext(toRemove, GetContext(collection)); + + // Call + info.OnNodeRemoved(context, context.ParentMapData); + + // Assert + CollectionAssert.AreEqual(new[] + { + otherData + }, collection.Collection); + } + + [Test] + public void ContextMenuStrip_Always_CallsBuilder() + { + // Setup + var mapData = new TestFeatureBasedMapData(); + FeatureBasedMapDataContext context = GetContext(mapData); + var builder = mocks.StrictMock(); + using (mocks.Ordered()) + { + builder.Expect(mb => mb.AddCustomItem(Arg.Is.NotNull)).Return(builder); + builder.Expect(mb => mb.AddSeparator()).Return(builder); + builder.Expect(mb => mb.AddDeleteItem()).Return(builder); + builder.Expect(mb => mb.AddSeparator()).Return(builder); + builder.Expect(mb => mb.AddPropertiesItem()).Return(builder); + builder.Expect(mb => mb.Build()).Return(null); + } + + contextMenuBuilderProvider.Expect(p => p.Get(context, null)).Return(builder); + + mocks.ReplayAll(); + + // Call + info.ContextMenuStrip(context, null, null); + + // Assert + // Assert expectancies are called in TearDown() + } + + [Test] + public void ContextMenuStrip_VisibleMapDataWithFeatures_ZoomToAllItemEnabled() + { + // Setup + var builder = new CustomItemsOnlyContextMenuBuilder(); + contextMenuBuilderProvider.Expect(p => p.Get(null, null)).IgnoreArguments().Return(builder); + + mocks.ReplayAll(); + + var mapData = new TestFeatureBasedMapData + { + IsVisible = true, + Features = new[] + { + new MapFeature(Enumerable.Empty()) + } + }; + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(GetContext(mapData), null, null)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, mapDataContextMenuZoomToAllIndex, + "&Zoom naar alles", + "Zet het zoomniveau van de kaart dusdanig dat deze kaartlaag precies in het beeld past.", + Resources.ZoomToAllIcon); + } + } + + [Test] + public void ContextMenuStrip_InvisibleMapData_ZoomToAllItemDisabled() + { + // Setup + var builder = new CustomItemsOnlyContextMenuBuilder(); + contextMenuBuilderProvider.Expect(p => p.Get(null, null)).IgnoreArguments().Return(builder); + + mocks.ReplayAll(); + + var mapData = new TestFeatureBasedMapData + { + IsVisible = false + }; + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(GetContext(mapData), null, null)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, mapDataContextMenuZoomToAllIndex, + "&Zoom naar alles", + "Om het zoomniveau aan te passen moet de kaartlaag zichtbaar zijn.", + Resources.ZoomToAllIcon, + false); + } + } + + [Test] + public void ContextMenuStrip_VisibleMapDataWithoutFeatures_ZoomToAllItemDisabled() + { + // Setup + var builder = new CustomItemsOnlyContextMenuBuilder(); + contextMenuBuilderProvider.Expect(p => p.Get(null, null)).IgnoreArguments().Return(builder); + + mocks.ReplayAll(); + + var mapData = new TestFeatureBasedMapData + { + IsVisible = true + }; + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(GetContext(mapData), null, null)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, mapDataContextMenuZoomToAllIndex, + "&Zoom naar alles", + "Om het zoomniveau aan te passen moet de kaartlaag elementen bevatten.", + Resources.ZoomToAllIcon, + false); + } + } + + [Test] + public void ContextMenuStrip_EnabledZoomToAllContextMenuItemClicked_DoZoomToVisibleData() + { + // Setup + var mapData = new TestFeatureBasedMapData + { + IsVisible = true, + Features = new[] + { + new MapFeature(Enumerable.Empty()) + } + }; + + var builder = new CustomItemsOnlyContextMenuBuilder(); + contextMenuBuilderProvider.Expect(p => p.Get(null, null)).IgnoreArguments().Return(builder); + var mapControl = mocks.StrictMock(); + mapControl.Expect(c => c.Data).Return(new MapDataCollection("name")); + mapControl.Expect(c => c.ZoomToAllVisibleLayers(mapData)); + mocks.ReplayAll(); + + mapLegendView.MapControl = mapControl; + + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(GetContext(mapData), null, null)) + { + // Call + contextMenu.Items[mapDataContextMenuZoomToAllIndex].PerformClick(); + + // Assert + // Assert expectancies are called in TearDown() + } + } + + [Test] + public void ContextMenuStrip_NoMapControlAndEnabledZoomToAllContextMenuItemClicked_DoesNotThrow() + { + // Setup + var mapData = new TestFeatureBasedMapData("A") + { + IsVisible = true, + Features = new[] + { + new MapFeature(Enumerable.Empty()) + } + }; + + var builder = new CustomItemsOnlyContextMenuBuilder(); + contextMenuBuilderProvider.Expect(p => p.Get(null, null)).IgnoreArguments().Return(builder); + mocks.ReplayAll(); + + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(GetContext(mapData), null, null)) + { + // Call + TestDelegate call = () => contextMenu.Items[mapDataContextMenuZoomToAllIndex].PerformClick(); + + // Assert + Assert.DoesNotThrow(call); + } + } + + private static FeatureBasedMapDataContext GetContext(FeatureBasedMapData mapData, MapDataCollectionContext parentMapDataCollectionContext = null) + { + return new FeatureBasedMapDataContext(mapData, parentMapDataCollectionContext ?? new MapDataCollectionContext(new MapDataCollection("test"), null)); + } + + private static MapDataCollectionContext GetContext(MapDataCollection mapDataCollection, MapDataCollectionContext parentMapDataCollectionContext = null) + { + return new MapDataCollectionContext(mapDataCollection, parentMapDataCollectionContext ?? new MapDataCollectionContext(new MapDataCollection("test"), null)); + } + } +} \ No newline at end of file Index: Core/Gui/test/Core.Gui.Test/Forms/Map/MapDataCollectionContextTreeNodeInfoTest.cs =================================================================== diff -u --- Core/Gui/test/Core.Gui.Test/Forms/Map/MapDataCollectionContextTreeNodeInfoTest.cs (revision 0) +++ Core/Gui/test/Core.Gui.Test/Forms/Map/MapDataCollectionContextTreeNodeInfoTest.cs (revision af6538ce2677998cbc514db20c2756c9dd2eac6f) @@ -0,0 +1,741 @@ +// Copyright (C) Stichting Deltares 2021. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer 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.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Windows.Forms; +using Core.Common.Base; +using Core.Common.Controls.TreeView; +using Core.Common.TestUtil; +using Core.Common.Util.Reflection; +using Core.Components.Gis.Data; +using Core.Components.Gis.Features; +using Core.Components.Gis.Forms; +using Core.Components.Gis.Geometries; +using Core.Components.Gis.TestUtil; +using Core.Gui.Commands; +using Core.Gui.ContextMenu; +using Core.Gui.Forms.Map; +using Core.Gui.Plugin; +using Core.Gui.PresentationObjects.Map; +using Core.Gui.Properties; +using Core.Gui.TestUtil.ContextMenu; +using NUnit.Extensions.Forms; +using NUnit.Framework; +using Rhino.Mocks; + +namespace Core.Gui.Test.Forms.Map +{ + [TestFixture] + public class MapDataCollectionContextTreeNodeInfoTest : NUnitFormTest + { + private const int contextMenuAddMapLayerIndex = 0; + private const int contextMenuZoomToAllIndex = 2; + + private MockRepository mocks; + private MapLegendView mapLegendView; + private TreeNodeInfo info; + private IContextMenuBuilderProvider contextMenuBuilderProvider; + + [Test] + public void Initialized_Always_ExpectedPropertiesSet() + { + // Assert + Assert.IsNotNull(info.Text); + Assert.IsNull(info.ForeColor); + Assert.IsNotNull(info.Image); + Assert.IsNotNull(info.ContextMenuStrip); + Assert.IsNull(info.EnsureVisibleOnCreate); + Assert.IsNull(info.ExpandOnCreate); + Assert.IsNotNull(info.ChildNodeObjects); + Assert.IsNull(info.CanRename); + Assert.IsNull(info.OnNodeRenamed); + Assert.IsNull(info.CanRemove); + Assert.IsNull(info.OnNodeRemoved); + Assert.IsNotNull(info.CanCheck); + Assert.IsNotNull(info.CheckedState); + Assert.IsNotNull(info.OnNodeChecked); + Assert.IsNotNull(info.CanDrag); + Assert.IsNotNull(info.CanDrop); + Assert.IsNotNull(info.CanInsert); + Assert.IsNotNull(info.OnDrop); + } + + [Test] + public void Text_WithContext_ReturnsNameFromMapData() + { + // Setup + var mapDataCollection = new MapDataCollection("Collectie"); + + // Call + string text = info.Text(GetContext(mapDataCollection)); + + // Assert + Assert.AreEqual(mapDataCollection.Name, text); + } + + [Test] + public void Image_Always_ReturnsImageFromResource() + { + // Call + Image image = info.Image(null); + + // Assert + TestHelper.AssertImagesAreEqual(Resources.folder, image); + } + + [Test] + public void ChildNodeObjects_Always_ReturnsChildrenWithContextAndDataReversed() + { + // Setup + var mapPointData = new MapPointData("points"); + var mapLineData = new MapLineData("lines"); + var nestedCollection = new MapDataCollection("nested"); + var mapPolygonData = new MapPolygonData("polygons"); + var mapDataCollection = new MapDataCollection("test data"); + + mapDataCollection.Add(mapPointData); + mapDataCollection.Add(mapLineData); + mapDataCollection.Add(nestedCollection); + mapDataCollection.Add(mapPolygonData); + + MapDataCollectionContext parentCollectionContext = GetContext(mapDataCollection); + + // Call + object[] objects = info.ChildNodeObjects(GetContext(mapDataCollection)); + + // Assert + CollectionAssert.AreEqual(new MapDataContext[] + { + new MapPolygonDataContext(mapPolygonData, parentCollectionContext), + GetContext(nestedCollection, parentCollectionContext), + new MapLineDataContext(mapLineData, parentCollectionContext), + new MapPointDataContext(mapPointData, parentCollectionContext) + }, objects); + } + + [Test] + public void CanCheck_Always_ReturnsTrue() + { + // Call + bool canCheck = info.CanCheck(null); + + // Assert + Assert.IsTrue(canCheck); + } + + [Test] + public void CheckedState_WithContextAndMapDataCollectionVisibilityVisible_ReturnsStateChecked() + { + // Setup + var featureBasedMapData = new TestFeatureBasedMapData(); + var mapDataCollection = new MapDataCollection("test"); + mapDataCollection.Add(featureBasedMapData); + + MapDataCollectionContext context = GetContext(mapDataCollection); + + // Call + TreeNodeCheckedState checkedState = info.CheckedState(context); + + // Assert + Assert.AreEqual(TreeNodeCheckedState.Checked, checkedState); + } + + [Test] + public void CheckedState_WithContextAndMapDataCollectionVisibilityNotVisible_ReturnsStateUnchecked() + { + // Setup + var featureBasedMapData = new TestFeatureBasedMapData + { + IsVisible = false + }; + var mapDataCollection = new MapDataCollection("test"); + mapDataCollection.Add(featureBasedMapData); + + MapDataCollectionContext context = GetContext(mapDataCollection); + + // Call + TreeNodeCheckedState checkedState = info.CheckedState(context); + + // Assert + Assert.AreEqual(TreeNodeCheckedState.Unchecked, checkedState); + } + + [Test] + public void CheckedState_WithContextAndMapDataCollectionVisibilityMixed_ReturnsStateMixed() + { + // Setup + var featureBasedMapData1 = new TestFeatureBasedMapData(); + var featureBasedMapData2 = new TestFeatureBasedMapData + { + IsVisible = false + }; + var mapDataCollection = new MapDataCollection("test"); + mapDataCollection.Add(featureBasedMapData1); + mapDataCollection.Add(featureBasedMapData2); + + MapDataCollectionContext context = GetContext(mapDataCollection); + + // Call + TreeNodeCheckedState checkedState = info.CheckedState(context); + + // Assert + Assert.AreEqual(TreeNodeCheckedState.Mixed, checkedState); + } + + [Test] + [TestCase(true)] + [TestCase(false)] + public void OnNodeChecked_WithContext_SetMapDataVisibilityAndNotifyObservers(bool initialVisibleState) + { + // Setup + var collectionObserver = mocks.StrictMock(); + collectionObserver.Expect(o => o.UpdateObserver()); + mocks.ReplayAll(); + + var featureBasedMapData = new TestFeatureBasedMapData(); + var mapDataCollection = new MapDataCollection("test"); + mapDataCollection.Add(featureBasedMapData); + + MapDataCollectionContext context = GetContext(mapDataCollection); + context.WrappedData.IsVisible = initialVisibleState; + + context.WrappedData.Attach(collectionObserver); + + // Call + info.OnNodeChecked(context, null); + + // Assert + Assert.AreEqual(!initialVisibleState, context.WrappedData.IsVisible); + Assert.AreEqual(!initialVisibleState, featureBasedMapData.IsVisible); + mocks.VerifyAll(); + } + + [Test] + public void OnNodeChecked_WithContextAndStateMixed_SetMapDataVisibilityAndNotifyObservers() + { + // Setup + var observer1 = mocks.StrictMock(); + var observer2 = mocks.StrictMock(); + observer2.Expect(o => o.UpdateObserver()); + mocks.ReplayAll(); + + var featureBasedMapData1 = new TestFeatureBasedMapData(); + var featureBasedMapData2 = new TestFeatureBasedMapData + { + IsVisible = false + }; + var mapDataCollection = new MapDataCollection("test"); + mapDataCollection.Add(featureBasedMapData1); + mapDataCollection.Add(featureBasedMapData2); + + MapDataCollectionContext context = GetContext(mapDataCollection); + + featureBasedMapData1.Attach(observer1); + featureBasedMapData2.Attach(observer2); + + // Call + info.OnNodeChecked(context, null); + + // Assert + Assert.IsTrue(context.WrappedData.IsVisible); + Assert.IsTrue(featureBasedMapData1.IsVisible); + Assert.IsTrue(featureBasedMapData2.IsVisible); + mocks.VerifyAll(); + } + + [Test] + [TestCase(true, 4)] + [TestCase(false, 3)] + public void OnNodeChecked_WithContext_NotifyObserversOfChangedChildrenOnly(bool initialVisibility, int expectedNotifications) + { + // Setup + var observer = mocks.StrictMock(); + observer.Expect(o => o.UpdateObserver()).Repeat.Times(expectedNotifications); + mocks.ReplayAll(); + + var featureBasedMapData1 = new TestFeatureBasedMapData(); + var featureBasedMapData2 = new TestFeatureBasedMapData + { + IsVisible = initialVisibility + }; + var featureBasedMapData3 = new TestFeatureBasedMapData + { + IsVisible = initialVisibility + }; + var nestedMapDataCollection = new MapDataCollection("nested"); + nestedMapDataCollection.Add(featureBasedMapData1); + nestedMapDataCollection.Add(featureBasedMapData3); + + var mapDataCollection = new MapDataCollection("test"); + mapDataCollection.Add(nestedMapDataCollection); + mapDataCollection.Add(featureBasedMapData2); + + MapDataCollectionContext context = GetContext(mapDataCollection); + + nestedMapDataCollection.Attach(observer); + featureBasedMapData1.Attach(observer); + featureBasedMapData2.Attach(observer); + featureBasedMapData3.Attach(observer); + + // Call + info.OnNodeChecked(context, null); + + // Assert + mocks.VerifyAll(); + } + + [Test] + public void OnNodeChecked_WithContext_NotifyObserversOfParentMapDataCollections() + { + // Setup + var collectionObserver = mocks.StrictMock(); + collectionObserver.Expect(o => o.UpdateObserver()); + var parentCollectionObserver = mocks.StrictMock(); + parentCollectionObserver.Expect(o => o.UpdateObserver()); + mocks.ReplayAll(); + + var featureBasedMapData = new TestFeatureBasedMapData(); + var nestedMapDataCollection = new MapDataCollection("nested"); + nestedMapDataCollection.Add(featureBasedMapData); + var mapDataCollection = new MapDataCollection("test"); + mapDataCollection.Add(nestedMapDataCollection); + + MapDataCollectionContext rootCollectionContext = GetContext(mapDataCollection); + MapDataCollectionContext nestedCollectionContext = GetContext(nestedMapDataCollection, rootCollectionContext); + + nestedMapDataCollection.Attach(collectionObserver); + mapDataCollection.Attach(parentCollectionObserver); + + // Call + info.OnNodeChecked(nestedCollectionContext, null); + + // Assert + mocks.VerifyAll(); + } + + [Test] + public void CanDrag_ParentContextNotNull_ReturnsTrue() + { + // Setup + MapDataCollectionContext context = GetContext(new MapDataCollection("test")); + + // Call + bool canDrag = info.CanDrag(context, null); + + // Assert + Assert.IsTrue(canDrag); + } + + [Test] + public void CanDrag_ParentContextNull_ReturnsFalse() + { + // Setup + var context = new MapDataCollectionContext(new MapDataCollection("test"), null); + + // Call + bool canDrag = info.CanDrag(context, null); + + // Assert + Assert.IsFalse(canDrag); + } + + [Test] + public void CanDrop_TargetIsSameAsSourceParent_ReturnsTrue() + { + // Setup + var mapDataCollection = new MapDataCollection("test 1"); + MapDataCollectionContext context1 = GetContext(mapDataCollection); + MapDataCollectionContext context2 = GetContext(new MapDataCollection("test 2"), context1); + + // Call + bool canDrop = info.CanDrop(context2, context1); + + // Assert + Assert.IsTrue(canDrop); + } + + [Test] + public void CanDrop_TargetParentNotSameAsSourceParent_ReturnsFalse() + { + // Setup + MapDataCollectionContext context = GetContext(new MapDataCollection("test")); + + // Call + bool canDrop = info.CanDrop(context, GetContext(new MapDataCollection("parent"))); + + // Assert + Assert.IsFalse(canDrop); + } + + [Test] + public void CanInsert_TargetParentIsSameAsSourceParent_ReturnsTrue() + { + // Setup + var mapDataCollection = new MapDataCollection("test 1"); + MapDataCollectionContext context1 = GetContext(mapDataCollection); + MapDataCollectionContext context2 = GetContext(new MapDataCollection("test 2"), context1); + + // Call + bool canInsert = info.CanInsert(context2, context1); + + // Assert + Assert.IsTrue(canInsert); + } + + [Test] + public void CanInsert_TargetParentNotSameAsSourceParent_ReturnsFalse() + { + // Setup + MapDataCollectionContext context = GetContext(new MapDataCollection("test")); + + // Call + bool canInsert = info.CanInsert(context, GetContext(new MapDataCollection("parent"))); + + // Assert + Assert.IsFalse(canInsert); + } + + [Test] + [TestCase(0)] + [TestCase(1)] + [TestCase(2)] + public void OnDrop_MapDataCollectionContextMovedToPositionInsideRange_SetsNewReverseOrder(int position) + { + // Setup + var observer = mocks.StrictMock(); + observer.Expect(o => o.UpdateObserver()); + mocks.ReplayAll(); + + var mapDataCollection1 = new MapDataCollection("Collection 1"); + var mapDataCollection2 = new MapDataCollection("Collection 2"); + var mapDataCollection3 = new MapDataCollection("Collection 3"); + var parentMapDataCollection = new MapDataCollection("test data"); + + parentMapDataCollection.Add(mapDataCollection1); + parentMapDataCollection.Add(mapDataCollection2); + parentMapDataCollection.Add(mapDataCollection3); + + MapDataCollectionContext parentContext = GetContext(parentMapDataCollection); + MapDataCollectionContext context = GetContext(mapDataCollection1); + + parentMapDataCollection.Attach(observer); + + using (var treeViewControl = new TreeViewControl()) + { + // Call + info.OnDrop(context, parentContext, parentContext, position, treeViewControl); + + // Assert + int reversedIndex = 2 - position; + Assert.AreSame(context.WrappedData, parentMapDataCollection.Collection.ElementAt(reversedIndex)); + } + } + + [Test] + [TestCase(-50)] + [TestCase(-1)] + [TestCase(4)] + [TestCase(50)] + public void OnDrop_MapDataCollectionContextMovedToPositionOutsideRange_ThrowsException(int position) + { + // Setup + var observer = mocks.StrictMock(); + mocks.ReplayAll(); + + var mapDataCollection1 = new MapDataCollection("Collection 1"); + var mapDataCollection2 = new MapDataCollection("Collection 2"); + var mapDataCollection3 = new MapDataCollection("Collection 3"); + var parentMapDataCollection = new MapDataCollection("test data"); + + parentMapDataCollection.Add(mapDataCollection1); + parentMapDataCollection.Add(mapDataCollection2); + parentMapDataCollection.Add(mapDataCollection3); + + parentMapDataCollection.Attach(observer); + + MapDataCollectionContext parentContext = GetContext(parentMapDataCollection); + MapDataCollectionContext context = GetContext(mapDataCollection1); + + parentMapDataCollection.Attach(observer); + + using (var treeViewControl = new TreeViewControl()) + { + // Call + TestDelegate test = () => info.OnDrop(context, parentContext, parentContext, position, treeViewControl); + + // Assert + Assert.Throws(test); + } + } + + [Test] + public void ContextMenuStrip_Always_CallsBuilder() + { + // Setup + var mapData = new MapDataCollection("test data"); + MapDataCollectionContext context = GetContext(mapData); + + var builder = mocks.StrictMock(); + using (mocks.Ordered()) + { + builder.Expect(mb => mb.AddImportItem(null, null, null)).IgnoreArguments().Return(builder); + builder.Expect(mb => mb.AddSeparator()).Return(builder); + builder.Expect(mb => mb.AddCustomItem(Arg.Is.NotNull)).Return(builder); + builder.Expect(mb => mb.AddSeparator()).Return(builder); + builder.Expect(mb => mb.AddPropertiesItem()).Return(builder); + builder.Expect(mb => mb.Build()).Return(null); + } + + contextMenuBuilderProvider.Expect(p => p.Get(context, null)).Return(builder); + + mocks.ReplayAll(); + + // Call + info.ContextMenuStrip(context, null, null); + + // Assert + // Assert expectancies are called in TearDown() + } + + [Test] + public void ContextMenuStrip_Always_ImportItemEnabled() + { + // Setup + var mapDataCollection = new MapDataCollection("test data"); + MapDataCollectionContext context = GetContext(mapDataCollection); + + var applicationFeatureCommands = mocks.Stub(); + var importCommandHandler = mocks.Stub(); + importCommandHandler.Stub(ich => ich.GetSupportedImportInfos(null)).IgnoreArguments().Return(new[] + { + new ImportInfo() + }); + var exportCommandHandler = mocks.Stub(); + var updateCommandHandler = mocks.Stub(); + var viewCommands = mocks.Stub(); + + using (var treeViewControl = new TreeViewControl()) + { + var builder = new ContextMenuBuilder(applicationFeatureCommands, + importCommandHandler, + exportCommandHandler, + updateCommandHandler, + viewCommands, + mapDataCollection, + treeViewControl); + + contextMenuBuilderProvider.Expect(cmbp => cmbp.Get(context, treeViewControl)).Return(builder); + mocks.ReplayAll(); + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(context, null, treeViewControl)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, contextMenuAddMapLayerIndex, + "&Voeg kaartlaag toe...", + "Importeer een nieuwe kaartlaag en voeg deze toe.", + Resources.MapPlusIcon); + } + } + } + + [Test] + public void ContextMenuStrip_VisibleFeatureBasedMapDataWithFeaturesInMapDataCollection_ZoomToAllItemEnabled() + { + // Setup + var featureBasedMapData = new TestFeatureBasedMapData + { + IsVisible = true, + Features = new[] + { + new MapFeature(Enumerable.Empty()) + } + }; + + var mapDataCollection = new MapDataCollection("test data"); + mapDataCollection.Add(featureBasedMapData); + + using (var treeViewControl = new TreeViewControl()) + { + var builder = new CustomItemsOnlyContextMenuBuilder(); + contextMenuBuilderProvider.Expect(cmbp => cmbp.Get(null, null)).IgnoreArguments().Return(builder); + mocks.ReplayAll(); + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(GetContext(mapDataCollection), null, treeViewControl)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, contextMenuZoomToAllIndex, + "&Zoom naar alles", + "Zet het zoomniveau van de kaart dusdanig dat alle zichtbare kaartlagen in deze map met kaartlagen precies in het beeld passen.", + Resources.ZoomToAllIcon); + } + } + } + + [Test] + public void ContextMenuStrip_InvisibleFeatureBasedMapDataInMapDataCollection_ZoomToAllItemDisabled() + { + // Setup + var featureBasedMapData = new TestFeatureBasedMapData + { + IsVisible = false + }; + var mapDataCollection = new MapDataCollection("test data"); + mapDataCollection.Add(featureBasedMapData); + + using (var treeViewControl = new TreeViewControl()) + { + var builder = new CustomItemsOnlyContextMenuBuilder(); + contextMenuBuilderProvider.Expect(cmbp => cmbp.Get(null, null)).IgnoreArguments().Return(builder); + + mocks.ReplayAll(); + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(GetContext(mapDataCollection), null, treeViewControl)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, contextMenuZoomToAllIndex, + "&Zoom naar alles", + "Om het zoomniveau aan te passen moet er minstens één kaartlaag in deze map met kaartlagen zichtbaar zijn.", + Resources.ZoomToAllIcon, + false); + } + } + } + + [Test] + public void ContextMenuStrip_VisibleFeatureBasedMapDataWithoutFeaturesInMapDataCollection_ZoomToAllItemDisabled() + { + // Setup + var featureBasedMapData = new TestFeatureBasedMapData + { + IsVisible = true + }; + var mapDataCollection = new MapDataCollection("test data"); + mapDataCollection.Add(featureBasedMapData); + + using (var treeViewControl = new TreeViewControl()) + { + var builder = new CustomItemsOnlyContextMenuBuilder(); + contextMenuBuilderProvider.Expect(cmbp => cmbp.Get(null, null)).IgnoreArguments().Return(builder); + mocks.ReplayAll(); + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(GetContext(mapDataCollection), null, treeViewControl)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, contextMenuZoomToAllIndex, + "&Zoom naar alles", + "Om het zoomniveau aan te passen moet minstens één van de zichtbare kaartlagen in deze map met kaartlagen elementen bevatten.", + Resources.ZoomToAllIcon, + false); + } + } + } + + [Test] + public void ContextMenuStrip_EnabledZoomToAllContextMenuItemClicked_DoZoomToVisibleData() + { + // Setup + var mapData = new MapDataCollection("A"); + var featureBasedMapData = new TestFeatureBasedMapData + { + IsVisible = true, + Features = new[] + { + new MapFeature(Enumerable.Empty()) + } + }; + mapData.Add(featureBasedMapData); + + var builder = new CustomItemsOnlyContextMenuBuilder(); + contextMenuBuilderProvider.Stub(p => p.Get(null, null)).IgnoreArguments().Return(builder); + var mapControl = mocks.StrictMock(); + mapControl.Expect(c => c.Data).Return(mapData); + mapControl.Expect(c => c.ZoomToAllVisibleLayers(mapData)); + mocks.ReplayAll(); + + mapLegendView.MapControl = mapControl; + + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(GetContext(mapData), null, null)) + { + // Call + contextMenu.Items[contextMenuZoomToAllIndex].PerformClick(); + + // Assert + // Assert expectancies are called in TearDown() + } + } + + [Test] + public void ContextMenuStrip_NoMapControlAndEnabledZoomToAllContextMenuItemClicked_DoesNotThrow() + { + // Setup + var builder = new CustomItemsOnlyContextMenuBuilder(); + contextMenuBuilderProvider.Stub(p => p.Get(null, null)).IgnoreArguments().Return(builder); + mocks.ReplayAll(); + + var mapData = new MapDataCollection("A") + { + IsVisible = true + }; + + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(GetContext(mapData), null, null)) + { + // Call + TestDelegate call = () => contextMenu.Items[contextMenuZoomToAllIndex].PerformClick(); + + // Assert + Assert.DoesNotThrow(call); + } + } + + public override void Setup() + { + mocks = new MockRepository(); + contextMenuBuilderProvider = mocks.Stub(); + mocks.ReplayAll(); + + mapLegendView = new MapLegendView(contextMenuBuilderProvider); + + var treeViewControl = TypeUtils.GetField(mapLegendView, "treeViewControl"); + var treeNodeInfoLookup = TypeUtils.GetField>(treeViewControl, "tagTypeTreeNodeInfoLookup"); + + info = treeNodeInfoLookup[typeof(MapDataCollectionContext)]; + } + + public override void TearDown() + { + mapLegendView.Dispose(); + + mocks.VerifyAll(); + } + + private static MapDataCollectionContext GetContext(MapDataCollection mapDataCollection, MapDataCollectionContext parentMapDataCollectionContext = null) + { + return new MapDataCollectionContext(mapDataCollection, parentMapDataCollectionContext ?? new MapDataCollectionContext(new MapDataCollection("test"), null)); + } + } +} \ No newline at end of file Index: Core/Gui/test/Core.Gui.Test/Forms/Map/MapLegendViewTest.cs =================================================================== diff -u --- Core/Gui/test/Core.Gui.Test/Forms/Map/MapLegendViewTest.cs (revision 0) +++ Core/Gui/test/Core.Gui.Test/Forms/Map/MapLegendViewTest.cs (revision af6538ce2677998cbc514db20c2756c9dd2eac6f) @@ -0,0 +1,264 @@ +// Copyright (C) Stichting Deltares 2021. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer 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.Threading; +using System.Windows.Forms; +using Core.Common.Controls.TreeView; +using Core.Common.Controls.Views; +using Core.Common.TestUtil; +using Core.Common.Util.Reflection; +using Core.Components.Gis.Data; +using Core.Components.Gis.Forms; +using Core.Components.Gis.TestUtil; +using Core.Gui.ContextMenu; +using Core.Gui.Forms.Map; +using Core.Gui.PresentationObjects.Map; +using NUnit.Framework; +using Rhino.Mocks; + +namespace Core.Gui.Test.Forms.Map +{ + [TestFixture] + public class MapLegendViewTest + { + private MockRepository mocks; + private IContextMenuBuilderProvider contextMenuBuilderProvider; + + [SetUp] + public void SetUp() + { + mocks = new MockRepository(); + contextMenuBuilderProvider = mocks.StrictMock(); + mocks.ReplayAll(); + } + + [TearDown] + public void TearDown() + { + mocks.VerifyAll(); + } + + [Test] + public void Constructor_ContextMenuBuilderProviderAndWindowNotNull_CreatesUserControlAndTreeViewControl() + { + // Call + using (var view = new MapLegendView(contextMenuBuilderProvider)) + { + var treeViewControl = TypeUtils.GetField(view, "treeViewControl"); + + // Assert + Assert.IsInstanceOf(view); + Assert.IsInstanceOf(view); + Assert.IsInstanceOf(view); + Assert.IsNull(view.Data); + Assert.AreEqual("Kaart", view.Text); + Assert.IsNotNull(treeViewControl); + Assert.IsInstanceOf(treeViewControl); + } + } + + [Test] + public void Constructor_ContextMenuBuilderProviderNull_ThrowsArgumentNullException() + { + // Call + TestDelegate test = () => new MapLegendView(null); + + // Assert + const string expectedMessage = "Cannot create a MapLegendView when the context menu builder provider is null."; + TestHelper.AssertThrowsArgumentExceptionAndTestMessage(test, expectedMessage); + } + + [Test] + public void Data_MapDataCollection_DataSet() + { + // Setup + using (var view = new MapLegendView(contextMenuBuilderProvider)) + { + var mapData = new MapDataCollection("test data"); + + // Call + view.Data = mapData; + + // Assert + Assert.IsInstanceOf(view.Data); + var viewData = (MapDataCollectionContext) view.Data; + Assert.AreSame(mapData, viewData.WrappedData); + Assert.IsNull(viewData.ParentMapData); + } + } + + [Test] + public void Data_Null_NullSet() + { + // Setup + using (var view = new MapLegendView(contextMenuBuilderProvider)) + { + // Call + view.Data = null; + + // Assert + Assert.IsNull(view.Data); + } + } + + [Test] + public void Data_OtherObjectType_ThrowsInvalidCastException() + { + // Setup + using (var view = new MapLegendView(contextMenuBuilderProvider)) + { + // Call + TestDelegate test = () => view.Data = new object(); + + // Assert + Assert.Throws(test); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void MapControl_MapControlHasMapWithData_DataReturnsWrappedMapDataOfMap() + { + // Setup + var mapData = new MapDataCollection("A"); + var mockRepository = new MockRepository(); + var mapControl = mockRepository.Stub(); + + mapControl.Expect(mc => mc.Data).Return(mapData); + mockRepository.ReplayAll(); + + using (var view = new MapLegendView(contextMenuBuilderProvider) + { + Data = new MapDataCollection("A") + }) + { + // Call + view.MapControl = mapControl; + + // Assert + Assert.AreSame(mapData, ((MapDataCollectionContext) view.Data).WrappedData); + } + + mockRepository.VerifyAll(); + } + + [Test] + public void MapControl_DataSetAndThenMapControlSetToNull_DataSetToNull() + { + // Setup + using (var view = new MapLegendView(contextMenuBuilderProvider) + { + Data = new MapDataCollection("A") + }) + { + // Call + view.MapControl = null; + + // Assert + Assert.IsNull(view.Data); + } + } + + [Test] + [Apartment(ApartmentState.STA)] + public void Selection_Always_ReturnsDataContext() + { + // Setup + var mapData = new TestFeatureBasedMapData(); + var mapDataCollection = new MapDataCollection("collection"); + + mapDataCollection.Add(mapData); + + using (var view = new MapLegendView(contextMenuBuilderProvider) + { + Data = mapDataCollection + }) + { + var treeViewControl = TypeUtils.GetField(view, "treeViewControl"); + WindowsFormsTestHelper.Show(treeViewControl); + treeViewControl.TrySelectNodeForData(view.Data); + + // Call + var selection = (MapDataCollectionContext) view.Selection; + + // Assert + Assert.AreSame(mapDataCollection, selection.WrappedData); + } + + WindowsFormsTestHelper.CloseAll(); + } + + [Test] + [Apartment(ApartmentState.STA)] + public void GivenMapLegendView_WhenSelectedNodeChanged_SelectionChangedFired() + { + // Given + var mapData = new MapPointData("test"); + var mapDataCollection = new MapDataCollection("collection"); + mapDataCollection.Add(mapData); + + using (var view = new MapLegendView(contextMenuBuilderProvider) + { + Data = mapDataCollection + }) + { + var treeViewControl = TypeUtils.GetField(view, "treeViewControl"); + WindowsFormsTestHelper.Show(treeViewControl); + + var selectionChangedCount = 0; + view.SelectionChanged += (sender, args) => selectionChangedCount++; + + // When + var context = new MapPointDataContext(mapData, new MapDataCollectionContext(mapDataCollection, null)); + treeViewControl.TrySelectNodeForData(context); + + // Then + Assert.AreEqual(1, selectionChangedCount); + } + + WindowsFormsTestHelper.CloseAll(); + } + + [Test] + [Apartment(ApartmentState.STA)] + public void GivenMapLegendView_WhenSettingData_SelectionChangedFired() + { + // Given + using (var view = new MapLegendView(contextMenuBuilderProvider)) + { + var selectionChangedCount = 0; + view.SelectionChanged += (sender, args) => selectionChangedCount++; + + var treeViewControl = TypeUtils.GetField(view, "treeViewControl"); + WindowsFormsTestHelper.Show(treeViewControl); + + // When + view.Data = new MapDataCollection("collection"); + + // Then + Assert.AreEqual(1, selectionChangedCount); + } + + WindowsFormsTestHelper.CloseAll(); + } + } +} \ No newline at end of file Fisheye: Tag af6538ce2677998cbc514db20c2756c9dd2eac6f refers to a dead (removed) revision in file `Core/Plugins/test/Core.Plugins.Map.Test/Legend/FeatureBasedMapDataContextTreeNodeInfoTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag af6538ce2677998cbc514db20c2756c9dd2eac6f refers to a dead (removed) revision in file `Core/Plugins/test/Core.Plugins.Map.Test/Legend/MapDataCollectionContextTreeNodeInfoTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag af6538ce2677998cbc514db20c2756c9dd2eac6f refers to a dead (removed) revision in file `Core/Plugins/test/Core.Plugins.Map.Test/Legend/MapLegendViewTest.cs'. Fisheye: No comparison available. Pass `N' to diff?