Skip to content

Commit

Permalink
Add initial test for inline diagnostics tagger
Browse files Browse the repository at this point in the history
  • Loading branch information
sharwell committed Dec 20, 2021
1 parent 9e35a98 commit 3e0e81d
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// 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.

using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.InlineDiagnostics;
using Microsoft.CodeAnalysis.Editor.UnitTests.Extensions;
using Microsoft.CodeAnalysis.Editor.UnitTests.Squiggles;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.VisualStudio.Text.Adornments;
using Microsoft.VisualStudio.Text.Tagging;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InlineDiagnostics
{
[UseExportProvider]
public class InlineDiagnosticsTaggerProviderTests
{
[WpfFact, Trait(Traits.Feature, Traits.Features.ErrorSquiggles)]
public async Task ErrorTagGeneratedForError()
{
var spans = await GetTagSpansAsync("class C {");
Assert.Equal(1, spans.Count());

var firstSpan = spans.First();
Assert.Equal(PredefinedErrorTypeNames.SyntaxError, firstSpan.Tag.ErrorType);
}

private static async Task<ImmutableArray<ITagSpan<InlineDiagnosticsTag>>> GetTagSpansAsync(string content)
{
using var workspace = TestWorkspace.CreateCSharp(content, composition: SquiggleUtilities.WpfCompositionWithSolutionCrawler);
return await GetTagSpansAsync(workspace);
}

private static async Task<ImmutableArray<ITagSpan<InlineDiagnosticsTag>>> GetTagSpansAsync(TestWorkspace workspace)
{
workspace.ApplyOptions(new[] { KeyValuePairUtil.Create(new OptionKey2(InlineDiagnosticsOptions.EnableInlineDiagnostics, LanguageNames.CSharp), (object)true) });
return (await TestDiagnosticTagProducer<InlineDiagnosticsTaggerProvider, InlineDiagnosticsTag>.GetDiagnosticsAndErrorSpans(workspace)).Item2;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void Test()
</Workspace>";

using var workspace = TestWorkspace.Create(workspaceXml);
var spans = (await TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider>.GetDiagnosticsAndErrorSpans(workspace)).Item2;
var spans = (await TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider, IErrorTag>.GetDiagnosticsAndErrorSpans(workspace)).Item2;

Assert.Equal(1, spans.Count());
Assert.Equal(PredefinedErrorTypeNames.SyntaxError, spans.First().Tag.ErrorType);
Expand Down Expand Up @@ -126,7 +126,7 @@ void Test()
}
};

var diagnosticsAndSpans = await TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider>.GetDiagnosticsAndErrorSpans(workspace, analyzerMap);
var diagnosticsAndSpans = await TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider, IErrorTag>.GetDiagnosticsAndErrorSpans(workspace, analyzerMap);

var spans =
diagnosticsAndSpans.Item1
Expand Down Expand Up @@ -204,7 +204,7 @@ public async Task SemanticErrorReported()
{
using var workspace = TestWorkspace.CreateCSharp("class C : Bar { }", composition: SquiggleUtilities.CompositionWithSolutionCrawler);

var spans = await TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider>.GetDiagnosticsAndErrorSpans(workspace);
var spans = await TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider, IErrorTag>.GetDiagnosticsAndErrorSpans(workspace);

Assert.Equal(1, spans.Item2.Count());

Expand Down Expand Up @@ -296,10 +296,10 @@ class Test
var updateArgs = DiagnosticsUpdatedArgs.DiagnosticsCreated(
new object(), workspace, workspace.CurrentSolution, document.Project.Id, document.Id,
ImmutableArray.Create(
TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider>.CreateDiagnosticData(document, new TextSpan(0, 0)),
TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider>.CreateDiagnosticData(document, new TextSpan(0, 1))));
TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider, IErrorTag>.CreateDiagnosticData(document, new TextSpan(0, 0)),
TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider, IErrorTag>.CreateDiagnosticData(document, new TextSpan(0, 1))));

var spans = await TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider>.GetErrorsFromUpdateSource(workspace, updateArgs);
var spans = await TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider, IErrorTag>.GetErrorsFromUpdateSource(workspace, updateArgs);

Assert.Equal(1, spans.Count());
var first = spans.First();
Expand Down Expand Up @@ -327,10 +327,10 @@ class Test
var updateArgs = DiagnosticsUpdatedArgs.DiagnosticsCreated(
new LiveId(), workspace, workspace.CurrentSolution, document.Project.Id, document.Id,
ImmutableArray.Create(
TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider>.CreateDiagnosticData(document, new TextSpan(0, 0)),
TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider>.CreateDiagnosticData(document, new TextSpan(0, 1))));
TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider, IErrorTag>.CreateDiagnosticData(document, new TextSpan(0, 0)),
TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider, IErrorTag>.CreateDiagnosticData(document, new TextSpan(0, 1))));

var spans = await TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider>.GetErrorsFromUpdateSource(workspace, updateArgs);
var spans = await TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider, IErrorTag>.GetErrorsFromUpdateSource(workspace, updateArgs);

Assert.Equal(2, spans.Count());
var first = spans.First();
Expand All @@ -350,7 +350,7 @@ public LiveId()
private static async Task<ImmutableArray<ITagSpan<IErrorTag>>> GetTagSpansAsync(string content)
{
using var workspace = TestWorkspace.CreateCSharp(content, composition: SquiggleUtilities.CompositionWithSolutionCrawler);
return (await TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider>.GetDiagnosticsAndErrorSpans(workspace)).Item2;
return (await TestDiagnosticTagProducer<DiagnosticsSquiggleTaggerProvider, IErrorTag>.GetDiagnosticsAndErrorSpans(workspace)).Item2;
}

