Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b1b97b2
Simply grouping and make toolbar style consistent with inspections.
comintern Feb 2, 2019
b8b12c4
Only invalidate test results if the code of the unit test has changed…
comintern Feb 2, 2019
2ef8d61
Allow selecting and running multiple tests. Closes #4701
comintern Feb 2, 2019
95c6934
Add context menu, option to run tests by group, and button for resett…
comintern Feb 3, 2019
ccd51b1
Give Rubberduck.UnitTesting its stuff back. Closes #4365, #4220, and …
comintern Feb 4, 2019
3c804dd
Address review comments.
comintern Feb 5, 2019
933e275
Refactor test setup for interface changes.
comintern Feb 5, 2019
b42949e
Start of unit testing command test rework.
comintern Feb 5, 2019
7308be1
Update remaining legacy tests, add null handling in commands.
comintern Feb 6, 2019
1e84e4f
Use a user defined precompiler argument in dual binding test template…
comintern Feb 6, 2019
e9edfc6
Pump messages in test engine between tests, rearrange status bar and …
comintern Feb 9, 2019
a56e3c7
Default test methods to Private. Closes #4658
comintern Feb 9, 2019
d297bfa
Add context menu items to run selected test or all tests in active mo…
comintern Feb 9, 2019
f6e8a80
merge next
comintern Feb 9, 2019
bcb0d22
Allow test run cancellation. Closes #3158
comintern Feb 10, 2019
8347076
Persist expanded state of GroupingBrid groups after changes to the gr…
comintern Feb 10, 2019
de2bdc6
Fix status bar, add test run summary, persist expanded state on group…
comintern Feb 11, 2019
0ff7572
Address review comments, add easter egg.
comintern Feb 11, 2019
ff75888
Fix typo
comintern Feb 11, 2019
355d459
Add unit tests, replace tests targeting old interface.
comintern Feb 15, 2019
e783298
Address review comments, test threading issues.
comintern Feb 16, 2019
aaf20c8
Comment out tests that pass individually, but not with "run all".
comintern Feb 16, 2019
4af510d
Comment out tests pending refactor.
comintern Feb 16, 2019
071a91f
merge next
comintern Feb 19, 2019
b8c6933
fix namespaces from merge.
comintern Feb 19, 2019
414c059
merge next
comintern Feb 19, 2019
6910972
fix merge faceplants.
comintern Feb 19, 2019
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
4 changes: 2 additions & 2 deletions Rubberduck.Core/Properties/Settings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Rubberduck.Core/Settings/ConfigurationLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using Rubberduck.SettingsProvider;
using Rubberduck.SmartIndenter;
using Rubberduck.UnitTesting.Settings;

namespace Rubberduck.Settings
{
Expand Down
1 change: 1 addition & 0 deletions Rubberduck.Core/Settings/UserSettings.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Xml.Serialization;
using Rubberduck.SmartIndenter;
using Rubberduck.UnitTesting.Settings;

namespace Rubberduck.Settings
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
using System;
using System.Linq;
using System.Runtime.InteropServices;
using Rubberduck.Interaction;
using Rubberduck.Navigation.CodeExplorer;
using Rubberduck.Parsing.VBA;
using Rubberduck.Settings;
using Rubberduck.UI.UnitTesting.Commands;
using Rubberduck.UnitTesting;
using Rubberduck.UnitTesting.CodeGeneration;
using Rubberduck.VBEditor.SafeComWrappers.Abstract;

namespace Rubberduck.UI.CodeExplorer.Commands
Expand All @@ -21,8 +19,8 @@ public class AddTestComponentCommand : AddTestModuleCommand
typeof(CodeExplorerMemberViewModel)
};

public AddTestComponentCommand(IVBE vbe, RubberduckParserState state, IGeneralConfigService configLoader, IMessageBox messageBox, IVBEInteraction interaction)
: base(vbe, state, configLoader, messageBox, interaction) { }
public AddTestComponentCommand(IVBE vbe, RubberduckParserState state, ITestCodeGenerator codeGenerator)
: base(vbe, state, codeGenerator) { }

protected override bool EvaluateCanExecute(object parameter)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ public enum CodePaneContextMenuItemDisplayOrder
FindSymbol,
FindAllReferences,
FindAllImplementations,
RunSelectedTestModule,
RunSelectedTest
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Rubberduck.Parsing.VBA;
using Rubberduck.UI.Command.MenuItems.ParentMenus;

