diff --git a/Wox.Infrastructure/StringMatcher.cs b/Wox.Infrastructure/StringMatcher.cs
index deff9ff7b..9c667ced0 100644
--- a/Wox.Infrastructure/StringMatcher.cs
+++ b/Wox.Infrastructure/StringMatcher.cs
@@ -12,7 +12,7 @@ namespace Wox.Infrastructure
{
public static MatchOption DefaultMatchOption = new MatchOption();
- public static int UserSettingSearchPrecision { get; set; }
+ public static SearchPrecisionScore UserSettingSearchPrecision { get; set; }
public static bool ShouldUsePinyin { get; set; }
@@ -41,7 +41,15 @@ namespace Wox.Infrastructure
}
///
- /// refer to https://github.com/mattyork/fuzzy
+ /// Current method:
+ /// Character matching + substring matching;
+ /// 1. Query search string is split into substrings, separator is whitespace.
+ /// 2. Check each query substring's characters against full compare string,
+ /// 3. if a character in the substring is matched, loop back to verify the previous character.
+ /// 4. If previous character also matches, and is the start of the substring, update list.
+ /// 5. Once the previous character is verified, move on to the next character in the query substring.
+ /// 6. Move onto the next substring's characters until all substrings are checked.
+ /// 7. Consider success and move onto scoring if every char or substring without whitespaces matched
///
public static MatchResult FuzzySearch(string query, string stringToCompare, MatchOption opt)
{
@@ -52,107 +60,93 @@ namespace Wox.Infrastructure
var fullStringToCompareWithoutCase = opt.IgnoreCase ? stringToCompare.ToLower() : stringToCompare;
var queryWithoutCase = opt.IgnoreCase ? query.ToLower() : query;
+
+ var querySubstrings = queryWithoutCase.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
+ int currentQuerySubstringIndex = 0;
+ var currentQuerySubstring = querySubstrings[currentQuerySubstringIndex];
+ var currentQuerySubstringCharacterIndex = 0;
- int currentQueryToCompareIndex = 0;
- var queryToCompareSeparated = queryWithoutCase.Split(' ');
- var currentQueryToCompare = queryToCompareSeparated[currentQueryToCompareIndex];
-
- var patternIndex = 0;
var firstMatchIndex = -1;
var firstMatchIndexInWord = -1;
var lastMatchIndex = 0;
- bool allMatched = false;
- bool isFullWordMatched = false;
- bool allWordsFullyMatched = true;
+ bool allQuerySubstringsMatched = false;
+ bool matchFoundInPreviousLoop = false;
+ bool allSubstringsContainedInCompareString = true;
var indexList = new List();
- for (var index = 0; index < fullStringToCompareWithoutCase.Length; index++)
+ for (var compareStringIndex = 0; compareStringIndex < fullStringToCompareWithoutCase.Length; compareStringIndex++)
{
- var ch = stringToCompare[index];
- if (fullStringToCompareWithoutCase[index] == currentQueryToCompare[patternIndex])
+ if (fullStringToCompareWithoutCase[compareStringIndex] != currentQuerySubstring[currentQuerySubstringCharacterIndex])
{
- if (firstMatchIndex < 0)
- { // first matched char will become the start of the compared string
- firstMatchIndex = index;
- }
+ matchFoundInPreviousLoop = false;
+ continue;
+ }
- if (patternIndex == 0)
- { // first letter of current word
- isFullWordMatched = true;
- firstMatchIndexInWord = index;
- }
- else if (!isFullWordMatched)
- { // we want to verify that there is not a better match if this is not a full word
- // in order to do so we need to verify all previous chars are part of the pattern
- int startIndexToVerify = index - patternIndex;
- bool allMatch = true;
- for (int indexToCheck = 0; indexToCheck < patternIndex; indexToCheck++)
- {
- if (fullStringToCompareWithoutCase[startIndexToVerify + indexToCheck] !=
- currentQueryToCompare[indexToCheck])
- {
- allMatch = false;
- }
- }
+ if (firstMatchIndex < 0)
+ {
+ // first matched char will become the start of the compared string
+ firstMatchIndex = compareStringIndex;
+ }
- if (allMatch)
- { // update to this as a full word
- isFullWordMatched = true;
- if (currentQueryToCompareIndex == 0)
- { // first word so we need to update start index
- firstMatchIndex = startIndexToVerify;
- }
+ if (currentQuerySubstringCharacterIndex == 0)
+ {
+ // first letter of current word
+ matchFoundInPreviousLoop = true;
+ firstMatchIndexInWord = compareStringIndex;
+ }
+ else if (!matchFoundInPreviousLoop)
+ {
+ // we want to verify that there is not a better match if this is not a full word
+ // in order to do so we need to verify all previous chars are part of the pattern
+ var startIndexToVerify = compareStringIndex - currentQuerySubstringCharacterIndex;
- indexList.RemoveAll(x => x >= firstMatchIndexInWord);
- for (int indexToCheck = 0; indexToCheck < patternIndex; indexToCheck++)
- { // update the index list
- indexList.Add(startIndexToVerify + indexToCheck);
- }
- }
- }
-
- lastMatchIndex = index + 1;
- indexList.Add(index);
-
- // increase the pattern matched index and check if everything was matched
- if (++patternIndex == currentQueryToCompare.Length)
+ if (AllPreviousCharsMatched(startIndexToVerify, currentQuerySubstringCharacterIndex, fullStringToCompareWithoutCase, currentQuerySubstring))
{
- if (++currentQueryToCompareIndex >= queryToCompareSeparated.Length)
- { // moved over all the words
- allMatched = true;
- break;
- }
+ matchFoundInPreviousLoop = true;
- // otherwise move to the next word
- currentQueryToCompare = queryToCompareSeparated[currentQueryToCompareIndex];
- patternIndex = 0;
- if (!isFullWordMatched)
- { // if any of the words was not fully matched all are not fully matched
- allWordsFullyMatched = false;
- }
+ // if it's the begining character of the first query substring that is matched then we need to update start index
+ firstMatchIndex = currentQuerySubstringIndex == 0 ? startIndexToVerify : firstMatchIndex;
+
+ indexList = GetUpdatedIndexList(startIndexToVerify, currentQuerySubstringCharacterIndex, firstMatchIndexInWord, indexList);
}
}
- else
+
+ lastMatchIndex = compareStringIndex + 1;
+ indexList.Add(compareStringIndex);
+
+ currentQuerySubstringCharacterIndex++;
+
+ // if finished looping through every character in the current substring
+ if (currentQuerySubstringCharacterIndex == currentQuerySubstring.Length)
{
- isFullWordMatched = false;
+ // if any of the substrings was not matched then consider as all are not matched
+ allSubstringsContainedInCompareString = !matchFoundInPreviousLoop ? false : allSubstringsContainedInCompareString;
+
+ currentQuerySubstringIndex++;
+
+ allQuerySubstringsMatched = AllQuerySubstringsMatched(currentQuerySubstringIndex, querySubstrings.Length);
+ if (allQuerySubstringsMatched)
+ break;
+
+ // otherwise move to the next query substring
+ currentQuerySubstring = querySubstrings[currentQuerySubstringIndex];
+ currentQuerySubstringCharacterIndex = 0;
}
}
-
-
- // return rendered string if we have a match for every char or all substring without whitespaces matched
- if (allMatched)
+
+ // proceed to calculate score if every char or substring without whitespaces matched
+ if (allQuerySubstringsMatched)
{
- // check if all query string was contained in string to compare
- bool containedFully = lastMatchIndex - firstMatchIndex == queryWithoutCase.Length;
- var score = CalculateSearchScore(query, stringToCompare, firstMatchIndex, lastMatchIndex - firstMatchIndex, containedFully, allWordsFullyMatched);
+ var score = CalculateSearchScore(query, stringToCompare, firstMatchIndex, lastMatchIndex - firstMatchIndex, allSubstringsContainedInCompareString);
var pinyinScore = ScoreForPinyin(stringToCompare, query);
var result = new MatchResult
{
Success = true,
MatchData = indexList,
- RawScore = Math.Max(score, pinyinScore)
+ RawScore = Math.Max(score, pinyinScore),
+ AllSubstringsContainedInCompareString = allSubstringsContainedInCompareString
};
return result;
@@ -161,8 +155,44 @@ namespace Wox.Infrastructure
return new MatchResult { Success = false };
}
- private static int CalculateSearchScore(string query, string stringToCompare, int firstIndex, int matchLen,
- bool isFullyContained, bool allWordsFullyMatched)
+ private static bool AllPreviousCharsMatched(int startIndexToVerify, int currentQuerySubstringCharacterIndex,
+ string fullStringToCompareWithoutCase, string currentQuerySubstring)
+ {
+ var allMatch = true;
+ for (int indexToCheck = 0; indexToCheck < currentQuerySubstringCharacterIndex; indexToCheck++)
+ {
+ if (fullStringToCompareWithoutCase[startIndexToVerify + indexToCheck] !=
+ currentQuerySubstring[indexToCheck])
+ {
+ allMatch = false;
+ }
+ }
+
+ return allMatch;
+ }
+
+ private static List GetUpdatedIndexList(int startIndexToVerify, int currentQuerySubstringCharacterIndex, int firstMatchIndexInWord, List indexList)
+ {
+ var updatedList = new List();
+
+ indexList.RemoveAll(x => x >= firstMatchIndexInWord);
+
+ updatedList.AddRange(indexList);
+
+ for (int indexToCheck = 0; indexToCheck < currentQuerySubstringCharacterIndex; indexToCheck++)
+ {
+ updatedList.Add(startIndexToVerify + indexToCheck);
+ }
+
+ return updatedList;
+ }
+
+ private static bool AllQuerySubstringsMatched(int currentQuerySubstringIndex, int querySubstringsLength)
+ {
+ return currentQuerySubstringIndex >= querySubstringsLength;
+ }
+
+ private static int CalculateSearchScore(string query, string stringToCompare, int firstIndex, int matchLen, bool allSubstringsContainedInCompareString)
{
// A match found near the beginning of a string is scored more than a match found near the end
// A match is scored more if the characters in the patterns are closer to each other,
@@ -179,15 +209,8 @@ namespace Wox.Infrastructure
score += 10;
}
- if (isFullyContained)
- {
- score += 20; // honestly I'm not sure what would be a good number here or should it factor the size of the pattern
- }
-
- if (allWordsFullyMatched)
- {
- score += 20;
- }
+ if (allSubstringsContainedInCompareString)
+ score += 10 * string.Concat(query.Where(c => !char.IsWhiteSpace(c))).Count();
return score;
}
@@ -256,6 +279,11 @@ namespace Wox.Infrastructure
}
}
+ ///
+ /// Indicates if all query's substrings are contained in the string to compare
+ ///
+ public bool AllSubstringsContainedInCompareString { get; set; }
+
///
/// Matched data to highlight.
///
@@ -268,7 +296,7 @@ namespace Wox.Infrastructure
private bool IsSearchPrecisionScoreMet(int score)
{
- return score >= UserSettingSearchPrecision;
+ return score >= (int)UserSettingSearchPrecision;
}
private int ApplySearchPrecisionFilter(int score)
diff --git a/Wox.Infrastructure/UserSettings/Settings.cs b/Wox.Infrastructure/UserSettings/Settings.cs
index 5a129832a..b11ec069c 100644
--- a/Wox.Infrastructure/UserSettings/Settings.cs
+++ b/Wox.Infrastructure/UserSettings/Settings.cs
@@ -45,16 +45,19 @@ namespace Wox.Infrastructure.UserSettings
{
try
{
- var precisionScore = (StringMatcher.SearchPrecisionScore)Enum.Parse(
- typeof(StringMatcher.SearchPrecisionScore),
- value);
+ var precisionScore = (StringMatcher.SearchPrecisionScore)Enum
+ .Parse(typeof(StringMatcher.SearchPrecisionScore), value);
+
QuerySearchPrecision = precisionScore;
- StringMatcher.UserSettingSearchPrecision = (int)precisionScore;
+ StringMatcher.UserSettingSearchPrecision = precisionScore;
}
- catch (System.Exception e)
+ catch (ArgumentException e)
{
- // what do we do here?!
- Logger.Log.Exception(nameof(Settings), "Fail to set QuerySearchPrecision", e);
+ Logger.Log.Exception(nameof(Settings), "Failed to load QuerySearchPrecisionString value from Settings file", e);
+
+ QuerySearchPrecision = StringMatcher.SearchPrecisionScore.Regular;
+ StringMatcher.UserSettingSearchPrecision = StringMatcher.SearchPrecisionScore.Regular;
+
throw;
}
}
diff --git a/Wox.Test/FuzzyMatcherTest.cs b/Wox.Test/FuzzyMatcherTest.cs
index b5fe58cac..1a8255987 100644
--- a/Wox.Test/FuzzyMatcherTest.cs
+++ b/Wox.Test/FuzzyMatcherTest.cs
@@ -4,7 +4,6 @@ using System.Diagnostics;
using System.Linq;
using NUnit.Framework;
using Wox.Infrastructure;
-using Wox.Infrastructure.UserSettings;
using Wox.Plugin;
namespace Wox.Test
@@ -122,115 +121,114 @@ namespace Wox.Test
}
}
- [TestCase]
- public void WhenGivenStringsForCalScoreMethodThenShouldReturnCurrentScoring()
+ [TestCase(Chrome, Chrome, 167)]
+ [TestCase(Chrome, LastIsChrome, 113)]
+ [TestCase(Chrome, HelpCureHopeRaiseOnMindEntityChrome, 21)]
+ [TestCase(Chrome, UninstallOrChangeProgramsOnYourComputer, 15)]
+ [TestCase(Chrome, CandyCrushSagaFromKing, 0)]
+ [TestCase("sql", MicrosoftSqlServerManagementStudio, 56)]
+ [TestCase("sql manag", MicrosoftSqlServerManagementStudio, 119)]//double spacing intended
+ public void WhenGivenQueryStringThenShouldReturnCurrentScoring(string queryString, string compareString, int expectedScore)
{
- // Arrange
- string searchTerm = "chrome"; // since this looks for specific results it will always be one case
- var searchStrings = new List
- {
- Chrome,//SCORE: 107
- LastIsChrome,//SCORE: 53
- HelpCureHopeRaiseOnMindEntityChrome,//SCORE: 21
- UninstallOrChangeProgramsOnYourComputer, //SCORE: 15
- CandyCrushSagaFromKing//SCORE: 0
- }
- .OrderByDescending(x => x)
- .ToList();
+ // When, Given
+ var rawScore = StringMatcher.FuzzySearch(queryString, compareString).RawScore;
- // Act
- var results = new List();
- foreach (var str in searchStrings)
- {
- results.Add(new Result
- {
- Title = str,
- Score = StringMatcher.FuzzySearch(searchTerm, str).RawScore
- });
- }
-
- // Assert
- VerifyResult(147, Chrome);
- VerifyResult(93, LastIsChrome);
- VerifyResult(41, HelpCureHopeRaiseOnMindEntityChrome);
- VerifyResult(35, UninstallOrChangeProgramsOnYourComputer);
- VerifyResult(0, CandyCrushSagaFromKing);
-
- void VerifyResult(int expectedScore, string expectedTitle)
- {
- var result = results.FirstOrDefault(x => x.Title == expectedTitle);
- if (result == null)
- {
- Assert.Fail($"Fail to find result: {expectedTitle} in result list");
- }
-
- Assert.AreEqual(expectedScore, result.Score, $"Expected score for {expectedTitle}: {expectedScore}, Actual: {result.Score}");
- }
+ // Should
+ Assert.AreEqual(expectedScore, rawScore, $"Expected score for compare string '{compareString}': {expectedScore}, Actual: {rawScore}");
}
- [TestCase("goo", "Google Chrome", (int)StringMatcher.SearchPrecisionScore.Regular, true)]
- [TestCase("chr", "Google Chrome", (int)StringMatcher.SearchPrecisionScore.Low, true)]
- [TestCase("chr", "Chrome", (int)StringMatcher.SearchPrecisionScore.Regular, true)]
- [TestCase("chr", "Help cure hope raise on mind entity Chrome", (int)StringMatcher.SearchPrecisionScore.Regular, false)]
- [TestCase("chr", "Help cure hope raise on mind entity Chrome", (int)StringMatcher.SearchPrecisionScore.Low, true)]
- [TestCase("chr", "Candy Crush Saga from King", (int)StringMatcher.SearchPrecisionScore.Regular, false)]
- [TestCase("chr", "Candy Crush Saga from King", (int)StringMatcher.SearchPrecisionScore.None, true)]
- [TestCase("ccs", "Candy Crush Saga from King", (int)StringMatcher.SearchPrecisionScore.Low, true)]
- [TestCase("cand", "Candy Crush Saga from King", (int)StringMatcher.SearchPrecisionScore.Regular, true)]
- [TestCase("cand", "Help cure hope raise on mind entity Chrome", (int)StringMatcher.SearchPrecisionScore.Regular, false)]
+ [TestCase("goo", "Google Chrome", StringMatcher.SearchPrecisionScore.Regular, true)]
+ [TestCase("chr", "Google Chrome", StringMatcher.SearchPrecisionScore.Low, true)]
+ [TestCase("chr", "Chrome", StringMatcher.SearchPrecisionScore.Regular, true)]
+ [TestCase("chr", "Help cure hope raise on mind entity Chrome", StringMatcher.SearchPrecisionScore.Regular, false)]
+ [TestCase("chr", "Help cure hope raise on mind entity Chrome", StringMatcher.SearchPrecisionScore.Low, true)]
+ [TestCase("chr", "Candy Crush Saga from King", StringMatcher.SearchPrecisionScore.Regular, false)]
+ [TestCase("chr", "Candy Crush Saga from King", StringMatcher.SearchPrecisionScore.None, true)]
+ [TestCase("ccs", "Candy Crush Saga from King", StringMatcher.SearchPrecisionScore.Low, true)]
+ [TestCase("cand", "Candy Crush Saga from King",StringMatcher.SearchPrecisionScore.Regular, true)]
+ [TestCase("cand", "Help cure hope raise on mind entity Chrome", StringMatcher.SearchPrecisionScore.Regular, false)]
public void WhenGivenDesiredPrecisionThenShouldReturnAllResultsGreaterOrEqual(
string queryString,
string compareString,
- int expectedPrecisionScore,
+ StringMatcher.SearchPrecisionScore expectedPrecisionScore,
bool expectedPrecisionResult)
{
- // Arrange
- var expectedPrecisionString = (StringMatcher.SearchPrecisionScore)expectedPrecisionScore;
- StringMatcher.UserSettingSearchPrecision = expectedPrecisionScore; // this is why static state is evil...
+ // When
+ StringMatcher.UserSettingSearchPrecision = expectedPrecisionScore;
- // Act
+ // Given
var matchResult = StringMatcher.FuzzySearch(queryString, compareString);
- // Assert
+ Debug.WriteLine("");
+ Debug.WriteLine("###############################################");
+ Debug.WriteLine($"QueryString: {queryString} CompareString: {compareString}");
+ Debug.WriteLine($"RAW SCORE: {matchResult.RawScore.ToString()}, PrecisionLevelSetAt: {expectedPrecisionScore} ({(int)expectedPrecisionScore})");
+ Debug.WriteLine("###############################################");
+ Debug.WriteLine("");
+
+ // Should
Assert.AreEqual(expectedPrecisionResult, matchResult.IsSearchPrecisionScoreMet(),
$"Query:{queryString}{Environment.NewLine} " +
$"Compare:{compareString}{Environment.NewLine}" +
$"Raw Score: {matchResult.RawScore}{Environment.NewLine}" +
- $"Precision Level: {expectedPrecisionString}={expectedPrecisionScore}");
+ $"Precision Score: {(int)expectedPrecisionScore}");
}
- [TestCase("exce", "OverLeaf-Latex: An online LaTeX editor", (int)StringMatcher.SearchPrecisionScore.Regular, false)]
- [TestCase("term", "Windows Terminal (Preview)", (int)StringMatcher.SearchPrecisionScore.Regular, true)]
- [TestCase("sql s managa", MicrosoftSqlServerManagementStudio, (int)StringMatcher.SearchPrecisionScore.Regular, false)]
- [TestCase("sql' s manag", MicrosoftSqlServerManagementStudio, (int)StringMatcher.SearchPrecisionScore.Regular, false)]
- [TestCase("sql s manag", MicrosoftSqlServerManagementStudio, (int)StringMatcher.SearchPrecisionScore.Regular, true)]
- [TestCase("sql manag", MicrosoftSqlServerManagementStudio, (int)StringMatcher.SearchPrecisionScore.Regular, true)]
- [TestCase("sql", MicrosoftSqlServerManagementStudio, (int)StringMatcher.SearchPrecisionScore.Regular, true)]
- [TestCase("sql serv", MicrosoftSqlServerManagementStudio, (int)StringMatcher.SearchPrecisionScore.Regular, true)]
- [TestCase("mic", MicrosoftSqlServerManagementStudio, (int)StringMatcher.SearchPrecisionScore.Regular, true)]
- [TestCase("chr", "Shutdown", (int)StringMatcher.SearchPrecisionScore.Regular, false)]
- [TestCase("chr", "Change settings for text-to-speech and for speech recognition (if installed).", (int)StringMatcher.SearchPrecisionScore.Regular, false)]
- [TestCase("a test", "This is a test", (int)StringMatcher.SearchPrecisionScore.Regular, true)]
- [TestCase("test", "This is a test", (int)StringMatcher.SearchPrecisionScore.Regular, true)]
+ [TestCase("exce", "OverLeaf-Latex: An online LaTeX editor", StringMatcher.SearchPrecisionScore.Regular, false)]
+ [TestCase("term", "Windows Terminal (Preview)", StringMatcher.SearchPrecisionScore.Regular, true)]
+ [TestCase("sql s managa", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
+ [TestCase("sql' s manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)]
+ [TestCase("sql s manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
+ [TestCase("sql manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
+ [TestCase("sql", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
+ [TestCase("sql serv", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
+ [TestCase("sql studio", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
+ [TestCase("mic", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)]
+ [TestCase("chr", "Shutdown", StringMatcher.SearchPrecisionScore.Regular, false)]
+ [TestCase("chr", "Change settings for text-to-speech and for speech recognition (if installed).", StringMatcher.SearchPrecisionScore.Regular, false)]
+ [TestCase("a test", "This is a test", StringMatcher.SearchPrecisionScore.Regular, true)]
+ [TestCase("test", "This is a test", StringMatcher.SearchPrecisionScore.Regular, true)]
public void WhenGivenQueryShouldReturnResultsContainingAllQuerySubstrings(
string queryString,
string compareString,
- int expectedPrecisionScore,
+ StringMatcher.SearchPrecisionScore expectedPrecisionScore,
bool expectedPrecisionResult)
{
- // Arrange
- var expectedPrecisionString = (StringMatcher.SearchPrecisionScore)expectedPrecisionScore;
- StringMatcher.UserSettingSearchPrecision = expectedPrecisionScore; // this is why static state is evil...
+ // When
+ StringMatcher.UserSettingSearchPrecision = expectedPrecisionScore;
- // Act
+ // Given
var matchResult = StringMatcher.FuzzySearch(queryString, compareString);
- // Assert
+ Debug.WriteLine("");
+ Debug.WriteLine("###############################################");
+ Debug.WriteLine($"QueryString: {queryString} CompareString: {compareString}");
+ Debug.WriteLine($"RAW SCORE: {matchResult.RawScore.ToString()}, PrecisionLevelSetAt: {expectedPrecisionScore} ({(int)expectedPrecisionScore})");
+ Debug.WriteLine("###############################################");
+ Debug.WriteLine("");
+
+ // Should
Assert.AreEqual(expectedPrecisionResult, matchResult.IsSearchPrecisionScoreMet(),
$"Query:{queryString}{Environment.NewLine} " +
$"Compare:{compareString}{Environment.NewLine}" +
$"Raw Score: {matchResult.RawScore}{Environment.NewLine}" +
- $"Precision Level: {expectedPrecisionString}={expectedPrecisionScore}");
+ $"Precision Score: {(int)expectedPrecisionScore}");
+ }
+
+ [TestCase("sql servman", MicrosoftSqlServerManagementStudio, false)]
+ [TestCase("sql serv man", MicrosoftSqlServerManagementStudio, true)]
+ [TestCase("sql", MicrosoftSqlServerManagementStudio, true)]
+ [TestCase("sqlserv", MicrosoftSqlServerManagementStudio, false)]
+ [TestCase("mssms", MicrosoftSqlServerManagementStudio, false)]
+ [TestCase("chr", "Change settings for text-to-speech and for speech recognition (if installed).", false)]
+ [TestCase("ch r", "Change settings for text-to-speech and for speech recognition (if installed).", true)]
+ public void WhenGivenQueryShouldEvaluateTrueFalseIfCompareStringContainsAllSubstrings(string queryString, string compareString, bool expectedResult)
+ {
+ // When, Given
+ var matchResult = StringMatcher.FuzzySearch(queryString, compareString).AllSubstringsContainedInCompareString;
+
+ // Should
+ Assert.AreEqual(matchResult, expectedResult);
}
}
}
\ No newline at end of file
diff --git a/Wox/App.xaml.cs b/Wox/App.xaml.cs
index aa5426d06..9436df475 100644
--- a/Wox/App.xaml.cs
+++ b/Wox/App.xaml.cs
@@ -55,7 +55,7 @@ namespace Wox
Alphabet.Initialize(_settings);
- StringMatcher.UserSettingSearchPrecision = (int)_settings.QuerySearchPrecision;
+ StringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
StringMatcher.ShouldUsePinyin = _settings.ShouldUsePinyin;
PluginManager.LoadPlugins(_settings.PluginSettings);
diff --git a/Wox/ViewModel/SettingWindowViewModel.cs b/Wox/ViewModel/SettingWindowViewModel.cs
index 67b8d7af0..19a31be58 100644
--- a/Wox/ViewModel/SettingWindowViewModel.cs
+++ b/Wox/ViewModel/SettingWindowViewModel.cs
@@ -73,7 +73,7 @@ namespace Wox.ViewModel
public List QuerySearchPrecisionStrings
{
get
- {
+ {
var precisionStrings = new List();
var enumList = Enum.GetValues(typeof(StringMatcher.SearchPrecisionScore)).Cast().ToList();