Skip to content

Commit 3f5b3bc

Browse files
committed
Merge pull request #711 from rubberduck-vba/GrammarIsFun
Mock UserForm
2 parents 26ab044 + b1d9556 commit 3f5b3bc

File tree

4 files changed

+153
-6
lines changed

4 files changed

+153
-6
lines changed

RubberduckTests/Mocks/MockProjectBuilder.cs

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@
77

88
namespace RubberduckTests.Mocks
99
{
10+
/// <summary>
11+
/// Builds a mock <see cref="VBProject"/>.
12+
/// </summary>
1013
public class MockProjectBuilder
1114
{
1215
private readonly Func<VBE> _getVbe;
1316
private readonly Mock<VBProject> _project;
1417
private readonly Mock<VBComponents> _vbComponents;
1518
private readonly Mock<References> _vbReferences;
1619

17-
private readonly List<Mock<VBComponent>> _components = new List<Mock<VBComponent>>();
18-
private readonly List<Mock<Reference>> _references = new List<Mock<Reference>>();
20+
private readonly ICollection<Mock<VBComponent>> _components = new List<Mock<VBComponent>>();
21+
private readonly ICollection<Mock<Reference>> _references = new List<Mock<Reference>>();
1922

2023
public MockProjectBuilder(string name, vbext_ProjectProtection protection, Func<VBE> getVbe)
2124
{
@@ -30,20 +33,58 @@ public MockProjectBuilder(string name, vbext_ProjectProtection protection, Func<
3033
_project.SetupGet(m => m.References).Returns(_vbReferences.Object);
3134
}
3235

36+
/// <summary>
37+
/// Adds a new component to the project.
38+
/// </summary>
39+
/// <param name="name">The name of the new component.</param>
40+
/// <param name="type">The type of component to create.</param>
41+
/// <param name="content">The VBA code associated to the component.</param>
42+
/// <returns>Returns the <see cref="MockProjectBuilder"/> instance.</returns>
3343
public MockProjectBuilder AddComponent(string name, vbext_ComponentType type, string content)
3444
{
3545
var component = CreateComponentMock(name, type, content);
36-
_components.Add(component);
46+
return AddComponent(component);
47+
}
3748

38-
return this;
49+
/// <summary>
50+
/// Adds a new mock component to the project.
51+
/// Use the <see cref="AddComponent(string,vbext_ComponentType,string)"/> overload to add module components.
52+
/// Use this overload to add user forms created with a <see cref="MockUserFormBuilder"/> instance.
53+
/// </summary>
54+
/// <param name="component">The component to add.</param>
55+
/// <returns>Returns the <see cref="MockProjectBuilder"/> instance.</returns>
56+
public MockProjectBuilder AddComponent(Mock<VBComponent> component)
57+
{
58+
_components.Add(component);
59+
return this;
3960
}
4061

62+
/// <summary>
63+
/// Adds a mock reference to the project.
64+
/// </summary>
65+
/// <param name="name">The name of the referenced library.</param>
66+
/// <param name="filePath">The path to the referenced library.</param>
67+
/// <returns>Returns the <see cref="MockProjectBuilder"/> instance.</returns>
4168
public MockProjectBuilder AddReference(string name, string filePath)
4269
{
4370
_references.Add(CreateReferenceMock(name, filePath));
4471
return this;
4572
}
4673

74+
/// <summary>
75+
/// Creates a <see cref="MockUserFormBuilder"/> to build a new form component.
76+
/// </summary>
77+
/// <param name="name">The name of the component.</param>
78+
/// <param name="content">The VBA code associated to the component.</param>
79+
public MockUserFormBuilder UserFormBuilder(string name, string content)
80+
{
81+
var component = CreateComponentMock(name, vbext_ComponentType.vbext_ct_MSForm, content);
82+
return new MockUserFormBuilder(component);
83+
}
84+
85+
/// <summary>
86+
/// Gets the mock <see cref="VBProject"/> instance.
87+
/// </summary>
4788
public Mock<VBProject> Build()
4889
{
4990
return _project;
@@ -70,8 +111,9 @@ private Mock<VBComponents> CreateComponentsMock()
70111
result.Setup(c => c.GetEnumerator()).Returns(() => _components.GetEnumerator());
71112
result.As<IEnumerable>().Setup(c => c.GetEnumerator()).Returns(() => _components.GetEnumerator());
72113

73-
result.Setup(m => m.Item(It.IsAny<int>())).Returns<int>(index => _components[index].Object);
114+
result.Setup(m => m.Item(It.IsAny<int>())).Returns<int>(index => _components.ElementAt(index).Object);
74115
result.Setup(m => m.Item(It.IsAny<string>())).Returns<string>(name => _components.Single(item => item.Object.Name == name).Object);
116+
result.SetupGet(m => m.Count).Returns(_components.Count);
75117

76118
return result;
77119
}
@@ -86,7 +128,8 @@ private Mock<References> CreateReferencesMock()
86128
result.Setup(m => m.GetEnumerator()).Returns(() => _references.GetEnumerator());
87129
result.As<IEnumerable>().Setup(m => m.GetEnumerator()).Returns(() => _references.GetEnumerator());
88130

89-
result.Setup(m => m.Item(It.IsAny<int>())).Returns<int>(index => _references[index].Object);
131+
result.Setup(m => m.Item(It.IsAny<int>())).Returns<int>(index => _references.ElementAt(index).Object);
132+
result.SetupGet(m => m.Count).Returns(_references.Count);
90133

91134
return result;
92135
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using Microsoft.Vbe.Interop;
6+
using Microsoft.Vbe.Interop.Forms;
7+
using Moq;
8+
9+
namespace RubberduckTests.Mocks
10+
{
11+
/// <summary>
12+
/// Builds a mock <see cref="UserForm"/> component.
13+
/// </summary>
14+
public class MockUserFormBuilder
15+
{
16+
private readonly Mock<VBComponent> _component;
17+
private readonly Mock<Controls> _vbControls;
18+
private readonly ICollection<Mock<Control>> _controls = new List<Mock<Control>>();
19+
20+
public MockUserFormBuilder(Mock<VBComponent> component)
21+
{
22+
if (component.Object.Type != vbext_ComponentType.vbext_ct_MSForm)
23+
{
24+
throw new InvalidOperationException("Component type must be 'vbext_ComponentType.vbext_ct_MSForm'.");
25+
}
26+
27+
_component = component;
28+
_vbControls = CreateControlsMock();
29+
}
30+
31+
/// <summary>
32+
/// Adds a <see cref="Control"/> to the form.
33+
/// </summary>
34+
/// <param name="name">The name of the control to add.</param>
35+
/// <returns></returns>
36+
public MockUserFormBuilder AddControl(string name)
37+
{
38+
var control = new Mock<Control>();
39+
control.SetupProperty(m => m.Name, name);
40+
41+
_controls.Add(control);
42+
return this;
43+
}
44+
45+
/// <summary>
46+
/// Gets the mock <see cref="UserForm"/> component.
47+
/// </summary>
48+
/// <returns></returns>
49+
public Mock<VBComponent> Build()
50+
{
51+
var designer = CreateMockDesigner();
52+
_component.SetupGet(m => m.Designer).Returns(() => designer);
53+
54+
return _component;
55+
}
56+
57+
private Mock<UserForm> CreateMockDesigner()
58+
{
59+
var result = new Mock<UserForm>();
60+
result.SetupGet(m => m.Controls).Returns(() => _vbControls.Object);
61+
62+
return result;
63+
}
64+
65+
private Mock<Controls> CreateControlsMock()
66+
{
67+
var result = new Mock<Controls>();
68+
result.Setup(m => m.GetEnumerator()).Returns(() => _controls.GetEnumerator());
69+
result.As<IEnumerable>().Setup(m => m.GetEnumerator()).Returns(() => _controls.GetEnumerator());
70+
71+
result.Setup(m => m.Item(It.IsAny<int>())).Returns<int>(index => _controls.ElementAt(index).Object);
72+
result.SetupGet(m => m.Count).Returns(_controls.Count);
73+
return result;
74+
}
75+
}
76+
}

RubberduckTests/Mocks/MockVbeBuilder.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
namespace RubberduckTests.Mocks
88
{
9+
/// <summary>
10+
/// Builds a mock <see cref="VBE"/>.
11+
/// </summary>
912
public class MockVbeBuilder
1013
{
1114
private readonly Mock<VBE> _vbe;
@@ -21,6 +24,12 @@ public MockVbeBuilder()
2124
_vbe = CreateVbeMock();
2225
}
2326

27+
/// <summary>
28+
/// Adds a project to the mock VBE.
29+
/// Use a <see cref="MockProjectBuilder"/> to build the <see cref="project"/>.
30+
/// </summary>
31+
/// <param name="project">A mock <see cref="VBProject"/>.</param>
32+
/// <returns>Returns the <see cref="MockVbeBuilder"/> instance.</returns>
2433
public MockVbeBuilder AddProject(Mock<VBProject> project)
2534
{
2635
project.SetupGet(m => m.VBE).Returns(_vbe.Object);
@@ -34,12 +43,20 @@ public MockVbeBuilder AddProject(Mock<VBProject> project)
3443
return this;
3544
}
3645

46+
/// <summary>
47+
/// Creates a <see cref="MockProjectBuilder"/> to build a new project.
48+
/// </summary>
49+
/// <param name="name">The name of the project to build.</param>
50+
/// <param name="protection">A value that indicates whether the project is protected.</param>
3751
public MockProjectBuilder ProjectBuilder(string name, vbext_ProjectProtection protection)
3852
{
3953
var result = new MockProjectBuilder(name, protection, () => _vbe.Object);
4054
return result;
4155
}
4256

57+
/// <summary>
58+
/// Gets the mock <see cref="VBE"/> instance.
59+
/// </summary>
4360
public Mock<VBE> Build()
4461
{
4562
return _vbe;
@@ -73,19 +90,26 @@ private Mock<VBE> CreateVbeMock()
7390
private Mock<VBProjects> CreateProjectsMock()
7491
{
7592
var result = new Mock<VBProjects>();
93+
7694
result.Setup(m => m.GetEnumerator()).Returns(_projects.GetEnumerator());
7795
result.As<IEnumerable>().Setup(m => m.GetEnumerator()).Returns(_projects.GetEnumerator());
96+
7897
result.Setup(m => m.Item(It.IsAny<int>())).Returns<int>(value => _projects.ElementAt(value));
98+
result.SetupGet(m => m.Count).Returns(_projects.Count);
99+
79100

80101
return result;
81102
}
82103

83104
private Mock<CodePanes> CreateCodePanesMock()
84105
{
85106
var result = new Mock<CodePanes>();
107+
86108
result.Setup(m => m.GetEnumerator()).Returns(_codePanes.GetEnumerator());
87109
result.As<IEnumerable>().Setup(m => m.GetEnumerator()).Returns(_codePanes.GetEnumerator());
110+
88111
result.Setup(m => m.Item(It.IsAny<int>())).Returns<int>(value => _codePanes.ElementAt(value));
112+
result.SetupGet(m => m.Count).Returns(_codePanes.Count);
89113

90114
return result;
91115
}

RubberduckTests/RubberduckTests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@
143143
<EmbedInteropTypes>True</EmbedInteropTypes>
144144
<HintPath>..\libs\Microsoft.Vbe.Interop.dll</HintPath>
145145
</Reference>
146+
<Reference Include="Microsoft.Vbe.Interop.Forms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
147+
<EmbedInteropTypes>True</EmbedInteropTypes>
148+
</Reference>
146149
<Reference Include="Moq">
147150
<HintPath>..\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll</HintPath>
148151
</Reference>
@@ -179,6 +182,7 @@
179182
<ItemGroup>
180183
<Compile Include="Mocks\MockProjectBuilder.cs" />
181184
<Compile Include="Mocks\MockFactory.cs" />
185+
<Compile Include="Mocks\MockUserFormBuilder.cs" />
182186
<Compile Include="Mocks\MockWindowsCollection.cs" />
183187
<Compile Include="Mocks\MockVbeBuilder.cs" />
184188
<Compile Include="VbeTestBase.cs" />

0 commit comments

Comments
 (0)