Skip to content

Commit 8a18e11

Browse files
committed
replacing part of assertion
1 parent b05341e commit 8a18e11

31 files changed

+597
-148
lines changed

src/FluentAssertions.BestPractices.Tests/TestAttributes.cs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Microsoft.VisualStudio.TestTools.UnitTesting;
22
using System;
33
using System.Collections.Generic;
4+
using System.Linq;
45

56
namespace FluentAssertions.BestPractices.Tests
67
{
@@ -21,21 +22,28 @@ public class AssertionDiagnosticAttribute : Attribute
2122
{
2223
public string Assertion { get; }
2324

24-
public AssertionDiagnosticAttribute(string assertion)
25+
public bool Ignore { get; }
26+
27+
public AssertionDiagnosticAttribute(string assertion, bool ignore = false)
2528
{
2629
Assertion = assertion;
30+
Ignore = ignore;
2731
}
2832
}
33+
2934
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
3035
public class AssertionCodeFixAttribute : Attribute
3136
{
3237
public string OldAssertion { get; }
3338
public string NewAssertion { get; }
3439

35-
public AssertionCodeFixAttribute(string oldAssertion, string newAssertion)
40+
public bool Ignore { get; }
41+
42+
public AssertionCodeFixAttribute(string oldAssertion, string newAssertion, bool ignore = false)
3643
{
3744
OldAssertion = oldAssertion;
3845
NewAssertion = newAssertion;
46+
Ignore = ignore;
3947
}
4048
}
4149

@@ -52,19 +60,19 @@ public override TestResult[] Execute(ITestMethod testMethod)
5260
var codeFixAttributes = testMethod.GetAttributes<AssertionCodeFixAttribute>(false);
5361

5462
var results = new List<TestResult>();
55-
for (int i = 0; i < diagnosticAttributes.Length; i++)
63+
foreach (var diagnosticAttribute in diagnosticAttributes.Where(attribute => !attribute.Ignore))
5664
{
57-
foreach (var assertion in GetTestCases(diagnosticAttributes[i]))
65+
foreach (var assertion in GetTestCases(diagnosticAttribute))
5866
{
5967
var result = testMethod.Invoke(new[] { assertion });
6068
result.DisplayName = assertion;
6169

6270
results.Add(result);
6371
}
6472
}
65-
for (int i = 0; i < codeFixAttributes.Length; i++)
73+
foreach (var codeFixAttribute in codeFixAttributes.Where(attribute => !attribute.Ignore))
6674
{
67-
foreach (var (oldAssertion, newAssertion) in GetTestCases(codeFixAttributes[i]))
75+
foreach (var (oldAssertion, newAssertion) in GetTestCases(codeFixAttribute))
6876
{
6977
var result = testMethod.Invoke(new[] { oldAssertion, newAssertion });
7078
result.DisplayName = $"{Environment.NewLine}old: \"{oldAssertion}\" {Environment.NewLine}new: \"{newAssertion}\"";

src/FluentAssertions.BestPractices.Tests/Tips/CollectionTests.cs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ public class CollectionTests
9191
newAssertion: "actual.Should().NotContain(x => x.BooleanProperty{0});")]
9292
[AssertionCodeFix(
9393
oldAssertion: "actual.Should().OnlyContain(x => !x.BooleanProperty{0});",
94-
newAssertion: "actual.Should().NotContain(x => x.BooleanProperty{0});")]
94+
newAssertion: "actual.Should().NotContain(x => x.BooleanProperty{0});",
95+
ignore: true)]
9596
[AssertionCodeFix(
9697
oldAssertion: "actual.AsEnumerable().Any(x => x.BooleanProperty).Should().BeFalse({0}).And.ToString();",
9798
newAssertion: "actual.AsEnumerable().Should().NotContain(x => x.BooleanProperty{0}).And.ToString();")]
@@ -100,7 +101,8 @@ public class CollectionTests
100101
newAssertion: "actual.AsEnumerable().Should().NotContain(x => x.BooleanProperty{0}).And.ToString();")]
101102
[AssertionCodeFix(
102103
oldAssertion: "actual.AsEnumerable().Should().OnlyContain(x => !x.BooleanProperty{0}).And.ToString();",
103-
newAssertion: "actual.AsEnumerable().Should().NotContain(x => x.BooleanProperty{0}).And.ToString();")]
104+
newAssertion: "actual.AsEnumerable().Should().NotContain(x => x.BooleanProperty{0}).And.ToString();",
105+
ignore: true)]
104106
[Implemented]
105107
public void CollectionShouldNotContainProperty_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldNotContainPropertyCodeFix, CollectionShouldNotContainPropertyAnalyzer>(oldAssertion, newAssertion);
106108

