Skip to content

Commit 7bc14f1

Browse files
authored
Merge pull request #3867 from bclothier/FixUnitTestingCheck
Removes host application explicit check for whether unit testing is supported (it is!)
2 parents 45befb8 + 120b280 commit 7bc14f1

File tree

8 files changed

+113
-205
lines changed

8 files changed

+113
-205
lines changed

Rubberduck.Core/UI/Command/AddTestModuleCommand.cs

Lines changed: 67 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
using Rubberduck.Parsing.VBA;
66
using Rubberduck.Settings;
77
using Rubberduck.UnitTesting;
8-
using Rubberduck.VBEditor.Extensions;
98
using Rubberduck.VBEditor.SafeComWrappers;
109
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
1110
using Rubberduck.VBEditor.SafeComWrappers.VBA;
1211
using System.Text;
1312
using Rubberduck.Parsing.Symbols;
13+
using System;
1414

1515
namespace Rubberduck.UI.Command
1616
{
@@ -23,13 +23,15 @@ public class AddTestModuleCommand : CommandBase
2323
private readonly IVBE _vbe;
2424
private readonly RubberduckParserState _state;
2525
private readonly IGeneralConfigService _configLoader;
26+
private readonly IMessageBox _messageBox;
2627

27-
public AddTestModuleCommand(IVBE vbe, RubberduckParserState state, IGeneralConfigService configLoader)
28+
public AddTestModuleCommand(IVBE vbe, RubberduckParserState state, IGeneralConfigService configLoader, IMessageBox messageBox)
2829
: base(LogManager.GetCurrentClassLogger())
2930
{
3031
_vbe = vbe;
3132
_state = state;
3233
_configLoader = configLoader;
34+
_messageBox = messageBox;
3335
}
3436

3537
private readonly string _testModuleEmptyTemplate = new StringBuilder()
@@ -137,7 +139,13 @@ private IVBProject GetProject()
137139

138140
protected override bool EvaluateCanExecute(object parameter)
139141
{
140-
return !GetProject().IsWrappingNullReference && _vbe.HostSupportsUnitTests();
142+
var project = GetProject();
143+
return !project.IsWrappingNullReference && CanExecuteCode(project);
144+
}
145+
146+
private bool CanExecuteCode(IVBProject project)
147+
{
148+
return project.Protection == ProjectProtection.Unprotected;
141149
}
142150

143151
protected override void OnExecute(object parameter)
@@ -159,71 +167,81 @@ protected override void OnExecute(object parameter)
159167
project.EnsureReferenceToAddInLibrary();
160168
}
161169

