diff --git a/src/TestUtils/src/DeviceTests.Runners/VisualRunner/Utils/FilteredCollectionView.cs b/src/TestUtils/src/DeviceTests.Runners/VisualRunner/Utils/FilteredCollectionView.cs index 1dae91bda6d3..e69409522884 100644 --- a/src/TestUtils/src/DeviceTests.Runners/VisualRunner/Utils/FilteredCollectionView.cs +++ b/src/TestUtils/src/DeviceTests.Runners/VisualRunner/Utils/FilteredCollectionView.cs @@ -39,6 +39,11 @@ public TFilterArg FilterArgument get { return filterArgument; } set { + if (filterArgument.Equals(value)) + { + return; + } + filterArgument = value; RefreshFilter(); } diff --git a/src/TestUtils/src/DeviceTests.Runners/VisualRunner/ViewModels/TestAssemblyViewModel.cs b/src/TestUtils/src/DeviceTests.Runners/VisualRunner/ViewModels/TestAssemblyViewModel.cs index 302ea0e8bb7b..ff33a392a6dd 100644 --- a/src/TestUtils/src/DeviceTests.Runners/VisualRunner/ViewModels/TestAssemblyViewModel.cs +++ b/src/TestUtils/src/DeviceTests.Runners/VisualRunner/ViewModels/TestAssemblyViewModel.cs @@ -3,18 +3,20 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Maui.Controls; +using Microsoft.Maui.Layouts; namespace Microsoft.Maui.TestUtils.DeviceTests.Runners.VisualRunner { public class TestAssemblyViewModel : ViewModelBase { readonly ObservableCollection _allTests; - readonly FilteredCollectionView _filteredTests; + readonly FilteredCollectionView _filteredTests; readonly ITestNavigation _navigation; readonly ITestRunner _runner; readonly List _results; @@ -70,10 +72,10 @@ internal TestAssemblyViewModel(AssemblyRunInfo runInfo, ITestNavigation navigati } }; - _filteredTests = new FilteredCollectionView( + _filteredTests = new FilteredCollectionView( _allTests, IsTestFilterMatch, - (SearchQuery, ResultFilter), + new FilterArgs(SearchQuery, ResultFilter), new TestComparer()); _filteredTests.ItemChanged += (sender, args) => UpdateCaption(); @@ -177,18 +179,19 @@ void FilterAfterDelay() Task.Delay(500, token) .ContinueWith( - x => { _filteredTests.FilterArgument = (SearchQuery, ResultFilter); }, + x => { _filteredTests.FilterArgument = new FilterArgs(SearchQuery, ResultFilter); }, token, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); } - static bool IsTestFilterMatch(TestCaseViewModel test, (string SearchQuery, TestState ResultFilter) query) + static bool IsTestFilterMatch(TestCaseViewModel test, FilterArgs query) { if (test == null) throw new ArgumentNullException(nameof(test)); - var (pattern, state) = query; + var state = query.State; + var pattern = query.Query; TestState? requiredTestState = state switch { @@ -334,4 +337,31 @@ public int Compare(TestCaseViewModel? x, TestCaseViewModel? y) => string.Compare(x?.DisplayName, y?.DisplayName, StringComparison.OrdinalIgnoreCase); } } + + struct FilterArgs + { + public string Query { get; set; } + public TestState State { get; set; } + + public FilterArgs(string query, TestState state) + { + Query = query; + State = state; + } + + public override bool Equals([NotNullWhen(true)] object? obj) + { + if (obj is FilterArgs args) + { + return args.State == State && args.Query == Query; + } + + return base.Equals(obj); + } + + public override int GetHashCode() + { + return Query.GetHashCode(StringComparison.InvariantCulture) ^ State.GetHashCode(); + } + } }