diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/MemberDataShouldReferenceValidMemberTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/MemberDataShouldReferenceValidMemberTests.cs index e6da9545..ec07d3cb 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/MemberDataShouldReferenceValidMemberTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/MemberDataShouldReferenceValidMemberTests.cs @@ -837,6 +837,69 @@ public void TestMethod(T? n) {{ }} await Verify.VerifyAnalyzer(LanguageVersion.CSharp10, source); } + [Fact] + public async void DoesNotFindWarning_WithIntArrayArguments() + { + var source = $@" +using System.Collections.Generic; +using Xunit; + +public class TestClass +{{ + public static IEnumerable GetSequences(IEnumerable seq) => + new List(); + + [Theory] + [MemberData(nameof(GetSequences), new int[] {{ 1, 2 }})] + [MemberData(nameof(GetSequences), new [] {{ 3, 4, 5}})] + public void Test(IEnumerable seq) + {{ + Assert.NotEmpty(seq); + }} +}} +"; + + await Verify.VerifyAnalyzer(LanguageVersion.CSharp10, source); + } + + [Fact] + public async void FindsWarning_WithObjectArrayArguments() + { + var source = $@" +using System.Collections.Generic; +using Xunit; + +public class TestClass +{{ + public static IEnumerable GetSequences(IEnumerable seq) => + new List(); + + [Theory] + [MemberData(nameof(GetSequences), new object[] {{ 1, 2 }})] + public void Test(IEnumerable seq) + {{ + Assert.NotEmpty(seq); + }} +}} +"; + + DiagnosticResult[] expected = + { + Verify + .Diagnostic("xUnit1035") + .WithSpan(11, 52, 11, 53) + .WithArguments("seq", "System.Collections.Generic.IEnumerable") + .WithSeverity(DiagnosticSeverity.Error), + Verify + .Diagnostic("xUnit1036") + .WithSpan(11, 55, 11, 56) + .WithArguments("2") + .WithSeverity(DiagnosticSeverity.Error) + }; + + await Verify.VerifyAnalyzer(LanguageVersion.CSharp10, source, expected); + } + [Theory] [MemberData(nameof(MemberSyntaxAndArgs))] public async void FindWarning_IfHasValidTheoryDataMemberWithTooManyTypeParameters( diff --git a/src/xunit.analyzers/X1000/MemberDataShouldReferenceValidMember.cs b/src/xunit.analyzers/X1000/MemberDataShouldReferenceValidMember.cs index 0f3e198b..0024efca 100644 --- a/src/xunit.analyzers/X1000/MemberDataShouldReferenceValidMember.cs +++ b/src/xunit.analyzers/X1000/MemberDataShouldReferenceValidMember.cs @@ -1,7 +1,10 @@ +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Reflection; +using System.Reflection.Metadata; +using System.Runtime.InteropServices.ComTypes; using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -215,7 +218,8 @@ public static (INamedTypeSymbol? TestClass, ITypeSymbol? MemberClass) GetClassTy return (testClassTypeSymbol, declaredMemberTypeSymbol); } - static IList? GetParameterExpressionsFromArrayArgument(List arguments) + static IList? GetParameterExpressionsFromArrayArgument( + List arguments, SemanticModel semanticModel) { if (arguments.Count > 1) return arguments.Select(a => a.Expression).ToList(); @@ -224,7 +228,8 @@ public static (INamedTypeSymbol? TestClass, ITypeSymbol? MemberClass) GetClassTy var argumentExpression = arguments.Single().Expression; - var initializer = argumentExpression.Kind() switch + var kind = argumentExpression.Kind(); + var initializer = kind switch { SyntaxKind.ArrayCreationExpression => ((ArrayCreationExpressionSyntax)argumentExpression).Initializer, SyntaxKind.ImplicitArrayCreationExpression => ((ImplicitArrayCreationExpressionSyntax)argumentExpression).Initializer, @@ -234,7 +239,12 @@ public static (INamedTypeSymbol? TestClass, ITypeSymbol? MemberClass) GetClassTy if (initializer is null) return new List { argumentExpression }; - return initializer.Expressions.ToList(); + // In the special case where the argument is an object[], treat like params + var type = semanticModel.GetTypeInfo(argumentExpression).Type; + if (type is IArrayTypeSymbol arrayType && arrayType.ElementType.SpecialType == SpecialType.System_Object) + return initializer.Expressions.ToList(); + + return new List { argumentExpression }; } public static ISymbol? FindMethodSymbol( @@ -493,7 +503,7 @@ static void VerifyDataMethodParameterUsage( string memberName, List extraArguments) { - var argumentSyntaxList = GetParameterExpressionsFromArrayArgument(extraArguments); + var argumentSyntaxList = GetParameterExpressionsFromArrayArgument(extraArguments, semanticModel); if (argumentSyntaxList is null) return;