Skip to content

Commit

Permalink
Fix false-positive errors from xunit/xunit#2826 (#170)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesTerwilliger authored Nov 27, 2023
1 parent e768a8b commit 45a493e
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,69 @@ public void TestMethod<T>(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<object[]> GetSequences(IEnumerable<int> seq) =>
new List<object[]>();
[Theory]
[MemberData(nameof(GetSequences), new int[] {{ 1, 2 }})]
[MemberData(nameof(GetSequences), new [] {{ 3, 4, 5}})]
public void Test(IEnumerable<int> 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<object[]> GetSequences(IEnumerable<object> seq) =>
new List<object[]>();
[Theory]
[MemberData(nameof(GetSequences), new object[] {{ 1, 2 }})]
public void Test(IEnumerable<int> seq)
{{
Assert.NotEmpty(seq);
}}
}}
";

DiagnosticResult[] expected =
{
Verify
.Diagnostic("xUnit1035")
.WithSpan(11, 52, 11, 53)
.WithArguments("seq", "System.Collections.Generic.IEnumerable<object>")
.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(
Expand Down
18 changes: 14 additions & 4 deletions src/xunit.analyzers/X1000/MemberDataShouldReferenceValidMember.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -215,7 +218,8 @@ public static (INamedTypeSymbol? TestClass, ITypeSymbol? MemberClass) GetClassTy
return (testClassTypeSymbol, declaredMemberTypeSymbol);
}

static IList<ExpressionSyntax>? GetParameterExpressionsFromArrayArgument(List<AttributeArgumentSyntax> arguments)
static IList<ExpressionSyntax>? GetParameterExpressionsFromArrayArgument(
List<AttributeArgumentSyntax> arguments, SemanticModel semanticModel)
{
if (arguments.Count > 1)
return arguments.Select(a => a.Expression).ToList();
Expand All @@ -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,
Expand All @@ -234,7 +239,12 @@ public static (INamedTypeSymbol? TestClass, ITypeSymbol? MemberClass) GetClassTy
if (initializer is null)
return new List<ExpressionSyntax> { 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<ExpressionSyntax> { argumentExpression };
}

public static ISymbol? FindMethodSymbol(
Expand Down Expand Up @@ -493,7 +503,7 @@ static void VerifyDataMethodParameterUsage(
string memberName,
List<AttributeArgumentSyntax> extraArguments)
{
var argumentSyntaxList = GetParameterExpressionsFromArrayArgument(extraArguments);
var argumentSyntaxList = GetParameterExpressionsFromArrayArgument(extraArguments, semanticModel);
if (argumentSyntaxList is null)
return;

Expand Down

0 comments on commit 45a493e

Please sign in to comment.