< Summary

Information
Class: SwitchBlade.Core.WindowSearchService
Assembly: SwitchBlade
File(s): D:\a\switchblade\switchblade\Core\WindowSearchService.cs
Tag: 203_23722840422
Line coverage
100%
Covered lines: 52
Uncovered lines: 0
Coverable lines: 52
Total lines: 94
Line coverage: 100%
Branch coverage
100%
Covered branches: 12
Total branches: 12
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%44100%
Search(...)100%88100%

File(s)

D:\a\switchblade\switchblade\Core\WindowSearchService.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using SwitchBlade.Contracts;
 5
 6namespace SwitchBlade.Core
 7{
 8    /// <summary>
 9    /// Provides window search and filtering capabilities.
 10    /// Extracted from MainViewModel to follow Single Responsibility Principle.
 11    /// </summary>
 12    public class WindowSearchService : IWindowSearchService
 13    {
 14        private readonly IRegexCache _regexCache;
 15        private readonly IMatcher _matcher;
 16
 17        /// <summary>
 18        /// Creates a new WindowSearchService with the specified regex cache and matcher.
 19        /// </summary>
 20        /// <param name="regexCache">The regex cache to use for pattern compilation.</param>
 21        /// <param name="matcher">The matching algorithm to use for fuzzy search.</param>
 1622        public WindowSearchService(IRegexCache regexCache, IMatcher? matcher = null)
 1623        {
 1624            _regexCache = regexCache ?? throw new ArgumentNullException(nameof(regexCache));
 1525            _matcher = matcher ?? new FuzzyMatcherAdapter();
 1526        }
 27
 28        /// <inheritdoc />
 29        public IList<WindowItem> Search(IEnumerable<WindowItem> windows, string query, bool useFuzzy)
 2230        {
 2231            if (windows == null)
 132                return new List<WindowItem>();
 33
 2134            var windowList = windows.ToList();
 35
 2136            if (string.IsNullOrWhiteSpace(query))
 737            {
 38                // Empty query: return all windows sorted alphabetically
 739                return windowList
 740                    .Distinct()
 741                    .OrderBy(w => w.ProcessName)
 742                    .ThenBy(w => w.Title)
 743                    .ThenBy(w => w.Hwnd.ToInt64())
 744                    .ToList();
 45            }
 46
 47            List<WindowItem> results;
 48
 1449            if (useFuzzy)
 1050            {
 51                // Fuzzy search: Score all items and filter/sort by score
 1052                results = windowList
 1353                    .Select(w => new { Item = w, Score = _matcher.Score(w.Title, query) })
 1354                    .Where(x => x.Score > 0)
 755                    .OrderByDescending(x => x.Score)
 756                    .ThenBy(x => x.Item.ProcessName)
 757                    .ThenBy(x => x.Item.Title)
 758                    .Select(x => x.Item)
 1059                    .Distinct()
 1060                    .ToList();
 1061            }
 62            else
 463            {
 64                // Regex/substring matching
 465                var regex = _regexCache.GetOrCreate(query);
 66
 467                if (regex != null)
 368                {
 369                    results = windowList
 570                        .Where(w => regex.IsMatch(w.Title))
 371                        .Distinct()
 372                        .ToList();
 373                }
 74                else
 175                {
 76                    // Fallback to substring matching if regex is invalid
 177                    results = windowList
 278                        .Where(w => w.Title.Contains(query, StringComparison.OrdinalIgnoreCase))
 179                        .Distinct()
 180                        .ToList();
 181                }
 82
 83                // Apply stable sort: Process Name -> Title -> Hwnd
 484                results = results
 285                    .OrderBy(w => w.ProcessName)
 286                    .ThenBy(w => w.Title)
 287                    .ThenBy(w => w.Hwnd.ToInt64())
 488                    .ToList();
 489            }
 90
 1491            return results;
 2292        }
 93    }
 94}