@@ -191,14 +193,13 @@ public class CollectionTests
191193
[AssertionCodeFix(
192194
oldAssertion: "actual.Count().Should().BeGreaterThan(6{0});",
193195
newAssertion: "actual.Should().HaveCountGreaterThan(6{0});")]
194-
[Implemented]
195196
[AssertionCodeFix(
196197
oldAssertion: "actual.AsEnumerable().Count().Should().BeGreaterThan(k{0}).And.ToString();",
197198
newAssertion: "actual.AsEnumerable().Should().HaveCountGreaterThan(k{0}).And.ToString();")]
198199
[AssertionCodeFix(
199200
oldAssertion: "actual.AsEnumerable().Count().Should().BeGreaterThan(6{0}).And.ToString();",
200201
newAssertion: "actual.AsEnumerable().Should().HaveCountGreaterThan(6{0}).And.ToString();")]
201-
[Ignore("Will be available in Fluent Assertions 5.0")]
202+
[Implemented, Ignore("Will be available in Fluent Assertions 5.0")]
202203
public void CollectionShouldHaveCountGreaterThan_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldHaveCountGreaterThanCodeFix, CollectionShouldHaveCountGreaterThanAnalyzer>(oldAssertion, newAssertion);
203204

204205
[AssertionDataTestMethod]
@@ -216,14 +217,13 @@ public class CollectionTests
216217
[AssertionCodeFix(
217218
oldAssertion: "actual.Count().Should().BeGreaterOrEqualTo(6{0});",
218219
newAssertion: "actual.Should().HaveCountGreaterOrEqualTo(6{0});")]
219-
[Implemented]
220220
[AssertionCodeFix(
221221
oldAssertion: "actual.AsEnumerable().Count().Should().BeGreaterOrEqualTo(k{0}).And.ToString();",
222222
newAssertion: "actual.AsEnumerable().Should().HaveCountGreaterOrEqualTo(k{0}).And.ToString();")]
223223
[AssertionCodeFix(
224224
oldAssertion: "actual.AsEnumerable().Count().Should().BeGreaterOrEqualTo(6{0}).And.ToString();",
225225
newAssertion: "actual.AsEnumerable().Should().HaveCountGreaterOrEqualTo(6{0}).And.ToString();")]
226-
[Ignore("Will be available in Fluent Assertions 5.0")]
226+
[Implemented, Ignore("Will be available in Fluent Assertions 5.0")]
227227
public void CollectionShouldHaveCountGreaterOrEqualTo_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldHaveCountGreaterOrEqualToCodeFix, CollectionShouldHaveCountGreaterOrEqualToAnalyzer>(oldAssertion, newAssertion);
228228

229229
[AssertionDataTestMethod]
@@ -241,14 +241,13 @@ public class CollectionTests
241241
[AssertionCodeFix(
242242
oldAssertion: "actual.Count().Should().BeLessThan(6{0});",
243243
newAssertion: "actual.Should().HaveCountLessThan(6{0});")]
244-
[Implemented]
245244
[AssertionCodeFix(
246245
oldAssertion: "actual.AsEnumerable().Count().Should().BeLessThan(k{0}).And.ToString();",
247246
newAssertion: "actual.AsEnumerable().Should().HaveCountLessThan(k{0}).And.ToString();")]
248247
[AssertionCodeFix(
249248
oldAssertion: "actual.AsEnumerable().Count().Should().BeLessThan(6{0}).And.ToString();",
250249
newAssertion: "actual.AsEnumerable().Should().HaveCountLessThan(6{0}).And.ToString();")]
251-
[Ignore("Will be available in Fluent Assertions 5.0")]
250+
[Implemented, Ignore("Will be available in Fluent Assertions 5.0")]
252251
public void CollectionShouldHaveCountLessThan_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldHaveCountLessThanCodeFix, CollectionShouldHaveCountLessThanAnalyzer>(oldAssertion, newAssertion);
253252

