Skip to content

Commit eb24483

Browse files
Hosch250retailcoder
authored andcommitted
Unit test tweaks (#1533)
* Disable commands when the parser state isn't ready. * No reparse between adding a module and the default stub. * Disable Add Test Method commands if the selected component is not a test module. * Close #1102
1 parent e79bde4 commit eb24483

16 files changed

+203
-105
lines changed

RetailCoder.VBE/UI/Command/AddTestMethodCommand.cs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
using System.Linq;
12
using System.Runtime.InteropServices;
2-
using Rubberduck.UI.UnitTesting;
3+
using Microsoft.Vbe.Interop;
4+
using Rubberduck.Parsing.Annotations;
5+
using Rubberduck.Parsing.Symbols;
6+
using Rubberduck.Parsing.VBA;
37
using Rubberduck.UnitTesting;
48

59
namespace Rubberduck.UI.Command
@@ -10,11 +14,26 @@ namespace Rubberduck.UI.Command
1014
[ComVisible(false)]
1115
public class AddTestMethodCommand : CommandBase
1216
{
17+
private readonly VBE _vbe;
1318
private readonly NewTestMethodCommand _command;
19+
private readonly RubberduckParserState _state;
1420

15-
public AddTestMethodCommand(NewTestMethodCommand command)
21+
public AddTestMethodCommand(VBE vbe, RubberduckParserState state, NewTestMethodCommand command)
1622
{
23+
_vbe = vbe;
1724
_command = command;
25+
_state = state;
26+
}
27+
28+
public override bool CanExecute(object parameter)
29+
{
30+
if (_state.Status != ParserState.Ready) { return false; }
31+
32+
var testModules = _state.AllUserDeclarations.Where(d =>
33+
d.DeclarationType == DeclarationType.ProceduralModule &&
34+
d.Annotations.Any(a => a.AnnotationType == AnnotationType.TestModule));
35+
36+
return testModules.Any(a => a.QualifiedName.QualifiedModuleName.Component == _vbe.SelectedVBComponent);
1837
}
1938

2039
public override void Execute(object parameter)

RetailCoder.VBE/UI/Command/AddTestMethodExpectedErrorCommand.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
using System.Linq;
12
using System.Runtime.InteropServices;
3+
using Microsoft.Vbe.Interop;
4+
using Rubberduck.Parsing.Annotations;
5+
using Rubberduck.Parsing.Symbols;
6+
using Rubberduck.Parsing.VBA;
27
using Rubberduck.UnitTesting;
38

49
namespace Rubberduck.UI.Command
@@ -9,11 +14,26 @@ namespace Rubberduck.UI.Command
914
[ComVisible(false)]
1015
public class AddTestMethodExpectedErrorCommand : CommandBase
1116
{
17+
private readonly VBE _vbe;
1218
private readonly NewTestMethodCommand _command;
19+
private readonly RubberduckParserState _state;
1320

14-
public AddTestMethodExpectedErrorCommand(NewTestMethodCommand command)
21+
public AddTestMethodExpectedErrorCommand(VBE vbe, RubberduckParserState state, NewTestMethodCommand command)
1522
{
23+
_vbe = vbe;
1624
_command = command;
25+
_state = state;
26+
}
27+
28+
public override bool CanExecute(object parameter)
29+
{
30+
if (_state.Status != ParserState.Ready) { return false; }
31+
32+
var testModules = _state.AllUserDeclarations.Where(d =>
33+
d.DeclarationType == DeclarationType.ProceduralModule &&
34+
d.Annotations.Any(a => a.AnnotationType == AnnotationType.TestModule));
35+
36+
return testModules.Any(a => a.QualifiedName.QualifiedModuleName.Component == _vbe.SelectedVBComponent);
1737
}
1838

1939
public override void Execute(object parameter)

RetailCoder.VBE/UI/Command/AddTestModuleCommand.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Runtime.InteropServices;
22
using Microsoft.Vbe.Interop;
3+
using Rubberduck.Parsing.VBA;
34
using Rubberduck.UnitTesting;
45
using Rubberduck.VBEditor.Extensions;
56

@@ -12,26 +13,26 @@ namespace Rubberduck.UI.Command
1213
public class AddTestModuleCommand : CommandBase
1314
{
1415
private readonly VBE _vbe;
16+
private readonly RubberduckParserState _state;
1517
private readonly NewUnitTestModuleCommand _command;
1618

17-
public AddTestModuleCommand(VBE vbe, NewUnitTestModuleCommand command)
19+
public AddTestModuleCommand(VBE vbe, RubberduckParserState state, NewUnitTestModuleCommand command)
1820
{
1921
_vbe = vbe;
22+
_state = state;
2023
_command = command;
2124
}
2225

2326
public override bool CanExecute(object parameter)
2427
{
2528
var app = _vbe.HostApplication();
26-
if (app == null)
29+
if (app == null || _state.Status != ParserState.Ready)
2730
{
2831
return false;
2932
}
30-
else
31-
{
32-
// Outlook requires test methods to be located in [ThisOutlookSession] class.
33-
return app.ApplicationName != "Outlook";
34-
}
33+
34+
// Outlook requires test methods to be located in [ThisOutlookSession] class.
35+
return app.ApplicationName != "Outlook";
3536
}
3637

3738
public override void Execute(object parameter)

RetailCoder.VBE/UI/Command/RunAllTestsCommand.cs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System;
2+
using System.Diagnostics;
13
using Rubberduck.Parsing.VBA;
24
using Rubberduck.UI.UnitTesting;
35
using Rubberduck.UnitTesting;
@@ -12,8 +14,8 @@ public class RunAllTestsCommand : CommandBase
1214
private readonly ITestEngine _engine;
1315
private readonly TestExplorerModel _model;
1416
private readonly RubberduckParserState _state;
15-
16-
public RunAllTestsCommand(ITestEngine engine, TestExplorerModel model, RubberduckParserState state)
17+
18+
public RunAllTestsCommand(RubberduckParserState state, ITestEngine engine, TestExplorerModel model)
1719
{
1820
_engine = engine;
1921
_model = model;
@@ -31,11 +33,39 @@ private void StateChanged(object sender, ParserStateEventArgs e)
3133
{
3234
if (e.State != ParserState.Ready) { return; }
3335

36+
var stopwatch = new Stopwatch();
37+
3438
_model.ClearLastRun();
3539
_model.IsBusy = true;
40+
41+
stopwatch.Start();
3642
_engine.Run(_model.Tests);
43+
stopwatch.Stop();
44+
3745
_model.IsBusy = false;
3846
_state.StateChanged -= StateChanged;
47+
48+
OnRunCompleted(new TestRunEventArgs(stopwatch.ElapsedMilliseconds));
49+
}
50+
51+
public event EventHandler<TestRunEventArgs> RunCompleted;
52+
protected virtual void OnRunCompleted(TestRunEventArgs e)
53+
{
54+
var handler = RunCompleted;
55+
if (handler != null)
56+
{
57+
handler.Invoke(this, e);
58+
}
59+
}
60+
}
61+
62+
public struct TestRunEventArgs
63+
{
64+
public long Duration { get; private set; }
65+
66+
public TestRunEventArgs(long duration)
67+
{
68+
Duration = duration;
3969
}
4070
}
4171
}

RetailCoder.VBE/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.

RetailCoder.VBE/UI/RubberduckUI.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,4 +1584,7 @@ All our stargazers, likers &amp; followers, for the warm fuzzies
15841584
<data name="TestOutcome_Ignored" xml:space="preserve">
15851585
<value>Ignored</value>
15861586
</data>
1587+
<data name="UnitTest_TotalDuration" xml:space="preserve">
1588+
<value>Total Duration</value>
1589+
</data>
15871590
</root>

RetailCoder.VBE/UI/UnitTesting/TestExplorerModel.cs

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
using System.Collections.ObjectModel;
33
using System.Linq;
44
using System.Windows.Media;
5-
using System.Windows.Threading;
65
using Microsoft.Vbe.Interop;
76
using Rubberduck.Parsing.VBA;
7+
using Rubberduck.UI.Command.MenuItems;
88
using Rubberduck.UnitTesting;
99

1010
namespace Rubberduck.UI.UnitTesting
@@ -13,15 +13,12 @@ public class TestExplorerModel : ViewModelBase
1313
{
1414
private readonly VBE _vbe;
1515
private readonly RubberduckParserState _state;
16-
private readonly Dispatcher _uiDispatcher;
1716

1817
public TestExplorerModel(VBE vbe, RubberduckParserState state)
1918
{
2019
_vbe = vbe;
2120
_state = state;
2221
_state.StateChanged += State_StateChanged;
23-
24-
_uiDispatcher = Dispatcher.CurrentDispatcher;
2522
}
2623

2724
private void State_StateChanged(object sender, ParserStateEventArgs e)
@@ -30,9 +27,6 @@ private void State_StateChanged(object sender, ParserStateEventArgs e)
3027

3128
var tests = UnitTestHelpers.GetAllTests(_vbe, _state).ToList();
3229

33-
UpdateTestList addTest = AddTest;
34-
UpdateTestList removeTest = RemoveTest;
35-
3630
var removedTests = Tests.Where(test =>
3731
!tests.Any(t =>
3832
t.Declaration.ComponentName == test.Declaration.ComponentName &&
@@ -42,7 +36,7 @@ private void State_StateChanged(object sender, ParserStateEventArgs e)
4236
// remove old tests
4337
foreach (var test in removedTests)
4438
{
45-
_uiDispatcher.Invoke(removeTest, test);
39+
UiDispatcher.Invoke(() => { Tests.Remove(test); });
4640
}
4741

4842
// update declarations for existing tests--declarations are immutable
@@ -64,23 +58,11 @@ private void State_StateChanged(object sender, ParserStateEventArgs e)
6458
t.Declaration.IdentifierName == test.Declaration.IdentifierName &&
6559
t.Declaration.ProjectId == test.Declaration.ProjectId))
6660
{
67-
_uiDispatcher.Invoke(addTest, test);
61+
UiDispatcher.Invoke(() => { Tests.Add(test); });
6862
}
6963
}
7064
}
7165

72-
private delegate void UpdateTestList(TestMethod test);
73-
74-
private void AddTest(TestMethod test)
75-
{
76-
Tests.Add(test);
77-
}
78-
79-
private void RemoveTest(TestMethod test)
80-
{
81-
Tests.Remove(test);
82-
}
83-
8466
private readonly ObservableCollection<TestMethod> _tests = new ObservableCollection<TestMethod>();
8567
public ObservableCollection<TestMethod> Tests { get { return _tests; } }
8668

0 commit comments

Comments
 (0)