Skip to content

Commit

Permalink
Coding style changes
Browse files Browse the repository at this point in the history
  • Loading branch information
bradwilson committed Jul 7, 2024
1 parent 0e8e4de commit f63f00a
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 107 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using System.Composition;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using System.Threading;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Editing;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

Expand All @@ -13,7 +13,7 @@ namespace Xunit.Analyzers.Fixes;
[ExportCodeFixProvider(LanguageNames.CSharp), Shared]
public class AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheckFixer : BatchedCodeFixProvider
{
public const string Key_UseAlternateAssert = "xUnit2017_UseAlternateAssert";
public const string Key_UseAlternateAssert = "xUnit2029_UseAlternateAssert";

public AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheckFixer() :
base(Descriptors.X2029_AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheck.Id)
Expand All @@ -30,9 +30,10 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
return;

context.RegisterCodeFix(
XunitCodeAction.Create(c => UseCheck(context.Document, invocation, c),
Key_UseAlternateAssert,
"Use DoesNotContain"
XunitCodeAction.Create(
c => UseCheck(context.Document, invocation, c),
Key_UseAlternateAssert,
"Use DoesNotContain"
),
context.Diagnostics
);
Expand All @@ -47,32 +48,15 @@ static async Task<Document> UseCheck(

var arguments = invocation.ArgumentList.Arguments;
if (arguments.Count == 1 && arguments[0].Expression is InvocationExpressionSyntax innerInvocationSyntax)
{
if (invocation.Expression is MemberAccessExpressionSyntax outerMemberAccess && innerInvocationSyntax.Expression is MemberAccessExpressionSyntax memberAccess)
{
if (innerInvocationSyntax.ArgumentList.Arguments[0].Expression is ExpressionSyntax innerArgument)
{
editor.ReplaceNode(invocation,
editor.ReplaceNode(
invocation,
invocation
.WithArgumentList(
ArgumentList(
SeparatedList(new[] {
Argument(memberAccess.Expression),
Argument(innerArgument) }
)
)
)
.WithExpression(
outerMemberAccess.WithName(
IdentifierName(Constants.Asserts.DoesNotContain)
)
)
.WithArgumentList(ArgumentList(SeparatedList([Argument(memberAccess.Expression), Argument(innerArgument)])))
.WithExpression(outerMemberAccess.WithName(IdentifierName(Constants.Asserts.DoesNotContain)))
);

}
}
}

return editor.GetChangedDocument();
}
}
Original file line number Diff line number Diff line change
@@ -1,144 +1,113 @@
using System;
using System.Threading.Tasks;
using Xunit;
using Verify = CSharpVerifier<Xunit.Analyzers.AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheck>;



public class AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheckTests
{
public static TheoryData<string> GetEnumerables(string typeName)
{
return new TheoryData<string>()
{
$"new System.Collections.Generic.List<{typeName}>()",
$"new System.Collections.Generic.HashSet<{typeName}>()",
$"new System.Collections.ObjectModel.Collection<{typeName}>()",
$"new {typeName}[0]",
$"System.Linq.Enumerable.Empty<{typeName}>()"
};
}

public static TheoryData<string> GetSampleStrings()
{
return new TheoryData<string>()
{
String.Empty,
"123",
@"abc\n\t\\\"""
};
}
public static TheoryData<string, string> GetEnumerables(
string typeName,
string comparison) =>
new()
{
{ $"new System.Collections.Generic.List<{typeName}>()", comparison },
{ $"new System.Collections.Generic.HashSet<{typeName}>()", comparison },
{ $"new System.Collections.ObjectModel.Collection<{typeName}>()", comparison },
{ $"new {typeName}[0]", comparison },
{ $"System.Linq.Enumerable.Empty<{typeName}>()", comparison },
};

[Theory]
[MemberData(nameof(GetEnumerables), "int")]
public async Task FindsWarningForIntEnumerableDoesNotContainCheckWithEmpty(string collection)
[MemberData(nameof(GetEnumerables), "int", "")]
[MemberData(nameof(GetEnumerables), "string", "")]
public async Task Containers_WithoutWhereClause_DoesNotTrigger(
string collection,
string _)
{
var source = $@"
using System.Linq;
class TestClass
{{
void TestMethod()
{{
[|Xunit.Assert.Empty({collection}.Where(f => f > 0))|];
Xunit.Assert.Empty({collection});
}}
}}";
await Verify.VerifyAnalyzer(source);
}

[Theory]
[MemberData(nameof(GetEnumerables), "string")]
public async Task FindsWarningForStringEnumerableDoesNotContainCheckWithEmpty(string collection)
[MemberData(nameof(GetEnumerables), "int", "f > 0")]
[MemberData(nameof(GetEnumerables), "string", "f.Length > 0")]
public async Task Containers_WithWhereClause_Triggers(
string collection,
string comparison)
{
var source = $@"
using System.Linq;
class TestClass
{{
void TestMethod()
{{
[|Xunit.Assert.Empty({collection}.Where(f => f.Length > 0))|];
[|Xunit.Assert.Empty({collection}.Where(f => {comparison}))|];
}}
}}";
await Verify.VerifyAnalyzer(source);
}

[Theory]
[MemberData(nameof(GetSampleStrings))]
public async Task FindsWarningForStringDoesNotContainCheckWithEmpty(string sampleString)
{
var source = $@"
using System.Linq;
class TestClass
{{
void TestMethod()
{{
[|Xunit.Assert.Empty(""{sampleString}"".Where(f => f > 0))|];
}}
}}";
await Verify.VerifyAnalyzer(source);
}

[Theory]
[MemberData(nameof(GetEnumerables), "int")]
public async Task DoesNotFindWarningForIntEnumerableDoesNotContainCheckWithEmptyWithIndex(string collection)
[MemberData(nameof(GetEnumerables), "int", "f > 0")]
[MemberData(nameof(GetEnumerables), "string", "f.Length > 0")]
public async Task Containers_WithWhereClauseWithIndex_DoesNotTrigger(
string collection,
string comparison)
{
var source = $@"
using System.Linq;
class TestClass
{{
void TestMethod()
{{
Xunit.Assert.Empty({collection}.Where((f, i) => f > 0 && i > 0));
Xunit.Assert.Empty({collection}.Where((f, i) => {comparison} && i > 0));
}}
}}";
await Verify.VerifyAnalyzer(source);
}

[Theory]
[MemberData(nameof(GetEnumerables), "string")]
public async Task DoesNotFindWarningForStringEnumerableDoesNotContainCheckWithEmptyWithIndex(string collection)
[MemberData(nameof(GetEnumerables), "int", "f > 0")]
[MemberData(nameof(GetEnumerables), "string", "f.Length > 0")]
public async Task DoesNotFindWarningForEnumurableEmptyCheckWithChainedLinq(
string collection,
string comparison)
{
var source = $@"
using System.Linq;
class TestClass
{{
void TestMethod()
{{
Xunit.Assert.Empty({collection}.Where((f, i) => f.Length > 0 && i > 0));
Xunit.Assert.Empty({collection}.Where(f => {comparison}).Select(f => f));
}}
}}";
await Verify.VerifyAnalyzer(source);
}

public static TheoryData<string> GetSampleStrings() =>
new(string.Empty, "123", @"abc\n\t\\\""");

[Theory]
[MemberData(nameof(GetEnumerables), "int")]
[MemberData(nameof(GetEnumerables), "string")]
public async Task DoesNotFindWarningForEnumerableEmptyCheckWithoutLinq(string collection)
[MemberData(nameof(GetSampleStrings))]
public async Task Strings_WithWhereClause_DoesNotTrigger(string sampleString)
{
var source = $@"
using System.Linq;
class TestClass
{{
void TestMethod()
{{
Xunit.Assert.Empty({collection});
[|Xunit.Assert.Empty(""{sampleString}"".Where(f => f > 0))|];
}}
}}";
await Verify.VerifyAnalyzer(source);
}

[Theory]
[MemberData(nameof(GetEnumerables), "int")]
[MemberData(nameof(GetEnumerables), "string")]
public async Task DoesNotFindWarningForEnumurableEmptyCheckWithChainedLinq(string collection)
{
var source = $@"
using System.Linq;
class TestClass
{{
void TestMethod()
{{
Xunit.Assert.Empty({collection}.Where(f => f.ToString().Length > 0).Select(f => f));
}}
}}";
await Verify.VerifyAnalyzer(source);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Operations;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;

namespace Xunit.Analyzers;

Expand All @@ -20,9 +20,9 @@ public AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheck()
{ }

protected override void AnalyzeInvocation(
OperationAnalysisContext context,
XunitContext xunitContext,
IInvocationOperation invocationOperation,
OperationAnalysisContext context,
XunitContext xunitContext,
IInvocationOperation invocationOperation,
IMethodSymbol method)
{
Guard.ArgumentNotNull(xunitContext);
Expand Down

0 comments on commit f63f00a

Please sign in to comment.