diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/StandardMenuStripVerb.cs b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/StandardMenuStripVerb.cs index 1cfdc63350f..993a7fffe0b 100644 --- a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/StandardMenuStripVerb.cs +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/StandardMenuStripVerb.cs @@ -27,9 +27,8 @@ internal class StandardMenuStripVerb /// internal StandardMenuStripVerb(ToolStripDesigner designer) { - Debug.Assert(designer is not null, "Can't have a StandardMenuStripVerb without an associated designer"); - _designer = designer; - _provider = designer.Component.Site; + _designer = designer.OrThrowIfNull(); + _provider = designer.Component.Site.OrThrowIfNull(); _host = (IDesignerHost)_provider.GetService(typeof(IDesignerHost)); _changeService = (IComponentChangeService)_provider.GetService(typeof(IComponentChangeService)); } diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/StandardMenuStripVerbTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/StandardMenuStripVerbTests.cs new file mode 100644 index 00000000000..d38ef325909 --- /dev/null +++ b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/StandardMenuStripVerbTests.cs @@ -0,0 +1,148 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.ComponentModel; +using System.ComponentModel.Design; +using System.ComponentModel.Design.Serialization; +using System.Windows.Forms.Design.Behavior; +using Moq; + +namespace System.Windows.Forms.Design.Tests; +public class StandardMenuStripVerbTests : IDisposable +{ + private readonly Mock _designerHostMock = new(); + private readonly Mock _serviceProviderMock = new(); + private readonly Mock _selectionServiceMock = new(); + private readonly Mock _componentChangeServiceMock = new(); + private readonly Mock _siteMock = new(); + private readonly Mock _mockTransaction = new(MockBehavior.Loose); + + private readonly DesignerFrame _designerFrame; + private readonly SelectionManager _selectionManager; + private readonly BehaviorService _behaviorService; + private readonly DesignerActionUIService _designerActionUIService; + + private readonly ToolStripDesigner _designer = new(); + private readonly ParentControlDesigner _parentControlDesigner = new(); + private readonly MenuStrip _menuStrip = new(); + + public StandardMenuStripVerbTests() + { + _siteMock.Setup(s => s.GetService(typeof(INestedContainer))).Returns(new Mock().Object); + _siteMock.Setup(s => s.Container).Returns(new Mock().Object as IContainer); + _siteMock.Setup(s => s.GetService(typeof(UndoEngine))).Returns(null!); + _siteMock.Setup(s => s.GetService(typeof(IDesignerHost))).Returns(_designerHostMock.Object); + _siteMock.Setup(s => s.GetService(typeof(IComponentChangeService))).Returns(_componentChangeServiceMock.Object); + + _designerFrame = new(_siteMock.Object); + _behaviorService = new(_serviceProviderMock.Object, _designerFrame); + _siteMock.Setup(s => s.GetService(typeof(BehaviorService))).Returns(_behaviorService); + _siteMock.Setup(s => s.GetService(typeof(ToolStripAdornerWindowService))).Returns(null!); + _siteMock.Setup(s => s.GetService(typeof(DesignerActionService))).Returns(new Mock(_siteMock.Object).Object); + + Mock nameCreationServiceMock = new(); + nameCreationServiceMock.Setup(n => n.IsValidName(It.IsAny())).Returns(true); + _siteMock.Setup(s => s.GetService(typeof(INameCreationService))).Returns(nameCreationServiceMock.Object); + _designerActionUIService = new(_siteMock.Object); + _siteMock.Setup(s => s.GetService(typeof(DesignerActionUIService))).Returns(_designerActionUIService); + + _serviceProviderMock.Setup(s => s.GetService(typeof(IDesignerHost))).Returns(_designerHostMock.Object); + _serviceProviderMock.Setup(s => s.GetService(typeof(IComponentChangeService))).Returns(new Mock().Object); + + _designerHostMock.Setup(h => h.RootComponent).Returns(_menuStrip); + _designerHostMock.Setup(h => h.CreateTransaction(It.IsAny())).Returns(_mockTransaction.Object); + _designerHostMock.Setup(h => h.GetService(typeof(IComponentChangeService))).Returns(_componentChangeServiceMock.Object); + _designerHostMock.Setup(h => h.AddService(typeof(ToolStripKeyboardHandlingService), It.IsAny())); + _designerHostMock.Setup(h => h.AddService(typeof(ISupportInSituService), It.IsAny())); + _designerHostMock.Setup(h => h.AddService(typeof(DesignerActionService), It.IsAny())); + _designerHostMock.Setup(h => h.GetDesigner(_menuStrip)).Returns(_parentControlDesigner); + _designerHostMock.Setup(h => h.AddService(typeof(DesignerActionUIService), It.IsAny())); + Mock toolStripMenuItemMock = new(); + using ToolStripDropDownMenu toolStripDropDownMenu = new(); + toolStripMenuItemMock.Object.DropDown = toolStripDropDownMenu; + + string[] menuItemImageNames = + [ + "file", "new", "open", "save", "saveAs", "print", "printPreview", "cut", "copy", "paste", "undo", "redo", + "delete", "selectAll", "edit", "exit", "saveAs", "saveAll", "tool", "tools", "customize", "options", "help", + "contents", "index", "search", "about", "cut", "copy", "Paste", "undo", "redo" + ]; + + foreach (string item in menuItemImageNames) + { + _designerHostMock.Setup(h => h.CreateComponent(typeof(ToolStripMenuItem), item + "ToolStripMenuItem")).Returns(toolStripMenuItemMock.Object); + } + + _designerHostMock.Setup(h => h.CreateComponent(typeof(ToolStripSeparator), "toolStripSeparator")).Returns(new Mock().Object); + _selectionServiceMock.Setup(s => s.GetComponentSelected(_menuStrip)).Returns(true); + _siteMock.Setup(s => s.GetService(typeof(ISelectionService))).Returns(_selectionServiceMock.Object); + _designerHostMock.Setup(h => h.AddService(typeof(ISelectionService), _selectionServiceMock.Object)); + _serviceProviderMock.Setup(s => s.GetService(typeof(ISelectionService))).Returns(_selectionServiceMock.Object); + _selectionManager = new(_serviceProviderMock.Object, _behaviorService!); + _siteMock.Setup(s => s.GetService(typeof(SelectionManager))).Returns(_selectionManager); + + _menuStrip.Site = _siteMock.Object; + + _designer.Initialize(_menuStrip); + _parentControlDesigner.Initialize(_menuStrip); + + IComponent[] components = []; + ComponentCollection componentCollection = new(components); + _selectionServiceMock.Setup(s => s.GetSelectedComponents()).Returns(components); + + Mock containerMock = new(); + containerMock.Setup(c => c.Components).Returns(componentCollection); + _designerHostMock.Setup(d => d.Container).Returns(containerMock.Object); + } + + public void Dispose() + { + _menuStrip?.Dispose(); + _parentControlDesigner.Dispose(); + _behaviorService?.Dispose(); + _selectionManager?.Dispose(); + _designerFrame.Dispose(); + _designer.Dispose(); + } + + [WinFormsFact] + public void StandardMenuStripVerb_Ctor() + { + StandardMenuStripVerb standardMenuStripVerb = new(_designer); + standardMenuStripVerb.Should().BeOfType(); + ToolStripDesigner toolStripDesigner = standardMenuStripVerb.TestAccessor().Dynamic._designer; + toolStripDesigner.Should().Be(_designer); + } + + [WinFormsFact] + public void Ctor_ThrowsIfDesignerIsNull() + { + Action action = () => new StandardMenuStripVerb(null); + action.Should().Throw(); + } + + [WinFormsFact] + public void Ctor_ThrowsIfComponentOrSiteIsNull() + { + Action action = () => + { + ToolStripDesigner toolStripDesigner = new(); + toolStripDesigner.Initialize(new MenuStrip()); + + new StandardMenuStripVerb(toolStripDesigner); + }; + + action.Should().Throw(); + } + + [WinFormsFact] + public void Ctor_AssignsHostAndChangeServiceIfAvailable() + { + StandardMenuStripVerb standardMenuStripVerb = new(_designer); + IDesignerHost host = standardMenuStripVerb.TestAccessor().Dynamic._host; + IComponentChangeService changeService = standardMenuStripVerb.TestAccessor().Dynamic._changeService; + + host.Should().BeSameAs(_designerHostMock.Object); + changeService.Should().BeSameAs(_componentChangeServiceMock.Object); + } +}