254253
[AssertionDataTestMethod]
@@ -266,14 +265,13 @@ public class CollectionTests
266265
[AssertionCodeFix(
267266
oldAssertion: "actual.Count().Should().BeLessOrEqualTo(6{0});",
268267
newAssertion: "actual.Should().HaveCountLessOrEqualTo(6{0});")]
269-
[Implemented]
270268
[AssertionCodeFix(
271269
oldAssertion: "actual.AsEnumerable().Count().Should().BeLessOrEqualTo(k{0}).And.ToString();",
272270
newAssertion: "actual.AsEnumerable().Should().HaveCountLessOrEqualTo(k{0}).And.ToString();")]
273271
[AssertionCodeFix(
274272
oldAssertion: "actual.AsEnumerable().Count().Should().BeLessOrEqualTo(6{0}).And.ToString();",
275273
newAssertion: "actual.AsEnumerable().Should().HaveCountLessOrEqualTo(6{0}).And.ToString();")]
276-
[Ignore("Will be available in Fluent Assertions 5.0")]
274+
[Implemented, Ignore("Will be available in Fluent Assertions 5.0")]
277275
public void CollectionShouldHaveCountLessOrEqualTo_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldHaveCountLessOrEqualToCodeFix, CollectionShouldHaveCountLessOrEqualToAnalyzer>(oldAssertion, newAssertion);
278276

279277
[AssertionDataTestMethod]
@@ -291,14 +289,13 @@ public class CollectionTests
291289
[AssertionCodeFix(
292290
oldAssertion: "actual.Count().Should().NotBe(6{0});",
293291
newAssertion: "actual.Should().NotHaveCount(6{0});")]
294-
[Implemented]
295292
[AssertionCodeFix(
296293
oldAssertion: "actual.AsEnumerable().Count().Should().NotBe(k{0}).And.ToString();",
297294
newAssertion: "actual.AsEnumerable().Should().NotHaveCount(k{0}).And.ToString();")]
298295
[AssertionCodeFix(
299296
oldAssertion: "actual.AsEnumerable().Count().Should().NotBe(6{0}).And.ToString();",
300297
newAssertion: "actual.AsEnumerable().Should().NotHaveCount(6{0}).And.ToString();")]
301-
[Ignore("Will be available in Fluent Assertions 5.0")]
298+
[Implemented, Ignore("Will be available in Fluent Assertions 5.0")]
302299
public void CollectionShouldNotHaveCount_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldNotHaveCountCodeFix, CollectionShouldNotHaveCountAnalyzer>(oldAssertion, newAssertion);
303300

304301
[AssertionDataTestMethod]
@@ -327,11 +324,10 @@ public class CollectionTests
327324
[AssertionCodeFix(
328325
oldAssertion: "actual.Count().Should().NotBe(unexpected.Count(){0});",
329326
newAssertion: "actual.Should().NotHaveSameCount(unexpected{0});")]
330-
[Implemented]
331327
[AssertionCodeFix(
332328
oldAssertion: "actual.AsEnumerable().Count().Should().NotBe(unexpected.Count(){0}).And.ToString();",
333329
newAssertion: "actual.AsEnumerable().Should().NotHaveSameCount(unexpected{0}).And.ToString();")]
334-
[Ignore("Will be available in Fluent Assertions 5.0")]
330+
[Implemented, Ignore("Will be available in Fluent Assertions 5.0")]
335331
public void CollectionShouldNotHaveSameCount_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldNotHaveSameCountCodeFix, CollectionShouldNotHaveSameCountAnalyzer>(oldAssertion, newAssertion);
336332

337333
[AssertionDataTestMethod]
@@ -374,14 +370,22 @@ public class CollectionTests
374370
oldAssertion: "actual.Should().NotBeEmpty().And.NotBeNull({0});",
375371
newAssertion: "actual.Should().NotBeNullOrEmpty({0});")]
376372
[AssertionCodeFix(
377-
oldAssertion: "actual.AsEnumerable().Should().NotBeNull().And.NotBeEmpty({0}).And.ToString();",
378-
newAssertion: "actual.AsEnumerable().Should().NotBeNullOrEmpty({0}).And.ToString();")]
373+
oldAssertion: "actual.Should().NotBeNull({0}).And.NotBeEmpty();",
374+
newAssertion: "actual.Should().NotBeNullOrEmpty({0});")]
375+
[AssertionCodeFix(
376+
oldAssertion: "actual.Should().NotBeEmpty({0}).And.NotBeNull();",
377+
newAssertion: "actual.Should().NotBeNullOrEmpty({0});")]
378+
[AssertionCodeFix(
379+
oldAssertion: "actual.AsEnumerable().Should().NotBeNull().And.HaveCount(2).And.NotBeEmpty({0}).And.ToString();",
380+
newAssertion: "actual.AsEnumerable().Should().NotBeNullOrEmpty({0}).And.HaveCount(2).And.ToString();")]
379381
[AssertionCodeFix(
380-
oldAssertion: "actual.AsEnumerable().Should().NotBeEmpty().And.NotBeNull({0}).And.ToString();",
381-
newAssertion: "actual.AsEnumerable().Should().NotBeNullOrEmpty({0}).And.ToString();")]
382+
oldAssertion: "actual.AsEnumerable().Should().NotBeEmpty().And.HaveCount(2).And.NotBeNull({0}).And.ToString();",
383+
newAssertion: "actual.AsEnumerable().Should().NotBeNullOrEmpty({0}).And.HaveCount(2).And.ToString();")]
382384
[Implemented]
383385
public void CollectionShouldNotBeNullOrEmpty_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldNotBeNullOrEmptyCodeFix, CollectionShouldNotBeNullOrEmptyAnalyzer>(oldAssertion, newAssertion);
384386

