diff --git a/xunit.runner.wpf/MainWindow.xaml b/xunit.runner.wpf/MainWindow.xaml
index 5940406..304d941 100644
--- a/xunit.runner.wpf/MainWindow.xaml
+++ b/xunit.runner.wpf/MainWindow.xaml
@@ -105,6 +105,16 @@
+
+
+
+
+
+
+
+
diff --git a/xunit.runner.wpf/ViewModel/MainViewModel.cs b/xunit.runner.wpf/ViewModel/MainViewModel.cs
index 93b6de8..9ef4e59 100644
--- a/xunit.runner.wpf/ViewModel/MainViewModel.cs
+++ b/xunit.runner.wpf/ViewModel/MainViewModel.cs
@@ -49,6 +49,7 @@ namespace xunit.runner.wpf.ViewModel
this.WindowLoadedCommand = new RelayCommand(OnExecuteWindowLoaded);
this.RunCommand = new RelayCommand(OnExecuteRun, CanExecuteRun);
this.CancelCommand = new RelayCommand(OnExecuteCancel, CanExecuteCancel);
+ this.TraitSelectionChangedCommand = new RelayCommand(OnTraitSelectionChanged);
}
private static bool TestCaseMatches(TestCaseViewModel testCase, SearchQuery searchQuery)
@@ -58,6 +59,24 @@ namespace xunit.runner.wpf.ViewModel
return false;
}
+ if (searchQuery.TraitSet.Count > 0)
+ {
+ var anyMatch = false;
+ foreach (var cur in testCase.Traits)
+ {
+ if (searchQuery.TraitSet.Contains(cur))
+ {
+ anyMatch = true;
+ break;
+ }
+ }
+
+ if (!anyMatch)
+ {
+ return false;
+ }
+ }
+
switch (testCase.State)
{
case TestState.Passed:
@@ -88,6 +107,7 @@ namespace xunit.runner.wpf.ViewModel
public ICommand WindowLoadedCommand { get; }
public RelayCommand RunCommand { get; }
public RelayCommand CancelCommand { get; }
+ public ICommand TraitSelectionChangedCommand { get; }
public CommandBindingCollection CommandBindings { get; }
@@ -364,8 +384,12 @@ namespace xunit.runner.wpf.ViewModel
private void OnTestDiscovered(object sender, TestCaseDataEventArgs e)
{
var t = e.TestCaseData;
- this.allTestCases.Add(new TestCaseViewModel(t.SerializedForm, t.DisplayName, t.AssemblyPath));
- this.traitCollectionView.Add(t.TraitMap);
+
+ var traitMap = t.TraitMap.Count == 0
+ ? ImmutableArray.Empty
+ : t.TraitMap.SelectMany(pair => pair.Value.Select(value => new TraitViewModel(pair.Key, value))).ToImmutableArray();
+ this.allTestCases.Add(new TestCaseViewModel(t.SerializedForm, t.DisplayName, t.AssemblyPath, traitMap));
+ this.traitCollectionView.Add(traitMap);
}
private void OnTestFinished(object sender, TestResultDataEventArgs e)
@@ -405,6 +429,14 @@ namespace xunit.runner.wpf.ViewModel
this.cancellationTokenSource.Cancel();
}
+ private void OnTraitSelectionChanged()
+ {
+ this.searchQuery.TraitSet = new HashSet(
+ this.traitCollectionView.Collection.Where(x => x.IsSelected),
+ TraitViewModelComparer.Instance);
+ FilterAfterDelay();
+ }
+
public bool IncludePassedTests
{
get { return searchQuery.IncludePassedTests; }
diff --git a/xunit.runner.wpf/ViewModel/SearchQuery.cs b/xunit.runner.wpf/ViewModel/SearchQuery.cs
index 36f5da7..5900b67 100644
--- a/xunit.runner.wpf/ViewModel/SearchQuery.cs
+++ b/xunit.runner.wpf/ViewModel/SearchQuery.cs
@@ -11,7 +11,7 @@ namespace xunit.runner.wpf.ViewModel
public bool IncludeFailedTests = true;
public bool IncludePassedTests = true;
public bool IncludeSkippedTests = true;
-
public string SearchString = string.Empty;
+ public HashSet TraitSet = new HashSet(TraitViewModelComparer.Instance);
}
}
diff --git a/xunit.runner.wpf/ViewModel/TestCaseViewModel.cs b/xunit.runner.wpf/ViewModel/TestCaseViewModel.cs
index ab6b7a0..3e5e321 100644
--- a/xunit.runner.wpf/ViewModel/TestCaseViewModel.cs
+++ b/xunit.runner.wpf/ViewModel/TestCaseViewModel.cs
@@ -1,6 +1,7 @@
using GalaSoft.MvvmLight;
using System;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Text;
@@ -11,24 +12,28 @@ namespace xunit.runner.wpf.ViewModel
{
public class TestCaseViewModel : ViewModelBase
{
- public TestCaseViewModel(string testCase, string displayName, string assemblyFileName)
+ private TestState _state = TestState.NotRun;
+
+ public TestCaseViewModel(string testCase, string displayName, string assemblyFileName, ImmutableArray traits)
{
this.TestCase = testCase;
this.DisplayName = displayName;
this.AssemblyFileName = assemblyFileName;
+ this.Traits = traits;
}
public string DisplayName { get; }
- private TestState state = TestState.NotRun;
public TestState State
{
- get { return state; }
- set { Set(ref state, value); }
+ get { return _state; }
+ set { Set(ref _state, value); }
}
public string AssemblyFileName { get; }
public string TestCase { get; }
+
+ public ImmutableArray Traits { get; }
}
}
diff --git a/xunit.runner.wpf/ViewModel/TraitCollectionView.TraitViewModelComparer.cs b/xunit.runner.wpf/ViewModel/TraitCollectionView.TraitViewModelComparer.cs
deleted file mode 100644
index d8b9358..0000000
--- a/xunit.runner.wpf/ViewModel/TraitCollectionView.TraitViewModelComparer.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace xunit.runner.wpf.ViewModel
-{
- public partial class TraitCollectionView
- {
- private sealed class TraitViewModelComparer : IEqualityComparer, IComparer
- {
- private readonly StringComparer _comparer = StringComparer.Ordinal;
-
- public int Compare(TraitViewModel x, TraitViewModel y)
- {
- var result = _comparer.Compare(x.Name, y.Name);
- if (result != 0)
- {
- return result;
- }
-
- return _comparer.Compare(x.Value, y.Value);
- }
-
- public bool Equals(TraitViewModel x, TraitViewModel y)
- {
- return _comparer.Equals(x.Name, y.Name)
- && _comparer.Equals(x.Value, y.Value);
- }
-
- public int GetHashCode(TraitViewModel obj)
- {
- return obj.Name.GetHashCode();
- }
- }
- }
-}
diff --git a/xunit.runner.wpf/ViewModel/TraitCollectionView.cs b/xunit.runner.wpf/ViewModel/TraitCollectionView.cs
index 30cacff..bb0f58d 100644
--- a/xunit.runner.wpf/ViewModel/TraitCollectionView.cs
+++ b/xunit.runner.wpf/ViewModel/TraitCollectionView.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
@@ -10,7 +11,7 @@ namespace xunit.runner.wpf.ViewModel
{
public sealed partial class TraitCollectionView
{
- private readonly TraitViewModelComparer _comparer = new TraitViewModelComparer();
+ private readonly TraitViewModelComparer _comparer = TraitViewModelComparer.Instance;
private readonly ObservableCollection _collection = new ObservableCollection();
public ObservableCollection Collection => _collection;
@@ -20,19 +21,16 @@ namespace xunit.runner.wpf.ViewModel
}
- public void Add(Dictionary> traitMap)
+ public void Add(ImmutableArray traitList)
{
- if (traitMap.Count == 0)
+ if (traitList.Length == 0)
{
return;
}
- foreach (var pair in traitMap)
+ foreach (var traitViewModel in traitList)
{
- foreach (var value in pair.Value)
- {
- TryInsert(new TraitViewModel(pair.Key, value));
- }
+ TryInsert(traitViewModel);
}
}
diff --git a/xunit.runner.wpf/ViewModel/TraitViewModel.cs b/xunit.runner.wpf/ViewModel/TraitViewModel.cs
index 72c7b46..11b2f1b 100644
--- a/xunit.runner.wpf/ViewModel/TraitViewModel.cs
+++ b/xunit.runner.wpf/ViewModel/TraitViewModel.cs
@@ -15,6 +15,7 @@ namespace xunit.runner.wpf.ViewModel
public string Name => _name;
public string Value => _value;
public string DisplayName => $"{Name}={Value}";
+ public bool IsSelected { get; set; }
public TraitViewModel(string name, string value)
{
diff --git a/xunit.runner.wpf/ViewModel/TraitViewModelComparer.cs b/xunit.runner.wpf/ViewModel/TraitViewModelComparer.cs
new file mode 100644
index 0000000..9970a0a
--- /dev/null
+++ b/xunit.runner.wpf/ViewModel/TraitViewModelComparer.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace xunit.runner.wpf.ViewModel
+{
+ internal sealed class TraitViewModelComparer : IEqualityComparer, IComparer
+ {
+ internal static readonly TraitViewModelComparer Instance = new TraitViewModelComparer();
+
+ private readonly StringComparer _comparer = StringComparer.Ordinal;
+
+ public int Compare(TraitViewModel x, TraitViewModel y)
+ {
+ var result = _comparer.Compare(x.Name, y.Name);
+ if (result != 0)
+ {
+ return result;
+ }
+
+ return _comparer.Compare(x.Value, y.Value);
+ }
+
+ public bool Equals(TraitViewModel x, TraitViewModel y)
+ {
+ return _comparer.Equals(x.Name, y.Name)
+ && _comparer.Equals(x.Value, y.Value);
+ }
+
+ public int GetHashCode(TraitViewModel obj)
+ {
+ return obj.Name.GetHashCode();
+ }
+ }
+}
diff --git a/xunit.runner.wpf/xunit.runner.wpf.csproj b/xunit.runner.wpf/xunit.runner.wpf.csproj
index 2812251..e8d4ace 100644
--- a/xunit.runner.wpf/xunit.runner.wpf.csproj
+++ b/xunit.runner.wpf/xunit.runner.wpf.csproj
@@ -94,7 +94,6 @@
LoadingDialog.xaml
-
@@ -102,6 +101,7 @@
+
Designer