162-
using(var components = project.VBComponents)
170+
try
163171
{
164-
using (var component = components.Add(ComponentType.StandardModule))
172+
using (var components = project.VBComponents)
165173
{
166-
using (var module = component.CodeModule)
174+
using (var component = components.Add(ComponentType.StandardModule))
167175
{
168-
component.Name = GetNextTestModuleName(project);
169-
170-
var hasOptionExplicit = false;
171-
if (module.CountOfLines > 0 && module.CountOfDeclarationLines > 0)
176+
using (var module = component.CodeModule)
172177
{
173-
hasOptionExplicit = module.GetLines(1, module.CountOfDeclarationLines)
174-
.Contains("Option Explicit");
175-
}
178+
component.Name = GetNextTestModuleName(project);
176179

177-
var options = string.Concat(hasOptionExplicit ? string.Empty : "Option Explicit\r\n",
178-
"Option Private Module\r\n\r\n");
180+
var hasOptionExplicit = false;
181+
if (module.CountOfLines > 0 && module.CountOfDeclarationLines > 0)
182+
{
183+
hasOptionExplicit = module.GetLines(1, module.CountOfDeclarationLines)
184+
.Contains("Option Explicit");
185+
}
179186

180-
if (parameterIsModuleDeclaration)
181-
{
182-
var moduleCodeBuilder = new StringBuilder();
183-
var declarationsToStub = GetDeclarationsToStub((Declaration) parameter);
187+
var options = string.Concat(hasOptionExplicit ? string.Empty : "Option Explicit\r\n",
188+
"Option Private Module\r\n\r\n");
184189

185-
foreach (var declaration in declarationsToStub)
190+
if (parameterIsModuleDeclaration)
186191
{
187-
var name = string.Empty;
192+
var moduleCodeBuilder = new StringBuilder();
193+
var declarationsToStub = GetDeclarationsToStub((Declaration) parameter);
188194

189-
switch (declaration.DeclarationType)
195+
foreach (var declaration in declarationsToStub)
190196
{
191-
case DeclarationType.Procedure:
192-
case DeclarationType.Function:
193-
name = declaration.IdentifierName;
194-
break;
195-
case DeclarationType.PropertyGet:
196-
name = $"Get{declaration.IdentifierName}";
197-
break;
198-
case DeclarationType.PropertyLet:
199-
name = $"Let{declaration.IdentifierName}";
200-
break;
201-
case DeclarationType.PropertySet:
202-
name = $"Set{declaration.IdentifierName}";
203-
break;
197+
var name = string.Empty;
198+
199+
switch (declaration.DeclarationType)
200+
{
201+
case DeclarationType.Procedure:
202+
case DeclarationType.Function:
203+
name = declaration.IdentifierName;
204+
break;
205+
case DeclarationType.PropertyGet:
206+
name = $"Get{declaration.IdentifierName}";
207+
break;
208+
case DeclarationType.PropertyLet:
209+
name = $"Let{declaration.IdentifierName}";
210+
break;
211+
case DeclarationType.PropertySet:
212+
name = $"Set{declaration.IdentifierName}";
213+
break;
214+
}
215+
216+
var stub = AddTestMethodCommand.TestMethodTemplate.Replace(
217+
AddTestMethodCommand.NamePlaceholder, $"{name}_Test");
218+
moduleCodeBuilder.AppendLine(stub);
204219
}
205220

206-
var stub = AddTestMethodCommand.TestMethodTemplate.Replace(
207-
AddTestMethodCommand.NamePlaceholder, $"{name}_Test");
208-
moduleCodeBuilder.AppendLine(stub);
221+
module.AddFromString(options + GetTestModule(settings) + moduleCodeBuilder);
209222
}
223+
else
224+
{
225+
var defaultTestMethod = settings.DefaultTestStubInNewModule
226+
? AddTestMethodCommand.TestMethodTemplate.Replace(
227+
AddTestMethodCommand.NamePlaceholder,
228+
"TestMethod1")
229+
: string.Empty;
210230

211-
module.AddFromString(options + GetTestModule(settings) + moduleCodeBuilder);
231+
module.AddFromString(options + GetTestModule(settings) + defaultTestMethod);
232+
}
212233
}
213-
else
214-
{
215-
var defaultTestMethod = settings.DefaultTestStubInNewModule
216-
? AddTestMethodCommand.TestMethodTemplate.Replace(AddTestMethodCommand.NamePlaceholder,
217-
"TestMethod1")
218-
: string.Empty;
219234

220-
module.AddFromString(options + GetTestModule(settings) + defaultTestMethod);
221-
}
235+
component.Activate();
222236
}
223-
224-
component.Activate();
225237
}
226238
}
239+
catch (Exception ex)
240+
{
241+
_messageBox.Show(RubberduckUI.Command_AddTestModule_Error);
242+
Logger.Warn("Unable to add test module. An exception was thrown.");
243+
Logger.Warn(ex);
244+
}
227245
_state.OnParseRequested(this);
228246
}
229247

Rubberduck.Core/UI/RubberduckUI.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Rubberduck.Core/UI/RubberduckUI.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,4 +1809,7 @@ NOTE: Restart is required for the setting to take effect.</value>
18091809
<data name="GeneralSettings_CompileBeforeParse_WarnCompileOnDemandEnabled_Caption" xml:space="preserve">
18101810
<value>Compile On Demand currently enabled</value>
18111811
</data>
1812+
<data name="Command_AddTestModule_Error" xml:space="preserve">
1813+
<value>Unable to create test module. The host application may not allow for creation of new modules or the project may be locked. For details, check the log.</value>
1814+
</data>
18121815
</root>

Rubberduck.Core/UI/UnitTesting/TestExplorerViewModel.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@ public class TestExplorerViewModel : ViewModelBase, INavigateSelection, IDisposa
2323
private readonly ITestEngine _testEngine;
2424
private readonly IClipboardWriter _clipboard;
2525
private readonly ISettingsFormFactory _settingsFormFactory;
26-
//private readonly IGeneralConfigService _configService;
27-
//private readonly IOperatingSystem _operatingSystem;
26+
private readonly IMessageBox _messageBox;
2827

