/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/CSharp/Test/Interactive/Commands/ResetInteractiveTests.cs
166 строк
7 KB
Cyrus Najmabadi
Use raw strings in tests
09 июл 2025, 08:52
09 июл 2025, 08:52
f265dce
Код
Авторство
О чём код?
// 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. #nullable disable extern alias InteractiveHost; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using InteractiveHost::Microsoft.CodeAnalysis.Interactive; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.InteractiveWindow; using Microsoft.VisualStudio.Text.Editor.OptionsExtensionMethods; using Microsoft.VisualStudio.Utilities; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Interactive.Commands; [UseExportProvider] public sealed class ResetInteractiveTests { private const string WorkspaceXmlStr = """ <Workspace> <Project Language="Visual Basic" AssemblyName="ResetInteractiveVisualBasicSubproject" CommonReferences="true"> <Document FilePath="VisualBasicDocument"></Document> </Project> <Project Language="C#" AssemblyName="ResetInteractiveTestsAssembly" CommonReferences="true"> <ProjectReference>ResetInteractiveVisualBasicSubproject</ProjectReference> <Document FilePath="ResetInteractiveTestsDocument"> namespace ResetInteractiveTestsDocument { class TestClass { } }</Document> </Project> </Workspace> """; [WpfFact] [Trait(Traits.Feature, Traits.Features.Interactive)] public async Task TestResetREPLWithProjectContext() { using var workspace = TestWorkspace.Create(WorkspaceXmlStr, composition: EditorTestCompositions.InteractiveWindow); var project = workspace.CurrentSolution.Projects.FirstOrDefault(p => p.AssemblyName == "ResetInteractiveTestsAssembly"); var document = project.Documents.FirstOrDefault(d => d.FilePath == "ResetInteractiveTestsDocument"); var replReferenceCommands = GetProjectReferences(workspace, project).Select(r => CreateReplReferenceCommand(r)); Assert.True(replReferenceCommands.Any(rc => rc.EndsWith(""" ResetInteractiveTestsAssembly.dll" """))); Assert.True(replReferenceCommands.Any(rc => rc.EndsWith(""" ResetInteractiveVisualBasicSubproject.dll" """))); var expectedReferences = replReferenceCommands.ToList(); var expectedUsings = new List<string> { @"using ""System"";", @"using ""ResetInteractiveTestsDocument"";" }; await AssertResetInteractiveAsync(workspace, project, buildSucceeds: true, expectedReferences: expectedReferences, expectedUsings: expectedUsings); // Test that no submissions are executed if the build fails. await AssertResetInteractiveAsync(workspace, project, buildSucceeds: false, expectedReferences: []); } private async Task AssertResetInteractiveAsync( TestWorkspace workspace, Project project, bool buildSucceeds, List<string> expectedReferences = null, List<string> expectedUsings = null) { expectedReferences ??= []; expectedUsings ??= []; var testHost = new InteractiveWindowTestHost(workspace.ExportProvider.GetExportedValue<IInteractiveWindowFactoryService>()); var executedSubmissionCalls = new List<string>(); void executeSubmission(object _, string code) => executedSubmissionCalls.Add(code); testHost.Evaluator.OnExecute += executeSubmission; var uiThreadOperationExecutor = workspace.GetService<IUIThreadOperationExecutor>(); var editorOptionsService = workspace.GetService<EditorOptionsService>(); var editorOptions = editorOptionsService.Factory.GetOptions(testHost.Window.CurrentLanguageBuffer); var newLineCharacter = editorOptions.GetNewLineCharacter(); var resetInteractive = new TestResetInteractive( uiThreadOperationExecutor, editorOptionsService, CreateReplReferenceCommand, CreateImport, buildSucceeds: buildSucceeds) { References = [.. GetProjectReferences(workspace, project)], ReferenceSearchPaths = ["rsp1", "rsp2"], SourceSearchPaths = ["ssp1", "ssp2"], ProjectNamespaces = ["System", "ResetInteractiveTestsDocument", "VisualBasicResetInteractiveTestsDocument"], NamespacesToImport = ["System", "ResetInteractiveTestsDocument"], ProjectDirectory = "pj", Platform = InteractiveHostPlatform.Desktop64, }; await resetInteractive.ExecuteAsync(testHost.Window, "Interactive C#"); // Validate that the project was rebuilt. Assert.Equal(1, resetInteractive.BuildProjectCount); Assert.Equal(0, resetInteractive.CancelBuildProjectCount); if (buildSucceeds) { Assert.Equal(InteractiveHostPlatform.Desktop64, testHost.Evaluator.ResetOptions.Platform); } else { Assert.Null(testHost.Evaluator.ResetOptions); } var expectedSubmissions = new List<string>(); if (expectedReferences.Any()) { expectedSubmissions.AddRange(expectedReferences.Select(r => r + newLineCharacter)); } if (expectedUsings.Any()) { expectedSubmissions.Add(string.Join(newLineCharacter, expectedUsings) + newLineCharacter); } AssertEx.Equal(expectedSubmissions, executedSubmissionCalls); testHost.Evaluator.OnExecute -= executeSubmission; } /// <summary> /// Simulates getting all project references. /// </summary> /// <param name="workspace">Workspace with the solution.</param> /// <param name="project">A project that should be built.</param> /// <returns>A list of paths that should be referenced.</returns> private static IEnumerable<string> GetProjectReferences(TestWorkspace workspace, Project project) { var metadataReferences = project.MetadataReferences.Select(r => r.Display); var projectReferences = project.ProjectReferences.SelectMany(p => GetProjectReferences( workspace, workspace.CurrentSolution.GetProject(p.ProjectId))); var outputReference = new string[] { project.OutputFilePath }; return metadataReferences.Union(projectReferences).Concat(outputReference); } private string CreateReplReferenceCommand(string referenceName) { return $""" #r "{referenceName}" """; } private string CreateImport(string importName) { return $@"using ""{importName}"";"; } }