public async Task TestAdditionalFile_OpenClose() { using (var workspace = CreateWorkspace()) { var startText = @"<setting value = ""goo"""; 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 = await doc.GetTextAsync(CancellationToken.None); var version = await doc.GetTextVersionAsync(CancellationToken.None); 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 async Task TestAdditionalFile_OpenClose() { using (var workspace = CreateWorkspace()) { var startText = @"<setting value = ""goo"""; 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 = await doc.GetTextAsync(CancellationToken.None); var version = await doc.GetTextVersionAsync(CancellationToken.None); workspace.OnAdditionalDocumentOpened(additionalDoc.Id, additionalDoc.GetOpenTextContainer()); // Make sure that additional documents are included in GetOpenDocumentIds. var openDocumentIds = workspace.GetOpenDocumentIds(); Assert.Single(openDocumentIds); Assert.Equal(additionalDoc.Id, openDocumentIds.Single()); workspace.OnAdditionalDocumentClosed(additionalDoc.Id, TextLoader.From(TextAndVersion.Create(text, version))); // Make sure that closed additional documents are not include in GetOpenDocumentIds. Assert.Empty(workspace.GetOpenDocumentIds()); // 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 async Task TestAdditionalFile_DocumentChanged() { using (var workspace = CreateWorkspace()) { var startText = @"<setting value = ""goo"""; var newText = @"<setting value = ""goo1"""; 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 = await project.GetSemanticVersionAsync(); // 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(await doc.GetTextVersionAsync(), await doc.GetTopLevelChangeTextVersionAsync()); Assert.NotEqual(oldVersion, await doc.Project.GetSemanticVersionAsync()); } }
public async Task 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, (await workspace.CurrentSolution.GetDocument(document.Id).GetTextAsync()).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, (await workspace.CurrentSolution.GetDocument(document.Id).GetTextAsync()).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 async Task 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 = await doc.GetSyntaxTreeAsync(CancellationToken.None); Assert.True(syntaxTree.GetRoot().Width() > 0, "syntaxTree.GetRoot().Width should be > 0"); workspace.CloseDocument(document.Id); workspace.OnProjectRemoved(project1.Id); } }
public async Task TestChangeOptions2() { using (var workspace = CreateWorkspace()) { var solution = workspace.CurrentSolution; var document = new TestHostDocument( @"#if GOO class C { } #else class D { } #endif"); var project1 = new TestHostProject(workspace, document, name: "project1"); workspace.AddTestProject(project1); workspace.OnDocumentOpened(document.Id, document.GetOpenTextContainer()); await VerifyRootTypeNameAsync(workspace, "D"); workspace.OnParseOptionsChanged(document.Id.ProjectId, new CSharpParseOptions(preprocessorSymbols: new[] { "GOO" })); await VerifyRootTypeNameAsync(workspace, "C"); workspace.CloseDocument(document.Id); } }
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; } } } }
public void TestRemoveProjectWithClosedDocuments() { 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.CloseDocument(document.Id); workspace.OnProjectRemoved(project1.Id); } }
public async Task 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 = await solutionY.GetProject(id2).GetCompilationAsync(); 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 = await docZ.GetTextAsync(); var compilation2Z = await solutionZ.GetProject(id2).GetCompilationAsync(); var classDz = compilation2Z.SourceModule.GlobalNamespace.GetTypeMembers("D").Single(); var classCz = classDz.BaseType; Assert.Equal(TypeKind.Error, classCz.TypeKind); } }
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); } }
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"); } }