Skip to content

Commit 728e247

Browse files
committed
Merge remote-tracking branch 'origin/Issue4149_TextExplorerFilter' into Issue4149_TextExplorerFilter
2 parents 1f62b6d + 0525de3 commit 728e247

File tree

7 files changed

+163
-47
lines changed

7 files changed

+163
-47
lines changed

Rubberduck.Core/UI/Inspections/InspectionResultsControl.xaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
<BitmapImage x:Key="GroupByLocationImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Custom/PNG/ObjectClass.png" />
6262
<BitmapImage x:Key="GroupBySeverityImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Custom/PNG/Severity.png" />
6363

64+
<BitmapImage x:Key="FilterImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/Funnel.png" />
6465
<BitmapImage x:Key="FilterByHintImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/information-white.png" />
6566
<BitmapImage x:Key="FilterBySuggestionImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/information.png" />
6667
<BitmapImage x:Key="FilterByWarningImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/exclamation.png" />
@@ -131,6 +132,8 @@
131132

132133
<Separator />
133134

135+
<Image Source="{StaticResource FilterImage}" />
136+
134137
<Label Content="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=GroupingGrid_Filter}" VerticalContentAlignment="Center" />
135138

136139
<ToggleButton Style="{StaticResource ToolBarToggleStyle}"

Rubberduck.Core/UI/UnitTesting/TestExplorerControl.xaml

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@
66
xmlns:local="clr-namespace:Rubberduck.UI.UnitTesting"
77
xmlns:vm="clr-namespace:Rubberduck.UI.UnitTesting.ViewModels"
88
xmlns:controls="clr-namespace:Rubberduck.UI.Controls"
9-
xmlns:themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
109
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
1110
xmlns:converters="clr-namespace:Rubberduck.UI.Converters"
1211
Language="{UICulture}"
1312
mc:Ignorable="d"
14-
d:DesignHeight="400" d:DesignWidth="600"
13+
d:DesignHeight="400" d:DesignWidth="800"
1514
d:DataContext="{d:DesignInstance local:TestExplorerViewModel}">
1615

1716
<UserControl.Resources>
@@ -49,6 +48,13 @@
4948

5049
<BitmapImage x:Key="CopyResultsImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/document-copy.png" />
5150

51+
<BitmapImage x:Key="FilterImage" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/Funnel.png" />
52+
<BitmapImage x:Key="OutcomeUnknown" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/question-white.png" />
53+
<BitmapImage x:Key="OutcomeSpectacularFail" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/skull-mad.png" />
54+
<BitmapImage x:Key="OutcomeFail" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/cross-circle.png" />
55+
<BitmapImage x:Key="OutcomeInconclusive" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/exclamation.png" />
56+
<BitmapImage x:Key="OutcomeSucceeded" UriSource="pack://application:,,,/Rubberduck.Resources;component/Icons/Fugue/tick-circle.png" />
57+
5258
<local:TestOutcomeImageSourceConverter x:Key="OutcomeIconConverter" />
5359
<converters:MillisecondToTimeMagnitudeConverter x:Key="FormattedTime" />
5460
<converters:InvertBoolValueConverter x:Key="InvertBoolValue" />
@@ -82,6 +88,7 @@
8288
<local:TestExplorerGroupingBooleanConverter x:Key="OutcomeConverter" />
8389
<local:TestExplorerGroupingBooleanConverter x:Key="LocationConverter" />
8490
<local:TestExplorerGroupingBooleanConverter x:Key="CategoryConverter" />
91+
<local:TestExplorerOutcomeFilterToBooleanConverter x:Key="OutcomeFilterConverter" />
8592
<Style x:Key="ToolBarToggleStyle" TargetType="ToggleButton">
8693
<Setter Property="Margin" Value="2" />
8794
<Setter Property="BorderBrush" Value="{x:Static SystemColors.ActiveBorderBrush}" />
@@ -216,15 +223,38 @@
216223

217224
<Separator />
218225

226+
<Image Source="{StaticResource FilterImage}" />
227+
219228
<Label Content="{Resx Key=TestExplorer_Filter, ResxName=Rubberduck.Resources.UnitTesting.TestExplorer}" />
220229
<controls:SearchBox Width="100"
221230
Text="{Binding TestNameFilter, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}" />
222231