387+
public void CollectionShouldNotBeNullOrEmptyMultipleReasons_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldNotBeNullOrEmptyCodeFix, CollectionShouldNotBeNullOrEmptyAnalyzer>(oldAssertion, newAssertion);
388+
385389
[AssertionDataTestMethod]
386390
[AssertionDiagnostic("actual.ElementAt(k).Should().Be(expectedItem{0});")]
387391
[AssertionDiagnostic("actual.ElementAt(6).Should().Be(expectedItem{0});")]
@@ -424,11 +428,11 @@ public class CollectionTests
424428
oldAssertion: "actual.AsEnumerable().ElementAt(6).Should().Be(expectedItem{0}).And.ToString();",
425429
newAssertion: "actual.AsEnumerable().Should().HaveElementAt(6, expectedItem{0}).And.ToString();")]
426430
[AssertionCodeFix(
427-
oldAssertion: "actual[k].Should().Be(expectedItem{0}).And.ToString();",
428-
newAssertion: "actual.AsEnumerable().Should().HaveElementAt(k, expectedItem{0}).And.ToString();")]
431+
oldAssertion: "actual.ToArray()[k].Should().Be(expectedItem{0}).And.ToString();",
432+
newAssertion: "actual.ToArray().Should().HaveElementAt(k, expectedItem{0}).And.ToString();")]
429433
[AssertionCodeFix(
430-
oldAssertion: "actual[6].Should().Be(expectedItem{0}).And.ToString();",
431-
newAssertion: "actual.AsEnumerable().Should().HaveElementAt(6, expectedItem{0}).And.ToString();")]
434+
oldAssertion: "actual.ToArray()[6].Should().Be(expectedItem{0}).And.ToString();",
435+
newAssertion: "actual.ToArray().Should().HaveElementAt(6, expectedItem{0}).And.ToString();")]
432436
[AssertionCodeFix(
433437
oldAssertion: "actual.AsEnumerable().Skip(k).First().Should().Be(expectedItem{0}).And.ToString();",
434438
newAssertion: "actual.AsEnumerable().Should().HaveElementAt(k, expectedItem{0}).And.ToString();")]
@@ -528,11 +532,10 @@ public class CollectionTests
528532
[AssertionCodeFix(
529533
oldAssertion: "actual.Select(x => x.BooleanProperty).Should().NotContainNulls({0});",
530534
newAssertion: "actual.Should().NotContainNulls(x => x.BooleanProperty{0});")]
531-
[Implemented]
532535
[AssertionCodeFix(
533536
oldAssertion: "actual.AsEnumerable().Select(x => x.BooleanProperty).Should().NotContainNulls({0}).And.ToString();",
534537
newAssertion: "actual.AsEnumerable().Should().NotContainNulls(x => x.BooleanProperty{0}).And.ToString();")]
535-
[Ignore("Will be available in Fluent Assertions 5.0")]
538+
[Implemented, Ignore("Will be available in Fluent Assertions 5.0")]
536539
public void CollectionShouldNotContainNulls_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldNotContainNullsCodeFix, CollectionShouldNotContainNullsAnalyzer>(oldAssertion, newAssertion);
537540

538541
[AssertionDataTestMethod]

src/FluentAssertions.BestPractices/Tips/Collections/CollectionShouldBeEmpty.cs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ public class CollectionShouldBeEmptyAnalyzer : FluentAssertionsAnalyzer
2727
}
2828
}
2929