2928
public TestExplorerViewModel(IVBE vbe,
3029
RubberduckParserState state,
3130
ITestEngine testEngine,
3231
TestExplorerModel model,
3332
IClipboardWriter clipboard,
3433
IGeneralConfigService configService,
35-
ISettingsFormFactory settingsFormFactory)
34+
ISettingsFormFactory settingsFormFactory,
35+
IMessageBox messageBox)
3636
{
3737
_vbe = vbe;
3838
_state = state;
@@ -41,13 +41,14 @@ public TestExplorerViewModel(IVBE vbe,
4141
Model = model;
4242
_clipboard = clipboard;
4343
_settingsFormFactory = settingsFormFactory;
44+
_messageBox = messageBox;
4445

4546
_navigateCommand = new NavigateCommand(_state.ProjectsProvider);
4647

4748
RunAllTestsCommand = new RunAllTestsCommand(vbe, state, testEngine, model, null);
4849
RunAllTestsCommand.RunCompleted += RunCompleted;
4950

50-
AddTestModuleCommand = new AddTestModuleCommand(vbe, state, configService);
51+
AddTestModuleCommand = new AddTestModuleCommand(vbe, state, configService, _messageBox);
5152
AddTestMethodCommand = new AddTestMethodCommand(vbe, state);
5253
AddErrorTestMethodCommand = new AddTestMethodExpectedErrorCommand(vbe, state);
5354

Rubberduck.VBEEditor/Extensions/IDEExtensions.cs

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -139,71 +139,6 @@ public static IHostApplication HostApplication(this IVBE vbe)
139139

140140
return null;
141141
}
142-
143-
/// <summary> Returns whether the host supports unit tests.</summary>
144-
public static bool HostSupportsUnitTests(this IVBE vbe)
145-
{
146-
var host = Path.GetFileName(System.Windows.Forms.Application.ExecutablePath).ToUpperInvariant();
147-
if (HostAppMap.ContainsKey(host)) return true;
148-
//Guessing the above will work like 99.9999% of the time for supported applications.
149-
150-
var project = vbe.ActiveVBProject;
151-
{
152-
if (project.IsWrappingNullReference)
153-
{
154-
const int ctlViewHost = 106;
155-
var commandBars = vbe.CommandBars;
156-
var hostAppControl = commandBars.FindControl(ControlType.Button, ctlViewHost);
157-
{
158-
if (hostAppControl.IsWrappingNullReference)
159-
{
160-
return false;
161-
}
162-
163-
switch (hostAppControl.Caption)
164-
{
165-
case "Microsoft Excel":
166-
case "Microsoft Access":
167-
case "Microsoft Word":
168-
case "Microsoft PowerPoint":
169-
case "Microsoft Outlook":
170-
case "Microsoft Project":
171-
case "Microsoft Publisher":
172-
case "Microsoft Visio":
173-
case "AutoCAD":
174-
case "CorelDRAW":
175-
case "SolidWorks":
176-
return true;
177-
default:
178-
return false;
179-
}
180-
}
181-
}
182-
183-
var references = project.References;
184-
{
185-
foreach (var reference in references.Where(reference => (reference.IsBuiltIn && reference.Name != "VBA") || (reference.Name == "AutoCAD")))
186-
{
187-
switch (reference.Name)
188-
{
189-
case "Excel":
190-
case "Access":
191-
case "Word":
192-
case "PowerPoint":
193-
case "Outlook":
194-
case "MSProject":
195-
case "Publisher":
196-
case "Visio":
197-
case "AutoCAD":
198-
case "CorelDRAW":
199-
case "SolidWorks":
200-
return true;
201-
}
202-
}
203-
}
204-
}
205-
return false;
206-
}
207142
}
208143

209144
public static class VBProjectExtensions

Rubberduck.VBEEditor/SafeComWrappers/VBA/VBE.cs

Lines changed: 1 addition & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -322,75 +322,7 @@ public IWindow ActiveMDIChild()
322322
}
323323
return null;
324324
}
325-
326-
/// <summary> Returns whether the host supports unit tests.</summary>
327-
public bool HostSupportsUnitTests()
328-
{
329-
var host = Path.GetFileName(System.Windows.Forms.Application.ExecutablePath).ToUpperInvariant();
330-
if (HostAppMap.ContainsKey(host))
331-
{
332-
return true;
333-
}
334-
//Guessing the above will work like 99.9999% of the time for supported applications.
335-
336-
var project = ActiveVBProject;
337-
{
338-
if (project.IsWrappingNullReference)
339-
{
340-
const int ctlViewHost = 106;
341-
var commandBars = CommandBars;
342-
var hostAppControl = commandBars.FindControl(ControlType.Button, ctlViewHost);
343-
{
344-
if (hostAppControl.IsWrappingNullReference)
345-
{
346-
return false;
347-
}
348-
349-
switch (hostAppControl.Caption)
350-
{
351-
case "Microsoft Excel":
352-
case "Microsoft Access":
353-
case "Microsoft Word":
354-
case "Microsoft PowerPoint":
355-
case "Microsoft Outlook":
356-
case "Microsoft Project":
357-
case "Microsoft Publisher":
358-
case "Microsoft Visio":
359-
case "AutoCAD":
360-
case "CorelDRAW":
361-
case "SolidWorks":
362-
return true;
363-
default:
364-
return false;
365-
}
366-
}
367-
}
368-
369-
var references = project.References;
370-
{
371-
foreach (var reference in references.Where(reference => (reference.IsBuiltIn && reference.Name != "VBA") || (reference.Name == "AutoCAD")))
372-
{
373-
switch (reference.Name)
374-
{
375-
case "Excel":
376-
case "Access":
377-
case "Word":
378-
case "PowerPoint":
379-
case "Outlook":
380-
case "MSProject":
381-
case "Publisher":
382-
case "Visio":
383-
case "AutoCAD":
384-
case "CorelDRAW":
385-
case "SolidWorks":
386-
return true;
387-
}
388-
}
389-
}
390-
}
391-
return false;
392-
}
393-
325+
394326
public QualifiedSelection? GetActiveSelection()
395327
{
396328
using (var activePane = ActiveCodePane)

0 commit comments

Comments
 (0)