Skip to content

Commit 5d908dd

Browse files
authored
Add code coverage for ControlCommandSet.cs file (#13130)
Related #10773 ## Proposed changes - Add unit test file: ControlCommandSetTests.cs for public methods and 2 protected methods of the ControlCommandSet.cs. ###### Microsoft Reviewers: [Open in CodeFlow](https://microsoft.github.io/open-pr/?codeflow=https://github.com/dotnet/winforms/pull/13130)
2 parents b01d566 + 7b13805 commit 5d908dd

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.ComponentModel;
5+
using System.ComponentModel.Design;
6+
using System.Drawing;
7+
using Moq;
8+
9+
namespace System.Windows.Forms.Design.Tests;
10+
11+
public class ControlCommandSetTests : IDisposable
12+
{
13+
private readonly Mock<ISite> _siteMock;
14+
private readonly Mock<IDesignerHost> _designerHostMock;
15+
private readonly Mock<IMenuCommandService> _menuServiceMock;
16+
private readonly Mock<IEventHandlerService> _eventHandlerServiceMock;
17+
private readonly Mock<ISelectionService> _selectionServiceMock;
18+
private readonly Mock<IDictionaryService> _dictionaryServiceMock;
19+
private readonly ControlCommandSet _controlCommandSet;
20+
private readonly Control _baseControl;
21+
22+
public ControlCommandSetTests()
23+
{
24+
_siteMock = new();
25+
_designerHostMock = new();
26+
_menuServiceMock = new();
27+
_eventHandlerServiceMock = new();
28+
_selectionServiceMock = new();
29+
_dictionaryServiceMock = new();
30+
_baseControl = new();
31+
32+
_siteMock.Setup(s => s.GetService(typeof(IDesignerHost))).Returns(_designerHostMock.Object);
33+
_siteMock.Setup(s => s.GetService(typeof(IMenuCommandService))).Returns(_menuServiceMock.Object);
34+
_siteMock.Setup(s => s.GetService(typeof(IEventHandlerService))).Returns(_eventHandlerServiceMock.Object);
35+
_siteMock.Setup(s => s.GetService(typeof(ISelectionService))).Returns(_selectionServiceMock.Object);
36+
_siteMock.Setup(s => s.GetService(typeof(IDictionaryService))).Returns(_dictionaryServiceMock.Object);
37+
_designerHostMock.Setup(h => h.RootComponent).Returns(_baseControl);
38+
39+
_controlCommandSet = new(_siteMock.Object);
40+
}
41+
42+
public void Dispose()
43+
{
44+
_controlCommandSet.Dispose();
45+
_baseControl.Dispose();
46+
}
47+
48+
[Fact]
49+
public void Constructor_ShouldInitializeCommandSet()
50+
{
51+
_controlCommandSet.Should().NotBeNull();
52+
53+
StatusCommandUI statusCommandUI = _controlCommandSet.TestAccessor().Dynamic._statusCommandUI;
54+
statusCommandUI.Should().NotBeNull();
55+
56+
MenuCommand[] commandSet = _controlCommandSet.TestAccessor().Dynamic._commandSet;
57+
commandSet.Should().NotBeNull();
58+
commandSet.Should().NotBeEmpty();
59+
60+
TabOrder tabOrder = _controlCommandSet.TestAccessor().Dynamic._tabOrder;
61+
tabOrder.Should().BeNull();
62+
}
63+
64+
[Fact]
65+
public void Dispose_ShouldRemoveCommandsFromMenuService()
66+
{
67+
_controlCommandSet.Dispose();
68+
69+
_menuServiceMock.Verify(m => m.RemoveCommand(It.IsAny<MenuCommand>()), Times.AtLeastOnce);
70+
}
71+
72+
[Fact]
73+
public void OnMenuLockControls_ShouldToggleLockControls()
74+
{
75+
using Control component = new();
76+
Mock<IContainer> containerMock = new();
77+
_siteMock.Setup(s => s.Container).Returns(containerMock.Object);
78+
component.Site = _siteMock.Object;
79+
80+
_designerHostMock.Setup(h => h.RootComponent).Returns(_baseControl);
81+
_designerHostMock.Setup(h => h.Container.Components).Returns(new ComponentCollection([component]));
82+
83+
CommandID commandID = new(Guid.NewGuid(), 0);
84+
MenuCommand menuCommand = new(null, commandID) { Checked = false };
85+
86+
_controlCommandSet.TestAccessor().Dynamic.OnMenuLockControls(menuCommand, EventArgs.Empty);
87+
88+
menuCommand.Checked.Should().BeTrue();
89+
}
90+
91+
[Fact]
92+
public void GetSnapInformation_WithSnapToGridPropertyInParent_ShouldReturnThatProperty()
93+
{
94+
using Control childComponent = new();
95+
using Control parentComponent = new();
96+
97+
childComponent.Parent = parentComponent;
98+
99+
Mock<IContainer> containerMock = new();
100+
_siteMock.Setup(s => s.Container).Returns(containerMock.Object);
101+
childComponent.Site = _siteMock.Object;
102+
parentComponent.Site = _siteMock.Object;
103+
104+
_designerHostMock.Setup(h => h.RootComponent).Returns(_baseControl);
105+
106+
Mock<IDesigner> designerMock = new();
107+
designerMock.Setup(d => d.Component).Returns(childComponent);
108+
_designerHostMock.Setup(h => h.GetDesigner(childComponent)).Returns(designerMock.Object);
109+
110+
Mock<PropertyDescriptor> snapPropertyDescriptorMock = new("SnapToGrid", Array.Empty<Attribute>());
111+
snapPropertyDescriptorMock.Setup(p => p.PropertyType).Returns(typeof(bool));
112+
snapPropertyDescriptorMock.Setup(p => p.ComponentType).Returns(typeof(Control));
113+
snapPropertyDescriptorMock.Setup(p => p.Name).Returns("SnapToGrid");
114+
115+
var originalProvider = TypeDescriptor.GetProvider(parentComponent);
116+
var mockProvider = new MockTypeDescriptionProvider(originalProvider, snapPropertyDescriptorMock.Object);
117+
TypeDescriptor.AddProvider(mockProvider, parentComponent);
118+
119+
try
120+
{
121+
_controlCommandSet.TestAccessor().Dynamic.GetSnapInformation(
122+
_designerHostMock.Object,
123+
childComponent,
124+
out Size snapSize,
125+
out IComponent snapComponent,
126+
out PropertyDescriptor snapProperty);
127+
128+
snapComponent.Should().Be(parentComponent);
129+
snapProperty.Should().NotBeNull();
130+
snapProperty.Name.Should().Be("SnapToGrid");
131+
snapSize.Should().Be(Size.Empty);
132+
}
133+
finally
134+
{
135+
TypeDescriptor.RemoveProvider(mockProvider, parentComponent);
136+
}
137+
}
138+
139+
/// <summary>
140+
/// Helper class to provide mock property descriptors.
141+
/// </summary>
142+
private class MockTypeDescriptionProvider : TypeDescriptionProvider
143+
{
144+
private readonly TypeDescriptionProvider _baseProvider;
145+
private readonly PropertyDescriptor _snapToGridProperty;
146+
147+
public MockTypeDescriptionProvider(TypeDescriptionProvider baseProvider, PropertyDescriptor snapToGridProperty)
148+
{
149+
_baseProvider = baseProvider;
150+
_snapToGridProperty = snapToGridProperty;
151+
}
152+
153+
public override ICustomTypeDescriptor? GetTypeDescriptor(Type objectType, object? instance)
154+
{
155+
var baseDescriptor = _baseProvider.GetTypeDescriptor(objectType, instance);
156+
return baseDescriptor is not null ? new MockCustomTypeDescriptor(baseDescriptor, _snapToGridProperty) : null;
157+
}
158+
}
159+
160+
private class MockCustomTypeDescriptor : CustomTypeDescriptor
161+
{
162+
private readonly PropertyDescriptor _snapToGridProperty;
163+
164+
public MockCustomTypeDescriptor(ICustomTypeDescriptor parent, PropertyDescriptor snapToGridProperty)
165+
: base(parent)
166+
{
167+
_snapToGridProperty = snapToGridProperty;
168+
}
169+
170+
public override PropertyDescriptorCollection GetProperties()
171+
{
172+
PropertyDescriptorCollection baseProperties = base.GetProperties();
173+
174+
PropertyDescriptor[] allProperties = new PropertyDescriptor[baseProperties.Count + 1];
175+
baseProperties.CopyTo(allProperties, 0);
176+
allProperties[baseProperties.Count] = _snapToGridProperty;
177+
178+
return new PropertyDescriptorCollection(allProperties);
179+
}
180+
181+
public override PropertyDescriptorCollection GetProperties(Attribute[]? attributes)
182+
{
183+
PropertyDescriptorCollection baseProperties = base.GetProperties(attributes);
184+
185+
PropertyDescriptor[] allProperties = new PropertyDescriptor[baseProperties.Count + 1];
186+
baseProperties.CopyTo(allProperties, 0);
187+
allProperties[baseProperties.Count] = _snapToGridProperty;
188+
189+
return new PropertyDescriptorCollection(allProperties);
190+
}
191+
}
192+
}

0 commit comments

Comments
 (0)