|
// 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.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.TaskList;
using Microsoft.CodeAnalysis.UnitTests;
using Microsoft.VisualStudio.IntegrationTest.Utilities;
using Microsoft.VisualStudio.LanguageServices;
using Microsoft.VisualStudio.LanguageServices.Options;
using Microsoft.VisualStudio.Settings;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Roslyn.VisualStudio.IntegrationTests;
using Xunit;
namespace Roslyn.VisualStudio.NewIntegrationTests.Options;
public sealed class GlobalOptionsTest : AbstractIntegrationTest
{
public GlobalOptionsTest()
{
}
[IdeFact]
public async Task ValidateAllOptions()
{
var globalOptions = (GlobalOptionService)await TestServices.Shell.GetComponentModelServiceAsync<IGlobalOptionService>(HangMitigatingCancellationToken);
var provider = await TestServices.Shell.GetComponentModelServiceAsync<VisualStudioOptionPersisterProvider>(HangMitigatingCancellationToken);
var vsSettingsPersister = (VisualStudioOptionPersister)await provider.GetOrCreatePersisterAsync(HangMitigatingCancellationToken);
var optionsInfo = OptionsTestInfo.CollectOptions(Path.GetDirectoryName(typeof(GlobalOptionsTest).Assembly.Location!));
var allLanguages = new[] { LanguageNames.CSharp, LanguageNames.VisualBasic };
var noLanguages = new[] { (string?)null };
var vsVersion = await TestServices.Shell.GetVersionAsync(HangMitigatingCancellationToken);
foreach (var (configName, optionInfo) in optionsInfo)
{
var option = optionInfo.Option;
// skip public options:
if (option is IPublicOption)
{
continue;
}
if (!VisualStudioOptionStorage.Storages.TryGetValue(configName, out var storage))
{
continue;
}
// TODO: issue https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1585884
if (option == TaskListOptionsStorage.Descriptors)
{
continue;
}
foreach (var language in option.IsPerLanguage ? allLanguages : noLanguages)
{
var key = new OptionKey2(option, language);
var currentValue = globalOptions.GetOption<object?>(key);
// do not attempt to update feature flags
if (storage is VisualStudioOptionStorage.FeatureFlagStorage)
{
Assert.True(currentValue is bool);
continue;
}
// TODO: Remove once test machines move to 17.6 Preview 1.
// Skip nullable types to avoid hitting https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1718326
if (vsVersion < new Version(17, 6) &&
storage is VisualStudioOptionStorage.RoamingProfileStorage &&
Nullable.GetUnderlyingType(option.Type) != null)
{
continue;
}
var differentValue = OptionsTestHelpers.GetDifferentValue(option.Type, currentValue);
await vsSettingsPersister.PersistAsync(storage, key, differentValue);
// make sure we fetch the value from the storage:
globalOptions.ClearCachedValues();
object? updatedValue;
try
{
updatedValue = globalOptions.GetOption<object?>(key);
}
finally
{
await vsSettingsPersister.PersistAsync(storage, key, currentValue);
}
AssertEx.AreEqual(differentValue, updatedValue, message: $"Option '{option.Definition.ConfigName}' failed to persist to VS settings.");
}
}
}
}
|