/// <summary> /// Verifies that <paramref name="code"/> produces no diagnostics when analyzed with <paramref name="analyzer"/>. /// </summary> /// <param name="analyzer">The analyzer.</param> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code"> /// The code to create the solution from. /// Can be a .cs, .csproj or .sln file /// </param> public static void Valid(DiagnosticAnalyzer analyzer, ExpectedDiagnostic expectedDiagnostic, FileInfo code) { AssertAnalyzerSupportsExpectedDiagnostic(analyzer, expectedDiagnostic, out var descriptor, out var suppressedDiagnostics); ValidAsync( analyzer, code, CodeFactory.DefaultCompilationOptions(descriptor, SuppressedDiagnostics.Concat(suppressedDiagnostics)), MetadataReferences) .GetAwaiter() .GetResult(); }
/// <summary> /// Verifies that /// 1. <paramref name="code"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <param name="fix">The <see cref="CodeFixProvider"/> to apply.</param> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code">The code to analyze.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void CodeFix(CodeFixProvider fix, ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> code, string fixedCode, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) { CodeFix( new PlaceholderAnalyzer(expectedDiagnostic.Id), fix, DiagnosticsAndSources.Create(expectedDiagnostic, code), fixedCode, SuppressedDiagnostics, MetadataReferences, fixTitle, allowCompilationErrors); }
/// <summary> /// Verifies that /// 1. <paramref name="code"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <param name="analyzer">The analyzer to run on the code..</param> /// <param name="fix">The code fix to apply.</param> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code">The code with error positions indicated.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void CodeFix(DiagnosticAnalyzer analyzer, CodeFixProvider fix, ExpectedDiagnostic expectedDiagnostic, string code, string fixedCode, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) { CodeFix( analyzer, fix, DiagnosticsAndSources.Create(expectedDiagnostic, code), fixedCode, SuppressedDiagnostics, MetadataReferences, fixTitle, allowCompilationErrors); }
/// <summary> /// Verifies that <paramref name="code"/> produces the expected diagnostics. /// </summary> /// <param name="analyzer">The analyzer to apply.</param> /// <param name="expectedDiagnostic">The expected diagnostic</param> /// <param name="code">The code to analyze.</param> public static void Diagnostics(DiagnosticAnalyzer analyzer, ExpectedDiagnostic expectedDiagnostic, params string[] code) { AssertAnalyzerSupportsExpectedDiagnostic(analyzer, expectedDiagnostic, out var descriptor, out var suppressedDiagnostics); DiagnosticsWithMetadataAsync( analyzer, DiagnosticsAndSources.Create(expectedDiagnostic, code), CodeFactory.DefaultCompilationOptions(descriptor, SuppressedDiagnostics.Concat(suppressedDiagnostics)), MetadataReferences, null) .GetAwaiter() .GetResult(); }
/// <summary> /// Verifies that /// 1. <paramref name="code"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <typeparam name="TCodeFix">The type of the code fix.</typeparam> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code">The code to analyze.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void CodeFix <TCodeFix>(ExpectedDiagnostic expectedDiagnostic, string code, string fixedCode, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) where TCodeFix : CodeFixProvider, new() { CodeFix( new PlaceholderAnalyzer(expectedDiagnostic.Id), new TCodeFix(), DiagnosticsAndSources.Create(expectedDiagnostic, code), fixedCode, SuppressedDiagnostics, MetadataReferences, fixTitle, allowCompilationErrors); }
/// <summary> /// Verifies that <paramref name="code"/> produces no diagnostics when analyzed with <paramref name="analyzerType"/>. /// </summary> /// <param name="analyzerType">The type of the analyzer.</param> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code">The code to analyze.</param> public static void Valid(Type analyzerType, ExpectedDiagnostic expectedDiagnostic, params string[] code) { var analyzer = (DiagnosticAnalyzer)Activator.CreateInstance(analyzerType); AssertAnalyzerSupportsExpectedDiagnostic(analyzer, expectedDiagnostic, out var descriptor, out var suppressedDiagnostics); ValidAsync( analyzer, code, CodeFactory.DefaultCompilationOptions(descriptor, SuppressedDiagnostics.Concat(suppressedDiagnostics)), MetadataReferences) .GetAwaiter() .GetResult(); }
/// <summary> /// Verifies that <paramref name="code"/> produces no diagnostics when analyzed with <typeparamref name="TAnalyzer"/>. /// </summary> /// <typeparam name="TAnalyzer">The type of the analyzer.</typeparam> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code">The code to analyze.</param> public static void Valid <TAnalyzer>(ExpectedDiagnostic expectedDiagnostic, params string[] code) where TAnalyzer : DiagnosticAnalyzer, new() { var analyzer = new TAnalyzer(); AssertAnalyzerSupportsExpectedDiagnostic(analyzer, expectedDiagnostic, out var descriptor, out var suppressedDiagnostics); ValidAsync( analyzer, code, CodeFactory.DefaultCompilationOptions(descriptor, SuppressedDiagnostics.Concat(suppressedDiagnostics)), MetadataReferences) .GetAwaiter() .GetResult(); }
/// <summary> /// Verifies that /// 1. <paramref name="codeWithErrorsIndicated"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <typeparam name="TAnalyzer">The type of the analyzer.</typeparam> /// <typeparam name="TCodeFix">The type of the code fix.</typeparam> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="codeWithErrorsIndicated">The code with error positions indicated.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void FixAll <TAnalyzer, TCodeFix>(ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> codeWithErrorsIndicated, IReadOnlyList <string> fixedCode, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) where TAnalyzer : DiagnosticAnalyzer, new() where TCodeFix : CodeFixProvider, new() { FixAll( new TAnalyzer(), new TCodeFix(), DiagnosticsAndSources.Create(expectedDiagnostic, codeWithErrorsIndicated), fixedCode, SuppressedDiagnostics, MetadataReferences, fixTitle, allowCompilationErrors); }
/// <summary> /// Get the expected diagnostics and cleaned sources. /// Either the <paramref name="expectedDiagnostic"/> or <paramref name="code"/> can have position or error position indicated but not both. /// </summary> /// <param name="expectedDiagnostic">The descriptor diagnosticId that is expected to produce diagnostics.</param> /// <param name="code">The code with errors indicated.</param> /// <returns>An instance of <see cref="DiagnosticsAndSources"/>.</returns> public static DiagnosticsAndSources Create(ExpectedDiagnostic expectedDiagnostic, string code) { if (expectedDiagnostic is null) { throw new ArgumentNullException(nameof(expectedDiagnostic)); } if (code is null) { throw new ArgumentNullException(nameof(code)); } return(Create(expectedDiagnostic, new[] { code })); }
/// <summary> /// Verifies that /// 1. <paramref name="code"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <param name="fix">The <see cref="CodeFixProvider"/> to apply.</param> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code">The code to analyze.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void FixAll(CodeFixProvider fix, ExpectedDiagnostic expectedDiagnostic, string code, string fixedCode, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) { var analyzer = new PlaceholderAnalyzer(expectedDiagnostic.Id); FixAll( analyzer, fix, DiagnosticsAndSources.Create(expectedDiagnostic, new[] { code }), new[] { fixedCode }, SuppressedDiagnostics, MetadataReferences, fixTitle, allowCompilationErrors); }
/// <summary> /// Verifies that /// 1. <paramref name="code"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <typeparam name="TCodeFix">The type of the code fix.</typeparam> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code">The code to analyze.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void FixAll <TCodeFix>(ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> code, IReadOnlyList <string> fixedCode, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) where TCodeFix : CodeFixProvider, new() { var analyzer = new PlaceholderAnalyzer(expectedDiagnostic.Id); FixAll( analyzer, new TCodeFix(), DiagnosticsAndSources.Create(expectedDiagnostic, code), fixedCode, SuppressedDiagnostics, MetadataReferences, fixTitle, allowCompilationErrors); }
/// <summary> /// Verifies that /// 1. <paramref name="code"/> produces the expected diagnostics /// 2. The code fix does not change the code. /// </summary> /// <typeparam name="TCodeFix">The type of the code fix.</typeparam> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code">The code to analyze.</param> public static void NoFix <TCodeFix>(ExpectedDiagnostic expectedDiagnostic, params string[] code) where TCodeFix : CodeFixProvider, new() { var analyzer = new PlaceholderAnalyzer(expectedDiagnostic.Id); AssertAnalyzerSupportsExpectedDiagnostic(analyzer, expectedDiagnostic, out var descriptor, out var suppressedDiagnostics); NoFixAsync( analyzer, new TCodeFix(), new DiagnosticsAndSources(new[] { expectedDiagnostic }, code), CodeFactory.DefaultCompilationOptions(descriptor, SuppressedDiagnostics.Concat(suppressedDiagnostics)), MetadataReferences) .GetAwaiter() .GetResult(); }
/// <summary> /// Verifies that /// 1. <paramref name="codeWithErrorsIndicated"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <typeparam name="TAnalyzer">The type of the analyzer.</typeparam> /// <typeparam name="TCodeFix">The type of the code fix.</typeparam> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="codeWithErrorsIndicated">The code with error positions indicated.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void FixAll <TAnalyzer, TCodeFix>(ExpectedDiagnostic expectedDiagnostic, string codeWithErrorsIndicated, string fixedCode, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) where TAnalyzer : DiagnosticAnalyzer, new() where TCodeFix : CodeFixProvider, new() { var analyzer = new TAnalyzer(); var codeFix = new TCodeFix(); FixAll( analyzer, codeFix, DiagnosticsAndSources.Create(expectedDiagnostic, new[] { codeWithErrorsIndicated }), new[] { fixedCode }, SuppressedDiagnostics, MetadataReferences, fixTitle, allowCompilationErrors); }
/// <summary> /// Verifies that /// 1. <paramref name="code"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <typeparam name="TCodeFix">The type of the code fix.</typeparam> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code">The code to analyze.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void CodeFix <TCodeFix>(ExpectedDiagnostic expectedDiagnostic, string code, string fixedCode, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) where TCodeFix : CodeFixProvider, new() { var analyzer = new PlaceholderAnalyzer(expectedDiagnostic.Id); CodeFixAsync( analyzer, new TCodeFix(), DiagnosticsAndSources.Create(expectedDiagnostic, new[] { code }), fixedCode, fixTitle, CodeFactory.DefaultCompilationOptions(analyzer, SuppressedDiagnostics), MetadataReferences, allowCompilationErrors) .GetAwaiter() .GetResult(); }
/// <summary> /// Verifies that <paramref name="code"/> produces the expected diagnostics. /// </summary> /// <param name="analyzer">The <see cref="DiagnosticAnalyzer"/> to check <paramref name="code"/> with.</param> /// <param name="expectedDiagnostic">The <see cref="ExpectedDiagnostic"/> with information about the expected <see cref="Diagnostic"/>. If <paramref name="analyzer"/> supports more than one <see cref="DiagnosticDescriptor.Id"/> this must be provided.</param> /// <param name="code">The code to analyze with <paramref name="analyzer"/>. Indicate error position with ↓ (alt + 25).</param> /// <param name="allowCompilationErrors">Specify if compilation errors are accepted in the fixed code. This can be for example syntax errors. Default value is <see cref="AllowCompilationErrors.No"/>.</param> /// <param name="suppressWarnings">A collection of <see cref="DiagnosticDescriptor.Id"/> to suppress when analyzing the code. Default is <see langword="null" /> meaning <see cref="SuppressedDiagnostics"/> are used.</param> /// <param name="metadataReferences">A collection of <see cref="MetadataReference"/> to use when compiling. Default is <see langword="null" /> meaning <see cref="MetadataReferences"/> are used.</param> /// <param name="compilationOptions">The <see cref="CSharpCompilationOptions"/>.</param> public static void Diagnostics( DiagnosticAnalyzer analyzer, ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> code, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No, IEnumerable <string>?suppressWarnings = null, IEnumerable <MetadataReference>?metadataReferences = null, CSharpCompilationOptions?compilationOptions = null) { Diagnostics( analyzer, DiagnosticsAndSources.Create(expectedDiagnostic, code), allowCompilationErrors: allowCompilationErrors, suppressWarnings: suppressWarnings, metadataReferences: metadataReferences, compilationOptions: compilationOptions); }
/// <summary> /// Verifies that /// 1. <paramref name="code"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <typeparam name="TCodeFix">The type of the code fix.</typeparam> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code">The code to analyze.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void CodeFix <TCodeFix>(ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> code, string fixedCode, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) where TCodeFix : CodeFixProvider, new() { var analyzer = new PlaceholderAnalyzer(expectedDiagnostic.Id); AssertAnalyzerSupportsExpectedDiagnostic(analyzer, expectedDiagnostic, out var descriptor, out var suppressedDiagnostics); CodeFixAsync( analyzer, new TCodeFix(), DiagnosticsAndSources.Create(expectedDiagnostic, code), fixedCode, fixTitle, CodeFactory.DefaultCompilationOptions(descriptor, SuppressedDiagnostics.Concat(suppressedDiagnostics)), MetadataReferences, allowCompilationErrors) .GetAwaiter() .GetResult(); }
/// <summary> /// Get the expected diagnostics and cleaned sources. /// Either the <paramref name="expectedDiagnostic"/> or <paramref name="code"/> can have position or error position indicated but not both. /// </summary> /// <param name="expectedDiagnostic">The descriptor diagnosticId that is expected to produce diagnostics.</param> /// <param name="code">The code with errors indicated.</param> /// <returns>An instance of <see cref="DiagnosticsAndSources"/>.</returns> public static DiagnosticsAndSources Create(ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> code) { if (HasErrorsIndicated(code)) { if (expectedDiagnostic.HasPosition) { var message = "Expected diagnostic has position indicated and the code has error position indicated with ↓\r\n" + "Use either:\r\n" + "a) Diagnostic with position and no error indicated in the code.\r\n" + "a) Diagnostic with position and no error indicated in the code.\r\n"; throw new InvalidOperationException(message); } return(CreateFromCodeWithErrorsIndicated(expectedDiagnostic.Id, expectedDiagnostic.Message, code)); } return(new DiagnosticsAndSources(new[] { expectedDiagnostic }, code)); }
/// <summary> /// Verifies that /// 1. <paramref name="codeWithErrorsIndicated"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <typeparam name="TAnalyzer">The type of the analyzer.</typeparam> /// <typeparam name="TCodeFix">The type of the code fix.</typeparam> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="codeWithErrorsIndicated">The code with error positions indicated.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void FixAll <TAnalyzer, TCodeFix>(ExpectedDiagnostic expectedDiagnostic, string codeWithErrorsIndicated, string fixedCode, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) where TAnalyzer : DiagnosticAnalyzer, new() where TCodeFix : CodeFixProvider, new() { var analyzer = new TAnalyzer(); AssertAnalyzerSupportsExpectedDiagnostic(analyzer, expectedDiagnostic, out var descriptor, out var suppressedDiagnostics); FixAllAsync( analyzer, new TCodeFix(), DiagnosticsAndSources.Create(expectedDiagnostic, new[] { codeWithErrorsIndicated }), new[] { fixedCode }, CodeFactory.DefaultCompilationOptions(descriptor, SuppressedDiagnostics.Concat(suppressedDiagnostics)), MetadataReferences, fixTitle, allowCompilationErrors) .GetAwaiter() .GetResult(); }
/// <summary> /// Verifies that /// 1. <paramref name="solution"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <param name="analyzer">The <see cref="DiagnosticAnalyzer"/> to check <paramref name="solution"/> with.</param> /// <param name="fix">The <see cref="CodeFixProvider"/> to apply on the <see cref="Diagnostic"/> reported.</param> /// <param name="expectedDiagnostic">The <see cref="ExpectedDiagnostic"/> with information about the expected <see cref="Diagnostic"/>. If <paramref name="analyzer"/> supports more than one <see cref="DiagnosticDescriptor.Id"/> this must be provided.</param> /// <param name="solution">The code to analyze with <paramref name="analyzer"/>. Indicate error position with ↓ (alt + 25).</param> /// <param name="after">The expected code produced by applying <paramref name="fix"/>.</param> /// <param name="fixTitle">The expected title of the fix. Must be provided if more than one code action is registered.</param> /// <param name="allowCompilationErrors">Specify if compilation errors are accepted in the fixed code. This can be for example syntax errors. Default value is <see cref="AllowCompilationErrors.No"/>.</param> public static void CodeFix( DiagnosticAnalyzer analyzer, CodeFixProvider fix, ExpectedDiagnostic expectedDiagnostic, Solution solution, string after, string?fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) { VerifyAnalyzerSupportsDiagnostic(analyzer, expectedDiagnostic); VerifyCodeFixSupportsAnalyzer(analyzer, fix); var diagnostics = Analyze.GetDiagnostics(analyzer, solution); var diagnosticsAndSources = DiagnosticsAndSources.Create( expectedDiagnostic, solution.Projects.SelectMany(x => x.Documents).Select(x => x.GetCode()).ToArray()); VerifyDiagnostics(diagnosticsAndSources, diagnostics, solution); VerifyFix(solution, diagnostics, analyzer, fix, MergeFixedCode(diagnosticsAndSources.Code, after), fixTitle, allowCompilationErrors); }
/// <summary> /// Verifies that /// 1. <paramref name="code"/> produces the expected diagnostics /// 2. The code fix does not change the code. /// </summary> /// <param name="analyzer">The <see cref="DiagnosticAnalyzer"/> to check <paramref name="code"/> with.</param> /// <param name="fix">The <see cref="CodeFixProvider"/> to apply on the <see cref="Diagnostic"/> reported.</param> /// <param name="expectedDiagnostic">The <see cref="ExpectedDiagnostic"/> with information about the expected <see cref="Diagnostic"/>. If <paramref name="analyzer"/> supports more than one <see cref="DiagnosticDescriptor.Id"/> this must be provided.</param> /// <param name="code">The code to analyze with <paramref name="analyzer"/>. Indicate error position with ↓ (alt + 25).</param> /// <param name="allowCompilationErrors">Specify if compilation errors are accepted in the fixed code. This can be for example syntax errors. Default value is <see cref="AllowCompilationErrors.No"/>.</param> /// <param name="suppressWarnings">A collection of <see cref="DiagnosticDescriptor.Id"/> to suppress when analyzing the code. Default is <see langword="null" /> meaning <see cref="SuppressedDiagnostics"/> are used.</param> /// <param name="metadataReferences">A collection of <see cref="MetadataReference"/> to use when compiling. Default is <see langword="null" /> meaning <see cref="MetadataReferences"/> are used.</param> /// <param name="compilationOptions">The <see cref="CSharpCompilationOptions"/>.</param> public static void NoFix( DiagnosticAnalyzer analyzer, CodeFixProvider fix, ExpectedDiagnostic expectedDiagnostic, string code, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No, IEnumerable <string>?suppressWarnings = null, IEnumerable <MetadataReference>?metadataReferences = null, CSharpCompilationOptions?compilationOptions = null) { NoFix( analyzer: analyzer, fix: fix, diagnosticsAndSources: DiagnosticsAndSources.Create(expectedDiagnostic, code), allowCompilationErrors: allowCompilationErrors, suppressWarnings: suppressWarnings, metadataReferences: metadataReferences, compilationOptions: compilationOptions); }
/// <summary> /// Verifies that /// 1. <paramref name="code"/> produces the expected diagnostics /// 2. The code fix does not change the code. /// </summary> /// <param name="fix">The <see cref="CodeFixProvider"/> to apply on the <see cref="Diagnostic"/> reported.</param> /// <param name="expectedDiagnostic">The <see cref="ExpectedDiagnostic"/> with information about the expected <see cref="Diagnostic"/>.</param> /// <param name="code">The code to analyze. Indicate error position with ↓ (alt + 25).</param> /// <param name="allowCompilationErrors">Specify if compilation errors are accepted in the fixed code. This can be for example syntax errors. Default value is <see cref="AllowCompilationErrors.No"/>.</param> /// <param name="suppressWarnings">A collection of <see cref="DiagnosticDescriptor.Id"/> to suppress when analyzing the code. Default is <see langword="null" /> meaning <see cref="SuppressedDiagnostics"/> are used.</param> /// <param name="metadataReferences">A collection of <see cref="MetadataReference"/> to use when compiling. Default is <see langword="null" /> meaning <see cref="MetadataReferences"/> are used.</param> /// <param name="compilationOptions">The <see cref="CSharpCompilationOptions"/>.</param> public static void NoFix( CodeFixProvider fix, ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> code, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No, IEnumerable <string>?suppressWarnings = null, IEnumerable <MetadataReference>?metadataReferences = null, CSharpCompilationOptions?compilationOptions = null) { var analyzer = new PlaceholderAnalyzer(expectedDiagnostic.Id); NoFix( analyzer: analyzer, fix: fix, diagnosticsAndSources: DiagnosticsAndSources.CreateFromCodeWithErrorsIndicated(analyzer, code), allowCompilationErrors: allowCompilationErrors, suppressWarnings: suppressWarnings, metadataReferences: metadataReferences, compilationOptions: compilationOptions); }
/// <summary> /// Verifies that /// 1. <paramref name="fix"/> supports fixing <paramref name="expectedDiagnostic"/>. /// 2. <paramref name="before"/> produces diagnostics fixable by <paramref name="fix"/>. /// 3. Applying <paramref name="fix"/> results in <paramref name="after"/>. /// </summary> /// <param name="fix">The <see cref="CodeFixProvider"/> to apply on the <see cref="Diagnostic"/> reported.</param> /// <param name="expectedDiagnostic">The <see cref="ExpectedDiagnostic"/> with information about the expected <see cref="Diagnostic"/>.</param> /// <param name="before">The code to analyze for <paramref name="expectedDiagnostic"/>. Indicate error position with ↓ (alt + 25).</param> /// <param name="after">The expected code produced by applying <paramref name="fix"/>.</param> /// <param name="fixTitle">The expected title of the fix. Must be provided if more than one code action is registered.</param> /// <param name="allowCompilationErrors">Specify if compilation errors are accepted in the fixed code. This can be for example syntax errors. Default value is <see cref="AllowCompilationErrors.No"/>.</param> /// <param name="suppressWarnings">A collection of <see cref="DiagnosticDescriptor.Id"/> to suppress when analyzing the code. Default is <see langword="null" /> meaning <see cref="SuppressedDiagnostics"/> are used.</param> /// <param name="metadataReferences">A collection of <see cref="MetadataReference"/> to use when compiling. Default is <see langword="null" /> meaning <see cref="MetadataReferences"/> are used.</param> /// <param name="compilationOptions">The <see cref="CSharpCompilationOptions"/>.</param> public static void CodeFix( CodeFixProvider fix, ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> before, IReadOnlyList <string> after, string?fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No, IEnumerable <string>?suppressWarnings = null, IEnumerable <MetadataReference>?metadataReferences = null, CSharpCompilationOptions?compilationOptions = null) { CodeFix( analyzer: new PlaceholderAnalyzer(expectedDiagnostic.Id), fix: fix, diagnosticsAndSources: DiagnosticsAndSources.Create(expectedDiagnostic, before), after: after, fixTitle: fixTitle, allowCompilationErrors: allowCompilationErrors, suppressWarnings: suppressWarnings, metadataReferences: metadataReferences, compilationOptions: compilationOptions); }
/// <summary> /// Verifies that /// 1. <paramref name="codeWithErrorsIndicated"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <param name="analyzer">The analyzer to run on the code..</param> /// <param name="codeFix">The code fix to apply.</param> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="codeWithErrorsIndicated">The code with error positions indicated.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="metadataReference">The meta data metadataReference to add to the compilation.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static Task FixAllAsync(DiagnosticAnalyzer analyzer, CodeFixProvider codeFix, ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> codeWithErrorsIndicated, IReadOnlyList <string> fixedCode, IReadOnlyList <MetadataReference> metadataReference, string fixTitle, AllowCompilationErrors allowCompilationErrors) { AssertAnalyzerSupportsExpectedDiagnostic(analyzer, expectedDiagnostic, out var descriptor, out var suppressedDiagnostics); return(FixAllAsync( analyzer, codeFix, DiagnosticsAndSources.Create(expectedDiagnostic, codeWithErrorsIndicated), fixedCode, CodeFactory.DefaultCompilationOptions(descriptor, SuppressedDiagnostics.Concat(suppressedDiagnostics)), metadataReference, fixTitle, allowCompilationErrors)); }
/// <summary> /// Verifies that /// 1. <paramref name="code"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <param name="analyzer">The analyzer to run on the code..</param> /// <param name="codeFix">The code fix to apply.</param> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code">The code with error positions indicated.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void CodeFix(DiagnosticAnalyzer analyzer, CodeFixProvider codeFix, ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> code, string fixedCode, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) { AssertCodeFixCanFixDiagnosticsFromAnalyzer(analyzer, codeFix); AssertAnalyzerSupportsExpectedDiagnostic(analyzer, expectedDiagnostic, out var descriptor, out var suppressedDiagnostics); CodeFixAsync( analyzer, codeFix, DiagnosticsAndSources.Create(expectedDiagnostic, code), fixedCode, fixTitle, CodeFactory.DefaultCompilationOptions(descriptor, SuppressedDiagnostics.Concat(suppressedDiagnostics)), MetadataReferences, allowCompilationErrors) .GetAwaiter() .GetResult(); }
/// <summary> /// Verifies that /// 1. <paramref name="codeWithErrorsIndicated"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <param name="analyzer">The analyzer to run on the code..</param> /// <param name="codeFix">The code fix to apply.</param> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="codeWithErrorsIndicated">The code with error positions indicated.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="metadataReferences">The meta data references to use when compiling the code.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void FixAll(DiagnosticAnalyzer analyzer, CodeFixProvider codeFix, ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> codeWithErrorsIndicated, IReadOnlyList <string> fixedCode, IReadOnlyList <MetadataReference> metadataReferences = null, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) { AssertAnalyzerSupportsExpectedDiagnostic(analyzer, expectedDiagnostic, out var descriptor, out var suppressedDiagnostics); FixAllAsync( analyzer, codeFix, DiagnosticsAndSources.Create(expectedDiagnostic, codeWithErrorsIndicated), fixedCode, CodeFactory.DefaultCompilationOptions(descriptor, SuppressedDiagnostics.Concat(suppressedDiagnostics)), metadataReferences ?? MetadataReferences, fixTitle, allowCompilationErrors) .GetAwaiter() .GetResult(); }
/// <summary> /// Verifies that /// 1. <paramref name="code"/> produces the expected diagnostics /// 2. The code fix does not change the code. /// </summary> /// <param name="analyzer">The type of the analyzer.</param> /// <param name="codeFix">The type of the code fix.</param> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="code">The code to analyze.</param> public static void NoFix(DiagnosticAnalyzer analyzer, CodeFixProvider codeFix, ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> code) { NoFix( analyzer, codeFix, DiagnosticsAndSources.Create(expectedDiagnostic, code), SuppressedDiagnostics, MetadataReferences); }
/// <summary> /// Verifies that /// 1. <paramref name="codeWithErrorsIndicated"/> produces the expected diagnostics /// 2. The code fix fixes the code. /// </summary> /// <param name="analyzer">The analyzer to run on the code..</param> /// <param name="codeFix">The code fix to apply.</param> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="codeWithErrorsIndicated">The code with error positions indicated.</param> /// <param name="fixedCode">The expected code produced by the code fix.</param> /// <param name="metadataReferences">The meta data references to use when compiling the code.</param> /// <param name="fixTitle">The title of the fix to apply if more than one.</param> /// <param name="allowCompilationErrors">If compilation errors are accepted in the fixed code.</param> public static void FixAll(DiagnosticAnalyzer analyzer, CodeFixProvider codeFix, ExpectedDiagnostic expectedDiagnostic, IReadOnlyList <string> codeWithErrorsIndicated, IReadOnlyList <string> fixedCode, IEnumerable <MetadataReference> metadataReferences = null, string fixTitle = null, AllowCompilationErrors allowCompilationErrors = AllowCompilationErrors.No) { FixAll( analyzer, codeFix, DiagnosticsAndSources.Create(expectedDiagnostic, codeWithErrorsIndicated), fixedCode, SuppressedDiagnostics, metadataReferences ?? MetadataReferences, fixTitle, allowCompilationErrors); }
private static void AssertAnalyzerSupportsExpectedDiagnostic(DiagnosticAnalyzer analyzer, ExpectedDiagnostic expectedDiagnostic, out DiagnosticDescriptor descriptor, out IReadOnlyList <string> suppressedDiagnostics) { var descriptors = analyzer.SupportedDiagnostics.Where(x => x.Id == expectedDiagnostic.Id).ToArray(); if (descriptors.Length == 0) { var message = $"Analyzer {analyzer} does not produce a diagnostic with ID {expectedDiagnostic.Id}.{Environment.NewLine}" + $"The analyzer produces the following diagnostics: {{{string.Join(", ", analyzer.SupportedDiagnostics.Select(d => d.Id))}}}{Environment.NewLine}" + $"The expected diagnostic is: {expectedDiagnostic.Id}"; throw AssertException.Create(message); } if (descriptors.Length > 1) { var message = $"Analyzer {analyzer} supports multiple diagnostics with ID {expectedDiagnostic.Id}.{Environment.NewLine}" + $"The analyzer produces the following diagnostics: {{{string.Join(", ", analyzer.SupportedDiagnostics.Select(d => d.Id))}}}{Environment.NewLine}" + $"The expected diagnostic is: {expectedDiagnostic.Id}"; throw AssertException.Create(message); } suppressedDiagnostics = analyzer.SupportedDiagnostics.Select(x => x.Id).Where(x => x != expectedDiagnostic.Id).ToArray(); descriptor = descriptors[0]; }
/// <summary> /// Create a Solution with diagnostic options set to warning for all supported diagnostics in <paramref name="analyzer"/>. /// </summary> /// <param name="code"> /// The code to create the solution from. /// Can be a .cs, .csproj or .sln file. /// </param> /// <param name="analyzer">The analyzer to add diagnostic options for.</param> /// <param name="expectedDiagnostic">The expected diagnostic.</param> /// <param name="suppressedDiagnostics">The suppressed diagnostics.</param> /// <param name="metadataReferences">The metadata references.</param> /// <returns>A <see cref="Solution"/>.</returns> public static Solution CreateSolution(FileInfo code, DiagnosticAnalyzer analyzer, ExpectedDiagnostic expectedDiagnostic, IEnumerable <string> suppressedDiagnostics = null, IEnumerable <MetadataReference> metadataReferences = null) { return(CreateSolution(code, DefaultCompilationOptions(analyzer, expectedDiagnostic, suppressedDiagnostics), metadataReferences)); }
/// <summary> /// Create default compilation options for <paramref name="analyzer"/> /// AD0001 is reported as error. /// </summary> /// <param name="analyzer">The analyzers to report warning or error for.</param> /// <param name="expectedDiagnostic">The diagnostics to check for.</param> /// <param name="suppressedDiagnostics">The analyzer IDs to suppress.</param> /// <returns>An instance of <see cref="CSharpCompilationOptions"/>.</returns> public static CSharpCompilationOptions DefaultCompilationOptions(DiagnosticAnalyzer analyzer, ExpectedDiagnostic expectedDiagnostic, IEnumerable <string> suppressedDiagnostics) { return(DefaultCompilationOptions(analyzer, expectedDiagnostic.Id, suppressedDiagnostics)); }