Skip to content

Commit be984ba

Browse files
committed
Merge pull request #1480 from Maxwe11/SA1117
2 parents 7847d19 + a92d65a commit be984ba

5 files changed

Lines changed: 544 additions & 11 deletions

File tree

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
3+
4+
namespace StyleCop.Analyzers.Test.ReadabilityRules
5+
{
6+
using System.Collections.Generic;
7+
using System.Threading;
8+
using System.Threading.Tasks;
9+
using Microsoft.CodeAnalysis.Diagnostics;
10+
using StyleCop.Analyzers.ReadabilityRules;
11+
using TestHelper;
12+
using Xunit;
13+
14+
public class SA1117UnitTests : DiagnosticVerifier
15+
{
16+
public static IEnumerable<object[]> GetTestDeclarations(string delimiter)
17+
{
18+
yield return new object[] { $"public Foo(int a, int b,{delimiter} string s) {{ }}" };
19+
yield return new object[] { $"public object Bar(int a, int b,{delimiter} string s) => null;" };
20+
yield return new object[] { $"public object this[int a, int b,{delimiter} string s] => null;" };
21+
yield return new object[] { $"public delegate void Bar(int a, int b,{delimiter} string s);" };
22+
}
23+
24+
public static IEnumerable<object[]> GetTestConstructorInitializers(string delimiter)
25+
{
26+
yield return new object[] { $"this(42, 43, {delimiter} \"hello\")" };
27+
yield return new object[] { $"base(42, 43, {delimiter} \"hello\")" };
28+
}
29+
30+
public static IEnumerable<object[]> GetTestExpressions(string delimiter)
31+
{
32+
yield return new object[] { $"Bar(1, 2, {delimiter} 2)", 13 };
33+
yield return new object[] { $"System.Action<int, int, int> func = (int x, int y, {delimiter} int z) => Bar(x, y, z)", 41 };
34+
yield return new object[] { $"System.Action<int, int, int> func = delegate(int x, int y, {delimiter} int z) {{ Bar(x, y, z); }}", 49 };
35+
yield return new object[] { $"new System.DateTime(2015, 9, {delimiter} 14)", 20 };
36+
yield return new object[] { $"var arr = new string[2, 2, {delimiter} 2];", 30 };
37+
yield return new object[] { $"char cc = (new char[3, 3, 3])[2, 2,{delimiter} 2];", 36 };
38+
yield return new object[] { $"char? c = (new char[3, 3, 3])?[2, 2,{delimiter} 2];", 37 };
39+
yield return new object[] { $"long ll = this[2, 2,{delimiter} 2];", 24 };
40+
}
41+
42+
public static IEnumerable<object[]> ValidTestExpressions()
43+
{
44+
yield return new object[] { $"System.Action func = () => Bar(0, 2, 3)", 0 };
45+
yield return new object[] { $"System.Action<int> func = x => Bar(x, 2, 3)", 0 };
46+
yield return new object[] { $"System.Action func = delegate {{ Bar(0, 0, 0); }}", 0 };
47+
yield return new object[] { "var weird = new int[10][,,,];", 0 };
48+
}
49+
50+
public static IEnumerable<object[]> ValidTestDeclarations()
51+
{
52+
yield return new object[]
53+
{
54+
$@"public Foo(
55+
int a, int b, string s) {{ }}"
56+
};
57+
yield return new object[]
58+
{
59+
$@"public Foo(
60+
int a,
61+
int b,
62+
string s) {{ }}"
63+
};
64+
}
65+
66+
[Theory]
67+
[MemberData(nameof(GetTestDeclarations), "")]
68+
[MemberData(nameof(ValidTestDeclarations))]
69+
public async Task TestValidDeclarationAsync(string declaration)
70+
{
71+
var testCode = $@"
72+
class Foo
73+
{{
74+
{declaration}
75+
}}";
76+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
77+
}
78+
79+
[Theory]
80+
[MemberData(nameof(GetTestDeclarations), "\r\n")]
81+
public async Task TestInvalidDeclarationAsync(string declaration)
82+
{
83+
var testCode = $@"
84+
class Foo
85+
{{
86+
{declaration}
87+
}}";
88+
89+
DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(5, 2);
90+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
91+
}
92+
93+
[Theory]
94+
[MemberData(nameof(GetTestConstructorInitializers), "")]
95+
public async Task TestValidConstructorInitializerAsync(string initializer)
96+
{
97+
var testCode = $@"
98+
class Base
99+
{{
100+
public Base(int a, int b, string s)
101+
{{
102+
}}
103+
}}
104+
105+
class Derived : Base
106+
{{
107+
public Derived()
108+
: {initializer}
109+
{{
110+
}}
111+
112+
public Derived(int i, int j, string z)
113+
: base(i, j, z)
114+
{{
115+
}}
116+
}}";
117+
118+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
119+
}
120+
121+
[Theory]
122+
[MemberData(nameof(GetTestConstructorInitializers), "\r\n")]
123+
public async Task TestInvalidConstructorInitializerAsync(string initializer)
124+
{
125+
var testCode = $@"
126+
class Base
127+
{{
128+
public Base(int a, int b, string s)
129+
{{
130+
}}
131+
}}
132+
133+
class Derived : Base
134+
{{
135+
public Derived()
136+
: {initializer}
137+
{{
138+
}}
139+
140+
public Derived(int i, int j, string z)
141+
: base(i, j, z)
142+
{{
143+
}}
144+
}}";
145+
146+
DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(13, 2);
147+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
148+
}
149+
150+
[Theory]
151+
[MemberData(nameof(GetTestExpressions), "")]
152+
[MemberData(nameof(ValidTestExpressions))]
153+
public async Task TestValidExpressionAsync(string expression, int column)
154+
{
155+
var testCode = $@"
156+
class Foo
157+
{{
158+
public void Bar(int i, int j, int k)
159+
{{
160+
}}
161+
162+
public void Baz()
163+
{{
164+
{expression};
165+
}}
166+
167+
public long this[int a, int b, int s] => a + b + s;
168+
}}";
169+
170+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
171+
}
172+
173+
[Theory]
174+
[MemberData(nameof(GetTestExpressions), "\r\n")]
175+
public async Task TestInvalidExpressionAsync(string expression, int column)
176+
{
177+
var testCode = $@"
178+
class Foo
179+
{{
180+
public void Bar(int i, int j, int k)
181+
{{
182+
}}
183+
184+
public void Baz()
185+
{{
186+
{expression};
187+
}}
188+
189+
public long this[int a, int b, int s] => a + b + s;
190+
}}";
191+
192+
DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(11, 2);
193+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
194+
}
195+
196+
[Fact]
197+
public async Task TestValidAttributeAsync()
198+
{
199+
var testCode = @"
200+
[System.AttributeUsage(System.AttributeTargets.Class)]
201+
public class MyAttribute : System.Attribute
202+
{
203+
public MyAttribute(int a, int b, int c)
204+
{
205+
}
206+
}
207+
208+
[MyAttribute(1, 2, 3)]
209+
class Foo
210+
{
211+
}
212+
213+
// This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1211
214+
[System.Obsolete]
215+
class ObsoleteType
216+
{
217+
}";
218+
219+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
220+
}
221+
222+
[Fact]
223+
public async Task TestInvalidAttributeAsync()
224+
{
225+
var testCode = @"
226+
[System.AttributeUsage(System.AttributeTargets.Class)]
227+
public class MyAttribute : System.Attribute
228+
{
229+
public MyAttribute(int a, int b, int c)
230+
{
231+
}
232+
}
233+
234+
[MyAttribute(
235+
1,
236+
2, 3)]
237+
class Foo
238+
{
239+
}";
240+
241+
DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(12, 8);
242+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
243+
}
244+
245+
/// <inheritdoc/>
246+
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
247+
{
248+
yield return new SA1117ParametersMustBeOnSameLineOrSeparateLines();
249+
}
250+
}
251+
}

StyleCop.Analyzers/StyleCop.Analyzers.Test/StyleCop.Analyzers.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@
291291
<Compile Include="ReadabilityRules\SA1114UnitTests.cs" />
292292
<Compile Include="ReadabilityRules\SA1115UnitTests.cs" />
293293
<Compile Include="ReadabilityRules\SA1116UnitTests.cs" />
294+
<Compile Include="ReadabilityRules\SA1117UnitTests.cs" />
294295
<Compile Include="ReadabilityRules\SA1118UnitTests.cs" />
295296
<Compile Include="ReadabilityRules\SA1120UnitTests.cs" />
296297
<Compile Include="ReadabilityRules\SA1121UnitTests.cs" />

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/ReadabilityResources.Designer.cs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/ReadabilityResources.resx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@
301301
<value>The parameters to a C# method or indexer call or declaration are not all on the same line or each on a separate line.</value>
302302
</data>
303303
<data name="SA1117MessageFormat" xml:space="preserve">
304-
<value />
304+
<value>The parameters must all be placed on the same line or each parameter must be placed on its own line.</value>
305305
</data>
306306
<data name="SA1117Title" xml:space="preserve">
307307
<value>Parameters must be on same line or separate lines</value>

0 commit comments

Comments
 (0)