diff --git a/eng/Versions.props b/eng/Versions.props index e4189148de13623f73f571226ee75ddd759c1460..90d066069cb1508af3ce1b2cab512314b39da95e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -62,10 +62,12 @@ 3.0.0 2.0.0-rc2-61102-09 $(MicrosoftCodeAnalysisTestingVersion) + $(MicrosoftCodeAnalysisTestingVersion) $(CodeStyleAnalyzerVersion) 0.10.6 2.0.19 $(MicrosoftCodeAnalysisTestingVersion) + $(MicrosoftCodeAnalysisTestingVersion) $(CodeStyleAnalyzerVersion) 3.0.0 $(RoslynDiagnosticsNugetPackageVersion) diff --git a/src/CodeStyle/Core/Tests/Microsoft.CodeAnalysis.CodeStyle.UnitTestUtilities.csproj b/src/CodeStyle/Core/Tests/Microsoft.CodeAnalysis.CodeStyle.UnitTestUtilities.csproj index 9047288484eebc866d5287a450d4342085151f5d..55d1fc693aea0351a154be516bfa7f3e75e306ae 100644 --- a/src/CodeStyle/Core/Tests/Microsoft.CodeAnalysis.CodeStyle.UnitTestUtilities.csproj +++ b/src/CodeStyle/Core/Tests/Microsoft.CodeAnalysis.CodeStyle.UnitTestUtilities.csproj @@ -12,9 +12,14 @@ + + + + + @@ -30,7 +35,9 @@ + + diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpCodeFixVerifier`2+Test.cs b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpCodeFixVerifier`2+Test.cs index 3f5cd44a9c817b9f5ba2e7136c177b6f02d86ab8..6da50e8d0013d3b0394f5c6198bc68503f7b2daf 100644 --- a/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpCodeFixVerifier`2+Test.cs +++ b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpCodeFixVerifier`2+Test.cs @@ -27,15 +27,6 @@ public static partial class CSharpCodeFixVerifier { public class Test : CSharpCodeFixTest { - /// - /// By default, the compiler reports diagnostics for nullable reference types at - /// , and the analyzer test framework defaults to only validating - /// diagnostics at . This map contains all compiler diagnostic IDs - /// related to nullability mapped to , which is then used to enable all - /// of these warnings for default validation during analyzer and code fix tests. - /// - private static readonly ImmutableDictionary s_nullableWarnings = GetNullableWarningsFromCompiler(); - public Test() { MarkupOptions = Testing.MarkupOptions.UseFirstDescriptor; @@ -46,7 +37,7 @@ public Test() solution = solution.WithProjectParseOptions(projectId, parseOptions.WithLanguageVersion(LanguageVersion)); var compilationOptions = solution.GetProject(projectId)!.CompilationOptions!; - compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(compilationOptions.SpecificDiagnosticOptions.SetItems(s_nullableWarnings)); + compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings)); solution = solution.WithProjectCompilationOptions(projectId, compilationOptions); var (analyzerConfigSource, remainingOptions) = CodeFixVerifierHelper.ConvertOptionsToAnalyzerConfig(DefaultFileExt, EditorConfig, Options); @@ -73,20 +64,6 @@ public Test() }); } - private static ImmutableDictionary GetNullableWarningsFromCompiler() - { - string[] args = { "/warnaserror:nullable" }; - var commandLineArguments = CSharpCommandLineParser.Default.Parse(args, baseDirectory: Environment.CurrentDirectory, sdkDirectory: Environment.CurrentDirectory); - var nullableWarnings = commandLineArguments.CompilationOptions.SpecificDiagnosticOptions; - - // Workaround for https://github.com/dotnet/roslyn/issues/41610 - nullableWarnings = nullableWarnings - .SetItem("CS8632", ReportDiagnostic.Error) - .SetItem("CS8669", ReportDiagnostic.Error); - - return nullableWarnings; - } - /// /// Gets or sets the language version to use for the test. The default value is /// . diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs new file mode 100644 index 0000000000000000000000000000000000000000..df3fd5dbb83d8106be0b4a8985916ff9ce789cd1 --- /dev/null +++ b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs @@ -0,0 +1,80 @@ +// 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. + +#nullable enable + +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Testing; +using Microsoft.CodeAnalysis.Testing.Verifiers; +using Microsoft.CodeAnalysis.CodeRefactorings; + +#if !CODE_STYLE +using System; +using Microsoft.CodeAnalysis.Diagnostics; +using Roslyn.Utilities; +#endif + +namespace Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions +{ + public static partial class CSharpCodeRefactoringVerifier + where TCodeRefactoring : CodeRefactoringProvider, new() + { + public class Test : CSharpCodeRefactoringTest + { + public Test() + { + SolutionTransforms.Add((solution, projectId) => + { + var parseOptions = (CSharpParseOptions)solution.GetProject(projectId)!.ParseOptions!; + solution = solution.WithProjectParseOptions(projectId, parseOptions.WithLanguageVersion(LanguageVersion)); + + var compilationOptions = solution.GetProject(projectId)!.CompilationOptions!; + compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings)); + solution = solution.WithProjectCompilationOptions(projectId, compilationOptions); + + var (analyzerConfigSource, remainingOptions) = CodeFixVerifierHelper.ConvertOptionsToAnalyzerConfig(DefaultFileExt, EditorConfig, Options); + if (analyzerConfigSource is object) + { + foreach (var id in solution.ProjectIds) + { + var documentId = DocumentId.CreateNewId(id, ".editorconfig"); + solution = solution.AddAnalyzerConfigDocument(documentId, ".editorconfig", analyzerConfigSource, filePath: "/.editorconfig"); + } + } + +#if !CODE_STYLE + var options = solution.Options; + foreach (var (key, value) in remainingOptions) + { + options = options.WithChangedOption(key, value); + } + + solution = solution.WithOptions(options); +#endif + + return solution; + }); + } + + /// + /// Gets or sets the language version to use for the test. The default value is + /// . + /// + public LanguageVersion LanguageVersion { get; set; } = LanguageVersion.CSharp8; + + /// + /// Gets a collection of options to apply to for testing. Values may be added + /// using a collection initializer. + /// + internal OptionsCollection Options { get; } = new OptionsCollection(LanguageNames.CSharp); + + public string? EditorConfig { get; set; } + +#if !CODE_STYLE + protected override AnalyzerOptions GetAnalyzerOptions(Project project) + => new WorkspaceAnalyzerOptions(base.GetAnalyzerOptions(project), project.Solution); +#endif + } + } +} diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1.cs b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1.cs new file mode 100644 index 0000000000000000000000000000000000000000..ffebf8227f44dd7a0ad20ad8db538495dc294ddb --- /dev/null +++ b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1.cs @@ -0,0 +1,42 @@ +// 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. + +#nullable enable + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeRefactorings; +using Microsoft.CodeAnalysis.Testing; + +namespace Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions +{ + public static partial class CSharpCodeRefactoringVerifier + where TCodeRefactoring : CodeRefactoringProvider, new() + { + /// + public static Task VerifyRefactoringAsync(string source, string fixedSource) + { + return VerifyRefactoringAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); + } + + /// + public static Task VerifyRefactoringAsync(string source, DiagnosticResult expected, string fixedSource) + { + return VerifyRefactoringAsync(source, new[] { expected }, fixedSource); + } + + /// + public static Task VerifyRefactoringAsync(string source, DiagnosticResult[] expected, string fixedSource) + { + var test = new Test + { + TestCode = source, + FixedCode = fixedSource + }; + + test.ExpectedDiagnostics.AddRange(expected); + return test.RunAsync(CancellationToken.None); + } + } +} diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpVerifierHelper.cs b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpVerifierHelper.cs new file mode 100644 index 0000000000000000000000000000000000000000..f3e2a4ec32c0a656c25fa11961a2433d27c71f35 --- /dev/null +++ b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/CSharpVerifierHelper.cs @@ -0,0 +1,36 @@ +// 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; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis.CSharp; + +namespace Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions +{ + internal static class CSharpVerifierHelper + { + /// + /// By default, the compiler reports diagnostics for nullable reference types at + /// , and the analyzer test framework defaults to only validating + /// diagnostics at . This map contains all compiler diagnostic IDs + /// related to nullability mapped to , which is then used to enable all + /// of these warnings for default validation during analyzer and code fix tests. + /// + internal static ImmutableDictionary NullableWarnings { get; } = GetNullableWarningsFromCompiler(); + + private static ImmutableDictionary GetNullableWarningsFromCompiler() + { + string[] args = { "/warnaserror:nullable" }; + var commandLineArguments = CSharpCommandLineParser.Default.Parse(args, baseDirectory: Environment.CurrentDirectory, sdkDirectory: Environment.CurrentDirectory); + var nullableWarnings = commandLineArguments.CompilationOptions.SpecificDiagnosticOptions; + + // Workaround for https://github.com/dotnet/roslyn/issues/41610 + nullableWarnings = nullableWarnings + .SetItem("CS8632", ReportDiagnostic.Error) + .SetItem("CS8669", ReportDiagnostic.Error); + + return nullableWarnings; + } + } +} diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/VisualBasicCodeRefactoringVerifier`1+Test.cs b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/VisualBasicCodeRefactoringVerifier`1+Test.cs new file mode 100644 index 0000000000000000000000000000000000000000..f789c7c94ee3f82765e1a258f6811a91fd2ba974 --- /dev/null +++ b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/VisualBasicCodeRefactoringVerifier`1+Test.cs @@ -0,0 +1,76 @@ +// 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. + +#nullable enable + +using Microsoft.CodeAnalysis.VisualBasic; +using Microsoft.CodeAnalysis.VisualBasic.Testing; +using Microsoft.CodeAnalysis.Testing.Verifiers; +using Microsoft.CodeAnalysis.CodeRefactorings; + +#if !CODE_STYLE +using System; +using Microsoft.CodeAnalysis.Diagnostics; +using Roslyn.Utilities; +#endif + +namespace Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions +{ + public static partial class VisualBasicCodeRefactoringVerifier + where TCodeRefactoring : CodeRefactoringProvider, new() + { + public class Test : VisualBasicCodeRefactoringTest + { + public Test() + { + SolutionTransforms.Add((solution, projectId) => + { + var parseOptions = (VisualBasicParseOptions)solution.GetProject(projectId)!.ParseOptions!; + solution = solution.WithProjectParseOptions(projectId, parseOptions.WithLanguageVersion(LanguageVersion)); + + var (analyzerConfigSource, remainingOptions) = CodeFixVerifierHelper.ConvertOptionsToAnalyzerConfig(DefaultFileExt, EditorConfig, Options); + if (analyzerConfigSource is object) + { + foreach (var id in solution.ProjectIds) + { + var documentId = DocumentId.CreateNewId(id, ".editorconfig"); + solution = solution.AddAnalyzerConfigDocument(documentId, ".editorconfig", analyzerConfigSource, filePath: "/.editorconfig"); + } + } + +#if !CODE_STYLE + var options = solution.Options; + foreach (var (key, value) in remainingOptions) + { + options = options.WithChangedOption(key, value); + } + + solution = solution.WithOptions(options); +#endif + + return solution; + }); + } + + /// + /// Gets or sets the language version to use for the test. The default value is + /// . + /// + public LanguageVersion LanguageVersion { get; set; } = LanguageVersion.VisualBasic16; + + /// + /// Gets a collection of options to apply to for testing. Values may be added + /// using a collection initializer. + /// + internal OptionsCollection Options { get; } = new OptionsCollection(LanguageNames.VisualBasic); + + public string? EditorConfig { get; set; } + +#if !CODE_STYLE + protected override AnalyzerOptions GetAnalyzerOptions(Project project) + => new WorkspaceAnalyzerOptions(base.GetAnalyzerOptions(project), project.Solution); +#endif + } + } +} diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/VisualBasicCodeRefactoringVerifier`1.cs b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/VisualBasicCodeRefactoringVerifier`1.cs new file mode 100644 index 0000000000000000000000000000000000000000..c1cf5d9fe14225406e2a085a884a0d4dd2303643 --- /dev/null +++ b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/VisualBasicCodeRefactoringVerifier`1.cs @@ -0,0 +1,42 @@ +// 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. + +#nullable enable + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeRefactorings; +using Microsoft.CodeAnalysis.Testing; + +namespace Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions +{ + public static partial class VisualBasicCodeRefactoringVerifier + where TCodeRefactoring : CodeRefactoringProvider, new() + { + /// + public static Task VerifyRefactoringAsync(string source, string fixedSource) + { + return VerifyRefactoringAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); + } + + /// + public static Task VerifyRefactoringAsync(string source, DiagnosticResult expected, string fixedSource) + { + return VerifyRefactoringAsync(source, new[] { expected }, fixedSource); + } + + /// + public static Task VerifyRefactoringAsync(string source, DiagnosticResult[] expected, string fixedSource) + { + var test = new Test + { + TestCode = source, + FixedCode = fixedSource + }; + + test.ExpectedDiagnostics.AddRange(expected); + return test.RunAsync(CancellationToken.None); + } + } +} diff --git a/src/Workspaces/CoreTestUtilities/Roslyn.Services.UnitTests.Utilities.csproj b/src/Workspaces/CoreTestUtilities/Roslyn.Services.UnitTests.Utilities.csproj index 46b7412319d19cf761d85fec60b6edef956c621e..418dff49161bf5e16c80b2986ccc56bbb68a1bfd 100644 --- a/src/Workspaces/CoreTestUtilities/Roslyn.Services.UnitTests.Utilities.csproj +++ b/src/Workspaces/CoreTestUtilities/Roslyn.Services.UnitTests.Utilities.csproj @@ -24,7 +24,9 @@ + +