diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1649UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1649UnitTests.cs index ae3405ecb..c8bdc0472 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1649UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1649UnitTests.cs @@ -4,12 +4,8 @@ namespace StyleCop.Analyzers.Test.DocumentationRules { using System.Collections.Generic; - using System.Collections.Immutable; - using System.Linq; using System.Threading; using System.Threading.Tasks; - using Microsoft.CodeAnalysis; - using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; using StyleCop.Analyzers.DocumentationRules; @@ -62,7 +58,7 @@ public static IEnumerable TypeKeywords [MemberData(nameof(TypeKeywords))] public async Task VerifyWrongFileNameAsync(string typeKeyword) { - var testCode = $@"namespace TestNameSpace + var testCode = $@"namespace TestNamespace {{ public {typeKeyword} TestType {{ @@ -81,7 +77,7 @@ public async Task VerifyWrongFileNameAsync(string typeKeyword) var expectedDiagnostic = this.CSharpDiagnostic().WithLocation("WrongFileName.cs", 3, 13 + typeKeyword.Length); await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None, "WrongFileName.cs").ConfigureAwait(false); await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None, "TestType.cs").ConfigureAwait(false); - await this.VerifyRenameAsync(testCode, "WrongFileName.cs", "TestType.cs", CancellationToken.None).ConfigureAwait(false); + await this.VerifyCSharpFixAsync(testCode, fixedCode, oldFileName: "WrongFileName.cs", newFileName: "TestType.cs", cancellationToken: CancellationToken.None).ConfigureAwait(false); } /// @@ -94,7 +90,7 @@ public async Task VerifyWrongFileNameAsync(string typeKeyword) [MemberData(nameof(TypeKeywords))] public async Task VerifyWrongFileNameMultipleExtensionsAsync(string typeKeyword) { - var testCode = $@"namespace TestNameSpace + var testCode = $@"namespace TestNamespace {{ public {typeKeyword} TestType {{ @@ -113,7 +109,7 @@ public async Task VerifyWrongFileNameMultipleExtensionsAsync(string typeKeyword) var expectedDiagnostic = this.CSharpDiagnostic().WithLocation("WrongFileName.svc.cs", 3, 13 + typeKeyword.Length); await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None, "WrongFileName.svc.cs").ConfigureAwait(false); await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None, "TestType.svc.cs").ConfigureAwait(false); - await this.VerifyRenameAsync(testCode, "WrongFileName.svc.cs", "TestType.svc.cs", CancellationToken.None).ConfigureAwait(false); + await this.VerifyCSharpFixAsync(testCode, fixedCode, oldFileName: "WrongFileName.svc.cs", newFileName: "TestType.svc.cs", cancellationToken: CancellationToken.None).ConfigureAwait(false); } /// @@ -126,7 +122,7 @@ public async Task VerifyWrongFileNameMultipleExtensionsAsync(string typeKeyword) [MemberData(nameof(TypeKeywords))] public async Task VerifyWrongFileNameNoExtensionAsync(string typeKeyword) { - var testCode = $@"namespace TestNameSpace + var testCode = $@"namespace TestNamespace {{ public {typeKeyword} TestType {{ @@ -145,7 +141,7 @@ public async Task VerifyWrongFileNameNoExtensionAsync(string typeKeyword) var expectedDiagnostic = this.CSharpDiagnostic().WithLocation("WrongFileName", 3, 13 + typeKeyword.Length); await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None, "WrongFileName").ConfigureAwait(false); await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None, "TestType").ConfigureAwait(false); - await this.VerifyRenameAsync(testCode, "WrongFileName", "TestType", CancellationToken.None).ConfigureAwait(false); + await this.VerifyCSharpFixAsync(testCode, fixedCode, oldFileName: "WrongFileName", newFileName: "TestType", cancellationToken: CancellationToken.None).ConfigureAwait(false); } /// @@ -157,7 +153,7 @@ public async Task VerifyWrongFileNameNoExtensionAsync(string typeKeyword) [MemberData(nameof(TypeKeywords))] public async Task VerifyCaseInsensitivityAsync(string typeKeyword) { - var testCode = $@"namespace TestNameSpace + var testCode = $@"namespace TestNamespace {{ public {typeKeyword} TestType {{ @@ -177,7 +173,7 @@ public async Task VerifyCaseInsensitivityAsync(string typeKeyword) [MemberData(nameof(TypeKeywords))] public async Task VerifyFirstTypeIsUsedAsync(string typeKeyword) { - var testCode = $@"namespace TestNameSpace + var testCode = $@"namespace TestNamespace {{ public {typeKeyword} TestType {{ @@ -201,7 +197,7 @@ public async Task VerifyFirstTypeIsUsedAsync(string typeKeyword) [MemberData(nameof(TypeKeywords))] public async Task VerifyThatPartialTypesAreIgnoredAsync(string typeKeyword) { - var testCode = $@"namespace TestNameSpace + var testCode = $@"namespace TestNamespace {{ public partial {typeKeyword} TestType {{ @@ -223,7 +219,7 @@ public async Task VerifyStyleCopNamingConventionForGenericTypeAsync(string typeK { this.useMetadataSettings = false; - var testCode = $@"namespace TestNameSpace + var testCode = $@"namespace TestNamespace {{ public {typeKeyword} TestType {{ @@ -235,7 +231,7 @@ public async Task VerifyStyleCopNamingConventionForGenericTypeAsync(string typeK await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None, "TestType`3.cs").ConfigureAwait(false); await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None, "TestType.cs").ConfigureAwait(false); await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None, "TestType{T1,T2,T3}.cs").ConfigureAwait(false); - await this.VerifyRenameAsync(testCode, "TestType`3.cs", "TestType{T1,T2,T3}.cs", CancellationToken.None).ConfigureAwait(false); + await this.VerifyCSharpFixAsync(testCode, testCode, oldFileName: "TestType`3.cs", newFileName: "TestType{T1,T2,T3}.cs", cancellationToken: CancellationToken.None).ConfigureAwait(false); } /// @@ -249,7 +245,7 @@ public async Task VerifyMetadataNamingConventionForGenericTypeAsync(string typeK { this.useMetadataSettings = true; - var testCode = $@"namespace TestNameSpace + var testCode = $@"namespace TestNamespace {{ public {typeKeyword} TestType {{ @@ -263,7 +259,7 @@ public async Task VerifyMetadataNamingConventionForGenericTypeAsync(string typeK expectedDiagnostic = this.CSharpDiagnostic().WithLocation("TestType.cs", 3, 13 + typeKeyword.Length); await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None, "TestType.cs").ConfigureAwait(false); await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None, "TestType`3.cs").ConfigureAwait(false); - await this.VerifyRenameAsync(testCode, "TestType.cs", "TestType`3.cs", CancellationToken.None).ConfigureAwait(false); + await this.VerifyCSharpFixAsync(testCode, testCode, oldFileName: "TestType.cs", newFileName: "TestType`3.cs", cancellationToken: CancellationToken.None).ConfigureAwait(false); } /// @@ -278,7 +274,7 @@ public async Task VerifyMetadataNamingConventionForGenericTypeMultipleExtensions { this.useMetadataSettings = true; - var testCode = $@"namespace TestNameSpace + var testCode = $@"namespace TestNamespace {{ public {typeKeyword} TestType {{ @@ -297,7 +293,7 @@ public async Task VerifyMetadataNamingConventionForGenericTypeMultipleExtensions var expectedDiagnostic = this.CSharpDiagnostic().WithLocation("TestType.svc.cs", 3, 13 + typeKeyword.Length); await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None, "TestType.svc.cs").ConfigureAwait(false); await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None, "TestType`1.svc.cs").ConfigureAwait(false); - await this.VerifyRenameAsync(testCode, "TestType.svc.cs", "TestType`1.svc.cs", CancellationToken.None).ConfigureAwait(false); + await this.VerifyCSharpFixAsync(testCode, fixedCode, oldFileName: "TestType.svc.cs", newFileName: "TestType`1.svc.cs", cancellationToken: CancellationToken.None).ConfigureAwait(false); } /// @@ -307,7 +303,7 @@ public async Task VerifyMetadataNamingConventionForGenericTypeMultipleExtensions [Fact] public async Task VerifyWithoutFirstTypeAsync() { - var testCode = @"namespace TestNameSpace + var testCode = @"namespace TestNamespace { } "; @@ -332,39 +328,5 @@ protected override string GetSettings() { return this.useMetadataSettings ? MetadataSettings : StyleCopSettings; } - - private async Task VerifyRenameAsync(string source, string sourceFileName, string expectedFileName, CancellationToken cancellationToken) - { - var analyzers = this.GetCSharpDiagnosticAnalyzers().ToImmutableArray(); - var document = this.CreateDocument(source, LanguageNames.CSharp, sourceFileName); - var analyzerDiagnostics = await GetSortedDiagnosticsFromDocumentsAsync(analyzers, new[] { document }, cancellationToken).ConfigureAwait(false); - - Assert.Equal(1, analyzerDiagnostics.Length); - - var actions = new List(); - var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), cancellationToken); - await this.GetCSharpCodeFixProvider().RegisterCodeFixesAsync(context).ConfigureAwait(false); - - Assert.Equal(1, actions.Count); - - var operations = await actions[0].GetOperationsAsync(cancellationToken).ConfigureAwait(false); - - var changedSolution = operations.OfType().Single().ChangedSolution; - - var solutionChanges = changedSolution.GetChanges(document.Project.Solution); - var projectChanges = solutionChanges.GetProjectChanges().ToArray(); - - Assert.Equal(1, projectChanges.Length); - - var removedDocuments = projectChanges[0].GetRemovedDocuments().ToArray(); - Assert.Equal(1, removedDocuments.Length); - Assert.Equal(document.Id, removedDocuments[0]); - - var addedDocuments = projectChanges[0].GetAddedDocuments().ToArray(); - Assert.Equal(1, addedDocuments.Length); - - var newDocument = changedSolution.GetDocument(addedDocuments[0]); - Assert.Equal(expectedFileName, newDocument.Name); - } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/Verifiers/CodeFixVerifier.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/Verifiers/CodeFixVerifier.cs index 4f7865413..a08cf5a55 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/Verifiers/CodeFixVerifier.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/Verifiers/CodeFixVerifier.cs @@ -39,6 +39,8 @@ public abstract partial class CodeFixVerifier : DiagnosticVerifier /// A class in the form of a string before the code fix was applied to it. /// A class in the form of a string after the code fix was applied to it. /// A class in the form of a string after the batch fixer was applied to it. + /// The name of the file in the project before the code fix was applied. + /// The name of the file in the project after the code fix was applied. /// Index determining which code fix to apply if there are multiple. /// A value indicating whether or not the test will fail if the code fix introduces other warnings after being applied. /// The number of iterations the incremental fixer will be called. @@ -48,9 +50,12 @@ public abstract partial class CodeFixVerifier : DiagnosticVerifier /// value is less than 0, the negated value is treated as an upper limit as opposed to an exact value. /// The that the task will observe. /// A representing the asynchronous operation. - protected Task VerifyCSharpFixAsync(string oldSource, string newSource, string batchNewSource = null, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false, int numberOfIncrementalIterations = DefaultNumberOfIncrementalIterations, int numberOfFixAllIterations = 1, CancellationToken cancellationToken = default(CancellationToken)) + protected Task VerifyCSharpFixAsync(string oldSource, string newSource, string batchNewSource = null, string oldFileName = null, string newFileName = null, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false, int numberOfIncrementalIterations = DefaultNumberOfIncrementalIterations, int numberOfFixAllIterations = 1, CancellationToken cancellationToken = default(CancellationToken)) { - return this.VerifyCSharpFixAsync(new[] { oldSource }, new[] { newSource }, batchNewSource == null ? null : new[] { batchNewSource }, null, codeFixIndex, allowNewCompilerDiagnostics, numberOfIncrementalIterations, numberOfFixAllIterations, cancellationToken); + var batchNewSources = batchNewSource == null ? null : new[] { batchNewSource }; + var oldFileNames = oldFileName == null ? null : new[] { oldFileName }; + var newFileNames = newFileName == null ? null : new[] { newFileName }; + return this.VerifyCSharpFixAsync(new[] { oldSource }, new[] { newSource }, batchNewSources, oldFileNames, newFileNames, codeFixIndex, allowNewCompilerDiagnostics, numberOfIncrementalIterations, numberOfFixAllIterations, cancellationToken); } /// @@ -59,6 +64,7 @@ public abstract partial class CodeFixVerifier : DiagnosticVerifier /// An array of sources in the form of strings before the code fix was applied to them. /// An array of sources in the form of strings after the code fix was applied to them. /// An array of sources in the form of a strings after the batch fixer was applied to them. + /// An array of file names in the project before the code fix was applied. /// An array of file names in the project after the code fix was applied. /// Index determining which code fix to apply if there are multiple. /// A value indicating whether or not the test will fail if the code fix introduces other warnings after being applied. @@ -69,9 +75,9 @@ public abstract partial class CodeFixVerifier : DiagnosticVerifier /// value is less than 0, the negated value is treated as an upper limit as opposed to an exact value. /// The that the task will observe. /// A representing the asynchronous operation. - protected async Task VerifyCSharpFixAsync(string[] oldSources, string[] newSources, string[] batchNewSources = null, string[] newFileNames = null, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false, int numberOfIncrementalIterations = DefaultNumberOfIncrementalIterations, int numberOfFixAllIterations = 1, CancellationToken cancellationToken = default(CancellationToken)) + protected async Task VerifyCSharpFixAsync(string[] oldSources, string[] newSources, string[] batchNewSources = null, string[] oldFileNames = null, string[] newFileNames = null, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false, int numberOfIncrementalIterations = DefaultNumberOfIncrementalIterations, int numberOfFixAllIterations = 1, CancellationToken cancellationToken = default(CancellationToken)) { - var t1 = this.VerifyFixInternalAsync(LanguageNames.CSharp, this.GetCSharpDiagnosticAnalyzers().ToImmutableArray(), this.GetCSharpCodeFixProvider(), oldSources, newSources, newFileNames, codeFixIndex, allowNewCompilerDiagnostics, numberOfIncrementalIterations, FixEachAnalyzerDiagnosticAsync, cancellationToken).ConfigureAwait(false); + var t1 = this.VerifyFixInternalAsync(LanguageNames.CSharp, this.GetCSharpDiagnosticAnalyzers().ToImmutableArray(), this.GetCSharpCodeFixProvider(), oldSources, newSources, oldFileNames, newFileNames, codeFixIndex, allowNewCompilerDiagnostics, numberOfIncrementalIterations, FixEachAnalyzerDiagnosticAsync, cancellationToken).ConfigureAwait(false); var fixAllProvider = this.GetCSharpCodeFixProvider().GetFixAllProvider(); Assert.NotEqual(WellKnownFixAllProviders.BatchFixer, fixAllProvider); @@ -87,19 +93,19 @@ public abstract partial class CodeFixVerifier : DiagnosticVerifier await t1; } - var t2 = this.VerifyFixInternalAsync(LanguageNames.CSharp, this.GetCSharpDiagnosticAnalyzers().ToImmutableArray(), this.GetCSharpCodeFixProvider(), oldSources, batchNewSources ?? newSources, newFileNames, codeFixIndex, allowNewCompilerDiagnostics, numberOfFixAllIterations, FixAllAnalyzerDiagnosticsInDocumentAsync, cancellationToken).ConfigureAwait(false); + var t2 = this.VerifyFixInternalAsync(LanguageNames.CSharp, this.GetCSharpDiagnosticAnalyzers().ToImmutableArray(), this.GetCSharpCodeFixProvider(), oldSources, batchNewSources ?? newSources, oldFileNames, newFileNames, codeFixIndex, allowNewCompilerDiagnostics, numberOfFixAllIterations, FixAllAnalyzerDiagnosticsInDocumentAsync, cancellationToken).ConfigureAwait(false); if (Debugger.IsAttached) { await t2; } - var t3 = this.VerifyFixInternalAsync(LanguageNames.CSharp, this.GetCSharpDiagnosticAnalyzers().ToImmutableArray(), this.GetCSharpCodeFixProvider(), oldSources, batchNewSources ?? newSources, newFileNames, codeFixIndex, allowNewCompilerDiagnostics, numberOfFixAllIterations, FixAllAnalyzerDiagnosticsInProjectAsync, cancellationToken).ConfigureAwait(false); + var t3 = this.VerifyFixInternalAsync(LanguageNames.CSharp, this.GetCSharpDiagnosticAnalyzers().ToImmutableArray(), this.GetCSharpCodeFixProvider(), oldSources, batchNewSources ?? newSources, oldFileNames, newFileNames, codeFixIndex, allowNewCompilerDiagnostics, numberOfFixAllIterations, FixAllAnalyzerDiagnosticsInProjectAsync, cancellationToken).ConfigureAwait(false); if (Debugger.IsAttached) { await t3; } - var t4 = this.VerifyFixInternalAsync(LanguageNames.CSharp, this.GetCSharpDiagnosticAnalyzers().ToImmutableArray(), this.GetCSharpCodeFixProvider(), oldSources, batchNewSources ?? newSources, newFileNames, codeFixIndex, allowNewCompilerDiagnostics, numberOfFixAllIterations, FixAllAnalyzerDiagnosticsInSolutionAsync, cancellationToken).ConfigureAwait(false); + var t4 = this.VerifyFixInternalAsync(LanguageNames.CSharp, this.GetCSharpDiagnosticAnalyzers().ToImmutableArray(), this.GetCSharpCodeFixProvider(), oldSources, batchNewSources ?? newSources, oldFileNames, newFileNames, codeFixIndex, allowNewCompilerDiagnostics, numberOfFixAllIterations, FixAllAnalyzerDiagnosticsInSolutionAsync, cancellationToken).ConfigureAwait(false); if (Debugger.IsAttached) { await t4; @@ -129,7 +135,7 @@ public abstract partial class CodeFixVerifier : DiagnosticVerifier /// A representing the asynchronous operation. protected async Task VerifyCSharpFixAllFixAsync(string oldSource, string newSource, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false, int numberOfIterations = 1, CancellationToken cancellationToken = default(CancellationToken)) { - await this.VerifyFixInternalAsync(LanguageNames.CSharp, this.GetCSharpDiagnosticAnalyzers().ToImmutableArray(), this.GetCSharpCodeFixProvider(), new[] { oldSource }, new[] { newSource }, null, codeFixIndex, allowNewCompilerDiagnostics, numberOfIterations, FixAllAnalyzerDiagnosticsInDocumentAsync, cancellationToken).ConfigureAwait(false); + await this.VerifyFixInternalAsync(LanguageNames.CSharp, this.GetCSharpDiagnosticAnalyzers().ToImmutableArray(), this.GetCSharpCodeFixProvider(), new[] { oldSource }, new[] { newSource }, null, null, codeFixIndex, allowNewCompilerDiagnostics, numberOfIterations, FixAllAnalyzerDiagnosticsInDocumentAsync, cancellationToken).ConfigureAwait(false); } /// @@ -349,6 +355,7 @@ private async Task VerifyFixInternalAsync( CodeFixProvider codeFixProvider, string[] oldSources, string[] newSources, + string[] oldFileNames, string[] newFileNames, int? codeFixIndex, bool allowNewCompilerDiagnostics, @@ -356,13 +363,19 @@ private async Task VerifyFixInternalAsync( Func, CodeFixProvider, int?, Project, int, CancellationToken, Task> getFixedProject, CancellationToken cancellationToken) { + if (oldFileNames != null) + { + // Make sure the test case is consistent regarding the number of sources and file names before the code fix + Assert.Equal($"{oldSources.Length} old file names", $"{oldFileNames.Length} old file names"); + } + if (newFileNames != null) { - // Make sure the test case is consistent regarding the number of expected sources and file names - Assert.Equal($"{newSources.Length} file names", $"{newFileNames.Length} file names"); + // Make sure the test case is consistent regarding the number of sources and file names after the code fix + Assert.Equal($"{newSources.Length} new file names", $"{newFileNames.Length} new file names"); } - var project = this.CreateProject(oldSources, language); + var project = this.CreateProject(oldSources, language, oldFileNames); var compilerDiagnostics = await GetCompilerDiagnosticsAsync(project, cancellationToken).ConfigureAwait(false); project = await getFixedProject(analyzers, codeFixProvider, codeFixIndex, project, numberOfIterations, cancellationToken).ConfigureAwait(false);