mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-04 11:59:07 +08:00
To remove the condition that space is needed after the Action keyword (#6003)
* Returning individual queries for each plugin * Changed cancellation token from Query type to directly using the rawQuery * Changed the way we get the plugins for which we execute the query * updated UpdateResultView to take a string instead of query * Changed the way we set a query for each plugin * removed todo comment * global plugins are added as a part of the query builder * Fix for plugin.json of Folder plugin being copied into the shell plugin * >,< and : are not allowed in file paths and indexer creates a query which searches compares if a file name is greater than or lesser than the query * Reformatted the regex * catching the exception * fixed existing tests * modified it so that it works with action keyword as well as action keywords * Added unit tests for non global plugins * fixed test * add back whitespace that was removed by mistake * fix regex * modified the cold start query * remove extra condition * terms being modified as expected * used key value pairs to iterate through the dictionary * renamed variable * added check for an empty dictionary * remove : because it may appear in the file path * fix some whitespace warnings that were being treated as errors
This commit is contained in:
parent
f6b5840e0e
commit
80f8c0399b
@ -40,7 +40,7 @@ namespace Microsoft.Plugin.Indexer
|
|||||||
private readonly IndexerDriveDetection _driveDetection = new IndexerDriveDetection(new RegistryWrapper());
|
private readonly IndexerDriveDetection _driveDetection = new IndexerDriveDetection(new RegistryWrapper());
|
||||||
|
|
||||||
// Reserved keywords in oleDB
|
// Reserved keywords in oleDB
|
||||||
private readonly string reservedStringPattern = @"^[\/\\\$\%]+$";
|
private readonly string reservedStringPattern = @"^[\/\\\$\%]+$|^.*[<>].*$";
|
||||||
|
|
||||||
private string WarningIconPath { get; set; }
|
private string WarningIconPath { get; set; }
|
||||||
|
|
||||||
|
@ -29,7 +29,9 @@ namespace PowerLauncher.ViewModel
|
|||||||
{
|
{
|
||||||
public class MainViewModel : BaseModel, ISavable, IDisposable
|
public class MainViewModel : BaseModel, ISavable, IDisposable
|
||||||
{
|
{
|
||||||
private static readonly Query _emptyQuery = new Query();
|
private string _currentQuery;
|
||||||
|
private static string _emptyQuery = string.Empty;
|
||||||
|
|
||||||
private static bool _disposed;
|
private static bool _disposed;
|
||||||
|
|
||||||
private readonly WoxJsonStorage<QueryHistory> _historyItemsStorage;
|
private readonly WoxJsonStorage<QueryHistory> _historyItemsStorage;
|
||||||
@ -43,7 +45,6 @@ namespace PowerLauncher.ViewModel
|
|||||||
private readonly Internationalization _translator = InternationalizationManager.Instance;
|
private readonly Internationalization _translator = InternationalizationManager.Instance;
|
||||||
private readonly System.Diagnostics.Stopwatch _hotkeyTimer = new System.Diagnostics.Stopwatch();
|
private readonly System.Diagnostics.Stopwatch _hotkeyTimer = new System.Diagnostics.Stopwatch();
|
||||||
|
|
||||||
private Query _currentQuery;
|
|
||||||
private string _queryTextBeforeLeaveResults;
|
private string _queryTextBeforeLeaveResults;
|
||||||
|
|
||||||
private CancellationTokenSource _updateSource;
|
private CancellationTokenSource _updateSource;
|
||||||
@ -113,7 +114,7 @@ namespace PowerLauncher.ViewModel
|
|||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
PluginManager.UpdatePluginMetadata(e.Results, pair.Metadata, e.Query);
|
PluginManager.UpdatePluginMetadata(e.Results, pair.Metadata, e.Query);
|
||||||
UpdateResultView(e.Results, e.Query, _updateToken);
|
UpdateResultView(e.Results, e.Query.RawQuery, _updateToken);
|
||||||
}, _updateToken);
|
}, _updateToken);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -461,24 +462,32 @@ namespace PowerLauncher.ViewModel
|
|||||||
_updateSource = currentUpdateSource;
|
_updateSource = currentUpdateSource;
|
||||||
var currentCancellationToken = _updateSource.Token;
|
var currentCancellationToken = _updateSource.Token;
|
||||||
_updateToken = currentCancellationToken;
|
_updateToken = currentCancellationToken;
|
||||||
|
var queryText = QueryText.Trim();
|
||||||
|
|
||||||
var query = QueryBuilder.Build(QueryText.Trim(), PluginManager.NonGlobalPlugins);
|
var pluginQueryPairs = QueryBuilder.Build(ref queryText, PluginManager.NonGlobalPlugins);
|
||||||
if (query != null)
|
if (pluginQueryPairs != null && pluginQueryPairs.Count > 0)
|
||||||
{
|
{
|
||||||
_currentQuery = query;
|
_currentQuery = queryText;
|
||||||
Task.Run(
|
Task.Run(
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
Thread.Sleep(20);
|
Thread.Sleep(20);
|
||||||
var plugins = PluginManager.ValidPluginsForQuery(query);
|
|
||||||
|
// Contains all the plugins for which this raw query is valid
|
||||||
|
var plugins = pluginQueryPairs.Keys.ToList();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
currentCancellationToken.ThrowIfCancellationRequested();
|
currentCancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
var resultPluginPair = new List<(List<Result>, PluginMetadata)>();
|
var resultPluginPair = new List<(List<Result>, PluginMetadata)>();
|
||||||
foreach (PluginPair plugin in plugins)
|
|
||||||
|
// To execute a query corresponding to each plugin
|
||||||
|
foreach (KeyValuePair<PluginPair, Query> pluginQueryItem in pluginQueryPairs)
|
||||||
{
|
{
|
||||||
|
var plugin = pluginQueryItem.Key;
|
||||||
|
var query = pluginQueryItem.Value;
|
||||||
|
|
||||||
if (!plugin.Metadata.Disabled)
|
if (!plugin.Metadata.Disabled)
|
||||||
{
|
{
|
||||||
var results = PluginManager.QueryForPlugin(plugin, query);
|
var results = PluginManager.QueryForPlugin(plugin, query);
|
||||||
@ -489,12 +498,12 @@ namespace PowerLauncher.ViewModel
|
|||||||
|
|
||||||
lock (_addResultsLock)
|
lock (_addResultsLock)
|
||||||
{
|
{
|
||||||
if (query.RawQuery == _currentQuery.RawQuery)
|
if (queryText.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
Results.Clear();
|
Results.Clear();
|
||||||
foreach (var p in resultPluginPair)
|
foreach (var p in resultPluginPair)
|
||||||
{
|
{
|
||||||
UpdateResultView(p.Item1, query, currentCancellationToken);
|
UpdateResultView(p.Item1, queryText, currentCancellationToken);
|
||||||
currentCancellationToken.ThrowIfCancellationRequested();
|
currentCancellationToken.ThrowIfCancellationRequested();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,7 +513,8 @@ namespace PowerLauncher.ViewModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentCancellationToken.ThrowIfCancellationRequested();
|
currentCancellationToken.ThrowIfCancellationRequested();
|
||||||
UpdateResultsListViewAfterQuery(query);
|
|
||||||
|
UpdateResultsListViewAfterQuery(queryText);
|
||||||
|
|
||||||
// Run the slower query of the DelayedExecution plugins
|
// Run the slower query of the DelayedExecution plugins
|
||||||
currentCancellationToken.ThrowIfCancellationRequested();
|
currentCancellationToken.ThrowIfCancellationRequested();
|
||||||
@ -514,13 +524,16 @@ namespace PowerLauncher.ViewModel
|
|||||||
{
|
{
|
||||||
if (!plugin.Metadata.Disabled)
|
if (!plugin.Metadata.Disabled)
|
||||||
{
|
{
|
||||||
|
Query query;
|
||||||
|
pluginQueryPairs.TryGetValue(plugin, out query);
|
||||||
|
|
||||||
var results = PluginManager.QueryForPlugin(plugin, query, true);
|
var results = PluginManager.QueryForPlugin(plugin, query, true);
|
||||||
currentCancellationToken.ThrowIfCancellationRequested();
|
currentCancellationToken.ThrowIfCancellationRequested();
|
||||||
if ((results?.Count ?? 0) != 0)
|
if ((results?.Count ?? 0) != 0)
|
||||||
{
|
{
|
||||||
lock (_addResultsLock)
|
lock (_addResultsLock)
|
||||||
{
|
{
|
||||||
if (query.RawQuery == _currentQuery.RawQuery)
|
if (queryText.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
currentCancellationToken.ThrowIfCancellationRequested();
|
currentCancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
@ -529,14 +542,15 @@ namespace PowerLauncher.ViewModel
|
|||||||
currentCancellationToken.ThrowIfCancellationRequested();
|
currentCancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
// Add the new results from the plugin
|
// Add the new results from the plugin
|
||||||
UpdateResultView(results, query, currentCancellationToken);
|
UpdateResultView(results, queryText, currentCancellationToken);
|
||||||
|
|
||||||
currentCancellationToken.ThrowIfCancellationRequested();
|
currentCancellationToken.ThrowIfCancellationRequested();
|
||||||
Results.Sort();
|
Results.Sort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentCancellationToken.ThrowIfCancellationRequested();
|
currentCancellationToken.ThrowIfCancellationRequested();
|
||||||
UpdateResultsListViewAfterQuery(query, true);
|
UpdateResultsListViewAfterQuery(queryText, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -556,7 +570,7 @@ namespace PowerLauncher.ViewModel
|
|||||||
{
|
{
|
||||||
QueryTimeMs = queryTimer.ElapsedMilliseconds,
|
QueryTimeMs = queryTimer.ElapsedMilliseconds,
|
||||||
NumResults = Results.Results.Count,
|
NumResults = Results.Results.Count,
|
||||||
QueryLength = query.RawQuery.Length,
|
QueryLength = queryText.Length,
|
||||||
};
|
};
|
||||||
PowerToysTelemetry.Log.WriteEvent(queryEvent);
|
PowerToysTelemetry.Log.WriteEvent(queryEvent);
|
||||||
}, currentCancellationToken);
|
}, currentCancellationToken);
|
||||||
@ -572,11 +586,11 @@ namespace PowerLauncher.ViewModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateResultsListViewAfterQuery(Query query, bool isDelayedInvoke = false)
|
private void UpdateResultsListViewAfterQuery(string queryText, bool isDelayedInvoke = false)
|
||||||
{
|
{
|
||||||
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||||
{
|
{
|
||||||
if (query.RawQuery == _currentQuery.RawQuery)
|
if (queryText.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
Results.Results.NotifyChanges();
|
Results.Results.NotifyChanges();
|
||||||
}
|
}
|
||||||
@ -740,7 +754,7 @@ namespace PowerLauncher.ViewModel
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// To avoid deadlock, this method should not called from main thread
|
/// To avoid deadlock, this method should not called from main thread
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void UpdateResultView(List<Result> list, Query originQuery, CancellationToken ct)
|
public void UpdateResultView(List<Result> list, string originQuery, CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (list == null)
|
if (list == null)
|
||||||
{
|
{
|
||||||
@ -764,7 +778,7 @@ namespace PowerLauncher.ViewModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (originQuery.RawQuery == _currentQuery.RawQuery)
|
if (originQuery.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
ct.ThrowIfCancellationRequested();
|
ct.ThrowIfCancellationRequested();
|
||||||
Results.AddResults(list, ct);
|
Results.AddResults(list, ct);
|
||||||
@ -786,10 +800,14 @@ namespace PowerLauncher.ViewModel
|
|||||||
|
|
||||||
// Fix Cold start for plugins
|
// Fix Cold start for plugins
|
||||||
string s = "m";
|
string s = "m";
|
||||||
var query = QueryBuilder.Build(s.Trim(), PluginManager.NonGlobalPlugins);
|
var pluginQueryPairs = QueryBuilder.Build(ref s, PluginManager.NonGlobalPlugins);
|
||||||
var plugins = PluginManager.ValidPluginsForQuery(query);
|
|
||||||
foreach (PluginPair plugin in plugins)
|
// To execute a query corresponding to each plugin
|
||||||
|
foreach (KeyValuePair<PluginPair, Query> pluginQueryItem in pluginQueryPairs)
|
||||||
{
|
{
|
||||||
|
var plugin = pluginQueryItem.Key;
|
||||||
|
var query = pluginQueryItem.Value;
|
||||||
|
|
||||||
if (!plugin.Metadata.Disabled && plugin.Metadata.Name != "Window Walker")
|
if (!plugin.Metadata.Disabled && plugin.Metadata.Name != "Window Walker")
|
||||||
{
|
{
|
||||||
_ = PluginManager.QueryForPlugin(plugin, query);
|
_ = PluginManager.QueryForPlugin(plugin, query);
|
||||||
|
@ -11,7 +11,7 @@ namespace Wox.Core.Plugin
|
|||||||
{
|
{
|
||||||
public static class QueryBuilder
|
public static class QueryBuilder
|
||||||
{
|
{
|
||||||
public static Query Build(string text, Dictionary<string, PluginPair> nonGlobalPlugins)
|
public static Dictionary<PluginPair, Query> Build(ref string text, Dictionary<string, PluginPair> nonGlobalPlugins)
|
||||||
{
|
{
|
||||||
// replace multiple white spaces with one white space
|
// replace multiple white spaces with one white space
|
||||||
var terms = text.Split(new[] { Query.TermSeparator }, StringSplitOptions.RemoveEmptyEntries);
|
var terms = text.Split(new[] { Query.TermSeparator }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
@ -20,32 +20,54 @@ namespace Wox.Core.Plugin
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This Dictionary contains the corresponding query for each plugin
|
||||||
|
Dictionary<PluginPair, Query> pluginQueryPair = new Dictionary<PluginPair, Query>();
|
||||||
|
|
||||||
var rawQuery = string.Join(Query.TermSeparator, terms);
|
var rawQuery = string.Join(Query.TermSeparator, terms);
|
||||||
string actionKeyword, search;
|
|
||||||
|
// This is the query on removing extra spaces which would be executed by global Plugins
|
||||||
|
text = rawQuery;
|
||||||
|
|
||||||
string possibleActionKeyword = terms[0];
|
string possibleActionKeyword = terms[0];
|
||||||
List<string> actionParameters;
|
|
||||||
if (nonGlobalPlugins.TryGetValue(possibleActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled)
|
|
||||||
{ // use non global plugin for query
|
|
||||||
actionKeyword = possibleActionKeyword;
|
|
||||||
actionParameters = terms.Skip(1).ToList();
|
|
||||||
search = actionParameters.Count > 0 ? rawQuery.Substring(actionKeyword.Length + 1) : string.Empty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // non action keyword
|
|
||||||
actionKeyword = string.Empty;
|
|
||||||
actionParameters = terms.ToList();
|
|
||||||
search = rawQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
var query = new Query
|
foreach (string pluginActionKeyword in nonGlobalPlugins.Keys)
|
||||||
{
|
{
|
||||||
Terms = terms,
|
if (possibleActionKeyword.StartsWith(pluginActionKeyword))
|
||||||
RawQuery = rawQuery,
|
{
|
||||||
ActionKeyword = actionKeyword,
|
if (nonGlobalPlugins.TryGetValue(pluginActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled)
|
||||||
Search = search,
|
{
|
||||||
};
|
// The search string is the raw query excluding the action keyword
|
||||||
|
string search = rawQuery.Substring(pluginActionKeyword.Length).Trim();
|
||||||
|
|
||||||
return query;
|
// To set the terms of the query after removing the action keyword
|
||||||
|
if (possibleActionKeyword.Length > pluginActionKeyword.Length)
|
||||||
|
{
|
||||||
|
// If the first term contains the action keyword, then set the remaining string to be the first term
|
||||||
|
terms[0] = possibleActionKeyword.Substring(pluginActionKeyword.Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the first term is the action keyword, then skip it.
|
||||||
|
terms = terms.Skip(1).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// A new query is constructed for each plugin as they have different action keywords
|
||||||
|
var query = new Query(rawQuery, search, terms, pluginActionKeyword);
|
||||||
|
|
||||||
|
pluginQueryPair.TryAdd(pluginPair, query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var globalplugins = PluginManager.GlobalPlugins;
|
||||||
|
|
||||||
|
foreach (PluginPair globalPlugin in PluginManager.GlobalPlugins)
|
||||||
|
{
|
||||||
|
var query = new Query(rawQuery, rawQuery, terms, string.Empty);
|
||||||
|
pluginQueryPair.Add(globalPlugin, query);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pluginQueryPair;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,45 +11,191 @@ namespace Wox.Test
|
|||||||
{
|
{
|
||||||
public class QueryBuilderTest
|
public class QueryBuilderTest
|
||||||
{
|
{
|
||||||
[Test]
|
private bool AreEqual(Query firstQuery, Query secondQuery)
|
||||||
public void ExclusivePluginQueryTest()
|
|
||||||
{
|
{
|
||||||
|
return firstQuery.ActionKeyword.Equals(secondQuery.ActionKeyword)
|
||||||
|
&& firstQuery.Search.Equals(secondQuery.Search)
|
||||||
|
&& firstQuery.RawQuery.Equals(secondQuery.RawQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void QueryBuilder_ShouldRemoveExtraSpaces_ForNonGlobalPlugin()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
var nonGlobalPlugins = new Dictionary<string, PluginPair>
|
var nonGlobalPlugins = new Dictionary<string, PluginPair>
|
||||||
{
|
{
|
||||||
{ ">", new PluginPair { Metadata = new PluginMetadata { ActionKeywords = new List<string> { ">" } } } },
|
{ ">", new PluginPair { Metadata = new PluginMetadata { ActionKeywords = new List<string> { ">" } } } },
|
||||||
};
|
};
|
||||||
|
string searchQuery = "> file.txt file2 file3";
|
||||||
|
|
||||||
Query q = QueryBuilder.Build("> file.txt file2 file3", nonGlobalPlugins);
|
// Act
|
||||||
|
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery, nonGlobalPlugins);
|
||||||
|
|
||||||
Assert.AreEqual("file.txt file2 file3", q.Search);
|
// Assert
|
||||||
Assert.AreEqual(">", q.ActionKeyword);
|
Assert.AreEqual("> file.txt file2 file3", searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ExclusivePluginQueryIgnoreDisabledTest()
|
public void QueryBuilder_ShouldRemoveExtraSpaces_ForDisabledNonGlobalPlugin()
|
||||||
{
|
{
|
||||||
|
// Arrange
|
||||||
var nonGlobalPlugins = new Dictionary<string, PluginPair>
|
var nonGlobalPlugins = new Dictionary<string, PluginPair>
|
||||||
{
|
{
|
||||||
{ ">", new PluginPair { Metadata = new PluginMetadata { ActionKeywords = new List<string> { ">" }, Disabled = true } } },
|
{ ">", new PluginPair { Metadata = new PluginMetadata { ActionKeywords = new List<string> { ">" }, Disabled = true } } },
|
||||||
};
|
};
|
||||||
|
string searchQuery = "> file.txt file2 file3";
|
||||||
|
|
||||||
Query q = QueryBuilder.Build("> file.txt file2 file3", nonGlobalPlugins);
|
// Act
|
||||||
|
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery, nonGlobalPlugins);
|
||||||
|
|
||||||
Assert.AreEqual("> file.txt file2 file3", q.Search);
|
// Assert
|
||||||
|
Assert.AreEqual("> file.txt file2 file3", searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void GenericPluginQueryTest()
|
public void QueryBuilder_ShouldRemoveExtraSpaces_ForGlobalPlugin()
|
||||||
{
|
{
|
||||||
Query q = QueryBuilder.Build("file.txt file2 file3", new Dictionary<string, PluginPair>());
|
// Arrange
|
||||||
|
string searchQuery = "file.txt file2 file3";
|
||||||
|
|
||||||
Assert.AreEqual("file.txt file2 file3", q.Search);
|
// Act
|
||||||
Assert.AreEqual(string.Empty, q.ActionKeyword);
|
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery, new Dictionary<string, PluginPair>());
|
||||||
|
|
||||||
Assert.AreEqual("file.txt", q.FirstSearch);
|
// Assert
|
||||||
Assert.AreEqual("file2", q.SecondSearch);
|
Assert.AreEqual("file.txt file2 file3", searchQuery);
|
||||||
Assert.AreEqual("file3", q.ThirdSearch);
|
}
|
||||||
Assert.AreEqual("file2 file3", q.SecondToEndSearch);
|
|
||||||
|
[Test]
|
||||||
|
public void QueryBuilder_ShouldGenerateSameQuery_IfEitherActionKeywordOrActionKeywordsListIsSet()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
string searchQuery = "> query";
|
||||||
|
var firstPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeywords = new List<string> { ">" } } };
|
||||||
|
var secondPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = ">" } };
|
||||||
|
|
||||||
|
var nonGlobalPluginWithActionKeywords = new Dictionary<string, PluginPair>
|
||||||
|
{
|
||||||
|
{ ">", firstPlugin },
|
||||||
|
};
|
||||||
|
|
||||||
|
var nonGlobalPluginWithActionKeyword = new Dictionary<string, PluginPair>
|
||||||
|
{
|
||||||
|
{ ">", secondPlugin },
|
||||||
|
};
|
||||||
|
string[] terms = { ">", "query" };
|
||||||
|
Query expectedQuery = new Query("> query", "query", terms, ">");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var queriesForPluginsWithActionKeywords = QueryBuilder.Build(ref searchQuery, nonGlobalPluginWithActionKeywords);
|
||||||
|
var queriesForPluginsWithActionKeyword = QueryBuilder.Build(ref searchQuery, nonGlobalPluginWithActionKeyword);
|
||||||
|
|
||||||
|
var firstQuery = queriesForPluginsWithActionKeyword.GetValueOrDefault(firstPlugin);
|
||||||
|
var secondQuery = queriesForPluginsWithActionKeywords.GetValueOrDefault(secondPlugin);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsTrue(AreEqual(firstQuery, expectedQuery));
|
||||||
|
Assert.IsTrue(AreEqual(firstQuery, secondQuery));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void QueryBuilder_ShouldGenerateCorrectQueries_ForPluginsWithMultipleActionKeywords()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var plugin = new PluginPair { Metadata = new PluginMetadata { ActionKeywords = new List<string> { "a", "b" } } };
|
||||||
|
var nonGlobalPlugins = new Dictionary<string, PluginPair>
|
||||||
|
{
|
||||||
|
{ "a", plugin },
|
||||||
|
{ "b", plugin },
|
||||||
|
};
|
||||||
|
|
||||||
|
var firstQueryText = "asearch";
|
||||||
|
var secondQueryText = "bsearch";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var firstPluginQueryPair = QueryBuilder.Build(ref firstQueryText, nonGlobalPlugins);
|
||||||
|
var firstQuery = firstPluginQueryPair.GetValueOrDefault(plugin);
|
||||||
|
|
||||||
|
var secondPluginQueryPairs = QueryBuilder.Build(ref secondQueryText, nonGlobalPlugins);
|
||||||
|
var secondQuery = secondPluginQueryPairs.GetValueOrDefault(plugin);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsTrue(AreEqual(firstQuery, new Query { ActionKeyword = "a", RawQuery = "asearch", Search = "search" }));
|
||||||
|
Assert.IsTrue(AreEqual(secondQuery, new Query { ActionKeyword = "b", RawQuery = "bsearch", Search = "search" }));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void QueryBuild_ShouldGenerateSameSearchQuery_WithOrWithoutSpaceAfterActionKeyword()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var plugin = new PluginPair { Metadata = new PluginMetadata { ActionKeywords = new List<string> { "a" } } };
|
||||||
|
var nonGlobalPlugins = new Dictionary<string, PluginPair>
|
||||||
|
{
|
||||||
|
{ "a", plugin },
|
||||||
|
};
|
||||||
|
|
||||||
|
var firstQueryText = "asearch";
|
||||||
|
var secondQueryText = "a search";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var firstPluginQueryPair = QueryBuilder.Build(ref firstQueryText, nonGlobalPlugins);
|
||||||
|
var firstQuery = firstPluginQueryPair.GetValueOrDefault(plugin);
|
||||||
|
|
||||||
|
var secondPluginQueryPairs = QueryBuilder.Build(ref secondQueryText, nonGlobalPlugins);
|
||||||
|
var secondQuery = secondPluginQueryPairs.GetValueOrDefault(plugin);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsTrue(firstQuery.Search.Equals(secondQuery.Search));
|
||||||
|
Assert.IsTrue(firstQuery.ActionKeyword.Equals(secondQuery.ActionKeyword));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void QueryBuild_ShouldGenerateCorrectQuery_ForPluginsWhoseActionKeywordsHaveSamePrefix()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
string searchQuery = "abcdefgh";
|
||||||
|
var firstPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = "ab", ID = "plugin1" } };
|
||||||
|
var secondPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = "abcd", ID = "plugin2" } };
|
||||||
|
|
||||||
|
var nonGlobalPlugins = new Dictionary<string, PluginPair>
|
||||||
|
{
|
||||||
|
{ "ab", firstPlugin },
|
||||||
|
{ "abcd", secondPlugin },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery, nonGlobalPlugins);
|
||||||
|
|
||||||
|
var firstQuery = pluginQueryPairs.GetValueOrDefault(firstPlugin);
|
||||||
|
var secondQuery = pluginQueryPairs.GetValueOrDefault(secondPlugin);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsTrue(AreEqual(firstQuery, new Query { RawQuery = searchQuery, Search = searchQuery.Substring(firstPlugin.Metadata.ActionKeyword.Length), ActionKeyword = firstPlugin.Metadata.ActionKeyword } ));
|
||||||
|
Assert.IsTrue(AreEqual(secondQuery, new Query { RawQuery = searchQuery, Search = searchQuery.Substring(secondPlugin.Metadata.ActionKeyword.Length), ActionKeyword = secondPlugin.Metadata.ActionKeyword }));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void QueryBuilder_ShouldSetTermsCorrently_WhenCalled()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
string searchQuery = "abcd efgh";
|
||||||
|
var firstPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = "ab", ID = "plugin1" } };
|
||||||
|
var secondPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = "abcd", ID = "plugin2" } };
|
||||||
|
|
||||||
|
var nonGlobalPlugins = new Dictionary<string, PluginPair>
|
||||||
|
{
|
||||||
|
{ "ab", firstPlugin },
|
||||||
|
{ "abcd", secondPlugin },
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery, nonGlobalPlugins);
|
||||||
|
|
||||||
|
var firstQuery = pluginQueryPairs.GetValueOrDefault(firstPlugin);
|
||||||
|
var secondQuery = pluginQueryPairs.GetValueOrDefault(secondPlugin);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsTrue(firstQuery.Terms[0].Equals("cd") && firstQuery.Terms[1].Equals("efgh") && firstQuery.Terms.Length == 2);
|
||||||
|
Assert.IsTrue(secondQuery.Terms[0].Equals("efgh") && secondQuery.Terms.Length == 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user