Skip to content

Commit f588028

Browse files
committed
Fix MSTEST0018 FP with IEnumerable<SomeType[]> (#3978)
1 parent 9aaa6ee commit f588028

File tree

2 files changed

+188
-18
lines changed

2 files changed

+188
-18
lines changed

src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs

+19-13
Original file line numberDiff line numberDiff line change
@@ -220,23 +220,29 @@ private static void AnalyzeDataSource(SymbolAnalysisContext context, AttributeDa
220220
}
221221

222222
// Validate member return type.
223-
if (member.GetMemberType() is not INamedTypeSymbol memberType)
223+
ITypeSymbol? memberTypeSymbol = member.GetMemberType();
224+
if (memberTypeSymbol is INamedTypeSymbol memberNamedType)
224225
{
225-
return;
226-
}
226+
if (!SymbolEqualityComparer.Default.Equals(memberNamedType.ConstructedFrom, ienumerableTypeSymbol)
227+
|| memberNamedType.TypeArguments.Length != 1)
228+
{
229+
context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(MemberTypeRule, declaringType.Name, memberName));
230+
return;
231+
}
227232

228-
if (!SymbolEqualityComparer.Default.Equals(memberType.ConstructedFrom, ienumerableTypeSymbol)
229-
|| memberType.TypeArguments.Length != 1)
230-
{
231-
context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(MemberTypeRule, declaringType.Name, memberName));
232-
return;
233+
ITypeSymbol collectionBoundType = memberNamedType.TypeArguments[0];
234+
if (!collectionBoundType.Inherits(itupleTypeSymbol)
235+
&& collectionBoundType is not IArrayTypeSymbol)
236+
{
237+
context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(MemberTypeRule, declaringType.Name, memberName));
238+
}
233239
}
234-
235-
ITypeSymbol collectionBoundType = memberType.TypeArguments[0];
236-
if (!collectionBoundType.Inherits(itupleTypeSymbol)
237-
&& (collectionBoundType is not IArrayTypeSymbol arrayTypeSymbol || arrayTypeSymbol.ElementType.SpecialType != SpecialType.System_Object))
240+
else if (memberTypeSymbol is IArrayTypeSymbol arrayType)
238241
{
239-
context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(MemberTypeRule, declaringType.Name, memberName));
242+
if (arrayType.ElementType is not IArrayTypeSymbol)
243+
{
244+
context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(MemberTypeRule, declaringType.Name, memberName));
245+
}
240246
}
241247
}
242248

test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs

+169-5
Original file line numberDiff line numberDiff line change
@@ -164,22 +164,126 @@ public void TestMethod214(int i, string s)
164164
{
165165
}
166166
167+
[DynamicData("DataJaggedArray")]
168+
[TestMethod]
169+
public void TestMethod301(MyTestClass[] testClasses)
170+
{
171+
}
172+
173+
[DynamicData("SomeDataJaggedArray", typeof(SomeClass))]
174+
[TestMethod]
175+
public void TestMethod302(MyTestClass[] testClasses)
176+
{
177+
}
178+
179+
[DynamicData(dynamicDataSourceName: "DataJaggedArray")]
180+
[TestMethod]
181+
public void TestMethod303(MyTestClass[] testClasses)
182+
{
183+
}
184+
185+
[DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "SomeDataJaggedArray")]
186+
[TestMethod]
187+
public void TestMethod304(MyTestClass[] testClasses)
188+
{
189+
}
190+
191+
[DynamicData("GetDataJaggedArray", DynamicDataSourceType.Method)]
192+
[TestMethod]
193+
public void TestMethod311(MyTestClass[] testClasses)
194+
{
195+
}
196+
197+
[DynamicData("GetSomeDataJaggedArray", typeof(SomeClass), DynamicDataSourceType.Method)]
198+
[TestMethod]
199+
public void TestMethod312(MyTestClass[] testClasses)
200+
{
201+
}
202+
203+
[DynamicData(dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetDataJaggedArray")]
204+
[TestMethod]
205+
public void TestMethod313(MyTestClass[] testClasses)
206+
{
207+
}
208+
209+
[DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetSomeDataJaggedArray")]
210+
[TestMethod]
211+
public void TestMethod314(MyTestClass[] testClasses)
212+
{
213+
}
214+
215+
[DynamicData("DataNonObjectTypeArray")]
216+
[TestMethod]
217+
public void TestMethod401(MyTestClass[] testClasses)
218+
{
219+
}
220+
221+
[DynamicData("SomeDataNonObjectTypeArray", typeof(SomeClass))]
222+
[TestMethod]
223+
public void TestMethod402(MyTestClass[] testClasses)
224+
{
225+
}
226+
227+
[DynamicData(dynamicDataSourceName: "DataNonObjectTypeArray")]
228+
[TestMethod]
229+
public void TestMethod403(MyTestClass[] testClasses)
230+
{
231+
}
232+
233+
[DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "SomeDataNonObjectTypeArray")]
234+
[TestMethod]
235+
public void TestMethod404(MyTestClass[] testClasses)
236+
{
237+
}
238+
239+
[DynamicData("GetDataNonObjectTypeArray", DynamicDataSourceType.Method)]
240+
[TestMethod]
241+
public void TestMethod411(MyTestClass[] testClasses)
242+
{
243+
}
244+
245+
[DynamicData("GetSomeDataNonObjectTypeArray", typeof(SomeClass), DynamicDataSourceType.Method)]
246+
[TestMethod]
247+
public void TestMethod412(MyTestClass[] testClasses)
248+
{
249+
}
250+
251+
[DynamicData(dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetDataNonObjectTypeArray")]
252+
[TestMethod]
253+
public void TestMethod413(MyTestClass[] testClasses)
254+
{
255+
}
256+
257+
[DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetSomeDataNonObjectTypeArray")]
258+
[TestMethod]
259+
public void TestMethod414(MyTestClass[] testClasses)
260+
{
261+
}
262+
167263
public static IEnumerable<object[]> Data => new List<object[]>();
168264
public static IEnumerable<Tuple<int, string>> DataTuple => new List<Tuple<int, string>>();
169265
public static IEnumerable<(int, string)> DataValueTuple => new List<(int, string)>();
266+
public static MyTestClass[][] DataJaggedArray => System.Array.Empty<MyTestClass[]>();
267+
public static IEnumerable<MyTestClass[]> DataNonObjectTypeArray => new List<MyTestClass[]>();
170268
public static IEnumerable<object[]> GetData() => new List<object[]>();
171269
public static IEnumerable<Tuple<int, string>> GetDataTuple() => new List<Tuple<int, string>>();
172270
public static IEnumerable<(int, string)> GetDataValueTuple() => new List<(int, string)>();
271+
public static MyTestClass[][] GetDataJaggedArray() => System.Array.Empty<MyTestClass[]>();
272+
public static IEnumerable<MyTestClass[]> GetDataNonObjectTypeArray() => new List<MyTestClass[]>();
173273
}
174274
175275
public class SomeClass
176276
{
177277
public static IEnumerable<object[]> SomeData => new List<object[]>();
178278
public static IEnumerable<Tuple<int, string>> SomeDataTuple => new List<Tuple<int, string>>();
179279
public static IEnumerable<(int, string)> SomeDataValueTuple => new List<(int, string)>();
280+
public static MyTestClass[][] SomeDataJaggedArray => System.Array.Empty<MyTestClass[]>();
281+
public static IEnumerable<MyTestClass[]> SomeDataNonObjectTypeArray => new List<MyTestClass[]>();
180282
public static IEnumerable<object[]> GetSomeData() => new List<object[]>();
181283
public static IEnumerable<Tuple<int, string>> GetSomeDataTuple() => new List<Tuple<int, string>>();
182284
public static IEnumerable<(int, string)> GetSomeDataValueTuple() => new List<(int, string)>();
285+
public static MyTestClass[][] GetSomeDataJaggedArray() => System.Array.Empty<MyTestClass[]>();
286+
public static IEnumerable<MyTestClass[]> GetSomeDataNonObjectTypeArray() => new List<MyTestClass[]>();
183287
}
184288
""";
185289

@@ -469,36 +573,88 @@ public void TestMethod4(object[] o)
469573
470574
[{|#4:DynamicData("GetData", DynamicDataSourceType.Method)|}]
471575
[TestMethod]
472-
public void TestMethod11(object[] o)
576+
public void TestMethod5(object[] o)
473577
{
474578
}
475579
476580
[{|#5:DynamicData("GetSomeData", typeof(SomeClass), DynamicDataSourceType.Method)|}]
477581
[TestMethod]
478-
public void TestMethod12(object[] o)
582+
public void TestMethod6(object[] o)
479583
{
480584
}
481585
482586
[{|#6:DynamicData(dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetData")|}]
483587
[TestMethod]
484-
public void TestMethod13(object[] o)
588+
public void TestMethod7(object[] o)
485589
{
486590
}
487591
488592
[{|#7:DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetSomeData")|}]
489593
[TestMethod]
490-
public void TestMethod14(object[] o)
594+
public void TestMethod8(object[] o)
595+
{
596+
}
597+
598+
[{|#8:DynamicData("DataArray")|}]
599+
[TestMethod]
600+
public void TestMethod9(MyTestClass[] o)
601+
{
602+
}
603+
604+
[{|#9:DynamicData("SomeDataArray", typeof(SomeClass))|}]
605+
[TestMethod]
606+
public void TestMethod10(MyTestClass[] o)
607+
{
608+
}
609+
610+
[{|#10:DynamicData(dynamicDataSourceName: "DataArray")|}]
611+
[TestMethod]
612+
public void TestMethod11(MyTestClass[] o)
613+
{
614+
}
615+
616+
[{|#11:DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "SomeDataArray")|}]
617+
[TestMethod]
618+
public void TestMethod12(MyTestClass[] o)
619+
{
620+
}
621+
622+
[{|#12:DynamicData("GetDataArray", DynamicDataSourceType.Method)|}]
623+
[TestMethod]
624+
public void TestMethod13(MyTestClass[] o)
625+
{
626+
}
627+
628+
[{|#13:DynamicData("GetSomeDataArray", typeof(SomeClass), DynamicDataSourceType.Method)|}]
629+
[TestMethod]
630+
public void TestMethod14(MyTestClass[] o)
631+
{
632+
}
633+
634+
[{|#14:DynamicData(dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetDataArray")|}]
635+
[TestMethod]
636+
public void TestMethod15(MyTestClass[] o)
637+
{
638+
}
639+
640+
[{|#15:DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetSomeDataArray")|}]
641+
[TestMethod]
642+
public void TestMethod16(MyTestClass[] o)
491643
{
492644
}
493645
494646
public static IEnumerable<object> Data => new List<object>();
647+
public static MyTestClass[] DataArray => System.Array.Empty<MyTestClass>();
495648
public static IEnumerable<object> GetData() => new List<object>();
649+
public static MyTestClass[] GetDataArray() => System.Array.Empty<MyTestClass>();
496650
}
497651
498652
public class SomeClass
499653
{
500654
public static IEnumerable<object> SomeData => new List<object>();
655+
public static MyTestClass[] SomeDataArray => System.Array.Empty<MyTestClass>();
501656
public static IEnumerable<object> GetSomeData() => new List<object>();
657+
public static MyTestClass[] GetSomeDataArray() => System.Array.Empty<MyTestClass>();
502658
}
503659
""";
504660

@@ -511,7 +667,15 @@ await VerifyCS.VerifyAnalyzerAsync(
511667
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(4).WithArguments("MyTestClass", "GetData"),
512668
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(5).WithArguments("SomeClass", "GetSomeData"),
513669
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(6).WithArguments("MyTestClass", "GetData"),
514-
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(7).WithArguments("SomeClass", "GetSomeData"));
670+
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(7).WithArguments("SomeClass", "GetSomeData"),
671+
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(8).WithArguments("MyTestClass", "DataArray"),
672+
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(9).WithArguments("SomeClass", "SomeDataArray"),
673+
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(10).WithArguments("MyTestClass", "DataArray"),
674+
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(11).WithArguments("SomeClass", "SomeDataArray"),
675+
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(12).WithArguments("MyTestClass", "GetDataArray"),
676+
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(13).WithArguments("SomeClass", "GetSomeDataArray"),
677+
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(14).WithArguments("MyTestClass", "GetDataArray"),
678+
VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(15).WithArguments("SomeClass", "GetSomeDataArray"));
515679
}
516680

517681
public async Task MemberIsNotStatic_Diagnostic()

0 commit comments

Comments
 (0)