diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1300CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1300CSharp10UnitTests.cs index 3796f58bb..a73681caa 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1300CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1300CSharp10UnitTests.cs @@ -58,7 +58,7 @@ public async Task TestAllowedLowerCaseFileScopedNamespaceIsNotReportedAsync() } [Fact] - public async Task TestLowerCaseComlicatedFileScopedNamespaceAsync() + public async Task TestLowerCaseComplicatedFileScopedNamespaceAsync() { var testCode = @"namespace {|#0:test|}.{|#1:foo|}.{|#2:bar|};"; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1201CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1201CSharp10UnitTests.cs index 88fe742ab..8b54e9dae 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1201CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/OrderingRules/SA1201CSharp10UnitTests.cs @@ -51,5 +51,42 @@ public struct {|#1:FooStruct|} { } await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } + + [Fact] + public async Task TestOuterOrderWithRecordStructCorrectOrderAsync() + { + var testCode = @"namespace Foo { } +public delegate void bar(); +public enum TestEnum { } +public interface IFoo { } +public record struct FooStruct { } +public class FooClass { } +"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + await VerifyCSharpDiagnosticAsync("namespace OuterNamespace { " + testCode + " }", DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } + + [Fact] + public async Task TestOuterOrderWithRecordStructWrongOrderAsync() + { + var testCode = @" +namespace Foo { } +public enum TestEnum { } +public delegate void {|#0:bar|}(); +public interface IFoo { } +public class FooClass { } +public record struct {|#1:FooStruct|} { } +"; + + var expected = new[] + { + Diagnostic().WithLocation(0).WithArguments("delegate", "enum"), + Diagnostic().WithLocation(1).WithArguments("record struct", "class"), + }; + + await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); + await VerifyCSharpDiagnosticAsync("namespace OuterNamespace { " + testCode + " }", expected, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1600UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1600UnitTests.cs index 593941aea..4e5561632 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1600UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1600UnitTests.cs @@ -56,6 +56,15 @@ public async Task TestBaseTypeWithDocumentationAsync(string type) await this.TestTypeWithDocumentationAsync(type).ConfigureAwait(false); } + [Theory] + [MemberData(nameof(CommonMemberData.TypeDeclarationKeywords), MemberType = typeof(CommonMemberData))] + public async Task TestPartialTypeWithoutDocumentationAsync(string type) + { + await this.TestTypeDeclarationDocumentationAsync(type, "partial", false, false).ConfigureAwait(false); + await this.TestTypeDeclarationDocumentationAsync(type, "internal partial", false, false).ConfigureAwait(false); + await this.TestTypeDeclarationDocumentationAsync(type, "public partial", false, false).ConfigureAwait(false); + } + [Fact] public async Task TestDelegateWithoutDocumentationAsync() { diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/HelperTests/AccessLevelHelperTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/HelperTests/AccessLevelHelperTests.cs index 5c3ef3598..ccf5da2eb 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/HelperTests/AccessLevelHelperTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/HelperTests/AccessLevelHelperTests.cs @@ -6,7 +6,9 @@ namespace StyleCop.Analyzers.Test.HelperTests { using System; + using System.Linq; using Microsoft.CodeAnalysis; + using Microsoft.CodeAnalysis.CSharp; using StyleCop.Analyzers.Helpers; using Xunit; @@ -50,5 +52,36 @@ public void TestCombineEffectiveAccessibility() Assert.Equal(Accessibility.Private, AccessLevelHelper.CombineEffectiveAccessibility(Accessibility.Private, Accessibility.Public)); Assert.Equal(Accessibility.Public, AccessLevelHelper.CombineEffectiveAccessibility(Accessibility.Public, Accessibility.Public)); } + + [Fact] + public void TestGetAccessLevel() + { + Check(AccessLevel.NotSpecified); + Check(AccessLevel.NotSpecified, SyntaxKind.PartialKeyword); + + Check(AccessLevel.Private, SyntaxKind.PrivateKeyword); + Check(AccessLevel.Private, SyntaxKind.OverrideKeyword, SyntaxKind.PrivateKeyword); + + Check(AccessLevel.PrivateProtected, SyntaxKind.PrivateKeyword, SyntaxKind.ProtectedKeyword); + Check(AccessLevel.PrivateProtected, SyntaxKind.ProtectedKeyword, SyntaxKind.PrivateKeyword); + + Check(AccessLevel.Protected, SyntaxKind.ProtectedKeyword); + Check(AccessLevel.Protected, SyntaxKind.VirtualKeyword, SyntaxKind.ProtectedKeyword); + + Check(AccessLevel.ProtectedInternal, SyntaxKind.ProtectedKeyword, SyntaxKind.InternalKeyword); + Check(AccessLevel.ProtectedInternal, SyntaxKind.InternalKeyword, SyntaxKind.ProtectedKeyword); + + Check(AccessLevel.Internal, SyntaxKind.InternalKeyword); + Check(AccessLevel.Internal, SyntaxKind.AbstractKeyword, SyntaxKind.InternalKeyword); + + Check(AccessLevel.Public, SyntaxKind.PublicKeyword); + Check(AccessLevel.Public, SyntaxKind.AsyncKeyword, SyntaxKind.PublicKeyword); + + static void Check(AccessLevel expectedAccessLevel, params SyntaxKind[] tokenKinds) + { + var tokenList = SyntaxFactory.TokenList(tokenKinds.Select(SyntaxFactory.Token)); + Assert.Equal(expectedAccessLevel, AccessLevelHelper.GetAccessLevel(tokenList)); + } + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/MaintainabilityRules/SA1404UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/MaintainabilityRules/SA1404UnitTests.cs index 038030a92..fa93d26ae 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/MaintainabilityRules/SA1404UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/MaintainabilityRules/SA1404UnitTests.cs @@ -16,17 +16,19 @@ namespace StyleCop.Analyzers.Test.MaintainabilityRules public class SA1404UnitTests { - [Fact] - public async Task TestSuppressionWithStringLiteralAsync() + [Theory] + [InlineData("SuppressMessage")] + [InlineData("SuppressMessageAttribute")] + public async Task TestSuppressionWithStringLiteralAsync(string attributeName) { - var testCode = @"public class Foo -{ - [System.Diagnostics.CodeAnalysis.SuppressMessage(null, null, Justification = ""a justification"")] + var testCode = $@"public class Foo +{{ + [System.Diagnostics.CodeAnalysis.{attributeName}(null, null, Justification = ""a justification"")] public void Bar() - { + {{ - } -}"; + }} +}}"; await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } @@ -410,5 +412,19 @@ public void Bar() }; await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } + + [Fact] + public async Task TestOtherAttributeAsync() + { + var testCode = @"public class Foo +{ + [System.Obsolete(""Method is obsolete!"")] + public void Bar() + { + } +}"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1300UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1300UnitTests.cs index 2146b87cd..f306feac4 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1300UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1300UnitTests.cs @@ -71,7 +71,7 @@ public async Task TestAllowedLowerCaseNamespaceIsNotReportedAsync() } [Fact] - public async Task TestLowerCaseComlicatedNamespaceAsync() + public async Task TestLowerCaseComplicatedNamespaceAsync() { var testCode = @"namespace test.foo.bar { @@ -789,7 +789,7 @@ public async Task TestNativeMethodsExceptionAsync() { var testCode = @"public class TestNativeMethods { -public string test; +public string test { get; set; } }"; await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1304UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1304UnitTests.cs index 75d7314dc..89616ceb8 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1304UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1304UnitTests.cs @@ -61,6 +61,17 @@ public async Task TestProtectedReadonlyFieldStartingWithUpperCaseAsync() await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } + [Fact] + public async Task TestFieldInNativeMethodsClassAsync() + { + var testCode = @"public class FooNativeMethods +{ + internal readonly string bar = ""baz""; +}"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } + [Fact] public async Task TestInternalReadonlyFieldStartingWithLowerCaseAsync() { diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1305UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1305UnitTests.cs index fb10c4f40..5736deac5 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1305UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1305UnitTests.cs @@ -62,6 +62,21 @@ public void TestMethod() await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } + [Fact] + public async Task TestVariableNamesInNativeMethodsClassAsync() + { + var testCode = @" +public class TypeNameNativeMethods +{ + public void MethodName() + { + bool abX; + } +}"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } + [Fact] public async Task TestInvalidFieldNamesAreReportedAsync() { diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1213UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1213UnitTests.cs index 108d17801..a02ee3d21 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1213UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1213UnitTests.cs @@ -242,5 +242,23 @@ public event EventHandler NameChanged await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } + + [Fact] + public async Task TestOnlyAddAccessorAsync() + { + var testCode = @" +using System; +public class Foo +{ + private EventHandler nameChanged; + + public event EventHandler {|CS0065:NameChanged|} + { + add { this.nameChanged += value; } + } +}"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1110UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1110UnitTests.cs index 9e1832e8a..913e715f7 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1110UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1110UnitTests.cs @@ -603,31 +603,33 @@ public void Bar() await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } - [Fact] - public async Task TestAttributeOpeningParenthesisOnTheNextLineAsync() + [Theory] + [InlineData("Conditional")] + [InlineData("System.Diagnostics.Conditional")] + public async Task TestAttributeOpeningParenthesisOnTheNextLineAsync(string attributeName) { - var testCode = @" + var testCode = $@" using System.Diagnostics; public class Foo -{ -[Conditional -(""DEBUG""), Conditional +{{ +[{attributeName} +(""DEBUG""), {attributeName} (""TEST1"")] public void Baz() - { - } -}"; - var fixedCode = @" + {{ + }} +}}"; + var fixedCode = $@" using System.Diagnostics; public class Foo -{ -[Conditional( -""DEBUG""), Conditional( +{{ +[{attributeName}( +""DEBUG""), {attributeName}( ""TEST1"")] public void Baz() - { - } -}"; + {{ + }} +}}"; DiagnosticResult[] expected = { @@ -638,19 +640,21 @@ public void Baz() await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); } - [Fact] - public async Task TestAttributeOpeningParenthesisOnTheSameLineAsync() + [Theory] + [InlineData("Conditional")] + [InlineData("System.Diagnostics.Conditional")] + public async Task TestAttributeOpeningParenthesisOnTheSameLineAsync(string attributeName) { - var testCode = @" + var testCode = $@" using System.Diagnostics; public class Foo -{ - [Conditional(""DEBUG""), Conditional(""TEST1"")] +{{ + [{attributeName}(""DEBUG""), {attributeName}(""TEST1"")] public void Baz() - { + {{ - } -}"; + }} +}}"; await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1131UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1131UnitTests.cs index ae5fd8f42..1ccd8509a 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1131UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1131UnitTests.cs @@ -373,7 +373,7 @@ public class TypeName public void Test() {{ int j = 6; - bool b = j {@operator} i; + bool b = i {@operator} j; }} }}"; await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); @@ -396,7 +396,7 @@ public class TypeName public void Test() {{ int j = 6; - bool b = j {@operator} i; + bool b = i {@operator} j; }} }}"; await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); @@ -419,7 +419,7 @@ public class TypeName public void Test() {{ int j = 6; - bool b = j {@operator} i; + bool b = i {@operator} j; }} }}"; await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/SpacingRules/SA1010UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/SpacingRules/SA1010UnitTests.cs index 317f3f0f9..2917f06d4 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/SpacingRules/SA1010UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/SpacingRules/SA1010UnitTests.cs @@ -216,5 +216,23 @@ public void TestMethod(IDictionary items) var expected = Diagnostic(DescriptorNotPreceded).WithLocation(8, 62); await VerifyCSharpFixAsync(testCode, expected, fixedTestCode, CancellationToken.None).ConfigureAwait(false); } + + // NOTE: This case is handled by SA1026, so it's intentionally allowed here + [Fact] + public async Task TestImplicitlyTypedArrayCreationAsync() + { + var testCode = @" +namespace TestNamespace +{ + public class TestClass + { + public void TestMethod() + { + var x = new [] { 0, 1 }; + } + } +}"; + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } } }