Skip to content

Commit f4e1e0c

Browse files
authored
Merge pull request #4034 from sharwell/default-interface-members
Update to support default interface members
2 parents 605c78d + 59e5c5c commit f4e1e0c

File tree

13 files changed

+420
-9
lines changed

13 files changed

+420
-9
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/DocumentationRules/SA1600CSharp8UnitTests.cs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,121 @@
33

44
namespace StyleCop.Analyzers.Test.CSharp8.DocumentationRules
55
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
68
using Microsoft.CodeAnalysis.CSharp;
9+
using Microsoft.CodeAnalysis.Testing;
710
using StyleCop.Analyzers.Test.CSharp7.DocumentationRules;
11+
using Xunit;
12+
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
13+
StyleCop.Analyzers.DocumentationRules.SA1600ElementsMustBeDocumented,
14+
StyleCop.Analyzers.DocumentationRules.SA1600CodeFixProvider>;
815

916
public partial class SA1600CSharp8UnitTests : SA1600CSharp7UnitTests
1017
{
1118
// Using 'Default' here makes sure that later test projects also run these tests with their own language version, without having to override this property
1219
protected override LanguageVersion LanguageVersion => LanguageVersion.Default;
20+
21+
[Fact]
22+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
23+
public async Task TestDefaultInterfaceMemberRequiresDocumentationAsync()
24+
{
25+
var testCode = @"using System;
26+
/// <summary>Summary.</summary>
27+
public interface ITest
28+
{
29+
public static int [|field1|];
30+
static int [|field2|];
31+
32+
public int [|Prop1|] { get => 0; }
33+
int [|Prop2|] { get => 0; }
34+
35+
int [|this|][int index] { get => 0; }
36+
37+
public event EventHandler [|Event1|];
38+
event EventHandler [|Event2|];
39+
40+
public event EventHandler [|Event3|] { add { } remove { } }
41+
event EventHandler [|Event4|] { add { } remove { } }
42+
43+
public void [|Method1|]() { }
44+
void [|Method2|]() { }
45+
46+
public delegate void [|Del1|]();
47+
delegate void [|Del2|]();
48+
49+
public class [|Class1|] { }
50+
class [|Class2|] { }
51+
52+
public struct [|Struct1|] { }
53+
struct [|Struct2|] { }
54+
55+
public interface [|Interface1|] { }
56+
interface [|Interface2|] { }
57+
}
58+
";
59+
60+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
61+
}
62+
63+
[Fact]
64+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
65+
public async Task TestDefaultInterfaceFieldRequiresDocumentationAsync()
66+
{
67+
var testCode = @"
68+
/// <summary>Summary.</summary>
69+
public interface ITest
70+
{
71+
public static int [|field1|];
72+
static int [|field2|];
73+
}
74+
";
75+
76+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
77+
}
78+
79+
[Fact]
80+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
81+
public async Task TestPrivateDefaultInterfaceMethodDoesNotRequireDocumentationByDefaultAsync()
82+
{
83+
var testCode = @"
84+
/// <summary>Summary.</summary>
85+
public interface ITest
86+
{
87+
private void M()
88+
{
89+
}
90+
}
91+
";
92+
93+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
94+
}
95+
96+
[Fact]
97+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
98+
public async Task TestPrivateDefaultInterfaceMethodHonorsDocumentPrivateElementsAsync()
99+
{
100+
var testCode = @"
101+
/// <summary>Summary.</summary>
102+
public interface ITest
103+
{
104+
private void [|M|]()
105+
{
106+
}
107+
}
108+
";
109+
110+
var settings = @"
111+
{
112+
""settings"": {
113+
""documentationRules"": {
114+
""documentPrivateElements"": true
115+
}
116+
}
117+
}
118+
";
119+
120+
await VerifyCSharpDiagnosticAsync(testCode, settings, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
121+
}
13122
}
14123
}

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/MaintainabilityRules/SA1400CSharp8UnitTests.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,101 @@
33

44
namespace StyleCop.Analyzers.Test.CSharp8.MaintainabilityRules
55
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
69
using StyleCop.Analyzers.Test.CSharp7.MaintainabilityRules;
10+
using StyleCop.Analyzers.Test.Helpers;
11+
using Xunit;
12+
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
13+
StyleCop.Analyzers.MaintainabilityRules.SA1400AccessModifierMustBeDeclared,
14+
StyleCop.Analyzers.MaintainabilityRules.SA1400CodeFixProvider>;
715

