private async Task TestSpanGetterAsync(string markup, Func <Document, int, TextSpan?, Task> continuation) { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(markup)) { var testHostDocument = workspace.Documents.Single(); var position = testHostDocument.CursorPosition.Value; var expectedSpan = testHostDocument.SelectedSpans.Any() ? testHostDocument.SelectedSpans.Single() : (TextSpan?)null; await continuation( workspace.CurrentSolution.Projects.First().Documents.First(), position, expectedSpan); } }
public async Task TestPreviewDiagnosticTagger() { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync("class { }")) using (var previewWorkspace = new PreviewWorkspace(workspace.CurrentSolution)) { //// preview workspace and owner of the solution now share solution and its underlying text buffer var hostDocument = workspace.Projects.First().Documents.First(); //// enable preview diagnostics previewWorkspace.EnableDiagnostic(); var spans = await SquiggleUtilities.GetErrorSpans(workspace); Assert.Equal(1, spans.Count); } }
private async Task TestProximityExpressionGetterAsync( string markup, Func <CSharpProximityExpressionsService, Document, int, Task> continuation) { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(markup)) { var testDocument = workspace.Documents.Single(); var caretPosition = testDocument.CursorPosition.Value; var snapshot = testDocument.TextBuffer.CurrentSnapshot; var languageDebugInfo = new CSharpLanguageDebugInfoService(); var document = workspace.CurrentSolution.GetDocument(testDocument.Id); var proximityExpressionsGetter = new CSharpProximityExpressionsService(); await continuation(proximityExpressionsGetter, document, caretPosition); } }
public async Task TestAngles() { var code = new string[] { "/// <summary>Foo</summary>", "public class C<T> {", " void Foo() {", " bool a = b < c;", " bool d = e > f;", " }", "} " }; using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(code, parseOptions: Options.Script)) { var buffer = workspace.Documents.First().GetTextBuffer(); // Before open angle of generic var result = ProduceTags(workspace, buffer, 42); Assert.True(result.Select(ts => ts.Span.Span).SetEquals(Enumerable(Span.FromBounds(42, 43), Span.FromBounds(44, 45)))); // After close angle of generic result = ProduceTags(workspace, buffer, 45); Assert.True(result.Select(ts => ts.Span.Span).SetEquals(Enumerable(Span.FromBounds(42, 43), Span.FromBounds(44, 45)))); Action <int, char> assertNoTags = (position, expectedChar) => { Assert.Equal(expectedChar, buffer.CurrentSnapshot[position]); result = ProduceTags(workspace, buffer, position); Assert.True(result.IsEmpty()); result = ProduceTags(workspace, buffer, position + 1); Assert.True(result.IsEmpty()); }; // Doesn't highlight angles of XML doc comments var xmlTagStartPosition = 4; assertNoTags(xmlTagStartPosition, '<'); var xmlTagEndPosition = 12; assertNoTags(xmlTagEndPosition, '>'); var xmlEndTagStartPosition = 16; assertNoTags(xmlEndTagStartPosition, '<'); var xmlEndTagEndPosition = 25; assertNoTags(xmlEndTagEndPosition, '>'); // Doesn't highlight operators var openAnglePosition = 15 + buffer.CurrentSnapshot.GetLineFromLineNumber(3).Start; assertNoTags(openAnglePosition, '<'); var closeAnglePosition = 15 + buffer.CurrentSnapshot.GetLineFromLineNumber(4).Start; assertNoTags(closeAnglePosition, '>'); } }
protected static async Task AssertFormatWithPasteOrReturnAsync(string expectedWithMarker, string codeWithMarker, bool allowDocumentChanges, bool isPaste = true) { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(codeWithMarker)) { workspace.CanApplyChangeDocument = allowDocumentChanges; // set up caret position var testDocument = workspace.Documents.Single(); var view = testDocument.GetTextView(); view.Caret.MoveTo(new SnapshotPoint(view.TextSnapshot, testDocument.CursorPosition.Value)); // get original buffer var buffer = workspace.Documents.First().GetTextBuffer(); var optionService = workspace.Services.GetService <IOptionService>(); if (isPaste) { optionService.SetOptions(optionService.GetOptions().WithChangedOption(FeatureOnOffOptions.FormatOnPaste, LanguageNames.CSharp, true)); var commandHandler = new FormatCommandHandler(TestWaitIndicator.Default, null, null); var commandArgs = new PasteCommandArgs(view, view.TextBuffer); commandHandler.ExecuteCommand(commandArgs, () => { }); } else { // Return Key Command var textUndoHistory = new Mock <ITextUndoHistoryRegistry>(); var editorOperationsFactory = new Mock <IEditorOperationsFactoryService>(); var editorOperations = new Mock <IEditorOperations>(); editorOperationsFactory.Setup(x => x.GetEditorOperations(testDocument.GetTextView())).Returns(editorOperations.Object); var commandHandler = new FormatCommandHandler(TestWaitIndicator.Default, textUndoHistory.Object, editorOperationsFactory.Object); var commandArgs = new ReturnKeyCommandArgs(view, view.TextBuffer); commandHandler.ExecuteCommand(commandArgs, () => { }); } string expected; int expectedPosition; MarkupTestFile.GetPosition(expectedWithMarker, out expected, out expectedPosition); Assert.Equal(expected, view.TextSnapshot.GetText()); var caretPosition = view.Caret.Position.BufferPosition.Position; Assert.True(expectedPosition == caretPosition, string.Format("Caret positioned incorrectly. Should have been {0}, but was {1}.", expectedPosition, caretPosition)); } }
private static async Task UncommentSelectionAsync(string markup, string expected) { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(markup)) { var doc = workspace.Documents.First(); SetupSelection(doc.GetTextView(), doc.SelectedSpans.Select(s => Span.FromBounds(s.Start, s.End))); var commandHandler = new CommentUncommentSelectionCommandHandler( TestWaitIndicator.Default, workspace.ExportProvider.GetExportedValue <ITextUndoHistoryRegistry>(), workspace.ExportProvider.GetExportedValue <IEditorOperationsFactoryService>()); var textView = doc.GetTextView(); var textBuffer = doc.GetTextBuffer(); commandHandler.ExecuteCommand(textView, textBuffer, CommentUncommentSelectionCommandHandler.Operation.Uncomment); Assert.Equal(expected, doc.TextBuffer.CurrentSnapshot.GetText()); } }
protected async Task AssertFormatAsync(string expected, string code, bool debugMode = false, Dictionary <OptionKey, object> changedOptionSet = null, bool useTab = false, bool testWithTransformation = true) { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(code)) { var hostdoc = workspace.Documents.First(); // get original buffer var buffer = hostdoc.GetTextBuffer(); // create new buffer with cloned content var clonedBuffer = EditorFactory.CreateBuffer( buffer.ContentType.TypeName, workspace.ExportProvider, buffer.CurrentSnapshot.GetText()); var document = workspace.CurrentSolution.GetDocument(hostdoc.Id); var syntaxTree = await document.GetSyntaxTreeAsync(); var formattingRuleProvider = workspace.Services.GetService <IHostDependentFormattingRuleFactoryService>(); var options = workspace.Options; if (changedOptionSet != null) { foreach (var entry in changedOptionSet) { options = options.WithChangedOption(entry.Key, entry.Value); } } options = options.WithChangedOption(FormattingOptions.UseTabs, LanguageNames.CSharp, useTab); var root = await syntaxTree.GetRootAsync(); var rules = formattingRuleProvider.CreateRule(workspace.CurrentSolution.GetDocument(syntaxTree), 0).Concat(Formatter.GetDefaultFormattingRules(workspace, root.Language)); AssertFormat(workspace, expected, options, rules, clonedBuffer, root); if (testWithTransformation) { // format with node and transform AssertFormatWithTransformation(workspace, expected, options, rules, root); } } }
public async Task TestFindReferencesSynchronousCall() { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync("class C { C() { new C(); } }")) { var findReferencesPresenter = new MockReferencedSymbolsPresenter(); var handler = new FindReferencesCommandHandler( TestWaitIndicator.Default, SpecializedCollections.SingletonEnumerable(findReferencesPresenter)); var textView = workspace.Documents[0].GetTextView(); textView.Caret.MoveTo(new SnapshotPoint(textView.TextSnapshot, 7)); handler.ExecuteCommand(new FindReferencesCommandArgs( textView, textView.TextBuffer), () => { }); AssertResult(findReferencesPresenter.Result, "C", ".ctor"); } }
public async Task TestPreviewDiagnosticTagger() { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync("class { }")) using (var previewWorkspace = new PreviewWorkspace(workspace.CurrentSolution)) { //// preview workspace and owner of the solution now share solution and its underlying text buffer var hostDocument = workspace.Projects.First().Documents.First(); //// enable preview diagnostics previewWorkspace.EnableDiagnostic(); var diagnosticsAndErrorsSpans = await SquiggleUtilities.GetDiagnosticsAndErrorSpans(workspace); const string AnalzyerCount = "Analyzer Count: "; Assert.Equal(AnalzyerCount + 1, AnalzyerCount + diagnosticsAndErrorsSpans.Item1.Length); const string SquigglesCount = "Squiggles Count: "; Assert.Equal(SquigglesCount + 1, SquigglesCount + diagnosticsAndErrorsSpans.Item2.Count); } }
protected async Task AssertFormatAsync(string expected, string code, IEnumerable <TextSpan> spans, bool debugMode = false, Dictionary <OptionKey, object> changedOptionSet = null, int?baseIndentation = null) { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(code)) { var hostdoc = workspace.Documents.First(); var buffer = hostdoc.GetTextBuffer(); var document = workspace.CurrentSolution.GetDocument(hostdoc.Id); var syntaxTree = await document.GetSyntaxTreeAsync(); // create new buffer with cloned content var clonedBuffer = EditorFactory.CreateBuffer( buffer.ContentType.TypeName, workspace.ExportProvider, buffer.CurrentSnapshot.GetText()); var formattingRuleProvider = workspace.Services.GetService <IHostDependentFormattingRuleFactoryService>(); if (baseIndentation.HasValue) { var factory = formattingRuleProvider as TestFormattingRuleFactoryServiceFactory.Factory; factory.BaseIndentation = baseIndentation.Value; factory.TextSpan = spans.First(); } var options = workspace.Options; if (changedOptionSet != null) { foreach (var entry in changedOptionSet) { options = options.WithChangedOption(entry.Key, entry.Value); } } var root = syntaxTree.GetRoot(); var rules = formattingRuleProvider.CreateRule(workspace.CurrentSolution.GetDocument(syntaxTree), 0).Concat(Formatter.GetDefaultFormattingRules(workspace, root.Language)); AssertFormat(workspace, expected, options, rules, clonedBuffer, root, spans); // format with node and transform AssertFormatWithTransformation(workspace, expected, options, rules, root, spans); } }
public async Task CSharpOutliningTagger() { var code = new string[] { "using System;", "namespace MyNamespace", "{", "#region MyRegion", " public class MyClass", " {", " static void Main(string[] args)", " {", " int x = 5;", " }", " }", "#endregion", "}" }; using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(code)) { var tags = GetTagsFromWorkspace(workspace); // ensure all 4 outlining region tags were found Assert.Equal(4, tags.Count); // ensure the method and #region outlining spans are marked as implementation Assert.False(tags[0].IsImplementation); Assert.False(tags[1].IsImplementation); Assert.True(tags[2].IsImplementation); Assert.True(tags[3].IsImplementation); // verify line counts var hints = tags.Select(x => x.CollapsedHintForm).Cast <ViewHostingControl>().Select(vhc => vhc.TextView_TestOnly).ToList(); Assert.Equal(12, hints[0].TextSnapshot.LineCount); // namespace Assert.Equal(7, hints[1].TextSnapshot.LineCount); // class Assert.Equal(9, hints[2].TextSnapshot.LineCount); // region Assert.Equal(4, hints[3].TextSnapshot.LineCount); // method hints.Do(v => v.Close()); } }
public async Task AnalyzeDocumentAsync_SemanticError_Change() { string source1 = @" class C { public static void Main() { System.Console.WriteLine(1); Bar(); // semantic error } } "; string source2 = @" class C { public static void Main() { System.Console.WriteLine(2); Bar(); // semantic error } } "; var analyzer = new CSharpEditAndContinueAnalyzer(); using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(source1)) { var documentId = workspace.CurrentSolution.Projects.First().Documents.First().Id; var oldSolution = workspace.CurrentSolution; var newSolution = workspace.CurrentSolution.WithDocumentText(documentId, SourceText.From(source2)); var baseActiveStatements = ImmutableArray.Create <ActiveStatementSpan>(); var result = await analyzer.AnalyzeDocumentAsync(oldSolution, baseActiveStatements, newSolution.GetDocument(documentId), default(CancellationToken)); Assert.True(result.HasChanges); Assert.True(result.HasChangesAndErrors); Assert.True(result.HasChangesAndCompilationErrors); } }
protected async Task ExpectExtractMethodToFailAsync( string codeWithMarker, string expected, bool allowMovingDeclaration = true, bool dontPutOutOrRefOnStruct = true, CSharpParseOptions parseOptions = null) { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(new[] { codeWithMarker }, parseOptions: parseOptions)) { var testDocument = workspace.Documents.Single(); var subjectBuffer = testDocument.TextBuffer; var tree = await ExtractMethodAsync(workspace, testDocument, succeed : false, allowMovingDeclaration : allowMovingDeclaration, dontPutOutOrRefOnStruct : dontPutOutOrRefOnStruct); using (var edit = subjectBuffer.CreateEdit()) { edit.Replace(0, edit.Snapshot.Length, tree.ToFullString()); edit.Apply(); } Assert.Equal(expected, subjectBuffer.CurrentSnapshot.GetText()); } }
protected async Task <int> GetSmartTokenFormatterIndentationAsync( string code, int indentationLine, char ch, int?baseIndentation = null, TextSpan span = default(TextSpan)) { // create tree service using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(code)) { if (baseIndentation.HasValue) { var factory = workspace.Services.GetService <IHostDependentFormattingRuleFactoryService>() as TestFormattingRuleFactoryServiceFactory.Factory; factory.BaseIndentation = baseIndentation.Value; factory.TextSpan = span; } var buffer = workspace.Documents.First().GetTextBuffer(); return(await GetSmartTokenFormatterIndentationWorkerAsync(workspace, buffer, indentationLine, ch)); } }
private async Task TestCachingAsync(string markup, params string[][] expectedArray) { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(markup)) { var testDocument = workspace.Documents.Single(); var spans = testDocument.AnnotatedSpans; var snapshot = testDocument.TextBuffer.CurrentSnapshot; var languageDebugInfo = new CachedProximityExpressionsGetter(new CSharpProximityExpressionsService()); var document = workspace.CurrentSolution.GetDocument(testDocument.Id); for (var i = 0; i < expectedArray.Length; i++) { int position; var key = spans.Keys.FirstOrDefault(k => k.StartsWith(i + "-", StringComparison.Ordinal)); if (key != null) { var parts = key.Split('-'); if (parts[1] == "OnDebugModeChanged") { languageDebugInfo.OnDebugModeChanged((DebugMode)Enum.Parse(typeof(DebugMode), parts[2])); } position = spans[key].First().Start; } else { position = spans[i.ToString()].First().Start; } var expected = expectedArray[i]; var result = await languageDebugInfo.DoAsync(document, position, string.Empty, CancellationToken.None); AssertEx.Equal(expectedArray[i], result); } } }
protected static async Task AssertFormatWithViewAsync(string expectedWithMarker, string codeWithMarker, bool debugMode = false) { var editorOperations = new Mock <IEditorOperations>(MockBehavior.Strict); var editorOperationsFactoryService = new Mock <IEditorOperationsFactoryService>(MockBehavior.Strict); editorOperations.Setup(o => o.AddAfterTextBufferChangePrimitive()); editorOperations.Setup(o => o.AddBeforeTextBufferChangePrimitive()); editorOperationsFactoryService.Setup(s => s.GetEditorOperations(It.IsAny <ITextView>())).Returns(editorOperations.Object); using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(codeWithMarker)) { // set up caret position var testDocument = workspace.Documents.Single(); var view = testDocument.GetTextView(); view.Caret.MoveTo(new SnapshotPoint(view.TextSnapshot, testDocument.CursorPosition.Value)); // get original buffer var buffer = workspace.Documents.First().GetTextBuffer(); var commandHandler = new FormatCommandHandler(TestWaitIndicator.Default, workspace.GetService <ITextUndoHistoryRegistry>(), editorOperationsFactoryService.Object); var commandArgs = new FormatDocumentCommandArgs(view, view.TextBuffer); commandHandler.ExecuteCommand(commandArgs, () => { }); string expected; int expectedPosition; MarkupTestFile.GetPosition(expectedWithMarker, out expected, out expectedPosition); Assert.Equal(expected, view.TextSnapshot.GetText()); var caretPosition = view.Caret.Position.BufferPosition.Position; Assert.True(expectedPosition == caretPosition, string.Format("Caret positioned incorrectly. Should have been {0}, but was {1}.", expectedPosition, caretPosition)); } }
protected async Task IterateAllAsync(string code) { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(new string[] { code }, CodeAnalysis.CSharp.Test.Utilities.TestOptions.Regular)) { var document = workspace.CurrentSolution.GetDocument(workspace.Documents.First().Id); Assert.NotNull(document); var semanticDocument = await SemanticDocument.CreateAsync(document, CancellationToken.None); var tree = await document.GetSyntaxTreeAsync(); var iterator = tree.GetRoot().DescendantNodesAndSelf().Cast <SyntaxNode>(); var options = document.Project.Solution.Workspace.Options .WithChangedOption(ExtractMethodOptions.AllowMovingDeclaration, document.Project.Language, true); foreach (var node in iterator) { try { var validator = new CSharpSelectionValidator(semanticDocument, node.Span, options); var result = await validator.GetValidSelectionAsync(CancellationToken.None); // check the obvious case if (!(node is ExpressionSyntax) && !node.UnderValidContext()) { Assert.True(result.Status.FailedWithNoBestEffortSuggestion()); } } catch (ArgumentException) { // catch and ignore unknown issue. currently control flow analysis engine doesn't support field initializer. } } } }
public async Task AnalyzeDocumentAsync_SyntaxError_NoChange() { string source = @" class C { public static void Main() { System.Console.WriteLine(1) // syntax error } } "; var analyzer = new CSharpEditAndContinueAnalyzer(); using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(source)) { var document = workspace.CurrentSolution.Projects.First().Documents.First(); var baseActiveStatements = ImmutableArray.Create <ActiveStatementSpan>(); var result = await analyzer.AnalyzeDocumentAsync(workspace.CurrentSolution, baseActiveStatements, document, default(CancellationToken)); Assert.False(result.HasChanges); Assert.False(result.HasChangesAndErrors); Assert.False(result.HasChangesAndCompilationErrors); } }
protected override Task <TestWorkspace> CreateTestWorkspaceAsync(string initialMarkup) { return(CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(initialMarkup)); }
protected override Task <TestWorkspace> CreateWorkspaceFromCodeAsync(string code) { return(CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(code)); }
public async Task GenerateBaseline() { Console.WriteLine(typeof(FactAttribute)); var text = Resources.ProximityExpressionsGetterTestFile; using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync(text)) { var languageDebugInfo = new CSharpLanguageDebugInfoService(); var hostdoc = workspace.Documents.First(); var snapshot = hostdoc.TextBuffer.CurrentSnapshot; var document = workspace.CurrentSolution.GetDocument(hostdoc.Id); var builder = new StringBuilder(); var statements = (await document.GetSyntaxRootAsync(CancellationToken.None)).DescendantTokens().Select(t => t.GetAncestor <StatementSyntax>()).Distinct().WhereNotNull(); // Try to get proximity expressions at every token position and the start of every // line. var index = 0; foreach (var statement in statements) { builder.AppendLine("[WpfFact, Trait(Traits.Feature, Traits.Features.DebuggingProximityExpressions)]"); builder.AppendLine("public void TestAtStartOfStatement_" + index + "()"); builder.AppendLine("{"); var token = statement.GetFirstToken(); var line = snapshot.GetLineFromPosition(token.SpanStart); builder.AppendLine(" //// Line " + (line.LineNumber + 1)); builder.AppendLine(); if (line.LineNumber > 0) { builder.AppendLine(" //// " + snapshot.GetLineFromLineNumber(line.LineNumber - 1).GetText()); } builder.AppendLine(" //// " + line.GetText()); var charIndex = token.SpanStart - line.Start; builder.AppendLine(" //// " + new string(' ', charIndex) + "^"); builder.AppendLine(" var tree = GetTree(\"ProximityExpressionsGetterTestFile.cs\");"); builder.AppendLine(" var terms = CSharpProximityExpressionsService.Do(tree, " + token.SpanStart + ");"); var proximityExpressionsGetter = new CSharpProximityExpressionsService(); var terms = await proximityExpressionsGetter.GetProximityExpressionsAsync(document, token.SpanStart, CancellationToken.None); if (terms == null) { builder.AppendLine(" Assert.Null(terms);"); } else { builder.AppendLine(" Assert.NotNull(terms);"); var termsString = terms.Select(t => "\"" + t + "\"").Join(", "); builder.AppendLine(" AssertEx.Equal(new[] { " + termsString + " }, terms);"); } builder.AppendLine("}"); builder.AppendLine(); index++; } var str = builder.ToString(); Console.WriteLine(str); } }
public async Task TestPreviewDiagnosticTaggerInPreviewPane() { using (var workspace = await CSharpWorkspaceFactory.CreateWorkspaceFromLinesAsync("class { }")) { // set up listener to wait until diagnostic finish running var diagnosticService = workspace.ExportProvider.GetExportedValue <IDiagnosticService>() as DiagnosticService; // no easy way to setup waiter. kind of hacky way to setup waiter var source = new CancellationTokenSource(); var taskSource = new TaskCompletionSource <DiagnosticsUpdatedArgs>(); diagnosticService.DiagnosticsUpdated += (s, a) => { source.Cancel(); source = new CancellationTokenSource(); var cancellationToken = source.Token; Task.Delay(2000, cancellationToken).ContinueWith(t => taskSource.TrySetResult(a), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Current); }; var hostDocument = workspace.Projects.First().Documents.First(); // make a change to remove squiggle var oldDocument = workspace.CurrentSolution.GetDocument(hostDocument.Id); var oldText = oldDocument.GetTextAsync().Result; var newDocument = oldDocument.WithText(oldText.WithChanges(new TextChange(new TextSpan(0, oldText.Length), "class C { }"))); // create a diff view var previewFactoryService = workspace.ExportProvider.GetExportedValue <IPreviewFactoryService>(); var diffView = (IWpfDifferenceViewer)(await previewFactoryService.CreateChangedDocumentPreviewViewAsync(oldDocument, newDocument, CancellationToken.None)); var foregroundService = workspace.GetService <IForegroundNotificationService>(); var optionsService = workspace.Services.GetService <IOptionService>(); var waiter = new ErrorSquiggleWaiter(); var listeners = AsynchronousOperationListener.CreateListeners(FeatureAttribute.ErrorSquiggles, waiter); // set up tagger for both buffers var leftBuffer = diffView.LeftView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First(); var leftProvider = new DiagnosticsSquiggleTaggerProvider(optionsService, diagnosticService, foregroundService, listeners); var leftTagger = leftProvider.CreateTagger <IErrorTag>(leftBuffer); using (var leftDisposable = leftTagger as IDisposable) { var rightBuffer = diffView.RightView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First(); var rightProvider = new DiagnosticsSquiggleTaggerProvider(optionsService, diagnosticService, foregroundService, listeners); var rightTagger = rightProvider.CreateTagger <IErrorTag>(rightBuffer); using (var rightDisposable = rightTagger as IDisposable) { // wait up to 20 seconds for diagnostics taskSource.Task.Wait(20000); if (!taskSource.Task.IsCompleted) { // something is wrong FatalError.Report(new System.Exception("not finished after 20 seconds")); } // wait taggers await waiter.CreateWaitTask(); // check left buffer var leftSnapshot = leftBuffer.CurrentSnapshot; var leftSpans = leftTagger.GetTags(leftSnapshot.GetSnapshotSpanCollection()).ToList(); Assert.Equal(1, leftSpans.Count); // check right buffer var rightSnapshot = rightBuffer.CurrentSnapshot; var rightSpans = rightTagger.GetTags(rightSnapshot.GetSnapshotSpanCollection()).ToList(); Assert.Equal(0, rightSpans.Count); } } } }