[PT Run] [Folder Plugin] Environment Variables With Autocomplete (#13811)

* search environment variables folders with autocomplete

* refactoring and tests

* fix
This commit is contained in:
Davide Giacometti
2021-10-20 15:27:15 +02:00
committed by GitHub
parent 15f3c2ff66
commit 64cc6b7af7
10 changed files with 296 additions and 0 deletions

View File

@@ -868,6 +868,7 @@ IEasing
IEnum IEnum
IEnumerable IEnumerable
IEnumerator IEnumerator
IEnvironment
IEquality IEquality
IEquatable IEquatable
IEvent IEvent

View File

@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.Plugin.Folder.Sources;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Microsoft.Plugin.Folder.UnitTests
{
[TestClass]
public class EnvironmentHelperTests
{
[DataTestMethod]
[DataRow(@"%", true)]
[DataRow(@"%P", true)]
[DataRow(@"%PROGRAMDATA%", true)]
[DataRow(@"", false)]
[DataRow(@"C:\ProgramData", false)]
public void IsValidEnvironmentVariable(string search, bool expectedSuccess)
{
var helper = new EnvironmentHelper();
var result = helper.IsEnvironmentVariable(search);
Assert.AreEqual(expectedSuccess, result);
}
}
}

View File

@@ -0,0 +1,67 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.IO.Abstractions.TestingHelpers;
using System.Linq;
using Microsoft.Plugin.Folder.Sources;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace Microsoft.Plugin.Folder.UnitTests
{
[TestClass]
public class QueryEnvironmentVariableTests
{
private static IQueryEnvironmentVariable _queryEnvironmentVariable;
private static MockFileSystem _fileSystem;
[TestInitialize]
public void SetupMock()
{
var environmentHelperMock = new Mock<IEnvironmentHelper>();
environmentHelperMock
.Setup(h => h.GetEnvironmentVariables())
.Returns(() => new Dictionary<string, string>
{
{ "OS", "Windows_NT" },
{ "WINDIR", @"C:\Windows" },
{ "PROGRAMDATA", @"C:\ProgramData" },
{ "PROGRAMFILES", @"C:\Program Files" },
});
_fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>()
{
{ @"C:\Windows", new MockDirectoryData() },
{ @"C:\ProgramData", new MockDirectoryData() },
{ @"C:\Program Files", new MockDirectoryData() },
});
_queryEnvironmentVariable = new QueryEnvironmentVariable(_fileSystem.Directory, environmentHelperMock.Object);
}
[DataTestMethod]
[DataRow(@"%OS%")] // Not a directory
[DataRow(@"%CUSTOM%")] // Directory doesn't exist
[DataRow(@"WINDIR")] // Not an environment variable
public void QueryWithEmptyResults(string search)
{
var results = _queryEnvironmentVariable.Query(search);
Assert.AreEqual(results.Count(), 0);
}
[DataTestMethod]
[DataRow(@"", 3)]
[DataRow(@"%", 3)]
[DataRow(@"%WIN", 1)]
[DataRow(@"%WINDIR%", 1)]
[DataRow(@"%PROGRAM", 2)]
public void QueryWithResults(string search, int numberOfResults)
{
var results = _queryEnvironmentVariable.Query(search);
Assert.AreEqual(results.Count(), numberOfResults);
}
}
}

View File

@@ -0,0 +1,39 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Plugin.Folder.Sources;
using Microsoft.Plugin.Folder.Sources.Result;
namespace Microsoft.Plugin.Folder
{
public class EnvironmentVariableProcessor : IFolderProcessor
{
private readonly IEnvironmentHelper _environmentHelper;
private readonly IQueryEnvironmentVariable _queryEnvironmentVariable;
public EnvironmentVariableProcessor(IEnvironmentHelper environmentHelper, IQueryEnvironmentVariable queryEnvironmentVariable)
{
_environmentHelper = environmentHelper;
_queryEnvironmentVariable = queryEnvironmentVariable;
}
public IEnumerable<IItemResult> Results(string actionKeyword, string search)
{
if (search == null)
{
throw new ArgumentNullException(nameof(search));
}
if (!_environmentHelper.IsEnvironmentVariable(search))
{
return Enumerable.Empty<IItemResult>();
}
return _queryEnvironmentVariable.Query(search);
}
}
}

View File

