Skip to content

Commit 0b2b098

Browse files
committed
Make SA1117 work with multiline arguments (fix #3106)
1 parent dc78ed3 commit 0b2b098

2 files changed

Lines changed: 157 additions & 193 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1117UnitTests.cs

Lines changed: 136 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
22
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
33

4-
// Several test methods in this file use the same member data, but in some cases the test does not use all of the
5-
// supported parameters. See https://github.com/xunit/xunit/issues/1556.
6-
#pragma warning disable xUnit1026 // Theory methods should use all of their parameters
7-
84
namespace StyleCop.Analyzers.Test.ReadabilityRules
95
{
106
using System.Collections.Generic;
@@ -19,36 +15,73 @@ public class SA1117UnitTests
1915
{
2016
public static IEnumerable<object[]> GetTestDeclarations(string delimiter)
2117
{
22-
yield return new object[] { $"public Foo(int a, int b,{delimiter} string s) {{ }}" };
23-
yield return new object[] { $"public object Bar(int a, int b,{delimiter} string s) => null;" };
24-
yield return new object[] { $"public object this[int a, int b,{delimiter} string s] => null;" };
25-
yield return new object[] { $"public delegate void Bar(int a, int b,{delimiter} string s);" };
18+
yield return new object[] { $"public Foo(int a, int b,{delimiter} string s) {{ }}", 5, 2 };
19+
yield return new object[] { $"public object Bar(int a, int b,{delimiter} string s) => null;", 5, 2 };
20+
yield return new object[] { $"public object this[int a, int b,{delimiter} string s] => null;", 5, 2 };
21+
yield return new object[] { $"public delegate void Bar(int a, int b,{delimiter} string s);", 5, 2 };
22+
}
23+
24+
public static IEnumerable<object[]> GetMultilineTestDeclarations(string delimiter)
25+
{
26+
yield return new object[] { $"public Foo(int a,{delimiter} string\r\ns) {{ }}", 4, 23 };
27+
yield return new object[] { $"public object Bar(int a,{delimiter} string\r\ns) => null;", 4, 30 };
28+
yield return new object[] { $"public object this[int a,{delimiter} string\r\ns] => null;", 4, 31 };
29+
yield return new object[] { $"public delegate void Bar(int a,{delimiter} string\r\ns);", 4, 37 };
2630
}
2731

2832
public static IEnumerable<object[]> GetTestConstructorInitializers(string delimiter)
2933
{
30-
yield return new object[] { $"this(42, 43, {delimiter} \"hello\")" };
31-
yield return new object[] { $"base(42, 43, {delimiter} \"hello\")" };
34+
yield return new object[] { $"this(42, 43, {delimiter} \"hello\")", 13, 2 };
35+
yield return new object[] { $"base(42, 43, {delimiter} \"hello\")", 13, 2 };
36+
}
37+
38+
public static IEnumerable<object[]> GetMultilineTestConstructorInitializers(string delimiter)
39+
{
40+
yield return new object[] { $"this(42\r\n+ 1, {delimiter} 43, {delimiter} \"hello\")", 13, 7 };
41+
yield return new object[] { $"base(42\r\n+ 1, {delimiter} 43, {delimiter} \"hello\")", 13, 7 };
3242
}
3343

3444
public static IEnumerable<object[]> GetTestExpressions(string delimiter)
3545
{
36-
yield return new object[] { $"Bar(1, 2, {delimiter} 2)", 13 };
37-
yield return new object[] { $"System.Action<int, int, int> func = (int x, int y, {delimiter} int z) => Bar(x, y, z)", 41 };
38-
yield return new object[] { $"System.Action<int, int, int> func = delegate(int x, int y, {delimiter} int z) {{ Bar(x, y, z); }}", 49 };
39-
yield return new object[] { $"new System.DateTime(2015, 9, {delimiter} 14)", 20 };
40-
yield return new object[] { $"var arr = new string[2, 2, {delimiter} 2];", 30 };
41-
yield return new object[] { $"char cc = (new char[3, 3, 3])[2, 2,{delimiter} 2];", 36 };
42-
yield return new object[] { $"char? c = (new char[3, 3, 3])?[2, 2,{delimiter} 2];", 37 };
43-
yield return new object[] { $"long ll = this[2, 2,{delimiter} 2];", 24 };
46+
yield return new object[] { $"Bar(1, 2, {delimiter} 2)", 11, 2 };
47+
yield return new object[] { $"System.Action<int, int, int> func = (int x, int y, {delimiter} int z) => Bar(x, y, z)", 11, 2 };
48+
yield return new object[] { $"System.Action<int, int, int> func = delegate(int x, int y, {delimiter} int z) {{ Bar(x, y, z); }}", 11, 2 };
49+
yield return new object[] { $"new System.DateTime(2015, 9, {delimiter} 14)", 11, 2 };
50+
yield return new object[] { $"var arr = new string[2, 2, {delimiter} 2];", 11, 2 };
51+
yield return new object[] { $"char cc = (new char[3, 3, 3])[2, 2,{delimiter} 2];", 11, 2 };
52+
yield return new object[] { $"char? c = (new char[3, 3, 3])?[2, 2,{delimiter} 2];", 11, 2 };
53+
yield return new object[] { $"long ll = this[2, 2,{delimiter} 2];", 11, 2 };
54+
}
55+
56+
public static IEnumerable<object[]> GetMultilineTestExpressions(string delimiter)
57+
{
58+
yield return new object[] { $"System.Action<int, int, int> func = (int x, {delimiter} int y, {delimiter} int\r\nz) => Bar(x, y, z)", 10, 62 };
59+
yield return new object[] { $"System.Action<int, int, int> func = delegate(int x, {delimiter} int y, {delimiter} int\r\nz) {{ Bar(x, y, z); }}", 10, 70 };
60+
yield return new object[] { $"var arr = new string[2, {delimiter} 2\r\n+ 2];", 10, 34 };
61+
yield return new object[] { $"char cc = (new char[3, 3])[2, {delimiter} 2\r\n+ 2];", 10, 40 };
62+
yield return new object[] { $"char? c = (new char[3, 3])?[2, {delimiter} 2\r\n+ 2];", 10, 41 };
63+
yield return new object[] { $"long ll = this[2,{delimiter} 2,{delimiter} 2\r\n+ 1];", 10, 30 };
64+
yield return new object[] { $"var str = string.Join(\r\n\"abc\"\r\n + \"cba\",{delimiter}\"def\");", 12, 10 };
65+
yield return new object[] { $"var str = string.Join(\r\n\"def\",{delimiter}\"abc\"\r\n + \"cba\");", 11, 7 };
66+
yield return new object[] { $"Bar(\r\n1\r\n + 2,{delimiter}3,\r\n 4);", 12, 6 };
67+
}
68+
69+
public static IEnumerable<object[]> GetTestAttributes(string delimiter)
70+
{
71+
yield return new object[] { $"[MyAttribute(1, {delimiter}2, 3)]", 11, 4 };
72+
}
73+
74+
public static IEnumerable<object[]> GetMultilineTestAttributes(string delimiter)
75+
{
76+
yield return new object[] { $"[MyAttribute(1, {delimiter}2, {delimiter}3\r\n+ 5)]", 10, 20 };
4477
}
4578

4679
public static IEnumerable<object[]> ValidTestExpressions()
4780
{
48-
yield return new object[] { $"System.Action func = () => Bar(0, 2, 3)", 0 };
49-
yield return new object[] { $"System.Action<int> func = x => Bar(x, 2, 3)", 0 };
50-
yield return new object[] { $"System.Action func = delegate {{ Bar(0, 0, 0); }}", 0 };
51-
yield return new object[] { "var weird = new int[10][,,,];", 0 };
81+
yield return new object[] { $"System.Action func = () => Bar(0, 2, 3)", 0, 0 };
82+
yield return new object[] { $"System.Action<int> func = x => Bar(x, 2, 3)", 0, 0 };
83+
yield return new object[] { $"System.Action func = delegate {{ Bar(0, 0, 0); }}", 0, 0 };
84+
yield return new object[] { "var weird = new int[10][,,,];", 0, 0 };
5285
}
5386

5487
public static IEnumerable<object[]> ValidTestDeclarations()
@@ -57,21 +90,52 @@ public static IEnumerable<object[]> ValidTestDeclarations()
5790
{
5891
$@"public Foo(
5992
int a, int b, string s) {{ }}",
93+
0,
94+
0,
6095
};
6196
yield return new object[]
6297
{
6398
$@"public Foo(
6499
int a,
65100
int b,
66101
string s) {{ }}",
102+
0,
103+
0,
104+
};
105+
}
106+
107+
public static IEnumerable<object[]> ValidTestAttribute()
108+
{
109+
// This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1211
110+
yield return new object[] { @"[System.Obsolete]", 0, 0 };
111+
yield return new object[]
112+
{
113+
@"[MyAttribute(
114+
1, 2, 3)]",
115+
0,
116+
0,
117+
};
118+
yield return new object[]
119+
{
120+
@"[MyAttribute(
121+
1,
122+
2,
123+
3)]",
124+
0,
125+
0,
67126
};
68127
}
69128