namespace Rubberduck.UI.Command.MenuItems
{
public class RunSelectedTestMethodCommandMenuItem : CommandMenuItemBase
{
public RunSelectedTestMethodCommandMenuItem(RunSelectedTestMethodCommand command) : base(command) { }

public override string Key => "ContextMenu_RunSelectedTest";
public override int DisplayOrder => (int)CodePaneContextMenuItemDisplayOrder.RunSelectedTest;

public override bool EvaluateCanExecute(RubberduckParserState state)
{
return state != null && Command.CanExecute(null);
}

public override bool HiddenWhenDisabled => true;

public override bool BeginGroup => false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Rubberduck.Parsing.VBA;
using Rubberduck.UI.Command.MenuItems.ParentMenus;

namespace Rubberduck.UI.Command.MenuItems
{
public class RunSelectedTestModuleCommandMenuItem : CommandMenuItemBase
{
public RunSelectedTestModuleCommandMenuItem(RunSelectedTestModuleCommand command) : base(command) { }

public override string Key => "ContextMenu_RunSelectedTestModule";
public override int DisplayOrder => (int)CodePaneContextMenuItemDisplayOrder.RunSelectedTestModule;

public override bool EvaluateCanExecute(RubberduckParserState state)
{
return state != null && Command.CanExecute(null);
}

public override bool HiddenWhenDisabled => true;

public override bool BeginGroup => true;
}
}
57 changes: 57 additions & 0 deletions Rubberduck.Core/UI/Command/RunSelectedTestMethodCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System.Linq;
using NLog;
using Rubberduck.Parsing.Annotations;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
using Rubberduck.UnitTesting;
using Rubberduck.VBEditor.Utility;

namespace Rubberduck.UI.Command
{
public class RunSelectedTestMethodCommand : CommandBase
{
private readonly ITestEngine _engine;
private readonly ISelectionService _selectionService;
private readonly IDeclarationFinderProvider _finderProvider;

public RunSelectedTestMethodCommand(ITestEngine engine, ISelectionService selectionService, IDeclarationFinderProvider finderProvider)
: base(LogManager.GetCurrentClassLogger())
{
_engine = engine;
_selectionService = selectionService;
_finderProvider = finderProvider;
}

protected override bool EvaluateCanExecute(object parameter)
{
return (parameter ?? FindDeclarationFromSelection()) is Declaration candidate &&
!(_engine.Tests.FirstOrDefault(test => test.Declaration.Equals(candidate)) is null) &&
_engine.CanRun;
}

protected override void OnExecute(object parameter)
{
if (!((parameter ?? FindDeclarationFromSelection()) is Declaration candidate) ||
!(_engine.Tests.FirstOrDefault(test => test.Declaration.Equals(candidate)) is TestMethod selectedTest) ||
!_engine.CanRun)
{
return;
}

_engine.Run(new [] { selectedTest });
}

private Declaration FindDeclarationFromSelection()
{
var active = _selectionService?.ActiveSelection();
if (!active.HasValue)
{
return null;
}

return _finderProvider.DeclarationFinder.FindDeclarationsForSelection(active.Value)
.SingleOrDefault(declaration => declaration.DeclarationType == DeclarationType.Procedure &&
declaration.Annotations.Any(annotation => annotation is TestMethodAnnotation));
}
}
}
62 changes: 62 additions & 0 deletions Rubberduck.Core/UI/Command/RunSelectedTestModuleCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System.Linq;
using NLog;
using Rubberduck.Parsing.Annotations;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
using Rubberduck.UnitTesting;
using Rubberduck.VBEditor.Utility;

namespace Rubberduck.UI.Command
{
public class RunSelectedTestModuleCommand : CommandBase
{
private readonly ITestEngine _engine;
private readonly ISelectionService _selectionService;
private readonly IDeclarationFinderProvider _finderProvider;

public RunSelectedTestModuleCommand(ITestEngine engine, ISelectionService selectionService, IDeclarationFinderProvider finderProvider)
: base(LogManager.GetCurrentClassLogger())
{
_engine = engine;
_selectionService = selectionService;
_finderProvider = finderProvider;
}

protected override bool EvaluateCanExecute(object parameter)
{
return (parameter ?? FindModuleFromSelection()) is Declaration candidate &&
candidate.DeclarationType == DeclarationType.ProceduralModule &&
candidate.Annotations.Any(annotation => annotation is TestModuleAnnotation) &&
_engine.CanRun &&
_engine.Tests.Any(test => test.Declaration.QualifiedModuleName.Equals(candidate.QualifiedModuleName));
}

protected override void OnExecute(object parameter)
{
if (!((parameter ?? FindModuleFromSelection()) is Declaration candidate) ||
candidate.DeclarationType != DeclarationType.ProceduralModule ||
!candidate.Annotations.Any(annotation => annotation is TestModuleAnnotation) ||
!_engine.CanRun)
{
return;
}

var tests = _engine.Tests.Where(test => test.Declaration.QualifiedModuleName.Equals(candidate.QualifiedModuleName)).ToList();

if (!tests.Any())
{
return;
}

_engine.Run(tests);
}

private Declaration FindModuleFromSelection()
{
var active = _selectionService?.ActiveSelection();
return !active.HasValue
? null
: _finderProvider.DeclarationFinder.ModuleDeclaration(active.Value.QualifiedName);
}
}
}
10 changes: 8 additions & 2 deletions Rubberduck.Core/UI/Controls/GroupingGrid.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Rubberduck.UI.Controls" x:Class="Rubberduck.UI.Controls.GroupingGrid"
xmlns:local="clr-namespace:Rubberduck.UI.Controls"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
x:Class="Rubberduck.UI.Controls.GroupingGrid"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<DataGrid.Resources>
Expand Down Expand Up @@ -60,7 +62,8 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander Background="WhiteSmoke" Foreground="Black" FontWeight="SemiBold">
<Expander Background="WhiteSmoke" Foreground="Black" FontWeight="SemiBold"
IsExpanded="{Binding InitialExpandedState, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:GroupingGrid}}}">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="4"
Expand All @@ -76,6 +79,9 @@
</StackPanel>
</Expander.Header>
<ItemsPresenter Margin="25,0,0,0" />
<i:Interaction.Behaviors>
<local:PersistGroupExpandedStateBehavior GroupName="{Binding Name}" />
</i:Interaction.Behaviors>
</Expander>
</ControlTemplate>
</Setter.Value>
Expand Down
11 changes: 10 additions & 1 deletion Rubberduck.Core/UI/Controls/GroupingGrid.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,21 @@ public partial class GroupingGrid
public static readonly DependencyProperty ShowGroupingItemCountProperty =
DependencyProperty.Register("ShowGroupingItemCount", typeof (bool), typeof(GroupingGrid));

public static readonly DependencyProperty InitialExpandedStateProperty =
DependencyProperty.Register("InitialExpandedState", typeof(bool), typeof(GroupingGrid));

public bool ShowGroupingItemCount
{
get => (bool) GetValue(ShowGroupingItemCountProperty);
get => (bool)GetValue(ShowGroupingItemCountProperty);
set => SetValue(ShowGroupingItemCountProperty, value);
}

public bool InitialExpandedState
{
get => (bool)GetValue(InitialExpandedStateProperty);
set => SetValue(InitialExpandedStateProperty, value);
}

public GroupingGrid()
{
InitializeComponent();
Expand Down
93 changes: 93 additions & 0 deletions Rubberduck.Core/UI/Controls/PersistGroupExpandedStateBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using GongSolutions.Wpf.DragDrop.Utilities;

namespace Rubberduck.UI.Controls
{
// Courtesy of @aKzenT - this is a heavily refactored implementation of https://stackoverflow.com/a/15924044/4088852
public class PersistGroupExpandedStateBehavior : Behavior<Expander>
{
public static readonly DependencyProperty InitialExpandedStateProperty = DependencyProperty.Register(
"InitialExpandedState",
typeof(bool),
typeof(PersistGroupExpandedStateBehavior),
new PropertyMetadata(default(bool)));

public static readonly DependencyProperty GroupNameProperty = DependencyProperty.Register(
"GroupName",
typeof(object),
typeof(PersistGroupExpandedStateBehavior),
new PropertyMetadata(default(object)));

private static readonly DependencyProperty ExpandedStateStoreProperty =
DependencyProperty.RegisterAttached(
"ExpandedStateStore",
typeof(IDictionary<object, bool>),
typeof(PersistGroupExpandedStateBehavior),
new PropertyMetadata(default(IDictionary<object, bool>)));

public bool InitialExpandedState
{
get => (bool)GetValue(InitialExpandedStateProperty);
set => SetValue(InitialExpandedStateProperty, value);
}

public object GroupName
{
get => GetValue(GroupNameProperty);
set => SetValue(GroupNameProperty, value);
}

protected override void OnAttached()
{
base.OnAttached();

var states = GetExpandedStateStore();
var expanded = !states.ContainsKey(GroupName ?? string.Empty) ? (bool?)null : states[GroupName ?? string.Empty];

if (expanded != null)
{
AssociatedObject.IsExpanded = InitialExpandedState;
}

AssociatedObject.Expanded += OnExpanded;
AssociatedObject.Collapsed += OnCollapsed;
}

protected override void OnDetaching()
{
AssociatedObject.Expanded -= OnExpanded;
AssociatedObject.Collapsed -= OnCollapsed;

base.OnDetaching();
}

private void OnCollapsed(object sender, RoutedEventArgs e) => SetExpanded(false);

private void OnExpanded(object sender, RoutedEventArgs e) => SetExpanded(true);

private void SetExpanded(bool expanded) => GetExpandedStateStore()[GroupName ?? string.Empty] = expanded;

private IDictionary<object, bool> GetExpandedStateStore()
{
if (!(AssociatedObject?.GetVisualAncestor<ItemsControl>() is ItemsControl items))
{
return null;
}

var states = (IDictionary<object, bool>)items.GetValue(ExpandedStateStoreProperty);

if (states != null)
{
return states;
}

states = new Dictionary<object, bool>();
items.SetValue(ExpandedStateStoreProperty, states);

return states;
}
}
}
Loading