@@ -26,11 +26,14 @@ namespace Microsoft.Plugin.Folder
private static readonly FolderSettings _settings = _storage.Load(); private static readonly FolderSettings _settings = _storage.Load();
private static readonly IQueryInternalDirectory _internalDirectory = new QueryInternalDirectory(_settings, new QueryFileSystemInfo(_fileSystem.DirectoryInfo), _fileSystem.Directory); private static readonly IQueryInternalDirectory _internalDirectory = new QueryInternalDirectory(_settings, new QueryFileSystemInfo(_fileSystem.DirectoryInfo), _fileSystem.Directory);
private static readonly FolderHelper _folderHelper = new FolderHelper(new DriveInformation(), new FolderLinksSettings(_settings)); private static readonly FolderHelper _folderHelper = new FolderHelper(new DriveInformation(), new FolderLinksSettings(_settings));
private static readonly IEnvironmentHelper _environmentHelper = new EnvironmentHelper();
private static readonly IQueryEnvironmentVariable _queryEnvironmentVariable = new QueryEnvironmentVariable(_fileSystem.Directory, _environmentHelper);
private static readonly ICollection<IFolderProcessor> _processors = new IFolderProcessor[] private static readonly ICollection<IFolderProcessor> _processors = new IFolderProcessor[]
{ {
new UserFolderProcessor(_folderHelper), new UserFolderProcessor(_folderHelper),
new InternalDirectoryProcessor(_folderHelper, _internalDirectory), new InternalDirectoryProcessor(_folderHelper, _internalDirectory),
new EnvironmentVariableProcessor(_environmentHelper, _queryEnvironmentVariable),
}; };
private static PluginInitContext _context; private static PluginInitContext _context;

View File

@@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
namespace Microsoft.Plugin.Folder.Sources
{
public class EnvironmentHelper : IEnvironmentHelper
{
public bool IsEnvironmentVariable(string search)
{
if (search == null)
{
throw new ArgumentNullException(paramName: nameof(search));
}
return search.StartsWith('%');
}
public IDictionary GetEnvironmentVariables()
{
return Environment.GetEnvironmentVariables();
}
}
}

View File

@@ -0,0 +1,15 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections;
namespace Microsoft.Plugin.Folder.Sources
{
public interface IEnvironmentHelper
{
bool IsEnvironmentVariable(string search);
IDictionary GetEnvironmentVariables();
}
}

View File

@@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using Microsoft.Plugin.Folder.Sources.Result;
namespace Microsoft.Plugin.Folder.Sources
{
public interface IQueryEnvironmentVariable
{
IEnumerable<IItemResult> Query(string querySearch);
}
}

View File

@@ -0,0 +1,56 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using Microsoft.Plugin.Folder.Sources.Result;
namespace Microsoft.Plugin.Folder.Sources
{
public class QueryEnvironmentVariable : IQueryEnvironmentVariable
{
private readonly IDirectory _directory;
private readonly IEnvironmentHelper _environmentHelper;
public QueryEnvironmentVariable(IDirectory directory, IEnvironmentHelper environmentHelper)
{
_directory = directory;
_environmentHelper = environmentHelper;
}
public IEnumerable<IItemResult> Query(string querySearch)
{
if (querySearch == null)
{
throw new ArgumentNullException(nameof(querySearch));
}
return GetEnvironmentVariables(querySearch)
.OrderBy(v => v.Title)
.Where(v => v.Title.StartsWith(querySearch, StringComparison.InvariantCultureIgnoreCase));
}
public IEnumerable<EnvironmentVariableResult> GetEnvironmentVariables(string querySearch)
{
foreach (DictionaryEntry variable in _environmentHelper.GetEnvironmentVariables())
{
if (variable.Value == null)
{
continue;
}
var name = "%" + (string)variable.Key + "%";
var path = (string)variable.Value;
if (_directory.Exists(path))
{
yield return new EnvironmentVariableResult(querySearch, name, path);
}
}
}
}
}

View File

@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Globalization;
using Wox.Infrastructure;
using Wox.Plugin;
namespace Microsoft.Plugin.Folder.Sources.Result
{
public class EnvironmentVariableResult : IItemResult
{
private readonly IShellAction _shellAction = new ShellAction();
public string Search { get; set; }
public string Title { get; private set; }
public string Subtitle { get; private set; }
public string Path { get; private set; }
public EnvironmentVariableResult(string search, string title, string path)
{
Search = search;
Title = title;
Path = path;
}
public Wox.Plugin.Result Create(IPublicAPI contextApi)
{
return new Wox.Plugin.Result(StringMatcher.FuzzySearch(Search, Title).MatchData)
{
Title = Title,
IcoPath = Path,
// Using CurrentCulture since this is user facing
SubTitle = string.Format(CultureInfo.CurrentCulture, Properties.Resources.wox_plugin_folder_select_folder_result_subtitle, Path),
QueryTextDisplay = Path,
ContextData = new SearchResult { Type = ResultType.Folder, FullPath = Path },
Action = c => _shellAction.Execute(Path, contextApi),
};
}
}
}