private async Task TestAsync( string initialMarkup, string expectedMarkup, CodeActionPriority?priority, TestParameters parameters) { MarkupTestFile.GetSpans( initialMarkup.NormalizeLineEndings(), out var initialMarkupWithoutSpans, out IDictionary <string, ImmutableArray <TextSpan> > initialSpanMap); const string UnnecessaryMarkupKey = "Unnecessary"; var unnecessarySpans = initialSpanMap.GetOrAdd(UnnecessaryMarkupKey, _ => ImmutableArray <TextSpan> .Empty); MarkupTestFile.GetSpans( expectedMarkup.NormalizeLineEndings(), out var expected, out IDictionary <string, ImmutableArray <TextSpan> > expectedSpanMap); var conflictSpans = expectedSpanMap.GetOrAdd("Conflict", _ => ImmutableArray <TextSpan> .Empty); var renameSpans = expectedSpanMap.GetOrAdd("Rename", _ => ImmutableArray <TextSpan> .Empty); var warningSpans = expectedSpanMap.GetOrAdd("Warning", _ => ImmutableArray <TextSpan> .Empty); var navigationSpans = expectedSpanMap.GetOrAdd("Navigation", _ => ImmutableArray <TextSpan> .Empty); using (var workspace = CreateWorkspaceFromOptions(initialMarkup, parameters)) { // Ideally this check would always run, but there are several hundred tests that would need to be // updated with {|Unnecessary:|} spans. if (unnecessarySpans.Any()) { var allDiagnostics = await GetDiagnosticsWorkerAsync(workspace, parameters .WithRetainNonFixableDiagnostics(true) .WithIncludeDiagnosticsOutsideSelection(true)); TestDiagnosticTags(allDiagnostics, unnecessarySpans, WellKnownDiagnosticTags.Unnecessary, UnnecessaryMarkupKey, initialMarkupWithoutSpans); } var(_, action) = await GetCodeActionsAsync(workspace, parameters); await TestActionAsync( workspace, expected, action, conflictSpans, renameSpans, warningSpans, navigationSpans, parameters); } }