/// <summary> /// Verifies that specified source will not produce diagnostic described with see <see cref="Descriptor"/> /// </summary> /// <param name="source">Source text that contains placeholder [||] to be replaced with <paramref name="sourceData"/>.</param> /// <param name="sourceData"></param> /// <param name="options"></param> /// <param name="cancellationToken"></param> public async Task VerifyNoDiagnosticAsync( string source, string sourceData, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { (_, string text) = TextParser.ReplaceEmptySpan(source, sourceData); await VerifyNoDiagnosticAsync( source : text, additionalSources : null, options : options, cancellationToken); }
public async Task VerifyNoRefactoringAsync( string source, TextSpan span, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { await VerifyNoRefactoringAsync( source, ImmutableArray.Create(span), equivalenceKey, options, cancellationToken).ConfigureAwait(false); }
/// <summary> /// Verifies that specified source will produce diagnostic described with see <see cref="Descriptor"/> /// </summary> /// <param name="source">A source code that should be tested. Tokens [| and |] represents start and end of selection respectively.</param> /// <param name="options"></param> /// <param name="cancellationToken"></param> 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); }
internal async Task VerifyNoRefactoringAsync( string source, IEnumerable <TextSpan> spans, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); options ??= Options; using (Workspace workspace = new AdhocWorkspace()) { Document document = WorkspaceFactory.CreateDocument(workspace.CurrentSolution, source, options); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken); ImmutableArray <Diagnostic> compilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); VerifyCompilerDiagnostics(compilerDiagnostics, options); using (IEnumerator <TextSpan> en = spans.GetEnumerator()) { if (!en.MoveNext()) { Assert.True(false, "Span on which a refactoring should be invoked was not found."); } 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); } while (en.MoveNext()); } } }
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 VerifyFixAsync( string source, string inlineSource, string inlineExpected, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { (_, string source2, string expected) = TextParser.ReplaceEmptySpan(source, inlineSource, inlineExpected); await VerifyFixAsync( source : source2, expected : expected, equivalenceKey : equivalenceKey, options : options, cancellationToken : cancellationToken); }
public async Task VerifyRefactoringAsync( string source, string expected, IEnumerable <string> additionalSources = null, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { TextParserResult result = TextParser.GetSpans(source, LinePositionSpanInfoComparer.IndexDescending); await VerifyRefactoringAsync( source : result.Text, expected : expected, spans : result.Spans.Select(f => f.Span), additionalSources : additionalSources, equivalenceKey : equivalenceKey, options : options, cancellationToken : cancellationToken); }
public async Task VerifyNoDiagnosticAsync( string source, IEnumerable <string> additionalSources = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); options ??= Options; if (SupportedDiagnostics.IndexOf(Descriptor, DiagnosticDescriptorComparer.Id) == -1) { 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); Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken); VerifyCompilerDiagnostics(compilerDiagnostics, options); if (!Descriptor.IsEnabledByDefault) { compilation = compilation.EnsureEnabled(Descriptor); } 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 VerifyDiagnosticAsync( string source, string inlineSource, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { (TextSpan span, string text) = TextParser.ReplaceEmptySpan(source, inlineSource); TextParserResult result = TextParser.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); } }
internal void VerifyCompilerDiagnostics( ImmutableArray <Diagnostic> diagnostics, CodeVerificationOptions options) { DiagnosticSeverity maxAllowedSeverity = options.AllowedCompilerDiagnosticSeverity; 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 && !IsAllowed(diagnostic)) { return(true); } } return(false); } bool IsAllowed(Diagnostic diagnostic) { foreach (string diagnosticId in allowedDiagnosticIds) { if (diagnostic.Id == diagnosticId) { return(true); } } return(false); } }
/// <summary> /// Verifies that a refactoring can be applied on a specified source code. /// </summary> /// <param name="source">Source text that contains placeholder [||] to be replaced with <paramref name="sourceData"/> and <paramref name="expectedData"/>.</param> /// <param name="sourceData"></param> /// <param name="expectedData"></param> /// <param name="title">Code action's title.</param> /// <param name="equivalenceKey">Code action's equivalence key.</param> /// <param name="options"></param> /// <param name="cancellationToken"></param> public async Task VerifyRefactoringAsync( string source, string sourceData, string expectedData, string title = null, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { (TextSpan span, string source2, string expected) = TextParser.ReplaceEmptySpan(source, sourceData, expectedData); TextParserResult result = TextParser.GetSpans(source2, LinePositionSpanInfoComparer.IndexDescending); if (result.Spans.Any()) { await VerifyRefactoringAsync( source : result.Text, expected : expected, spans : result.Spans.Select(f => f.Span), title : title, equivalenceKey : equivalenceKey, options : options, cancellationToken : cancellationToken); } else { await VerifyRefactoringAsync( source : source2, expected : expected, span : span, title : title, equivalenceKey : equivalenceKey, options : options, cancellationToken : cancellationToken); } }
public async Task VerifyDiagnosticAsync( string source, IEnumerable <Diagnostic> expectedDiagnostics, IEnumerable <string> additionalSources = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); options ??= Options; using (Workspace workspace = new AdhocWorkspace()) { Project project = WorkspaceFactory.AddProject(workspace.CurrentSolution, options); Document document = WorkspaceFactory.AddDocument(project, source, additionalSources); Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken); VerifyCompilerDiagnostics(compilerDiagnostics, options); if (!Descriptor.IsEnabledByDefault) { compilation = compilation.EnsureEnabled(Descriptor); } ImmutableArray <Diagnostic> diagnostics = await compilation.GetAnalyzerDiagnosticsAsync(Analyzer, DiagnosticComparer.SpanStart, cancellationToken).ConfigureAwait(false); if (diagnostics.Length > 0 && 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); } } } }
public Document CreateDocument(Solution solution, string source, CodeVerificationOptions options) { return(CreateDocument(solution, source, additionalSource: null, options)); }
public Document CreateDocument(Solution solution, string source, IEnumerable <string> additionalSource, CodeVerificationOptions options) { Project project = AddProject(solution, options); return(AddDocument(project, source, additionalSource)); }
public async Task VerifyRefactoringAsync( string source, string expected, TextSpan span, IEnumerable <string> additionalSources = null, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); options ??= Options; using (Workspace workspace = new AdhocWorkspace()) { Project project = WorkspaceFactory.AddProject(workspace.CurrentSolution, options); Document document = WorkspaceFactory.AddDocument(project, source, additionalSources); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); 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); VerifyNoNewCompilerDiagnostics(compilerDiagnostics, newCompilerDiagnostics, options); string actual = await document.ToFullStringAsync(simplify : true, format : true, cancellationToken).ConfigureAwait(false); Assert.Equal(expected, actual); } }
public virtual Project AddProject(Solution solution, CodeVerificationOptions options) { return(solution .AddProject(DefaultProjectName, DefaultProjectName, Language) .WithMetadataReferences(options.MetadataReferences)); }
internal 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); } }