Esempio n. 1
0
        public async Task 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.
                        await WaitForWorkspaceOperationsToComplete(workspace);

                        // Wait to receive 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.
                        await WaitForWorkspaceOperationsToComplete(workspace);

                        // Verifying 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 ReportDiagnostics()
        {
            var source = new EditAndContinueDiagnosticUpdateSource();

            var updates = new List <string>();

            source.DiagnosticsUpdated += (object sender, DiagnosticsUpdatedArgs e)
                                         => updates.Add($"{e.Kind} p={e.ProjectId} d={e.DocumentId}: {string.Join(",", e.Diagnostics.Select(d => d.Id.ToString()))}");

            var srcC1 = "class C1 {}";
            var srcC2 = "class C2 {}";
            var srcD1 = "class D1 {}";
            var srcD2 = "class D2 {}";
            var docC1 = new TestHostDocument(srcC1, displayName: "DocC1");
            var docC2 = new TestHostDocument(srcC2, displayName: "DocC2");
            var docD1 = new TestHostDocument(srcD1, displayName: "DocD1");
            var docD2 = new TestHostDocument(srcD2, displayName: "DocD2");

            var workspace = new TestWorkspace();
            var projC     = new TestHostProject(workspace, "ProjC");

            projC.AddDocument(docC1);
            projC.AddDocument(docC2);
            var projD = new TestHostProject(workspace, "ProjD");

            projD.AddDocument(docD1);
            projD.AddDocument(docD2);

            workspace.AddTestProject(projC);
            workspace.AddTestProject(projD);

            var treeC1 = workspace.CurrentSolution.GetDocument(docC1.Id).GetSyntaxTreeAsync().Result;
            var treeC2 = workspace.CurrentSolution.GetDocument(docC2.Id).GetSyntaxTreeAsync().Result;
            var treeD1 = workspace.CurrentSolution.GetDocument(docD1.Id).GetSyntaxTreeAsync().Result;
            var treeD2 = workspace.CurrentSolution.GetDocument(docD2.Id).GetSyntaxTreeAsync().Result;

            var diagnostics = new[]
            {
                Diagnostic.Create(new DiagnosticDescriptor("TST0001", "title1", "message1", "category", DiagnosticSeverity.Error, true), Location.Create(treeC1, new TextSpan(1, 1))),
                Diagnostic.Create(new DiagnosticDescriptor("TST0002", "title2", "message2", "category", DiagnosticSeverity.Error, true), Location.Create(treeC1, new TextSpan(1, 2))),
                Diagnostic.Create(new DiagnosticDescriptor("TST0003", "title3", "message3", "category", DiagnosticSeverity.Error, true), Location.Create(treeD1, new TextSpan(1, 2))),
                Diagnostic.Create(new DiagnosticDescriptor("TST0004", "title4", "message4", "category", DiagnosticSeverity.Error, true), Location.Create(treeD2, new TextSpan(1, 2))),
                Diagnostic.Create(new DiagnosticDescriptor("TST0005", "title5", "message5", "category", DiagnosticSeverity.Error, true), Location.None),
            };

            updates.Clear();
            source.ReportDiagnostics(workspace, workspace.CurrentSolution, projC.Id, diagnostics);
            AssertEx.Equal(new[]
            {
                $"DiagnosticsCreated p={projC.Id} d={docC1.Id}: TST0001,TST0002",
                $"DiagnosticsCreated p={projC.Id} d={docD1.Id}: TST0003",
                $"DiagnosticsCreated p={projC.Id} d={docD2.Id}: TST0004",
                $"DiagnosticsCreated p={projC.Id} d=: TST0005"
            }, updates);

            updates.Clear();
            source.ReportDiagnostics(workspace, workspace.CurrentSolution, projD.Id, diagnostics);
            AssertEx.Equal(new[]
            {
                $"DiagnosticsCreated p={projD.Id} d={docC1.Id}: TST0001,TST0002",
                $"DiagnosticsCreated p={projD.Id} d={docD1.Id}: TST0003",
                $"DiagnosticsCreated p={projD.Id} d={docD2.Id}: TST0004",
                $"DiagnosticsCreated p={projD.Id} d=: TST0005"
            }, updates);

            updates.Clear();
            source.ReportDiagnostics(workspace, workspace.CurrentSolution, null, diagnostics);
            AssertEx.Equal(new[]
            {
                $"DiagnosticsCreated p= d={docC1.Id}: TST0001,TST0002",
                $"DiagnosticsCreated p= d={docD1.Id}: TST0003",
                $"DiagnosticsCreated p= d={docD2.Id}: TST0004",
                $"DiagnosticsCreated p= d=: TST0005"
            }, updates);
        }
Esempio n. 3
0
        public async Task 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 = 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");

                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  = (await doc1Z.GetTextAsync()).ToString().Contains("X");

                    if (hasX)
                    {
                        var doc2Z        = cs.GetDocument(document2.Id);
                        var partialDoc2Z = await doc2Z.WithFrozenPartialSemanticsAsync(CancellationToken.None);

                        var compilation2Z = await partialDoc2Z.Project.GetCompilationAsync();

                        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");
            }
        }