/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/Core/Test.Next/Options/VisualStudioUnifiedSettingsOptionPersisterTests.cs
206 строк
8 KB
Cyrus Najmabadi
Fixup
02 дек 2025, 18:22
02 дек 2025, 18:22
664fdbf
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation 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.Threading.Tasks; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Options; using Microsoft.VisualStudio.LanguageServices.Options; using Microsoft.VisualStudio.Utilities.UnifiedSettings; using Xunit; namespace Microsoft.CodeAnalysis.UnitTests; public class VisualStudioUnifiedSettingsOptionPersisterTests { private sealed class MockUnifiedSettingsManager : ISettingsManager { public Func<string, Type, SettingRetrieval<object>>? GetValueImpl { set => _settingsReader.GetValueImpl = value; } public Action<string, object?>? SetValueImpl { set => _settingsWriter.SetValueImpl = value; } private readonly MockSettingsReader _settingsReader = new(); private readonly MockSettingsWriter _settingsWriter = new(); public ISettingsReader GetReader() => _settingsReader; public ISettingsWriter GetWriter(string callerName) => _settingsWriter; public ISettingsWriter GetWriter(string callerName, Guid eventSource) => _settingsWriter; } private sealed class MockSettingsReader : ISettingsReader { public Func<string, Type, SettingRetrieval<object>>? GetValueImpl; public SettingRetrieval<IReadOnlyList<T>> GetArray<T>(string moniker, SettingReadOptions readOptions = SettingReadOptions.RequireValidation) where T : notnull { throw new NotImplementedException(); } public IReadOnlyList<T> GetArrayOrThrow<T>(string moniker) where T : notnull { throw new NotImplementedException(); } public SettingRetrieval<T> GetValue<T>(string moniker, SettingReadOptions readOptions = SettingReadOptions.RequireValidation) where T : notnull { var retrieval = GetValueImpl!(moniker, null!); return new SettingRetrieval<T>(retrieval.Outcome, retrieval.Message, retrieval.Value is T ? (T)retrieval.Value : default); } public SettingRetrieval<object> GetValue(string moniker, Type targetType, SettingReadOptions readOptions = SettingReadOptions.RequireValidation) { throw new NotImplementedException(); } public T GetValueOrThrow<T>(string moniker) where T : notnull { throw new NotImplementedException(); } public object GetValueOrThrow(string moniker, Type targetType) { throw new NotImplementedException(); } public IDisposable SubscribeToChanges(Action<SettingsUpdate> handler, params string[] monikerPatterns) => null!; } private sealed class MockSettingsWriter : ISettingsWriter { internal Action<string, object?>? SetValueImpl; public SettingCommitResult Commit(string changeDescription) { throw new NotImplementedException(); } public SettingChangeResult EnqueueArrayChange<T>(string moniker, IReadOnlyList<T> value) where T : notnull { throw new NotImplementedException(); } public SettingChangeResult EnqueueChange<T>(string moniker, T value) where T : notnull { SetValueImpl!(moniker, value); return new SettingChangeResult(SettingChangeOutcome.PendingCommit, true, null); } public SettingChangeResult EnqueueChange<T>(string moniker, T value, SettingWriteOptions options) where T : notnull { throw new NotImplementedException(); } public SettingRetrieval<IReadOnlyList<T>> GetArray<T>(string moniker, SettingReadOptions readOptions = SettingReadOptions.RequireValidation) where T : notnull { throw new NotImplementedException(); } public IReadOnlyList<T> GetArrayOrThrow<T>(string moniker) where T : notnull { throw new NotImplementedException(); } public SettingRetrieval<T> GetValue<T>(string moniker, SettingReadOptions readOptions = SettingReadOptions.RequireValidation) where T : notnull { throw new NotImplementedException(); } public SettingRetrieval<object> GetValue(string moniker, Type targetType, SettingReadOptions readOptions = SettingReadOptions.RequireValidation) { throw new NotImplementedException(); } public T GetValueOrThrow<T>(string moniker) where T : notnull { throw new NotImplementedException(); } public object GetValueOrThrow(string moniker, Type targetType) { throw new NotImplementedException(); } public SettingCommitResult RequestCommit(string changeDescription) { return new SettingCommitResult(SettingCommitOutcome.Success, null); } public IDisposable SubscribeToChanges(Action<SettingsUpdate> handler, params string[] monikerPatterns) { throw new NotImplementedException(); } } [Theory] [InlineData("indent_size", 2, "2")] [InlineData("indent_size", 4, "4")] [InlineData("indent_style", true, "tab")] [InlineData("indent_style", false, "space")] [InlineData("tab_width", 2, "2")] [InlineData("tab_width", 4, "4")] [InlineData("smart_indent", FormattingOptions2.IndentStyle.None, "none")] [InlineData("smart_indent", FormattingOptions2.IndentStyle.Block, "block")] [InlineData("smart_indent", FormattingOptions2.IndentStyle.Smart, "smart")] public async Task ValidateSettingManagerSettings( string key, object value, string finalValue) { var mockManager = new MockUnifiedSettingsManager(); var persister = new VisualStudioUnifiedSettingsOptionPersister( (_, _) => { }, mockManager); // read var manager = (VisualStudioOptionStorage.UnifiedSettingsManagerStorage)VisualStudioOptionStorage.Storages[key]; IPerLanguageValuedOption option = key switch { "indent_size" => FormattingOptions2.IndentationSize, "indent_style" => FormattingOptions2.UseTabs, "tab_width" => FormattingOptions2.TabSize, "smart_indent" => FormattingOptions2.SmartIndent, _ => throw ExceptionUtilities.UnexpectedValue(key), }; var optionKey = new OptionKey2(option, LanguageNames.CSharp); // Ensure that if the settings manager doesn't find the item, we are resilient. mockManager.GetValueImpl = (_, _) => new SettingRetrieval<object>(SettingRetrievalOutcome.NotRegistered, null, null); Assert.False(manager.TryFetch(persister, optionKey, out _)); // Ensure that if the settings manager finds and return nothing, we are resilient. mockManager.GetValueImpl = (_, _) => new SettingRetrieval<object>(SettingRetrievalOutcome.Success, null, null); Assert.False(manager.TryFetch(persister, optionKey, out _)); // Ensure that if the settings manager finds and return an unexpected type, we are resilient. mockManager.GetValueImpl = (_, _) => new SettingRetrieval<object>(SettingRetrievalOutcome.Success, null, true); Assert.False(manager.TryFetch(persister, optionKey, out _)); // Ensure that We don't try to get when doing a store. Also ensure that the value stored is the appropriate // string value of the original value passed in. mockManager.GetValueImpl = null; mockManager.SetValueImpl = (name, storedValue) => { Assert.Equal(finalValue, storedValue); }; await manager.PersistAsync(persister, optionKey, value); // Attempt to read the value back. If the settings manager gets it back properly, ensure that we can read it // into the actual in-memory (non-string) value we expect. mockManager.SetValueImpl = null; mockManager.GetValueImpl = (name, type) => new SettingRetrieval<object>(SettingRetrievalOutcome.Success, null, finalValue); Assert.True(manager.TryFetch(persister, optionKey, out var fetchedValue)); Assert.Equal(value, fetchedValue); } }