70129
[Theory]
71130
[MemberData(nameof(GetTestDeclarations), "")]
131+
[MemberData(nameof(GetMultilineTestDeclarations), "\r\n")]
72132
[MemberData(nameof(ValidTestDeclarations))]
73-
public async Task TestValidDeclarationAsync(string declaration)
133+
public async Task TestValidDeclarationAsync(string declaration, int row, int column)
74134
{
135+
// Not needed for this test
136+
_ = row;
137+
_ = column;
138+
75139
var testCode = $@"
76140
class Foo
77141
{{
@@ -82,22 +146,28 @@ class Foo
82146

83147
[Theory]
84148
[MemberData(nameof(GetTestDeclarations), "\r\n")]
85-
public async Task TestInvalidDeclarationAsync(string declaration)
149+
[MemberData(nameof(GetMultilineTestDeclarations), "")]
150+
public async Task TestInvalidDeclarationAsync(string declaration, int row, int column)
86151
{
87152
var testCode = $@"
88153
class Foo
89154
{{
90155
{declaration}
91156
}}";
92157

93-
DiagnosticResult expected = Diagnostic().WithLocation(5, 2);
158+
DiagnosticResult expected = Diagnostic().WithLocation(row, column);
94159
await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
95160
}
96161

97162
[Theory]
98163
[MemberData(nameof(GetTestConstructorInitializers), "")]
99-
public async Task TestValidConstructorInitializerAsync(string initializer)
164+
[MemberData(nameof(GetMultilineTestConstructorInitializers), "\r\n")]
165+
public async Task TestValidConstructorInitializerAsync(string initializer, int row, int column)
100166
{
167+
// Not needed for this test
168+
_ = row;
169+
_ = column;
170+
101171
var testCode = $@"
102172
class Base
103173
{{
@@ -124,7 +194,8 @@ public Derived(int i, int j, string z)
124194

125195
[Theory]
126196
[MemberData(nameof(GetTestConstructorInitializers), "\r\n")]
127-
public async Task TestInvalidConstructorInitializerAsync(string initializer)
197+
[MemberData(nameof(GetMultilineTestConstructorInitializers), "")]
198+
public async Task TestInvalidConstructorInitializerAsync(string initializer, int row, int column)
128199
{
129200
var testCode = $@"
130201
class Base
@@ -147,16 +218,18 @@ public Derived(int i, int j, string z)
147218
}}
148219
}}";
149220

150-
DiagnosticResult expected = Diagnostic().WithLocation(13, 2);
221+
DiagnosticResult expected = Diagnostic().WithLocation(row, column);
151222
await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
152223
}
153224

154225
[Theory]
155226
[MemberData(nameof(GetTestExpressions), "")]
227+
[MemberData(nameof(GetMultilineTestExpressions), "\r\n")]
156228
[MemberData(nameof(ValidTestExpressions))]
157-
public async Task TestValidExpressionAsync(string expression, int column)
229+
public async Task TestValidExpressionAsync(string expression, int row, int column)
158230
{
159231
// Not needed for this test
232+
_ = row;
160233
_ = column;
161234

162235
var testCode = $@"
@@ -179,11 +252,9 @@ public void Baz()
179252

180253
[Theory]
181254
[MemberData(nameof(GetTestExpressions), "\r\n")]
182-
public async Task TestInvalidExpressionAsync(string expression, int column)
255+
[MemberData(nameof(GetMultilineTestExpressions), "")]
256+
public async Task TestInvalidExpressionAsync(string expression, int row, int column)
183257
{
184-
// Not needed for this test
185-
_ = column;
186-
187258
var testCode = $@"
188259
class Foo
189260
{{
@@ -199,56 +270,58 @@ public void Baz()
199270
public long this[int a, int b, int s] => a + b + s;
200271
}}";
201272

202-
DiagnosticResult expected = Diagnostic().WithLocation(11, 2);
273+
DiagnosticResult expected = Diagnostic().WithLocation(row, column);
203274
await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
204275
}
205276

206-
[Fact]
207-
public async Task TestValidAttributeAsync()
277+
[Theory]
278+
[MemberData(nameof(GetTestAttributes), "")]
279+
[MemberData(nameof(GetMultilineTestAttributes), "\r\n")]
280+
[MemberData(nameof(ValidTestAttribute))]
281+
public async Task TestValidAttributeAsync(string attribute, int row, int column)
208282
{
209-
var testCode = @"
283+
// Not needed for this test
284+
_ = row;
285+
_ = column;
286+
287+
var testCode = $@"
210288
[System.AttributeUsage(System.AttributeTargets.Class)]
211289
public class MyAttribute : System.Attribute
212-
{
290+
{{
213291
public MyAttribute(int a, int b, int c)
214-
{
215-
}
216-
}
292+
{{
293+
}}
294+
}}
217295
218-
[MyAttribute(1, 2, 3)]
296+
{attribute}
219297
class Foo
220-
{
221-
}
222-
223-
// This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1211
224-
[System.Obsolete]
225-
class ObsoleteType
226-
{
227-
}";
298+
{{
299+
}}";
228300

229301
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
230302
}
231303

232-
[Fact]
233-
public async Task TestInvalidAttributeAsync()
304+
[Theory]
305+
[MemberData(nameof(GetTestAttributes), "\r\n")]
306+
[MemberData(nameof(GetMultilineTestAttributes), "")]
307+
public async Task TestInvalidAttributeAsync(string attribute, int row, int column)
234308
{
235-
var testCode = @"
309+
var testCode = $@"
236310
[System.AttributeUsage(System.AttributeTargets.Class)]
237311
public class MyAttribute : System.Attribute
238-
{
312+
{{
239313
public MyAttribute(int a, int b, int c)
240-
{
241-
}
242-
}
314+
{{
315+
}}
316+
}}
243317
244-
[MyAttribute(
245-
1,
246-
2, 3)]
318+
{attribute}
247319
class Foo
248-
{
249-
}";
320+
{{
321+
}}";
322+
323+
DiagnosticResult expected = Diagnostic().WithLocation(row, column);
250324

251-
DiagnosticResult expected = Diagnostic().WithLocation(12, 8);
252325
await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
253326
}
254327
}

0 commit comments

Comments
 (0)