30-
private class AnyShouldBeFalseSyntaxVisitor : FluentAssertionsWithoutLambdaArgumentCSharpSyntaxVisitor
30+
public class AnyShouldBeFalseSyntaxVisitor : FluentAssertionsWithoutLambdaArgumentCSharpSyntaxVisitor
3131
{
3232
protected override string MathodNotContainingLambda => "Any";
3333

3434
public AnyShouldBeFalseSyntaxVisitor() : base("Any", "Should", "BeFalse")
3535
{
3636
}
3737
}
38-
private class ShouldHaveCount0SyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
38+
public class ShouldHaveCount0SyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
3939
{
4040
private bool _haveCountMethodHas0Argument;
4141

@@ -62,8 +62,35 @@ node.Arguments[0].Expression is LiteralExpressionSyntax literal
6262
public class CollectionShouldBeEmptyCodeFix : FluentAssertionsCodeFixProvider
6363
{
6464
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(CollectionShouldBeEmptyAnalyzer.DiagnosticId);
65+
66+
protected override StatementSyntax GetNewStatement(ExpressionStatementSyntax statement, FluentAssertionsDiagnosticProperties properties)
67+
{
68+
switch (properties.VisitorName)
69+
{
70+
case nameof(CollectionShouldBeEmptyAnalyzer.AnyShouldBeFalseSyntaxVisitor):
71+
return GetNewStatement(statement, NodeReplacement.Remove("Any"), NodeReplacement.Rename("BeFalse", "BeEmpty"));
72+
case nameof(CollectionShouldBeEmptyAnalyzer.ShouldHaveCount0SyntaxVisitor):
73+
return GetNewStatement(statement, new HaveCountNodeReplacement());
74+
default:
75+
throw new System.InvalidOperationException($"Invalid visitor name - {properties.VisitorName}");
76+
}
77+
}
6578

66-
protected override StatementSyntax GetNewStatement(FluentAssertionsDiagnosticProperties properties)
67-
=> SyntaxFactory.ParseStatement($"{properties.VariableName}.Should().BeEmpty({properties.BecauseArgumentsString});");
79+
private class HaveCountNodeReplacement : NodeReplacement
80+
{
81+
public override bool IsValidNode(MemberAccessExpressionSyntax node) => node.Name.Identifier.Text == "HaveCount";
82+
public override SyntaxNode ComputeOld(LinkedListNode<MemberAccessExpressionSyntax> listNode) => listNode.Value.Parent;
83+
public override SyntaxNode ComputeNew(LinkedListNode<MemberAccessExpressionSyntax> listNode)
84+
{
85+
var invocation = (InvocationExpressionSyntax)listNode.Value.Parent;
86+
87+
invocation = invocation.ReplaceNode(listNode.Value, listNode.Value.WithName(SyntaxFactory.IdentifierName("BeEmpty")));
88+
89+
// remove the 0 argument
90+
var arguments = invocation.ArgumentList.Arguments.RemoveAt(0);
91+
92+
return invocation.WithArgumentList(invocation.ArgumentList.WithArguments(arguments));
93+
}
94+
}
6895
}
6996
}

src/FluentAssertions.BestPractices/Tips/Collections/CollectionShouldBeInAscendingOrder.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,15 @@ public override void VisitArgumentList(ArgumentListSyntax node)
5555
public class CollectionShouldBeInAscendingOrderCodeFix : FluentAssertionsCodeFixProvider
5656
{
5757
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(CollectionShouldBeInAscendingOrderAnalyzer.DiagnosticId);
58+
59+
protected override StatementSyntax GetNewStatement(ExpressionStatementSyntax statement, FluentAssertionsDiagnosticProperties properties)
60+
{
61+
var remove = NodeReplacement.RemoveAndExtractArguments("OrderBy");
62+
var newStatement = GetNewStatement(statement, remove);
63+
64+
newStatement = GetNewStatement(newStatement, NodeReplacement.RenameAndRemoveFirstArgument("Equal", "BeInAscendingOrder"));
5865

59-
protected override StatementSyntax GetNewStatement(FluentAssertionsDiagnosticProperties properties)
60-
=> SyntaxFactory.ParseStatement($"{properties.VariableName}.Should().BeInAscendingOrder({properties.CombineWithBecauseArgumentsString(properties.LambdaString)});");
66+
return GetNewStatement(newStatement, NodeReplacement.PrependArguments("BeInAscendingOrder", remove.Arguments));
67+
}
6168
}
6269
}

0 commit comments

Comments
 (0)