Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 8 additions & 21 deletions RubberduckTests/Mocks/MockFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,30 +58,17 @@ internal static Mock<VBE> CreateVbeMock(MockWindowsCollection windows)
{
var vbe = new Mock<VBE>();
windows.VBE = vbe.Object;
vbe.Setup(v => v.Windows).Returns(windows);
vbe.Setup(m => m.Windows).Returns(windows);
vbe.SetupProperty(m => m.ActiveCodePane);
vbe.SetupProperty(m => m.ActiveVBProject);
vbe.SetupGet(m => m.SelectedVBComponent).Returns(() => vbe.Object.ActiveCodePane.CodeModule.Parent);
vbe.SetupGet(m => m.ActiveWindow).Returns(() => vbe.Object.ActiveCodePane.Window);

//setting up a main window lets the native window functions fun
var mainWindow = new Mock<Window>();
mainWindow.Setup(w => w.HWnd).Returns(0);
mainWindow.Setup(m => m.HWnd).Returns(0);

vbe.SetupGet(v => v.MainWindow).Returns(mainWindow.Object);

return vbe;
}

/// <summary>
/// Creates a new <see cref="Mock{VBE}"/> with the <see cref="VBE.Windows"/> and <see cref="VBE.VBProjects"/> properties setup.
/// </summary>
/// <param name="windows">
/// A <see cref="MockWindowsCollection"/> is expected.
/// Other objects implementing the<see cref="Windows"/> interface could cause issues.
/// </param>
/// <param name="projects"><see cref="VBProjects"/> collecction.</param>
/// <returns></returns>
internal static Mock<VBE> CreateVbeMock(MockWindowsCollection windows, VBProjects projects)
{
var vbe = CreateVbeMock(windows);
vbe.SetupGet(v => v.VBProjects).Returns(projects);
vbe.SetupGet(m => m.MainWindow).Returns(mainWindow.Object);

return vbe;
}
Expand Down Expand Up @@ -116,7 +103,7 @@ internal static Mock<CodePane> CreateCodePaneMock(Mock<VBE> vbe, string name)
/// </summary>
/// <param name="code">A block of VBA code.</param>
/// <returns></returns>
internal static Mock<CodeModule> CreateCodeModuleMock(string code)
private static Mock<CodeModule> CreateCodeModuleMock(string code)
{
var lines = code.Split(new[] {Environment.NewLine}, StringSplitOptions.None).ToList();

Expand Down
181 changes: 181 additions & 0 deletions RubberduckTests/Mocks/MockProjectBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Vbe.Interop;
using Moq;

namespace RubberduckTests.Mocks
{
public class MockProjectBuilder
{
private readonly Func<VBE> _getVbe;
private readonly Mock<VBProject> _project;
private readonly Mock<VBComponents> _vbComponents;
private readonly Mock<References> _vbReferences;

private readonly List<Mock<VBComponent>> _components = new List<Mock<VBComponent>>();
private readonly List<Mock<Reference>> _references = new List<Mock<Reference>>();

public MockProjectBuilder(string name, vbext_ProjectProtection protection, Func<VBE> getVbe)
{
_getVbe = getVbe;

_project = CreateProjectMock(name, protection);

_vbComponents = CreateComponentsMock();
_project.SetupGet(m => m.VBComponents).Returns(_vbComponents.Object);

_vbReferences = CreateReferencesMock();
_project.SetupGet(m => m.References).Returns(_vbReferences.Object);
}

public MockProjectBuilder AddComponent(string name, vbext_ComponentType type, string content)
{
var component = CreateComponentMock(name, type, content);
_components.Add(component);

return this;
}

public MockProjectBuilder AddReference(string name, string filePath)
{
_references.Add(CreateReferenceMock(name, filePath));
return this;
}

public Mock<VBProject> Build()
{
return _project;
}

private Mock<VBProject> CreateProjectMock(string name, vbext_ProjectProtection protection)
{
var result = new Mock<VBProject>();

result.SetupProperty(m => m.Name, name);
result.SetupGet(m => m.Protection).Returns(() => protection);
result.SetupGet(m => m.VBE).Returns(_getVbe);

return result;
}

private Mock<VBComponents> CreateComponentsMock()
{
var result = new Mock<VBComponents>();

result.SetupGet(m => m.Parent).Returns(() => _project.Object);
result.SetupGet(m => m.VBE).Returns(_getVbe);

result.Setup(c => c.GetEnumerator()).Returns(() => _components.GetEnumerator());
result.As<IEnumerable>().Setup(c => c.GetEnumerator()).Returns(() => _components.GetEnumerator());

result.Setup(m => m.Item(It.IsAny<int>())).Returns<int>(index => _components[index].Object);
result.Setup(m => m.Item(It.IsAny<string>())).Returns<string>(name => _components.Single(item => item.Object.Name == name).Object);

return result;
}

private Mock<References> CreateReferencesMock()
{
var result = new Mock<References>();

result.SetupGet(m => m.Parent).Returns(() => _project.Object);
result.SetupGet(m => m.VBE).Returns(_getVbe);

result.Setup(m => m.GetEnumerator()).Returns(() => _references.GetEnumerator());
result.As<IEnumerable>().Setup(m => m.GetEnumerator()).Returns(() => _references.GetEnumerator());

result.Setup(m => m.Item(It.IsAny<int>())).Returns<int>(index => _references[index].Object);

return result;
}

private Mock<Reference> CreateReferenceMock(string name, string filePath)
{
var result = new Mock<Reference>();

result.SetupGet(m => m.VBE).Returns(_getVbe);
result.SetupGet(m => m.Collection).Returns(() => _vbReferences.Object);

result.SetupGet(m => m.Name).Returns(() => name);
result.SetupGet(m => m.FullPath).Returns(() => filePath);

return result;
}

private Mock<VBComponent> CreateComponentMock(string name, vbext_ComponentType type, string content)
{
var result = new Mock<VBComponent>();

result.SetupGet(m => m.VBE).Returns(_getVbe);
result.SetupGet(m => m.Collection).Returns(() => _vbComponents.Object);
result.SetupGet(m => m.Type).Returns(() => type);
result.SetupProperty(m => m.Name, name);

var module = CreateCodeModuleMock(name, content);
result.SetupGet(m => m.CodeModule).Returns(() => module.Object);

result.Setup(m => m.Activate());

return result;
}

private Mock<CodeModule> CreateCodeModuleMock(string name, string content)
{
var codePane = CreateCodePaneMock(name);
codePane.SetupGet(m => m.VBE).Returns(_getVbe);

var result = CreateCodeModuleMock(content);
result.SetupGet(m => m.VBE).Returns(_getVbe);
result.SetupGet(m => m.CodePane).Returns(() => codePane.Object);

codePane.SetupGet(m => m.CodeModule).Returns(() => result.Object);
return result;
}

private Mock<CodeModule> CreateCodeModuleMock(string content)
{
var lines = content.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList();

var codeModule = new Mock<CodeModule>();
codeModule.SetupGet(c => c.CountOfLines).Returns(() => lines.Count);

// ReSharper disable once UseIndexedProperty
codeModule.Setup(m => m.get_Lines(It.IsAny<int>(), It.IsAny<int>()))
.Returns<int, int>((start, count) => String.Join(Environment.NewLine, lines.Skip(start - 1).Take(count)));

codeModule.Setup(m => m.ReplaceLine(It.IsAny<int>(), It.IsAny<string>()))
.Callback<int, string>((index, str) => lines[index - 1] = str);

codeModule.Setup(m => m.DeleteLines(It.IsAny<int>(), It.IsAny<int>()))
.Callback<int, int>((index, count) => lines.RemoveRange(index - 1, count));

codeModule.Setup(m => m.InsertLines(It.IsAny<int>(), It.IsAny<string>()))
.Callback<int, string>((index, newLine) => lines.Insert(index - 1, newLine));

return codeModule;
}

private Mock<CodePane> CreateCodePaneMock(string name)
{
var windows = _getVbe().Windows as MockWindowsCollection;
if (windows == null)
{
throw new InvalidOperationException("VBE.Windows collection must be a MockWindowsCollection object.");
}

var codePane = new Mock<CodePane>();
var window = windows.CreateWindow(name);
windows.Add(window);

codePane.Setup(p => p.SetSelection(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<int>()));
codePane.Setup(p => p.Show());

codePane.SetupGet(p => p.VBE).Returns(_getVbe);
codePane.SetupGet(p => p.Window).Returns(() => window);

return codePane;
}
}
}
93 changes: 93 additions & 0 deletions RubberduckTests/Mocks/MockVbeBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Vbe.Interop;
using Moq;

namespace RubberduckTests.Mocks
{
public class MockVbeBuilder
{
private readonly Mock<VBE> _vbe;

private Mock<VBProjects> _vbProjects;
private readonly ICollection<VBProject> _projects = new List<VBProject>();

private Mock<CodePanes> _vbCodePanes;
private readonly ICollection<CodePane> _codePanes = new List<CodePane>();

public MockVbeBuilder()
{
_vbe = CreateVbeMock();
}

public MockVbeBuilder AddProject(Mock<VBProject> project)
{
project.SetupGet(m => m.VBE).Returns(_vbe.Object);
_projects.Add(project.Object);

foreach (var component in _projects.SelectMany(vbProject => vbProject.VBComponents.Cast<VBComponent>()))
{
_codePanes.Add(component.CodeModule.CodePane);
}

return this;
}

public MockProjectBuilder ProjectBuilder(string name, vbext_ProjectProtection protection)
{
var result = new MockProjectBuilder(name, protection, () => _vbe.Object);
return result;
}

public Mock<VBE> Build()
{
return _vbe;
}

private Mock<VBE> CreateVbeMock()
{
var vbe = new Mock<VBE>();
var windows = new MockWindowsCollection {VBE = vbe.Object};
vbe.Setup(m => m.Windows).Returns(windows);
vbe.SetupProperty(m => m.ActiveCodePane);
vbe.SetupProperty(m => m.ActiveVBProject);

vbe.SetupGet(m => m.SelectedVBComponent).Returns(() => vbe.Object.ActiveCodePane.CodeModule.Parent);
vbe.SetupGet(m => m.ActiveWindow).Returns(() => vbe.Object.ActiveCodePane.Window);

var mainWindow = new Mock<Window>();
mainWindow.Setup(m => m.HWnd).Returns(0);

vbe.SetupGet(m => m.MainWindow).Returns(mainWindow.Object);

_vbProjects = CreateProjectsMock();
_vbe.SetupGet(m => m.VBProjects).Returns(() => _vbProjects.Object);

_vbCodePanes = CreateCodePanesMock();
_vbe.SetupGet(m => m.CodePanes).Returns(() => _vbCodePanes.Object);

return vbe;
}

private Mock<VBProjects> CreateProjectsMock()
{
var result = new Mock<VBProjects>();
result.Setup(m => m.GetEnumerator()).Returns(_projects.GetEnumerator());
result.As<IEnumerable>().Setup(m => m.GetEnumerator()).Returns(_projects.GetEnumerator());
result.Setup(m => m.Item(It.IsAny<int>())).Returns<int>(value => _projects.ElementAt(value));

return result;
}

private Mock<CodePanes> CreateCodePanesMock()
{
var result = new Mock<CodePanes>();
result.Setup(m => m.GetEnumerator()).Returns(_codePanes.GetEnumerator());
result.As<IEnumerable>().Setup(m => m.GetEnumerator()).Returns(_codePanes.GetEnumerator());
result.Setup(m => m.Item(It.IsAny<int>())).Returns<int>(value => _codePanes.ElementAt(value));

return result;
}
}
}
6 changes: 3 additions & 3 deletions RubberduckTests/Mocks/MockWindowsCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ internal MockWindowsCollection()
:this(new List<Window>{MockFactory.CreateWindowMock().Object})
{ }

internal MockWindowsCollection(IList<Window> windows)
internal MockWindowsCollection(ICollection<Window> windows)
{
_windows = windows;
}

private readonly IList<Window> _windows;
private readonly ICollection<Window> _windows;

[SuppressMessage("ReSharper", "InconsistentNaming")]
[SuppressMessage("ReSharper", "RedundantAssignment")]
Expand Down Expand Up @@ -97,7 +97,7 @@ public Window Item(object index)
{
if (index is ValueType)
{
return _windows[(int) index];
return _windows.ElementAt((int) index);
}

return _windows.FirstOrDefault(window => window.Caption == index.ToString());
Expand Down
6 changes: 2 additions & 4 deletions RubberduckTests/RubberduckTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,6 @@
<HintPath>..\packages\Ninject.3.2.2.0\lib\net45-full\Ninject.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=3.2.1.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.3.2.1\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Office, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<SpecificVersion>False</SpecificVersion>
<EmbedInteropTypes>True</EmbedInteropTypes>
Expand Down Expand Up @@ -181,8 +177,10 @@
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="Mocks\MockProjectBuilder.cs" />
<Compile Include="Mocks\MockFactory.cs" />
<Compile Include="Mocks\MockWindowsCollection.cs" />
<Compile Include="Mocks\MockVbeBuilder.cs" />
<Compile Include="VbeTestBase.cs" />
<Compile Include="Refactoring\RemoveParametersTests.cs" />
<Compile Include="Refactoring\RenameTests.cs" />
Expand Down
6 changes: 1 addition & 5 deletions RubberduckTests/VbeTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ public abstract class VbeTestBase
public void Initialize()
{
_ide = MockFactory.CreateVbeMock();
_ide.SetupProperty(m => m.ActiveCodePane);
_ide.SetupProperty(m => m.ActiveVBProject);
_ide.SetupGet(m => m.SelectedVBComponent).Returns(() => _ide.Object.ActiveCodePane.CodeModule.Parent);
_ide.SetupGet(m => m.ActiveWindow).Returns(() => _ide.Object.ActiveCodePane.Window);

_projects = new List<VBProject>();
var projects = MockFactory.CreateProjectsMock(_projects);
Expand All @@ -42,7 +38,7 @@ protected QualifiedSelection GetQualifiedSelection(Selection selection)
_ide.Object.ActiveVBProject = _ide.Object.VBProjects.Item(0);
_ide.Object.ActiveCodePane = _ide.Object.ActiveVBProject.VBComponents.Item(0).CodeModule.CodePane;
}
return GetQualifiedSelection(selection, _ide.Object.ActiveCodePane.CodeModule.Parent);
return new QualifiedSelection(new QualifiedModuleName(_ide.Object.ActiveCodePane.CodeModule.Parent), selection);
}

protected QualifiedSelection GetQualifiedSelection(Selection selection, VBComponent component)
Expand Down