816
public partial class SA1400CSharp8UnitTests : SA1400CSharp7UnitTests
917
{
18+
[Fact]
19+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
20+
public async Task TestDefaultInterfaceImplementationWithoutAccessModifierAsync()
21+
{
22+
var testCode = @"
23+
public interface ITest
24+
{
25+
void M()
26+
{
27+
}
28+
29+
int P
30+
{
31+
get
32+
{
33+
return 0;
34+
}
35+
}
36+
}
37+
";
38+
39+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
40+
}
41+
42+
[Fact]
43+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
44+
public async Task TestStaticInterfaceMemberWithoutAccessModifierAsync()
45+
{
46+
var testCode = @"
47+
public interface ITest
48+
{
49+
static void M()
50+
{
51+
}
52+
}
53+
";
54+
55+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
56+
}
57+
58+
[Fact]
59+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
60+
public async Task TestDelegateDeclarationInsideInterfaceAsync()
61+
{
62+
var testCode = @"
63+
public interface ITest
64+
{
65+
delegate void Handler();
66+
}
67+
";
68+
69+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
70+
}
71+
72+
[Fact]
73+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
74+
public async Task TestStaticFieldInsideInterfaceAsync()
75+
{
76+
var testCode = @"
77+
public interface ITest
78+
{
79+
static int Value = 0;
80+
}
81+
";
82+
83+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
84+
}
85+
86+
[Theory]
87+
[MemberData(nameof(CommonMemberData.BaseTypeDeclarationKeywords), MemberType = typeof(CommonMemberData))]
88+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
89+
public async Task TestTypeDeclarationInsideInterfaceAsync(string typeKind)
90+
{
91+
var testCode = $@"
92+
public interface ITest
93+
{{
94+
{typeKind} NestedType
95+
{{
96+
}}
97+
}}
98+
";
99+
100+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
101+
}
10102
}
11103
}

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/OrderingRules/SA1202CSharp8UnitTests.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ namespace StyleCop.Analyzers.Test.CSharp8.OrderingRules
55
{
66
using System.Threading;
77
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
89
using StyleCop.Analyzers.Test.CSharp7.OrderingRules;
10+
using StyleCop.Analyzers.Test.Helpers;
911
using Xunit;
1012
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
1113
StyleCop.Analyzers.OrderingRules.SA1202ElementsMustBeOrderedByAccess,
@@ -57,5 +59,70 @@ public async Task TestPropertiesOfInterfaceAsync()
5759
NumberOfFixAllIterations = 2,
5860
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
5961
}
62+
63+
[Fact]
64+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
65+
public async Task TestDefaultInterfaceMembersRequireAccessOrderingAsync()
66+
{
67+
var testCode = @"public interface ITest
68+
{
69+
private void Helper() { }
70+
public void {|#0:DoWork|}() { }
71+
}
72+
";
73+
74+
var fixedCode = @"public interface ITest
75+
{
76+
public void DoWork() { }
77+
private void Helper() { }
78+
}
79+
";
80+
81+
await VerifyCSharpFixAsync(testCode, Diagnostic().WithLocation(0).WithArguments("public", "private"), fixedCode, CancellationToken.None).ConfigureAwait(false);
82+
}
83+
84+
[Fact]
85+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
86+
public async Task TestDefaultInterfaceMembersCorrectOrderingAsync()
87+
{
88+
var testCode = @"public interface ITest
89+
{
90+
public void DoWork() { }
91+
private void Helper() { }
92+
}
93+
";
94+
95+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
96+
}
97+
98+
[Fact]
99+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
100+
public async Task TestInterfaceMembersMixingImplicitAndExplicitAccessibilityAsync()
101+
{
102+
var testCode = @"public interface ITest
103+
{
104+
private void Helper() { }
105+
void {|#0:ImplicitPublic|}() { }
106+
public void ExplicitPublic() { }
107+
}
108+
";
109+
110+
var fixedCode = @"public interface ITest
111+
{
112+
void ImplicitPublic() { }
113+
public void ExplicitPublic() { }
114+
private void Helper() { }
115+
}
116+
";
117+
118+
await new CSharpTest
119+
{
120+
TestCode = testCode,
121+
ExpectedDiagnostics = { Diagnostic().WithLocation(0).WithArguments("public", "private") },
122+
FixedCode = fixedCode,
123+
NumberOfIncrementalIterations = 2,
124+
NumberOfFixAllIterations = 2,
125+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
126+
}
60127
}
61128
}

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/OrderingRules/SA1204CSharp8UnitTests.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,46 @@
33

44
namespace StyleCop.Analyzers.Test.CSharp8.OrderingRules
55
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
69
using StyleCop.Analyzers.Test.CSharp7.OrderingRules;
10+
using Xunit;
11+
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
12+
StyleCop.Analyzers.OrderingRules.SA1204StaticElementsMustAppearBeforeInstanceElements,
13+
StyleCop.Analyzers.OrderingRules.ElementOrderCodeFixProvider>;
714

815
public partial class SA1204CSharp8UnitTests : SA1204CSharp7UnitTests
916
{
17+
[Fact]
18+
[WorkItem(3002, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3002")]
19+
public async Task TestStaticMemberAfterDefaultInterfaceMethodAsync()
20+
{
21+
var testCode = @"public interface ITest
22+
{
23+
void InstanceMethod()
24+
{
25+
}
26+
27+
static void [|StaticMethod|]()
28+
{
29+
}
30+
}
31+
";
32+
33+
var fixedCode = @"public interface ITest
34+
{
35+
static void StaticMethod()
36+
{
37+
}
38+
39+
void InstanceMethod()
40+
{
41+
}
42+
}
43+
";
44+
45+
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false);
46+
}
1047
}
1148
}

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1600UnitTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public async Task TestDelegateWithDocumentationAsync()
9999
public async Task TestMethodWithoutDocumentationAsync()
100100
{
101101
await this.TestMethodDeclarationDocumentationAsync(string.Empty, false, false, false).ConfigureAwait(false);
102-
await this.TestMethodDeclarationDocumentationAsync(string.Empty, true, true, false).ConfigureAwait(false);
102+
await this.TestMethodDeclarationDocumentationAsync(string.Empty, true, false, false).ConfigureAwait(false);
103103
await this.TestMethodDeclarationDocumentationAsync("private", false, false, false).ConfigureAwait(false);
104104
await this.TestMethodDeclarationDocumentationAsync("protected", false, true, false).ConfigureAwait(false);
105105
await this.TestMethodDeclarationDocumentationAsync("internal", false, true, false).ConfigureAwait(false);
@@ -291,7 +291,7 @@ public async Task TestFieldWithDocumentationAsync()
291291
public async Task TestPropertyWithoutDocumentationAsync()
292292
{
293293
await this.TestPropertyDeclarationDocumentationAsync(string.Empty, false, false, false).ConfigureAwait(false);
294-
await this.TestPropertyDeclarationDocumentationAsync(string.Empty, true, true, false).ConfigureAwait(false);
294+
await this.TestPropertyDeclarationDocumentationAsync(string.Empty, true, false, false).ConfigureAwait(false);
295295
await this.TestPropertyDeclarationDocumentationAsync("private", false, false, false).ConfigureAwait(false);
296296
await this.TestPropertyDeclarationDocumentationAsync("protected", false, true, false).ConfigureAwait(false);
297297
await this.TestPropertyDeclarationDocumentationAsync("internal", false, true, false).ConfigureAwait(false);
@@ -319,7 +319,7 @@ public async Task TestPropertyWithDocumentationAsync()
319319
public async Task TestIndexerWithoutDocumentationAsync()
320320
{
321321
await this.TestIndexerDeclarationDocumentationAsync(string.Empty, false, false, false).ConfigureAwait(false);
322-
await this.TestIndexerDeclarationDocumentationAsync(string.Empty, true, true, false).ConfigureAwait(false);
322+
await this.TestIndexerDeclarationDocumentationAsync(string.Empty, true, false, false).ConfigureAwait(false);
323323
await this.TestIndexerDeclarationDocumentationAsync("private", false, false, false).ConfigureAwait(false);
324324
await this.TestIndexerDeclarationDocumentationAsync("protected", false, true, false).ConfigureAwait(false);
325325
await this.TestIndexerDeclarationDocumentationAsync("internal", false, true, false).ConfigureAwait(false);
@@ -347,7 +347,7 @@ public async Task TestIndexerWithDocumentationAsync()
347347
public async Task TestEventWithoutDocumentationAsync()
348348
{
349349
await this.TestEventDeclarationDocumentationAsync(string.Empty, false, false, false).ConfigureAwait(false);
350-
await this.TestEventDeclarationDocumentationAsync(string.Empty, true, true, false).ConfigureAwait(false);
350+
await this.TestEventDeclarationDocumentationAsync(string.Empty, true, false, false).ConfigureAwait(false);
351351
await this.TestEventDeclarationDocumentationAsync("private", false, false, false).ConfigureAwait(false);
352352
await this.TestEventDeclarationDocumentationAsync("protected", false, true, false).ConfigureAwait(false);
353353
await this.TestEventDeclarationDocumentationAsync("internal", false, true, false).ConfigureAwait(false);

0 commit comments

Comments
 (0)