223232
<Label Content="{Resx Key=TestExplorer_Outcome, ResxName=Rubberduck.Resources.UnitTesting.TestExplorer}" />
224-
225-
<ComboBox Width="100"
226-
ItemsSource="{Binding OutcomeFilters, UpdateSourceTrigger=PropertyChanged}"
227-
SelectedItem="{Binding SelectedOutcomeFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
233+
<ToggleButton Style="{StaticResource ToolBarToggleStyle}"
234+
ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=TestOutcome_Unknown}"
235+
IsChecked="{Binding Path=OutcomeFilter, Converter={StaticResource OutcomeFilterConverter}, ConverterParameter={x:Static local:TestExplorerOutcomeFilter.Unknown}}" >
236+
<Image Source="{StaticResource OutcomeUnknown}" />
237+
</ToggleButton>
238+
<ToggleButton Style="{StaticResource ToolBarToggleStyle}"
239+
ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=TestOutcome_SpectacularFail}"
240+
IsChecked="{Binding Path=OutcomeFilter, Converter={StaticResource OutcomeFilterConverter}, ConverterParameter={x:Static local:TestExplorerOutcomeFilter.SpectacularFail}}" >
241+
<Image Source="{StaticResource OutcomeSpectacularFail}" />
242+
</ToggleButton>
243+
<ToggleButton Style="{StaticResource ToolBarToggleStyle}"
244+
ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=TestOutcome_Fail}"
245+
IsChecked="{Binding Path=OutcomeFilter, Converter={StaticResource OutcomeFilterConverter}, ConverterParameter={x:Static local:TestExplorerOutcomeFilter.Fail}}" >
246+
<Image Source="{StaticResource OutcomeFail}" />
247+
</ToggleButton>
248+
<ToggleButton Style="{StaticResource ToolBarToggleStyle}"
249+
ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=TestOutcome_Inconclusive}"
250+
IsChecked="{Binding Path=OutcomeFilter, Converter={StaticResource OutcomeFilterConverter}, ConverterParameter={x:Static local:TestExplorerOutcomeFilter.Inconclusive}}" >
251+
<Image Source="{StaticResource OutcomeInconclusive}" />
252+
</ToggleButton>
253+
<ToggleButton Style="{StaticResource ToolBarToggleStyle}"
254+
ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=TestOutcome_Succeeded}"
255+
IsChecked="{Binding Path=OutcomeFilter, Converter={StaticResource OutcomeFilterConverter}, ConverterParameter={x:Static local:TestExplorerOutcomeFilter.Succeeded}}" >
256+
<Image Source="{StaticResource OutcomeSucceeded}" />
257+
</ToggleButton>
228258

229259
<Separator />
230260

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Windows.Data;
4+
5+
namespace Rubberduck.UI.UnitTesting
6+
{
7+
class TestExplorerOutcomeFilterToBooleanConverter : IValueConverter
8+
{
9+
private TestExplorerOutcomeFilter _cachedOutcomeFilter;
10+
11+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
12+
{
13+
if (!(parameter is TestExplorerOutcomeFilter outcomeParameter)
14+
|| !(value is TestExplorerOutcomeFilter outcomeCurrentlyFiltering))
15+
{
16+
return false;
17+
}
18+
19+
_cachedOutcomeFilter = outcomeCurrentlyFiltering;
20+
return _cachedOutcomeFilter.HasFlag(outcomeParameter);
21+
}
22+
23+
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
24+
{
25+
if (!(parameter is TestExplorerOutcomeFilter outcomeParameter)
26+
|| !(value is bool isApplied))
27+
{
28+
return _cachedOutcomeFilter;
29+
}
30+
31+
_cachedOutcomeFilter = isApplied
32+
? _cachedOutcomeFilter | outcomeParameter
33+
: _cachedOutcomeFilter ^ outcomeParameter;
34+
return _cachedOutcomeFilter;
35+
}
36+
}
37+
}

Rubberduck.Core/UI/UnitTesting/TestExplorerViewModel.cs

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@
1616
using Rubberduck.UI.UnitTesting.Commands;
1717
using Rubberduck.UI.UnitTesting.ViewModels;
1818
using Rubberduck.UnitTesting;
19-
using Rubberduck.VBEditor.ComManagement;
2019
using Rubberduck.VBEditor.Utility;
2120
using DataFormats = System.Windows.DataFormats;
22-
using Rubberduck.Resources.UnitTesting;
2321

2422
namespace Rubberduck.UI.UnitTesting
2523
{
@@ -31,6 +29,18 @@ public enum TestExplorerGrouping
3129
Location
3230
}
3331

32+
[Flags]
33+
public enum TestExplorerOutcomeFilter
34+
{
35+
None = 0,
36+
Unknown = 1,
37+
SpectacularFail = 1 << 1,
38+
Fail = 1 << 2,
39+
Inconclusive = 1 << 3,
40+
Succeeded = 1 << 4,
41+
All = Unknown | SpectacularFail | Fail | Inconclusive | Succeeded
42+
}
43+
3444
internal sealed class TestExplorerViewModel : ViewModelBase, INavigateSelection, IDisposable
3545
{
3646
private readonly IClipboardWriter _clipboard;
@@ -70,11 +80,7 @@ public TestExplorerViewModel(ISelectionService selectionService,
7080
OnPropertyChanged(nameof(Tests));
7181
TestGrouping = TestExplorerGrouping.Outcome;
7282

73-
74-
OutcomeFilters = new System.Collections.ObjectModel.ObservableCollection<object>(
75-
new[] { _allResultsFilter }
76-
.Concat(Enum.GetNames(typeof(TestOutcome)).Select(s => s.ToString()))
77-
.OrderBy(s => s));
83+
OutcomeFilter = TestExplorerOutcomeFilter.All;
7884
}
7985

8086
public TestExplorerModel Model { get; }
@@ -140,23 +146,21 @@ public TestExplorerGrouping TestGrouping
140146
}
141147
}
142148

143-
public ObservableCollection<object> OutcomeFilters { get; }
144-
145-
private TestOutcome? _filtering = null;
146-
147-
public TestOutcome? TestFiltering
149+
private TestExplorerOutcomeFilter _outcomeFilter = TestExplorerOutcomeFilter.All;
150+
public TestExplorerOutcomeFilter OutcomeFilter
148151
{
149-
get => _filtering;
152+
get => _outcomeFilter;
150153
set
151154
{
152-
if (value == _filtering)
155+
if (value == _outcomeFilter)
153156
{
154157
return;
155158
}
156159

157-
_filtering = value;
158-
Tests.Refresh();
160+
_outcomeFilter = value;
159161
OnPropertyChanged();
162+
163+
Tests.Filter = FilterResults;
160164
}
161165
}
162166

@@ -186,36 +190,20 @@ public bool ExpandedState
186190
OnPropertyChanged();
187191
}
188192
}
189-
190-
private static readonly string _allResultsFilter = TestExplorer.ResourceManager.GetString("TestExplorer_AllResults", CultureInfo.CurrentUICulture);
191-
private string _selectedOutcomeFilter = _allResultsFilter;
192-
public string SelectedOutcomeFilter
193-
{
194-
get => _selectedOutcomeFilter;
195-
set
196-
{
197-
if (_selectedOutcomeFilter != value)
198-
{
199-
_selectedOutcomeFilter = value.Replace(" ", string.Empty);
200-
OnPropertyChanged();
201-
Tests.Filter = FilterResults;
202-
OnPropertyChanged(nameof(Tests));
203-
}
204-
}
205-
}
206-
207193
/// <summary>
208194
/// Filtering for displaying the correct tests.
209-
/// Uses both <see cref="SelectedOutcomeFilter"/> and <see cref="TestNameFilter"/>
195+
/// Uses both <see cref="OutcomeFilter"/> and <see cref="TestNameFilter"/>
210196
/// </summary>
211197
private bool FilterResults(object unitTest)
212198
{
213199
var testMethodViewModel = unitTest as TestMethodViewModel;
214-
var memberName = testMethodViewModel.QualifiedName.MemberName;
215200

216-
return memberName.ToUpper().Contains(TestNameFilter?.ToUpper() ?? string.Empty)
217-
&& (SelectedOutcomeFilter.Equals(_allResultsFilter) || testMethodViewModel.Result.Outcome.ToString().Equals(_selectedOutcomeFilter));
201+
var passesNameFilter = testMethodViewModel.QualifiedName.MemberName.ToUpper().Contains(TestNameFilter?.ToUpper() ?? string.Empty);
202+
203+
Enum.TryParse(testMethodViewModel.Result.Outcome.ToString(), out TestExplorerOutcomeFilter convertedOutcome);
204+
var passesOutcomeFilter = (OutcomeFilter & convertedOutcome) == convertedOutcome;
218205

206+
return passesNameFilter && passesOutcomeFilter;
219207
}
220208

221209
private void HandleTestCompletion(object sender, TestCompletedEventArgs e)

Rubberduck.Core/UI/UnitTesting/TestExplorerWindow.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Windows.Forms;
1+
using System.Windows.Forms;
32
using Rubberduck.Resources.UnitTesting;
43

54
namespace Rubberduck.UI.UnitTesting

Rubberduck.Resources/RubberduckUI.Designer.cs

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

Rubberduck.Resources/RubberduckUI.resx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1548,7 +1548,6 @@ NOTE: Restart is required for the setting to take effect.</value>
15481548
</data>
15491549
<data name="RefactoringFailure_BaseMessage" xml:space="preserve">
15501550
<value>Refactoring failed.</value>
1551-
15521551
</data>
15531552
<data name="RefactoringFailure_NoActiveSelection" xml:space="preserve">
15541553
<value>There is no active selection.</value>
@@ -1594,4 +1593,19 @@ NOTE: Restart is required for the setting to take effect.</value>
15941593
<value>Declaration type of target '{0}' is '{1}' instead of one of the expected '{2}'.</value>
15951594
<comment>{0}: name of target; {1}: actual declaration type; {2}: expected declaration types</comment>
15961595
</data>
1596+
<data name="TestOutcome_Fail" xml:space="preserve">
1597+
<value>Fail</value>
1598+
</data>
1599+
<data name="TestOutcome_Inconclusive" xml:space="preserve">
1600+
<value>Inconclusive</value>
1601+
</data>
1602+
<data name="TestOutcome_SpectacularFail" xml:space="preserve">
1603+
<value>SpectacularFail</value>
1604+
</data>
1605+
<data name="TestOutcome_Succeeded" xml:space="preserve">
1606+
<value>Suceeded</value>
1607+
</data>
1608+
<data name="TestOutcome_Unknown" xml:space="preserve">
1609+
<value>Unknown</value>
1610+
</data>
15971611
</root>

0 commit comments

Comments
 (0)