private sealed class ReportOnClassWithLink : DiagnosticAnalyzer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void M() {
{ LanguageNames.CSharp, ImmutableArray.Create<DiagnosticAnalyzer>(new CSharpUseObjectInitializerDiagnosticAnalyzer()) }
};

var spans = (await TestDiagnosticTagProducer<DiagnosticsSuggestionTaggerProvider>.GetDiagnosticsAndErrorSpans(workspace, analyzerMap)).Item2;
var spans = (await TestDiagnosticTagProducer<DiagnosticsSuggestionTaggerProvider, IErrorTag>.GetDiagnosticsAndErrorSpans(workspace, analyzerMap)).Item2;
return (spans, workspace.Documents.Single().SelectedSpans.Single());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics;
using Microsoft.CodeAnalysis.Editor.InlineDiagnostics;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Shared.TestHooks;
Expand Down Expand Up @@ -76,7 +77,8 @@ public ITaggerProvider TaggerProvider

if (typeof(TProvider) == typeof(DiagnosticsSquiggleTaggerProvider)
|| typeof(TProvider) == typeof(DiagnosticsSuggestionTaggerProvider)
|| typeof(TProvider) == typeof(DiagnosticsClassificationTaggerProvider))
|| typeof(TProvider) == typeof(DiagnosticsClassificationTaggerProvider)
|| typeof(TProvider) == typeof(InlineDiagnosticsTaggerProvider))
{
_taggerProvider = _workspace.ExportProvider.GetExportedValues<ITaggerProvider>()
.OfType<TProvider>()
Expand Down
12 changes: 8 additions & 4 deletions src/EditorFeatures/TestUtilities/Squiggles/SquiggleUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ public static class SquiggleUtilities
internal static TestComposition CompositionWithSolutionCrawler = EditorTestCompositions.EditorFeatures
.RemoveParts(typeof(MockWorkspaceEventListenerProvider));

internal static async Task<(ImmutableArray<DiagnosticData>, ImmutableArray<ITagSpan<IErrorTag>>)> GetDiagnosticsAndErrorSpansAsync<TProvider>(
internal static TestComposition WpfCompositionWithSolutionCrawler = EditorTestCompositions.EditorFeaturesWpf
.RemoveParts(typeof(MockWorkspaceEventListenerProvider));

internal static async Task<(ImmutableArray<DiagnosticData>, ImmutableArray<ITagSpan<TTag>>)> GetDiagnosticsAndErrorSpansAsync<TProvider, TTag>(
TestWorkspace workspace,
IReadOnlyDictionary<string, ImmutableArray<DiagnosticAnalyzer>> analyzerMap = null)
where TProvider : AbstractDiagnosticsAdornmentTaggerProvider<IErrorTag>
where TProvider : AbstractDiagnosticsAdornmentTaggerProvider<TTag>
where TTag : class, ITag
{
using var wrapper = new DiagnosticTaggerWrapper<TProvider, IErrorTag>(workspace, analyzerMap);
var tagger = wrapper.TaggerProvider.CreateTagger<IErrorTag>(workspace.Documents.First().GetTextBuffer());
using var wrapper = new DiagnosticTaggerWrapper<TProvider, TTag>(workspace, analyzerMap);
var tagger = wrapper.TaggerProvider.CreateTagger<TTag>(workspace.Documents.First().GetTextBuffer());

using var disposable = tagger as IDisposable;
await wrapper.WaitForTags();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,25 @@

namespace Microsoft.CodeAnalysis.Editor.UnitTests.Squiggles
{
internal sealed class TestDiagnosticTagProducer<TProvider>
where TProvider : AbstractDiagnosticsAdornmentTaggerProvider<IErrorTag>
internal sealed class TestDiagnosticTagProducer<TProvider, TTag>
where TProvider : AbstractDiagnosticsAdornmentTaggerProvider<TTag>
where TTag : class, ITag
{
internal static Task<(ImmutableArray<DiagnosticData>, ImmutableArray<ITagSpan<IErrorTag>>)> GetDiagnosticsAndErrorSpans(
internal static Task<(ImmutableArray<DiagnosticData>, ImmutableArray<ITagSpan<TTag>>)> GetDiagnosticsAndErrorSpans(
TestWorkspace workspace,
IReadOnlyDictionary<string, ImmutableArray<DiagnosticAnalyzer>> analyzerMap = null)
{
return SquiggleUtilities.GetDiagnosticsAndErrorSpansAsync<TProvider>(workspace, analyzerMap);
return SquiggleUtilities.GetDiagnosticsAndErrorSpansAsync<TProvider, TTag>(workspace, analyzerMap);
}

internal static async Task<IList<ITagSpan<IErrorTag>>> GetErrorsFromUpdateSource(TestWorkspace workspace, DiagnosticsUpdatedArgs updateArgs)
internal static async Task<IList<ITagSpan<TTag>>> GetErrorsFromUpdateSource(TestWorkspace workspace, DiagnosticsUpdatedArgs updateArgs)
{
var globalOptions = workspace.GetService<IGlobalOptionService>();
var source = new TestDiagnosticUpdateSource(globalOptions);

using var wrapper = new DiagnosticTaggerWrapper<TProvider, IErrorTag>(workspace, updateSource: source);
using var wrapper = new DiagnosticTaggerWrapper<TProvider, TTag>(workspace, updateSource: source);

var tagger = wrapper.TaggerProvider.CreateTagger<IErrorTag>(workspace.Documents.First().GetTextBuffer());
var tagger = wrapper.TaggerProvider.CreateTagger<TTag>(workspace.Documents.First().GetTextBuffer());
using var disposable = (IDisposable)tagger;

source.RaiseDiagnosticsUpdated(updateArgs);
Expand Down

0 comments on commit 3e0e81d

Please sign in to comment.