public async Task VerifyNoRefactoringAsync( string source, IEnumerable <TextSpan> spans, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); Document document = CreateDocument(source); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); if (options == null) { options = Options; } VerifyCompilerDiagnostics(compilerDiagnostics, options); using (IEnumerator <TextSpan> en = spans.GetEnumerator()) { if (!en.MoveNext()) { throw new InvalidOperationException($"'{nameof(spans)}' contains no elements."); } do { cancellationToken.ThrowIfCancellationRequested(); var context = new CodeRefactoringContext( document, en.Current, a => { if (equivalenceKey == null || string.Equals(a.EquivalenceKey, equivalenceKey, StringComparison.Ordinal)) { Assert.True(false, "No code refactoring expected."); } }, CancellationToken.None); await RefactoringProvider.ComputeRefactoringsAsync(context).ConfigureAwait(false); } while (en.MoveNext()); } }
public async Task VerifyDiagnosticAsync( string source, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { TextParserResult result = TextParser.GetSpans(source); await VerifyDiagnosticAsync( result.Text, result.Spans.Select(f => CreateDiagnostic(f.Span, f.LineSpan)), additionalSources : null, options : options, cancellationToken).ConfigureAwait(false); }
public async Task VerifyNoDiagnosticAsync( string theory, string fromData, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { (string source, TextSpan span) = TestSourceText.ReplaceSpan(theory, fromData); await VerifyNoDiagnosticAsync( source : source, additionalSources : null, options : options, cancellationToken).ConfigureAwait(false); }
public async Task VerifyNoDiagnosticAsync( string theory, string fromData, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { (TextSpan span, string text) = TextParser.ReplaceEmptySpan(theory, fromData); await VerifyNoDiagnosticAsync( source : text, additionalSources : null, options : options, cancellationToken).ConfigureAwait(false); }
public async Task VerifyDiagnosticAndFixAsync( string source, string expected, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { TestSourceTextAnalysis analysis = TestSourceText.GetSpans(source); IEnumerable <Diagnostic> diagnostics = analysis.Spans.Select(f => CreateDiagnostic(f.Span, f.LineSpan)); await VerifyDiagnosticAsync(analysis.Source, diagnostics, additionalSources : null, options : options, cancellationToken : cancellationToken).ConfigureAwait(false); await VerifyFixAsync(analysis.Source, expected, options, cancellationToken).ConfigureAwait(false); }
public async Task VerifyNoRefactoringAsync( string source, TextSpan span, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { await VerifyNoRefactoringAsync( source, ImmutableArray.Create(span), equivalenceKey, options, cancellationToken).ConfigureAwait(false); }
public async Task VerifyDiagnosticAsync( string source, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { TestSourceTextAnalysis analysis = TestSourceText.GetSpans(source); await VerifyDiagnosticAsync( analysis.Source, analysis.Spans.Select(f => CreateDiagnostic(f.Span, f.LineSpan)), additionalSources : null, options : options, cancellationToken).ConfigureAwait(false); }
public async Task VerifyNoRefactoringAsync( string source, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { TextParserResult result = TextParser.GetSpans(source, LinePositionSpanInfoComparer.IndexDescending); await VerifyNoRefactoringAsync( source : result.Text, spans : result.Spans.Select(f => f.Span), equivalenceKey : equivalenceKey, options : options, cancellationToken : cancellationToken).ConfigureAwait(false); }
public async Task VerifyNoRefactoringAsync( string source, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { TextSpanParserResult result = SpanParser.GetSpans(source, reverse: true); await VerifyNoRefactoringAsync( source : result.Text, spans : result.Spans.Select(f => f.Span), equivalenceKey : equivalenceKey, options : options, cancellationToken : cancellationToken).ConfigureAwait(false); }
public async Task VerifyFixAsync( string theory, string fromData, string toData, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { (string source, string expected, TextSpan span) = TestSourceText.ReplaceSpan(theory, fromData, toData); await VerifyFixAsync( source : source, expected : expected, options : options, cancellationToken : cancellationToken).ConfigureAwait(false); }
public async Task VerifyNoRefactoringAsync( string source, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { TestSourceTextAnalysis analysis = TestSourceText.GetSpans(source, reverse: true); await VerifyNoRefactoringAsync( source : analysis.Source, spans : analysis.Spans.Select(f => f.Span), equivalenceKey : equivalenceKey, options : options, cancellationToken : cancellationToken).ConfigureAwait(false); }
public async Task VerifyNoFixAsync( string source, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); Document document = CreateDocument(source); Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <string> fixableDiagnosticIds = FixProvider.FixableDiagnosticIds; foreach (Diagnostic diagnostic in compilation.GetDiagnostics(cancellationToken: cancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); if (!fixableDiagnosticIds.Contains(diagnostic.Id)) { continue; } var context = new CodeFixContext( document, diagnostic, (a, d) => { if (!d.Contains(diagnostic)) { return; } if (equivalenceKey != null && !string.Equals(a.EquivalenceKey, equivalenceKey, StringComparison.Ordinal)) { return; } Assert.True(false, "No code fix expected."); }, CancellationToken.None); await FixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false); } }
public async Task VerifyNoDiagnosticAsync( string source, string[] additionalSources = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); if (!Analyzer.Supports(Descriptor)) { Assert.True(false, $"Diagnostic \"{Descriptor.Id}\" is not supported by analyzer \"{Analyzer.GetType().Name}\"."); } using (Workspace workspace = new AdhocWorkspace()) { Project project = WorkspaceFactory.AddProject(workspace.CurrentSolution, options); Document document = WorkspaceFactory.AddDocument(project, source, additionalSources ?? Array.Empty <string>()); Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken); if (options == null) { options = Options; } VerifyCompilerDiagnostics(compilerDiagnostics, options); if (options.EnableDiagnosticsDisabledByDefault) { compilation = compilation.EnableDiagnosticsDisabledByDefault(Analyzer); } ImmutableArray <Diagnostic> analyzerDiagnostics = await compilation.GetAnalyzerDiagnosticsAsync(Analyzer, DiagnosticComparer.SpanStart, cancellationToken).ConfigureAwait(false); foreach (Diagnostic diagnostic in analyzerDiagnostics) { if (string.Equals(diagnostic.Id, Descriptor.Id, StringComparison.Ordinal)) { Assert.True(false, $"No diagnostic expected{analyzerDiagnostics.Where(f => string.Equals(f.Id, Descriptor.Id, StringComparison.Ordinal)).ToDebugString()}"); } } } }
public async Task VerifyFixAsync( string theory, string fromData, string toData, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { (TextSpan span, string source, string expected) = SpanParser.ReplaceSpan(theory, fromData, toData); await VerifyFixAsync( source : source, expected : expected, equivalenceKey : equivalenceKey, options : options, cancellationToken : cancellationToken).ConfigureAwait(false); }
public static void VerifyCompilerDiagnostics( ImmutableArray <Diagnostic> diagnostics, CodeVerificationOptions options) { DiagnosticSeverity maxAllowedSeverity = options.MaxAllowedCompilerDiagnosticSeverity; ImmutableArray <string> allowedDiagnosticIds = options.AllowedCompilerDiagnosticIds; if (IsAny()) { IEnumerable <Diagnostic> notAllowed = diagnostics .Where(f => f.Severity > maxAllowedSeverity && !allowedDiagnosticIds.Any(id => id == f.Id)); Assert.True(false, $"No compiler diagnostics with severity higher than '{maxAllowedSeverity}' expected{notAllowed.ToDebugString()}"); } bool IsAny() { foreach (Diagnostic diagnostic in diagnostics) { if (diagnostic.Severity <= maxAllowedSeverity) { continue; } bool isAllowed = false; foreach (string diagnosticId in allowedDiagnosticIds) { if (diagnostic.Id == diagnosticId) { isAllowed = true; break; } } if (!isAllowed) { return(true); } } return(false); } }
public async Task VerifyDiagnosticAsync( string theory, string fromData, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { (string source, TextSpan span) = TestSourceText.ReplaceSpan(theory, fromData); TestSourceTextAnalysis analysis = TestSourceText.GetSpans(source); if (analysis.Spans.Any()) { await VerifyDiagnosticAsync(analysis.Source, analysis.Spans.Select(f => f.Span), options, cancellationToken).ConfigureAwait(false); } else { await VerifyDiagnosticAsync(source, span, options, cancellationToken).ConfigureAwait(false); } }
public async Task VerifyRefactoringAsync( string source, string expected, string[] additionalSources = null, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { TextParserResult result = TextParser.GetSpans(source, reverse: true); await VerifyRefactoringAsync( source : result.Text, expected : expected, spans : result.Spans.Select(f => f.Span), additionalSources : additionalSources, equivalenceKey : equivalenceKey, options : options, cancellationToken : cancellationToken).ConfigureAwait(false); }
public async Task VerifyDiagnosticAsync( string theory, string fromData, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { (TextSpan span, string text) = SpanParser.ReplaceSpan(theory, fromData); SpanParserResult result = SpanParser.GetSpans(text); if (result.Spans.Any()) { await VerifyDiagnosticAsync(result.Text, result.Spans.Select(f => f.Span), options, cancellationToken).ConfigureAwait(false); } else { await VerifyDiagnosticAsync(text, span, options, cancellationToken).ConfigureAwait(false); } }
public async Task VerifyRefactoringAsync( string source, string expected, IEnumerable <TextSpan> spans, string equivalenceKey = null, string[] additionalSources = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { foreach (TextSpan span in spans) { cancellationToken.ThrowIfCancellationRequested(); await VerifyRefactoringAsync( source : source, expected : expected, span, equivalenceKey : equivalenceKey, additionalSources : additionalSources, options : options, cancellationToken : cancellationToken).ConfigureAwait(false); } }
public virtual Project AddProject(Solution solution, CodeVerificationOptions options = null) { return(solution .AddProject(DefaultProjectName, DefaultProjectName, Language) .WithMetadataReferences(DefaultProjectReferences)); }
public async Task VerifyFixAsync( string source, string expected, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); if (!FixProvider.CanFixAny(Analyzer.SupportedDiagnostics)) { Assert.True(false, $"Code fix provider '{FixProvider.GetType().Name}' cannot fix any diagnostic supported by analyzer '{Analyzer}'."); } Document document = CreateDocument(source); Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken); if (options == null) { options = Options; } VerifyCompilerDiagnostics(compilerDiagnostics, options); if (options.EnableDiagnosticsDisabledByDefault) { compilation = compilation.EnableDiagnosticsDisabledByDefault(Analyzer); } ImmutableArray <Diagnostic> diagnostics = await compilation.GetAnalyzerDiagnosticsAsync(Analyzer, DiagnosticComparer.SpanStart, cancellationToken).ConfigureAwait(false); ImmutableArray <string> fixableDiagnosticIds = FixProvider.FixableDiagnosticIds; bool fixRegistered = false; while (diagnostics.Length > 0) { cancellationToken.ThrowIfCancellationRequested(); Diagnostic diagnostic = FindFirstFixableDiagnostic(); if (diagnostic == null) { break; } CodeAction action = null; var context = new CodeFixContext( document, diagnostic, (a, d) => { if (d.Contains(diagnostic) && action == null) { action = a; } }, CancellationToken.None); await FixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false); if (action == null) { break; } fixRegistered = true; document = await document.ApplyCodeActionAsync(action).ConfigureAwait(false); compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> newCompilerDiagnostics = compilation.GetDiagnostics(cancellationToken); VerifyCompilerDiagnostics(newCompilerDiagnostics, options); if (!options.AllowNewCompilerDiagnostics) { VerifyNoNewCompilerDiagnostics(compilerDiagnostics, newCompilerDiagnostics, options); } if (options.EnableDiagnosticsDisabledByDefault) { compilation = compilation.EnableDiagnosticsDisabledByDefault(Analyzer); } diagnostics = await compilation.GetAnalyzerDiagnosticsAsync(Analyzer, DiagnosticComparer.SpanStart, cancellationToken).ConfigureAwait(false); } Assert.True(fixRegistered, "No code fix has been registered."); string actual = await document.ToFullStringAsync(simplify : true, format : true).ConfigureAwait(false); Assert.Equal(expected, actual); Diagnostic FindFirstFixableDiagnostic() { foreach (Diagnostic diagnostic in diagnostics) { if (fixableDiagnosticIds.Contains(diagnostic.Id)) { return(diagnostic); } } return(null); } }
public async Task VerifyRefactoringAsync( string source, string expected, TextSpan span, string equivalenceKey = null, string[] additionalSources = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); Document document = CreateDocument(source, additionalSources ?? Array.Empty <string>()); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); if (options == null) { options = Options; } VerifyCompilerDiagnostics(compilerDiagnostics, options); CodeAction action = null; var context = new CodeRefactoringContext( document, span, a => { if (equivalenceKey == null || string.Equals(a.EquivalenceKey, equivalenceKey, StringComparison.Ordinal)) { if (action == null) { action = a; } } }, CancellationToken.None); await RefactoringProvider.ComputeRefactoringsAsync(context).ConfigureAwait(false); Assert.True(action != null, "No code refactoring has been registered."); document = await document.ApplyCodeActionAsync(action).ConfigureAwait(false); semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> newCompilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); VerifyCompilerDiagnostics(newCompilerDiagnostics, options); if (!options.AllowNewCompilerDiagnostics) { VerifyNoNewCompilerDiagnostics(compilerDiagnostics, newCompilerDiagnostics, options); } string actual = await document.ToFullStringAsync(simplify : true, format : true).ConfigureAwait(false); Assert.Equal(expected, actual); }
public static void VerifyNoNewCompilerDiagnostics( ImmutableArray <Diagnostic> diagnostics, ImmutableArray <Diagnostic> newDiagnostics, CodeVerificationOptions options) { ImmutableArray <string> allowedDiagnosticIds = options.AllowedCompilerDiagnosticIds; if (allowedDiagnosticIds.IsDefault) { allowedDiagnosticIds = ImmutableArray <string> .Empty; } if (IsAnyNewCompilerDiagnostic()) { IEnumerable <Diagnostic> diff = newDiagnostics .Where(diagnostic => !allowedDiagnosticIds.Any(id => id == diagnostic.Id)) .Except(diagnostics, DiagnosticDeepEqualityComparer.Instance); Assert.True(false, $"Code fix introduced new compiler diagnostics.{diff.ToDebugString()}"); } bool IsAnyNewCompilerDiagnostic() { foreach (Diagnostic newDiagnostic in newDiagnostics) { if (!IsAllowed(newDiagnostic) && !EqualsAny(newDiagnostic)) { return(true); } } return(false); } bool IsAllowed(Diagnostic diagnostic) { foreach (string diagnosticId in allowedDiagnosticIds) { if (diagnostic.Id == diagnosticId) { return(true); } } return(false); } bool EqualsAny(Diagnostic newDiagnostic) { foreach (Diagnostic diagnostic in diagnostics) { if (DiagnosticDeepEqualityComparer.Instance.Equals(diagnostic, newDiagnostic)) { return(true); } } return(false); } }
public async Task VerifyFixAsync( string source, string expected, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); if (!FixProvider.FixableDiagnosticIds.Contains(DiagnosticId)) { Assert.True(false, $"Code fix provider '{FixProvider.GetType().Name}' cannot fix diagnostic '{DiagnosticId}'."); } Document document = CreateDocument(source); Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> diagnostics = compilation.GetDiagnostics(cancellationToken: cancellationToken); diagnostics = diagnostics.Sort((x, y) => - DiagnosticComparer.SpanStart.Compare(x, y)); bool fixRegistered = false; while (diagnostics.Length > 0) { cancellationToken.ThrowIfCancellationRequested(); Diagnostic diagnostic = FindDiagnostic(); if (diagnostic == null) { break; } CodeAction action = null; var context = new CodeFixContext( document, diagnostic, (a, d) => { if (action != null) { return; } if (!d.Contains(diagnostic)) { return; } if (equivalenceKey != null && !string.Equals(a.EquivalenceKey, equivalenceKey, StringComparison.Ordinal)) { return; } action = a; }, CancellationToken.None); await FixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false); if (action == null) { break; } fixRegistered = true; document = await document.ApplyCodeActionAsync(action).ConfigureAwait(false); compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> newDiagnostics = compilation.GetDiagnostics(cancellationToken: cancellationToken); if (options == null) { options = Options; } if (!options.AllowNewCompilerDiagnostics) { VerifyNoNewCompilerDiagnostics(diagnostics, newDiagnostics, options); } diagnostics = newDiagnostics; } Assert.True(fixRegistered, "No code fix has been registered."); string actual = await document.ToFullStringAsync(simplify : true, format : true).ConfigureAwait(false); Assert.Equal(expected, actual); Diagnostic FindDiagnostic() { foreach (Diagnostic diagnostic in diagnostics) { if (string.Equals(diagnostic.Id, DiagnosticId, StringComparison.Ordinal)) { return(diagnostic); } } return(null); } }
public async Task VerifyDiagnosticAsync( string source, IEnumerable <Diagnostic> expectedDiagnostics, string[] additionalSources = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); using (Workspace workspace = new AdhocWorkspace()) { Project project = WorkspaceFactory.AddProject(workspace.CurrentSolution, options); Document document = WorkspaceFactory.AddDocument(project, source, additionalSources ?? Array.Empty <string>()); Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken); if (options == null) { options = Options; } VerifyCompilerDiagnostics(compilerDiagnostics, options); if (options.EnableDiagnosticsDisabledByDefault) { compilation = compilation.EnableDiagnosticsDisabledByDefault(Analyzer); } ImmutableArray <Diagnostic> diagnostics = await compilation.GetAnalyzerDiagnosticsAsync(Analyzer, DiagnosticComparer.SpanStart, cancellationToken).ConfigureAwait(false); if (diagnostics.Length > 0 && Analyzer.SupportedDiagnostics.Length > 1) { VerifyDiagnostics(FilterDiagnostics(diagnostics), expectedDiagnostics, cancellationToken); } else { VerifyDiagnostics(diagnostics, expectedDiagnostics, cancellationToken); } } IEnumerable <Diagnostic> FilterDiagnostics(ImmutableArray <Diagnostic> diagnostics) { foreach (Diagnostic diagnostic in diagnostics) { bool success = false; foreach (Diagnostic expectedDiagnostic in expectedDiagnostics) { if (DiagnosticComparer.Id.Equals(diagnostic, expectedDiagnostic)) { success = true; break; } } if (success) { yield return(diagnostic); } } } }