internal static IList<ITagSpan<IErrorTag>> GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs) { var source = new TestDiagnosticUpdateSource(); var diagnosticWaiter = new DiagnosticServiceWaiter(); var diagnosticListeners = SpecializedCollections.SingletonEnumerable(new Lazy<IAsynchronousOperationListener, FeatureMetadata>( () => diagnosticWaiter, new FeatureMetadata(new Dictionary<string, object>() { { "FeatureName", FeatureAttribute.DiagnosticService } }))); var optionsService = workspace.Services.GetService<IOptionService>(); var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable<IDiagnosticUpdateSource>(source), diagnosticListeners); var squiggleWaiter = new ErrorSquiggleWaiter(); var foregroundService = new TestForegroundNotificationService(); var buffer = document.GetTextBuffer(); var taggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(buffer, foregroundService, diagnosticService, optionsService, squiggleWaiter); source.RaiseDiagnosticsUpdated(updateArgs); diagnosticWaiter.CreateWaitTask().PumpingWait(); squiggleWaiter.CreateWaitTask().PumpingWait(); var snapshot = buffer.CurrentSnapshot; var intervalTree = taggerSource.GetTagIntervalTreeForBuffer(buffer); var spans = intervalTree.GetIntersectingSpans(new SnapshotSpan(snapshot, 0, snapshot.Length)); taggerSource.TestOnly_Dispose(); return spans; }
internal static IList<ITagSpan<IErrorTag>> GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs) { var source = new TestDiagnosticUpdateSource(); var listener = new AsynchronousOperationListener(); var listeners = AsynchronousOperationListener.CreateListeners( ValueTuple.Create(FeatureAttribute.DiagnosticService, listener), ValueTuple.Create(FeatureAttribute.ErrorSquiggles, listener)); var optionsService = workspace.Services.GetService<IOptionService>(); var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable<IDiagnosticUpdateSource>(source), listeners); var foregroundService = workspace.GetService<IForegroundNotificationService>(); //new TestForegroundNotificationService(); var buffer = document.GetTextBuffer(); var provider = new DiagnosticsSquiggleTaggerProvider(optionsService, diagnosticService, foregroundService, listeners); var tagger = provider.CreateTagger<IErrorTag>(buffer); source.RaiseDiagnosticsUpdated(updateArgs); listener.CreateWaitTask().PumpingWait(); var snapshot = buffer.CurrentSnapshot; var spans = tagger.GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(snapshot, 0, snapshot.Length))).ToImmutableArray(); ((IDisposable)tagger).Dispose(); return spans; }
public EncapsulateFieldTestState(TestWorkspace workspace) { Workspace = workspace; _testDocument = Workspace.Documents.Single(d => d.CursorPosition.HasValue || d.SelectedSpans.Any()); TargetDocument = Workspace.CurrentSolution.GetDocument(_testDocument.Id); var notificationService = Workspace.Services.GetService<INotificationService>() as INotificationServiceCallback; var callback = new Action<string, string, NotificationSeverity>((message, title, severity) => NotificationMessage = message); notificationService.NotificationCallback = callback; }
public EncapsulateFieldTestState(string markup) { Workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFile(markup, exportProvider: s_exportProvider); _testDocument = Workspace.Documents.Single(d => d.CursorPosition.HasValue || d.SelectedSpans.Any()); TargetDocument = Workspace.CurrentSolution.GetDocument(_testDocument.Id); var notificationService = Workspace.Services.GetService<INotificationService>() as INotificationServiceCallback; var callback = new Action<string, string, NotificationSeverity>((message, title, severity) => NotificationMessage = message); notificationService.NotificationCallback = callback; }
public RenameTrackingTestState( string markup, string languageName, bool onBeforeGlobalSymbolRenamedReturnValue = true, bool onAfterGlobalSymbolRenamedReturnValue = true) { this.Workspace = CreateTestWorkspace(markup, languageName, TestExportProvider.CreateExportProviderWithCSharpAndVisualBasic()); _hostDocument = Workspace.Documents.First(); _view = _hostDocument.GetTextView(); _view.Caret.MoveTo(new SnapshotPoint(_view.TextSnapshot, _hostDocument.CursorPosition.Value)); _editorOperations = Workspace.GetService<IEditorOperationsFactoryService>().GetEditorOperations(_view); _historyRegistry = Workspace.ExportProvider.GetExport<ITextUndoHistoryRegistry>().Value; _mockRefactorNotifyService = new MockRefactorNotifyService { OnBeforeSymbolRenamedReturnValue = onBeforeGlobalSymbolRenamedReturnValue, OnAfterSymbolRenamedReturnValue = onAfterGlobalSymbolRenamedReturnValue }; var optionService = this.Workspace.Services.GetService<IOptionService>(); // Mock the action taken by the workspace INotificationService var notificationService = Workspace.Services.GetService<INotificationService>() as INotificationServiceCallback; var callback = new Action<string, string, NotificationSeverity>((message, title, severity) => _notificationMessage = message); notificationService.NotificationCallback = callback; var tracker = new RenameTrackingTaggerProvider( _historyRegistry, Workspace.ExportProvider.GetExport<Host.IWaitIndicator>().Value, Workspace.ExportProvider.GetExport<IInlineRenameService>().Value, Workspace.ExportProvider.GetExport<IDiagnosticAnalyzerService>().Value, SpecializedCollections.SingletonEnumerable(_mockRefactorNotifyService), Workspace.ExportProvider.GetExports<IAsynchronousOperationListener, FeatureMetadata>()); _tagger = tracker.CreateTagger<RenameTrackingTag>(_hostDocument.GetTextBuffer()); if (languageName == LanguageNames.CSharp) { _codeFixProvider = new CSharpRenameTrackingCodeFixProvider( Workspace.ExportProvider.GetExport<Host.IWaitIndicator>().Value, _historyRegistry, SpecializedCollections.SingletonEnumerable(_mockRefactorNotifyService)); } else if (languageName == LanguageNames.VisualBasic) { _codeFixProvider = new VisualBasicRenameTrackingCodeFixProvider( Workspace.ExportProvider.GetExport<Host.IWaitIndicator>().Value, _historyRegistry, SpecializedCollections.SingletonEnumerable(_mockRefactorNotifyService)); } else { throw new ArgumentException("Invalid langauge name: " + languageName, "languageName"); } }
public ChangeSignatureTestState(TestWorkspace workspace) { Workspace = workspace; _testDocument = Workspace.Documents.SingleOrDefault(d => d.CursorPosition.HasValue); if (_testDocument == null) { throw new ArgumentException("markup does not contain a cursor position", "workspace"); } InvocationDocument = Workspace.CurrentSolution.GetDocument(_testDocument.Id); ChangeSignatureService = InvocationDocument.GetLanguageService<AbstractChangeSignatureService>(); }
public ExtractInterfaceTestState(TestWorkspace workspace) { Workspace = workspace; OriginalSolution = Workspace.CurrentSolution; _testDocument = Workspace.Documents.SingleOrDefault(d => d.CursorPosition.HasValue); if (_testDocument == null) { throw new ArgumentException("markup does not contain a cursor position", nameof(workspace)); } ExtractFromDocument = Workspace.CurrentSolution.GetDocument(_testDocument.Id); ExtractInterfaceService = ExtractFromDocument.GetLanguageService<AbstractExtractInterfaceService>(); }
internal static async Task<IList<ITagSpan<IErrorTag>>> GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs) { var source = new TestDiagnosticUpdateSource(); using (var wrapper = new DiagnosticTaggerWrapper(workspace, source)) { var tagger = wrapper.TaggerProvider.CreateTagger<IErrorTag>(workspace.Documents.First().GetTextBuffer()); using (var disposable = tagger as IDisposable) { source.RaiseDiagnosticsUpdated(updateArgs); await wrapper.WaitForTags(); var snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot; var spans = tagger.GetTags(snapshot.GetSnapshotSpanCollection()).ToImmutableArray(); return spans; } } }
private GenerateTypeTestState(string projectToBeModified, string typeName, string existingFileName, TestWorkspace testWorkspace) { Workspace = testWorkspace; _testDocument = Workspace.Documents.SingleOrDefault(d => d.CursorPosition.HasValue); if (_testDocument == null) { throw new ArgumentException("markup does not contain a cursor position", "workspace"); } TriggeredProject = Workspace.CurrentSolution.GetProject(_testDocument.Project.Id); if (projectToBeModified == null) { // Select the project from which the Codefix was triggered ProjectToBeModified = Workspace.CurrentSolution.GetProject(_testDocument.Project.Id); } else { ProjectToBeModified = Workspace.CurrentSolution.Projects.FirstOrDefault(proj => proj.Name.Equals(projectToBeModified)); if (ProjectToBeModified == null) { throw new ArgumentException("Project with the given name does not exist", "workspace"); } } InvocationDocument = Workspace.CurrentSolution.GetDocument(_testDocument.Id); if (projectToBeModified == null && existingFileName == null) { ExistingDocument = InvocationDocument; } else if (existingFileName != null) { ExistingDocument = ProjectToBeModified.Documents.FirstOrDefault(doc => doc.Name.Equals(existingFileName)); } TypeName = typeName; }
public void TestGetCompilationOnCrossLanguageDependentProjectChangedInProgress() { using (var workspace = CreateWorkspace(disablePartialSolutions: false)) { var solutionX = workspace.CurrentSolution; var document1 = new TestHostDocument(@"public class C { }"); var project1 = new TestHostProject(workspace, document1, name: "project1"); var document2 = new TestHostDocument("Public Class D \r\n Inherits C\r\nEnd Class"); var project2 = new TestHostProject(workspace, document2, language: LanguageNames.VisualBasic, name: "project2", projectReferences: new[] { project1 }); workspace.AddTestProject(project1); workspace.AddTestProject(project2); var solutionY = workspace.CurrentSolution; var id1 = solutionY.Projects.First(p => p.Name == project1.Name).Id; var id2 = solutionY.Projects.First(p => p.Name == project2.Name).Id; var compilation2y = solutionY.GetProject(id2).GetCompilationAsync().Result; var errors = compilation2y.GetDiagnostics(); var classDy = compilation2y.SourceModule.GlobalNamespace.GetTypeMembers("D").Single(); var classCy = classDy.BaseType; Assert.NotEqual(TypeKind.Error, classCy.TypeKind); // open both documents so background compiler works on their compilations workspace.OnDocumentOpened(document1.Id, document1.GetOpenTextContainer()); workspace.OnDocumentOpened(document2.Id, document2.GetOpenTextContainer()); // change C to X var buffer1 = document1.GetTextBuffer(); buffer1.Replace(new Span(13, 1), "X"); var foundTheError = false; for (int iter = 0; iter < 10; iter++) { WaitHelper.WaitForDispatchedOperationsToComplete(System.Windows.Threading.DispatcherPriority.ApplicationIdle); Thread.Sleep(1000); // the current solution should eventually have the change var cs = workspace.CurrentSolution; var doc1Z = cs.GetDocument(document1.Id); var hasX = doc1Z.GetTextAsync().Result.ToString().Contains("X"); if (hasX) { var doc2Z = cs.GetDocument(document2.Id); var partialDoc2Z = doc2Z.WithFrozenPartialSemanticsAsync(CancellationToken.None).Result; var compilation2Z = partialDoc2Z.Project.GetCompilationAsync().Result; var classDz = compilation2Z.SourceModule.GlobalNamespace.GetTypeMembers("D").Single(); var classCz = classDz.BaseType; if (classCz.TypeKind == TypeKind.Error) { foundTheError = true; break; } } } Assert.True(foundTheError, "Did not find error"); } }
public TestHostDocument CreateProjectionBufferDocument( string markup, IList <TestHostDocument> baseDocuments, string path = "projectionbufferdocumentpath", ProjectionBufferOptions options = ProjectionBufferOptions.None, IProjectionEditResolver?editResolver = null) { GetSpansAndCaretFromSurfaceBufferMarkup(markup, baseDocuments, out var projectionBufferSpans, out var mappedSpans, out var mappedCaretLocation); var projectionBufferFactory = this.GetService <IProjectionBufferFactoryService>(); var projectionBuffer = projectionBufferFactory.CreateProjectionBuffer(editResolver, projectionBufferSpans, options); // Add in mapped spans from each of the base documents foreach (var document in baseDocuments) { mappedSpans[string.Empty] = mappedSpans.ContainsKey(string.Empty) ? mappedSpans[string.Empty] : ImmutableArray <TextSpan> .Empty; foreach (var span in document.SelectedSpans) { var snapshotSpan = span.ToSnapshotSpan(document.GetTextBuffer().CurrentSnapshot); var mappedSpan = projectionBuffer.CurrentSnapshot.MapFromSourceSnapshot(snapshotSpan).Single(); mappedSpans[string.Empty] = mappedSpans[string.Empty].Add(mappedSpan.ToTextSpan()); } // Order unnamed spans as they would be ordered by the normal span finding // algorithm in MarkupTestFile mappedSpans[string.Empty] = mappedSpans[string.Empty].OrderBy(s => s.End).ThenBy(s => - s.Start).ToImmutableArray(); foreach (var kvp in document.AnnotatedSpans) { mappedSpans[kvp.Key] = mappedSpans.ContainsKey(kvp.Key) ? mappedSpans[kvp.Key] : ImmutableArray <TextSpan> .Empty; foreach (var span in kvp.Value) { var snapshotSpan = span.ToSnapshotSpan(document.GetTextBuffer().CurrentSnapshot); var mappedSpan = projectionBuffer.CurrentSnapshot.MapFromSourceSnapshot(snapshotSpan).Cast <Span?>().SingleOrDefault(); if (mappedSpan == null) { // not all span on subject buffer needs to exist on surface buffer continue; } // but if they do, it must be only 1 mappedSpans[kvp.Key] = mappedSpans[kvp.Key].Add(mappedSpan.Value.ToTextSpan()); } } } var projectionDocument = new TestHostDocument( ExportProvider, languageServiceProvider: null, projectionBuffer.CurrentSnapshot.GetText(), path, mappedCaretLocation, mappedSpans, textBuffer: projectionBuffer); this.ProjectionDocuments.Add(projectionDocument); return(projectionDocument); }
internal void AddAnalyzerConfigDocument(TestHostDocument document) { this.AnalyzerConfigDocuments = this.AnalyzerConfigDocuments.Concat(new TestHostDocument[] { document }); document.SetProject(this); }
public void TestAdditionalFile_OpenClose() { using (var workspace = CreateWorkspace()) { var startText = @"<setting value = ""foo"""; var document = new TestHostDocument("public class C { }"); var additionalDoc = new TestHostDocument(startText); var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, additionalDocuments: new[] { additionalDoc }); workspace.AddTestProject(project1); var buffer = additionalDoc.GetTextBuffer(); var doc = workspace.CurrentSolution.GetAdditionalDocument(additionalDoc.Id); var text = doc.GetTextAsync(CancellationToken.None).PumpingWaitResult(); var version = doc.GetTextVersionAsync(CancellationToken.None).PumpingWaitResult(); workspace.OnAdditionalDocumentOpened(additionalDoc.Id, additionalDoc.GetOpenTextContainer()); // We don't have a GetOpenAdditionalDocumentIds since we don't need it. But make sure additional documents // don't creep into OpenDocumentIds (Bug: 1087470) Assert.Empty(workspace.GetOpenDocumentIds()); workspace.OnAdditionalDocumentClosed(additionalDoc.Id, TextLoader.From(TextAndVersion.Create(text, version))); // Reopen and close to make sure we are not leaking anything. workspace.OnAdditionalDocumentOpened(additionalDoc.Id, additionalDoc.GetOpenTextContainer()); workspace.OnAdditionalDocumentClosed(additionalDoc.Id, TextLoader.From(TextAndVersion.Create(text, version))); Assert.Empty(workspace.GetOpenDocumentIds()); } }
public void TestAdditionalFile_Properties() { using (var workspace = CreateWorkspace()) { var document = new TestHostDocument("public class C { }"); var additionalDoc = new TestHostDocument("some text"); var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, additionalDocuments: new[] { additionalDoc }); workspace.AddTestProject(project1); var project = workspace.CurrentSolution.Projects.Single(); Assert.Equal(1, project.Documents.Count()); Assert.Equal(1, project.AdditionalDocuments.Count()); Assert.Equal(1, project.AdditionalDocumentIds.Count); var doc = project.GetDocument(additionalDoc.Id); Assert.Null(doc); var additionalDocument = project.GetAdditionalDocument(additionalDoc.Id); Assert.Equal("some text", additionalDocument.GetTextAsync().PumpingWaitResult().ToString()); } }
internal void RemoveAdditionalDocument(TestHostDocument document) => this.AdditionalDocuments = this.AdditionalDocuments.Where(d => d != document);
public void TestGetCompilationOnCrossLanguageDependentProject() { using (var workspace = CreateWorkspace()) { var solution = workspace.CurrentSolution; var document1 = new TestHostDocument(@"public class C { }"); var project1 = new TestHostProject(workspace, document1, name: "project1"); var document2 = new TestHostDocument("Public Class D \r\n Inherits C\r\nEnd Class"); var project2 = new TestHostProject(workspace, document2, language: LanguageNames.VisualBasic, name: "project2", projectReferences: new[] { project1 }); workspace.AddTestProject(project1); workspace.AddTestProject(project2); var snapshot = workspace.CurrentSolution; var id1 = snapshot.Projects.First(p => p.Name == project1.Name).Id; var id2 = snapshot.Projects.First(p => p.Name == project2.Name).Id; var compilation2 = snapshot.GetProject(id2).GetCompilationAsync().Result; var classD = compilation2.SourceModule.GlobalNamespace.GetTypeMembers("D").Single(); var classC = classD.BaseType; } }
public void TestRemoveOpenedDocument() { using (var workspace = CreateWorkspace()) { var solution = workspace.CurrentSolution; var document = new TestHostDocument(string.Empty); var project1 = new TestHostProject(workspace, document, name: "project1"); workspace.AddTestProject(project1); workspace.OnDocumentOpened(document.Id, document.GetOpenTextContainer()); Assert.Throws<ArgumentException>(() => workspace.OnDocumentRemoved(document.Id)); workspace.OnDocumentClosed(document.Id); workspace.OnProjectRemoved(project1.Id); } }
internal void RemoveAnalyzerConfigDocument(TestHostDocument document) => this.AnalyzerConfigDocuments = this.AnalyzerConfigDocuments.Where(d => d != document);
private static IList <TestHostProject> CreateSubmissions( TestWorkspace workspace, IEnumerable <XElement> submissionElements, ExportProvider exportProvider) { var submissions = new List <TestHostProject>(); var submissionIndex = 0; foreach (var submissionElement in submissionElements) { var submissionName = "Submission" + (submissionIndex++); var languageName = GetLanguage(workspace, submissionElement); // The document var markupCode = submissionElement.NormalizedValue(); MarkupTestFile.GetPositionAndSpans(markupCode, out var code, out var cursorPosition, out IDictionary <string, ImmutableArray <TextSpan> > spans); var languageServices = workspace.Services.GetLanguageServices(languageName); var contentTypeLanguageService = languageServices.GetService <IContentTypeLanguageService>(); var contentType = contentTypeLanguageService.GetDefaultContentType(); var textBuffer = EditorFactory.CreateBuffer(contentType.TypeName, exportProvider, code); // The project var document = new TestHostDocument(exportProvider, languageServices, textBuffer, submissionName, cursorPosition, spans, SourceCodeKind.Script); var documents = new List <TestHostDocument> { document }; if (languageName == NoCompilationConstants.LanguageName) { submissions.Add( new TestHostProject( languageServices, compilationOptions: null, parseOptions: null, assemblyName: submissionName, projectName: submissionName, references: null, documents: documents, isSubmission: true)); continue; } var syntaxFactory = languageServices.GetService <ISyntaxTreeFactoryService>(); var compilationFactory = languageServices.GetService <ICompilationFactoryService>(); var compilationOptions = compilationFactory.GetDefaultCompilationOptions().WithOutputKind(OutputKind.DynamicallyLinkedLibrary); var parseOptions = syntaxFactory.GetDefaultParseOptions().WithKind(SourceCodeKind.Script); var references = CreateCommonReferences(workspace, submissionElement); var project = new TestHostProject( languageServices, compilationOptions, parseOptions, submissionName, submissionName, references, documents, isSubmission: true); submissions.Add(project); } return(submissions); }
internal void RemoveDocument(TestHostDocument document) => this.Documents = this.Documents.Where(d => d != document);
internal TestDocumentLoader(TestHostDocument hostDocument, string text) { _hostDocument = hostDocument; _text = text; }
public void TestChangeOptions2() { using (var workspace = CreateWorkspace()) { var solution = workspace.CurrentSolution; var document = new TestHostDocument( @"#if FOO class C { } #else class D { } #endif"); var project1 = new TestHostProject(workspace, document, name: "project1"); workspace.AddTestProject(project1); workspace.OnDocumentOpened(document.Id, document.GetOpenTextContainer()); VerifyRootTypeName(workspace, "D"); workspace.OnParseOptionsChanged(document.Id.ProjectId, new CSharpParseOptions(preprocessorSymbols: new[] { "FOO" })); VerifyRootTypeName(workspace, "C"); workspace.OnDocumentClosed(document.Id); } }
public void TestApplyChangesWithDocumentTextUpdated() { using (var workspace = CreateWorkspace()) { var startText = "public class C { }"; var newText = "public class D { }"; var document = new TestHostDocument(startText); var project1 = new TestHostProject(workspace, document, name: "project1"); workspace.AddTestProject(project1); var buffer = document.GetTextBuffer(); workspace.OnDocumentOpened(document.Id, document.GetOpenTextContainer()); // prove the document has the correct text Assert.Equal(startText, workspace.CurrentSolution.GetDocument(document.Id).GetTextAsync().PumpingWaitResult().ToString()); // fork the solution to introduce a change. var oldSolution = workspace.CurrentSolution; var newSolution = oldSolution.WithDocumentText(document.Id, SourceText.From(newText)); // prove that current document text is unchanged Assert.Equal(startText, workspace.CurrentSolution.GetDocument(document.Id).GetTextAsync().PumpingWaitResult().ToString()); // prove buffer is unchanged too Assert.Equal(startText, buffer.CurrentSnapshot.GetText()); workspace.TryApplyChanges(newSolution); // new text should have been pushed into buffer Assert.Equal(newText, buffer.CurrentSnapshot.GetText()); } }
public void TestGetCompilation() { using (var workspace = CreateWorkspace()) { var solution = workspace.CurrentSolution; var document = new TestHostDocument(@"class C { }"); var project1 = new TestHostProject(workspace, document, name: "project1"); workspace.AddTestProject(project1); VerifyRootTypeName(workspace, "C"); var snapshot = workspace.CurrentSolution; var id1 = snapshot.Projects.First(p => p.Name == project1.Name).Id; var compilation = snapshot.GetProject(id1).GetCompilationAsync().Result; var classC = compilation.SourceModule.GlobalNamespace.GetMembers("C").Single(); } }
public void TestApplyChangesWithDocumentRemoved() { using (var workspace = CreateWorkspace()) { var doc1Text = "public class C { }"; var document = new TestHostDocument(doc1Text); var project1 = new TestHostProject(workspace, document, name: "project1"); workspace.AddTestProject(project1); // fork the solution to introduce a change. var oldSolution = workspace.CurrentSolution; var newSolution = oldSolution.RemoveDocument(document.Id); workspace.TryApplyChanges(newSolution); // document should have been removed Assert.Equal(0, workspace.CurrentSolution.GetProject(project1.Id).Documents.Count()); } }
public void TestGetCompilationOnCrossLanguageDependentProjectChanged() { using (var workspace = CreateWorkspace()) { var solutionX = workspace.CurrentSolution; var document1 = new TestHostDocument(@"public class C { }"); var project1 = new TestHostProject(workspace, document1, name: "project1"); var document2 = new TestHostDocument("Public Class D \r\n Inherits C\r\nEnd Class"); var project2 = new TestHostProject(workspace, document2, language: LanguageNames.VisualBasic, name: "project2", projectReferences: new[] { project1 }); workspace.AddTestProject(project1); workspace.AddTestProject(project2); var solutionY = workspace.CurrentSolution; var id1 = solutionY.Projects.First(p => p.Name == project1.Name).Id; var id2 = solutionY.Projects.First(p => p.Name == project2.Name).Id; var compilation2 = solutionY.GetProject(id2).GetCompilationAsync().Result; var errors = compilation2.GetDiagnostics(); var classD = compilation2.SourceModule.GlobalNamespace.GetTypeMembers("D").Single(); var classC = classD.BaseType; Assert.NotEqual(TypeKind.Error, classC.TypeKind); // change the class name in document1 workspace.OnDocumentOpened(document1.Id, document1.GetOpenTextContainer()); var buffer1 = document1.GetTextBuffer(); // change C to X buffer1.Replace(new Span(13, 1), "X"); // this solution should have the change var solutionZ = workspace.CurrentSolution; var docZ = solutionZ.GetDocument(document1.Id); var docZText = docZ.GetTextAsync().PumpingWaitResult(); var compilation2Z = solutionZ.GetProject(id2).GetCompilationAsync().Result; var classDz = compilation2Z.SourceModule.GlobalNamespace.GetTypeMembers("D").Single(); var classCz = classDz.BaseType; Assert.Equal(TypeKind.Error, classCz.TypeKind); } }
internal void AddAdditionalDocument(TestHostDocument document) { this.AdditionalDocuments = this.AdditionalDocuments.Concat(new TestHostDocument[] { document }); document.SetProject(this); }
public void TestOpenAndChangeDocument() { using (var workspace = CreateWorkspace()) { var solution = workspace.CurrentSolution; var document = new TestHostDocument(string.Empty); var project1 = new TestHostProject(workspace, document, name: "project1"); workspace.AddTestProject(project1); var buffer = document.GetTextBuffer(); workspace.OnDocumentOpened(document.Id, document.GetOpenTextContainer()); buffer.Insert(0, "class C {}"); solution = workspace.CurrentSolution; var doc = solution.Projects.Single().Documents.First(); var syntaxTree = doc.GetSyntaxTreeAsync(CancellationToken.None).Result; Assert.True(syntaxTree.GetRoot().Width() > 0, "syntaxTree.GetRoot().Width should be > 0"); workspace.OnDocumentClosed(document.Id); workspace.OnProjectRemoved(project1.Id); } }
public async Task TestChangeOptions1() { using (var workspace = CreateWorkspace()) { var solution = workspace.CurrentSolution; var document = new TestHostDocument( @"#if FOO class C { } #else class D { } #endif"); var project1 = new TestHostProject(workspace, document, name: "project1"); workspace.AddTestProject(project1); await VerifyRootTypeNameAsync(workspace, "D"); workspace.OnParseOptionsChanged(document.Id.ProjectId, new CSharpParseOptions(preprocessorSymbols: new[] { "FOO" })); await VerifyRootTypeNameAsync(workspace, "C"); } }
public void TestApplyChangesWithDocumentAdded() { using (var workspace = CreateWorkspace()) { var doc1Text = "public class C { }"; var doc2Text = "public class D { }"; var document = new TestHostDocument(doc1Text); var project1 = new TestHostProject(workspace, document, name: "project1"); workspace.AddTestProject(project1); // fork the solution to introduce a change. var oldSolution = workspace.CurrentSolution; var newSolution = oldSolution.AddDocument(DocumentId.CreateNewId(project1.Id), "Doc2", SourceText.From(doc2Text)); workspace.TryApplyChanges(newSolution); // new document should have been added. Assert.Equal(2, workspace.CurrentSolution.GetProject(project1.Id).Documents.Count()); } }
public async void TestAddedSubmissionParseTreeHasEmptyFilePath() { using (var workspace = CreateWorkspace()) { var document1 = new TestHostDocument("var x = 1;", displayName: "Sub1", sourceCodeKind: SourceCodeKind.Script); var project1 = new TestHostProject(workspace, document1, name: "Submission"); var document2 = new TestHostDocument("var x = 2;", displayName: "Sub2", sourceCodeKind: SourceCodeKind.Script, filePath: "a.csx"); var project2 = new TestHostProject(workspace, document2, name: "Script"); workspace.AddTestProject(project1); workspace.AddTestProject(project2); workspace.TryApplyChanges(workspace.CurrentSolution); // Check that a parse tree for a submission has an empty file path. SyntaxTree tree1 = await workspace.CurrentSolution .GetProjectState(project1.Id) .GetDocumentState(document1.Id) .GetSyntaxTreeAsync(CancellationToken.None); Assert.Equal("", tree1.FilePath); // Check that a parse tree for a script does not have an empty file path. SyntaxTree tree2 = await workspace.CurrentSolution .GetProjectState(project2.Id) .GetDocumentState(document2.Id) .GetSyntaxTreeAsync(CancellationToken.None); Assert.Equal("a.csx", tree2.FilePath); } }
public void TestDocumentEvents() { using (var workspace = CreateWorkspace()) { var doc1Text = "public class C { }"; var document = new TestHostDocument(doc1Text); var project1 = new TestHostProject(workspace, document, name: "project1"); var longEventTimeout = TimeSpan.FromMinutes(5); var shortEventTimeout = TimeSpan.FromSeconds(5); workspace.AddTestProject(project1); // Creating two waiters that will allow us to know for certain if the events have fired. using (var closeWaiter = new EventWaiter()) using (var openWaiter = new EventWaiter()) { // Wrapping event handlers so they can notify us on being called. var documentOpenedEventHandler = openWaiter.Wrap<DocumentEventArgs>( (sender, args) => Assert.True(args.Document.Id == document.Id, "The document given to the 'DocumentOpened' event handler did not have the same id as the one created for the test.")); var documentClosedEventHandler = closeWaiter.Wrap<DocumentEventArgs>( (sender, args) => Assert.True(args.Document.Id == document.Id, "The document given to the 'DocumentClosed' event handler did not have the same id as the one created for the test.")); workspace.DocumentOpened += documentOpenedEventHandler; workspace.DocumentClosed += documentClosedEventHandler; workspace.OpenDocument(document.Id); workspace.CloseDocument(document.Id); // Wait for all workspace tasks to finish. After this is finished executing, all handlers should have been notified. WaitForWorkspaceOperationsToComplete(workspace); // Wait to recieve signal that events have fired. Assert.True(openWaiter.WaitForEventToFire(longEventTimeout), string.Format("event 'DocumentOpened' was not fired within {0} minutes.", longEventTimeout.Minutes)); Assert.True(closeWaiter.WaitForEventToFire(longEventTimeout), string.Format("event 'DocumentClosed' was not fired within {0} minutes.", longEventTimeout.Minutes)); workspace.DocumentOpened -= documentOpenedEventHandler; workspace.DocumentClosed -= documentClosedEventHandler; workspace.OpenDocument(document.Id); workspace.CloseDocument(document.Id); // Wait for all workspace tasks to finish. After this is finished executing, all handlers should have been notified. WaitForWorkspaceOperationsToComplete(workspace); // Verifiying that an event has not been called is difficult to prove. // All events should have already been called so we wait 5 seconds and then assume the event handler was removed correctly. Assert.False(openWaiter.WaitForEventToFire(shortEventTimeout), string.Format("event handler 'DocumentOpened' was called within {0} seconds though it was removed from the list.", shortEventTimeout.Seconds)); Assert.False(closeWaiter.WaitForEventToFire(shortEventTimeout), string.Format("event handler 'DocumentClosed' was called within {0} seconds though it was removed from the list.", shortEventTimeout.Seconds)); } } }
public void TestRemoveProjectWithOpenedDocuments() { using (var workspace = CreateWorkspace()) { var solution = workspace.CurrentSolution; var document = new TestHostDocument(string.Empty); var project1 = new TestHostProject(workspace, document, name: "project1"); workspace.AddTestProject(project1); workspace.OnDocumentOpened(document.Id, document.GetOpenTextContainer()); workspace.OnProjectRemoved(project1.Id); Assert.False(workspace.IsDocumentOpen(document.Id)); Assert.Empty(workspace.CurrentSolution.Projects); } }
public void TestAdditionalFile_DocumentChanged() { using (var workspace = CreateWorkspace()) { var startText = @"<setting value = ""foo"""; var newText = @"<setting value = ""foo1"""; var document = new TestHostDocument("public class C { }"); var additionalDoc = new TestHostDocument(startText); var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, additionalDocuments: new[] { additionalDoc }); workspace.AddTestProject(project1); var buffer = additionalDoc.GetTextBuffer(); workspace.OnAdditionalDocumentOpened(additionalDoc.Id, additionalDoc.GetOpenTextContainer()); var project = workspace.CurrentSolution.Projects.Single(); var oldVersion = project.GetSemanticVersionAsync().PumpingWaitResult(); // fork the solution to introduce a change. var oldSolution = workspace.CurrentSolution; var newSolution = oldSolution.WithAdditionalDocumentText(additionalDoc.Id, SourceText.From(newText)); workspace.TryApplyChanges(newSolution); var doc = workspace.CurrentSolution.GetAdditionalDocument(additionalDoc.Id); // new text should have been pushed into buffer Assert.Equal(newText, buffer.CurrentSnapshot.GetText()); // Text changes are considered top level changes and they change the project's semantic version. Assert.Equal(doc.GetTextVersionAsync().PumpingWaitResult(), doc.GetTopLevelChangeTextVersionAsync().PumpingWaitResult()); Assert.NotEqual(oldVersion, doc.Project.GetSemanticVersionAsync().PumpingWaitResult()); } }
public async Task TestGetCompilationOnDependentProject() { using (var workspace = CreateWorkspace()) { var solution = workspace.CurrentSolution; var document1 = new TestHostDocument(@"public class C { }"); var project1 = new TestHostProject(workspace, document1, name: "project1"); var document2 = new TestHostDocument(@"class D : C { }"); var project2 = new TestHostProject(workspace, document2, name: "project2", projectReferences: new[] { project1 }); workspace.AddTestProject(project1); workspace.AddTestProject(project2); var snapshot = workspace.CurrentSolution; var id1 = snapshot.Projects.First(p => p.Name == project1.Name).Id; var id2 = snapshot.Projects.First(p => p.Name == project2.Name).Id; var compilation2 = await snapshot.GetProject(id2).GetCompilationAsync(); var classD = compilation2.SourceModule.GlobalNamespace.GetTypeMembers("D").Single(); var classC = classD.BaseType; } }
public void TestAdditionalFile_AddRemove_FromProject() { using (var workspace = CreateWorkspace()) { var startText = @"<setting value = ""foo"""; var document = new TestHostDocument("public class C { }"); var additionalDoc = new TestHostDocument(startText, "original.config"); var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, additionalDocuments: new[] { additionalDoc }); workspace.AddTestProject(project1); var project = workspace.CurrentSolution.Projects.Single(); // fork the solution to introduce a change. var doc = project.AddAdditionalDocument("app.config", "text"); workspace.TryApplyChanges(doc.Project.Solution); Assert.Equal(1, workspace.CurrentSolution.GetProject(project1.Id).Documents.Count()); Assert.Equal(2, workspace.CurrentSolution.GetProject(project1.Id).AdditionalDocuments.Count()); // Now remove the newly added document project = workspace.CurrentSolution.Projects.Single(); workspace.TryApplyChanges(project.RemoveAdditionalDocument(doc.Id).Solution); Assert.Equal(1, workspace.CurrentSolution.GetProject(project1.Id).Documents.Count()); Assert.Equal(1, workspace.CurrentSolution.GetProject(project1.Id).AdditionalDocuments.Count()); Assert.Equal("original.config", workspace.CurrentSolution.GetProject(project1.Id).AdditionalDocuments.Single().Name); } }
public async Task TestDependentSemanticVersionChangesWhenNotOriginallyAccessed() { using (var workspace = CreateWorkspace(disablePartialSolutions: false)) { var solutionX = workspace.CurrentSolution; var document1 = new TestHostDocument(@"public class C { }"); var project1 = new TestHostProject(workspace, document1, name: "project1"); var document2 = new TestHostDocument("Public Class D \r\n Inherits C\r\nEnd Class"); var project2 = new TestHostProject(workspace, document2, language: LanguageNames.VisualBasic, name: "project2", projectReferences: new[] { project1 }); workspace.AddTestProject(project1); workspace.AddTestProject(project2); var solutionY = workspace.CurrentSolution; var id1 = solutionY.Projects.First(p => p.Name == project1.Name).Id; var id2 = solutionY.Projects.First(p => p.Name == project2.Name).Id; var compilation2y = await solutionY.GetProject(id2).GetCompilationAsync(); var errors = compilation2y.GetDiagnostics(); var classDy = compilation2y.SourceModule.GlobalNamespace.GetTypeMembers("D").Single(); var classCy = classDy.BaseType; Assert.NotEqual(TypeKind.Error, classCy.TypeKind); // open both documents so background compiler works on their compilations workspace.OnDocumentOpened(document1.Id, document1.GetOpenTextContainer()); workspace.OnDocumentOpened(document2.Id, document2.GetOpenTextContainer()); // change C to X var buffer1 = document1.GetTextBuffer(); buffer1.Replace(new Span(13, 1), "X"); for (int iter = 0; iter < 10; iter++) { WaitHelper.WaitForDispatchedOperationsToComplete(System.Windows.Threading.DispatcherPriority.ApplicationIdle); Thread.Sleep(1000); // the current solution should eventually have the change var cs = workspace.CurrentSolution; var doc1Z = cs.GetDocument(document1.Id); var hasX = (await doc1Z.GetTextAsync()).ToString().Contains("X"); if (hasX) { var newVersion = await cs.GetProject(project1.Id).GetDependentSemanticVersionAsync(); var newVersionX = await doc1Z.Project.GetDependentSemanticVersionAsync(); Assert.NotEqual(VersionStamp.Default, newVersion); Assert.Equal(newVersion, newVersionX); break; } } } }
protected static async Task<SyntaxNode> ExtractMethodAsync( TestWorkspace workspace, TestHostDocument testDocument, bool succeed = true, bool allowMovingDeclaration = true, bool dontPutOutOrRefOnStruct = true) { var document = workspace.CurrentSolution.GetDocument(testDocument.Id); Assert.NotNull(document); var originalOptions = await document.GetOptionsAsync(); var options = originalOptions.WithChangedOption(ExtractMethodOptions.AllowMovingDeclaration, document.Project.Language, allowMovingDeclaration) .WithChangedOption(ExtractMethodOptions.DontPutOutOrRefOnStruct, document.Project.Language, dontPutOutOrRefOnStruct); var semanticDocument = await SemanticDocument.CreateAsync(document, CancellationToken.None); var validator = new CSharpSelectionValidator(semanticDocument, testDocument.SelectedSpans.Single(), options); var selectedCode = await validator.GetValidSelectionAsync(CancellationToken.None); if (!succeed && selectedCode.Status.FailedWithNoBestEffortSuggestion()) { return null; } Assert.True(selectedCode.ContainsValidContext); // extract method var extractor = new CSharpMethodExtractor((CSharpSelectionResult)selectedCode); var result = await extractor.ExtractMethodAsync(CancellationToken.None); Assert.NotNull(result); Assert.Equal(succeed, result.Succeeded || result.SucceededWithSuggestion); return await result.Document.GetSyntaxRootAsync(); }
internal TestDocumentLoader(TestHostDocument hostDocument) { _hostDocument = hostDocument; }