Skip to content

Commit 29457fb

Browse files
committed
{EnumerableAnalyzer} - added some FA 5.0 assertions
1 parent 90021b5 commit 29457fb

File tree

9 files changed

+73
-86
lines changed

9 files changed

+73
-86
lines changed

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,27 +136,35 @@ public class CollectionTests
136136

137137
[AssertionDataTestMethod]
138138
[AssertionDiagnostic("actual.Count().Should().BeGreaterOrEqualTo(k{0});")]
139-
[NotImplemented]
139+
[AssertionDiagnostic("actual.Count().Should().BeGreaterOrEqualTo(6{0});")]
140+
[Implemented]
140141
public void CollectionShouldHaveCountGreaterOrEqualTo_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<CollectionShouldHaveCountGreaterOrEqualToAnalyzer>(assertion);
141142

142143
[AssertionDataTestMethod]
143144
[AssertionCodeFix(
144145
oldAssertion: "actual.Count().Should().BeGreaterOrEqualTo(k{0});",
145146
newAssertion: "actual.Should().HaveCountGreaterOrEqualTo(k{0});")]
146-
[NotImplemented]
147+
[AssertionCodeFix(
148+
oldAssertion: "actual.Count().Should().BeGreaterOrEqualTo(6{0});",
149+
newAssertion: "actual.Should().HaveCountGreaterOrEqualTo(6{0});")]
150+
[Implemented]
147151
[Ignore("Waiting for official FluentAssertions 5.0")]
148152
public void CollectionShouldHaveCountGreaterOrEqualTo_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldHaveCountGreaterOrEqualToCodeFix, CollectionShouldHaveCountGreaterOrEqualToAnalyzer>(oldAssertion, newAssertion);
149153

150154
[AssertionDataTestMethod]
151155
[AssertionDiagnostic("actual.Count().Should().BeLessThan(k{0});")]
152-
[NotImplemented]
156+
[AssertionDiagnostic("actual.Count().Should().BeLessThan(6{0});")]
157+
[Implemented]
153158
public void CollectionShouldHaveCountLessThan_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<CollectionShouldHaveCountLessThanAnalyzer>(assertion);
154159

155160
[AssertionDataTestMethod]
156161
[AssertionCodeFix(
157162
oldAssertion: "actual.Count().Should().BeLessThan(k{0});",
158163
newAssertion: "actual.Should().HaveCountLessThan(k{0});")]
159-
[NotImplemented]
164+
[AssertionCodeFix(
165+
oldAssertion: "actual.Count().Should().BeLessThan(6{0});",
166+
newAssertion: "actual.Should().HaveCountLessThan(6{0});")]
167+
[Implemented]
160168
[Ignore("Waiting for official FluentAssertions 5.0")]
161169
public void CollectionShouldHaveCountLessThan_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldHaveCountLessThanCodeFix, CollectionShouldHaveCountLessThanAnalyzer>(oldAssertion, newAssertion);
162170

src/FluentAssertions.BestPractices/Constants.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public static class DiagnosticProperties
1010
public const string ExpectedItemString = nameof(ExpectedItemString);
1111
public const string UnexpectedItemString = nameof(UnexpectedItemString);
1212
public const string BecauseArgumentsString = nameof(BecauseArgumentsString);
13-
public const string CountArgument = nameof(CountArgument);
13+
public const string ArgumentString = nameof(ArgumentString);
1414
}
1515

1616
public static class Tips

src/FluentAssertions.BestPractices/FluentAssertions.BestPractices.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<metadata>
44
<id>FluentAssertions.BestPractices</id>
55
<title>Fluent Assertions Best Practice</title>
6-
<version>0.1.0</version>
6+
<version>0.1.1</version>
77
<owners>Meir Blachman</owners>
88
<authors>Meir Blachman</authors>
99
<summary>

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public CountShouldBeSyntaxVisitor() : base("Count", "Should", "Be")
3737
}
3838

3939
public override ImmutableDictionary<string, string> ToDiagnosticProperties()
40-
=> base.ToDiagnosticProperties().Add(Constants.DiagnosticProperties.CountArgument, CountArgument);
40+
=> base.ToDiagnosticProperties().Add(Constants.DiagnosticProperties.ArgumentString, CountArgument);
4141

4242
public override void VisitArgumentList(ArgumentListSyntax node)
4343
{
@@ -55,6 +55,6 @@ public class CollectionShouldHaveCountCodeFix : FluentAssertionsCodeFixProvider
5555
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(CollectionShouldHaveCountAnalyzer.DiagnosticId);
5656

5757
protected override StatementSyntax GetNewStatement(FluentAssertionsDiagnosticProperties properties)
58-
=> SyntaxFactory.ParseStatement($"{properties.VariableName}.Should().HaveCount({properties.CombineWithBecauseArgumentsString(properties.CountArgument)});");
58+
=> SyntaxFactory.ParseStatement($"{properties.VariableName}.Should().HaveCount({properties.CombineWithBecauseArgumentsString(properties.ArgumentString)});");
5959
}
6060
}
Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Microsoft.CodeAnalysis;
22
using Microsoft.CodeAnalysis.CodeFixes;
3+
using Microsoft.CodeAnalysis.CSharp;
34
using Microsoft.CodeAnalysis.CSharp.Syntax;
45
using Microsoft.CodeAnalysis.Diagnostics;
56
using System.Collections.Generic;
@@ -17,29 +18,20 @@ public class CollectionShouldHaveCountGreaterOrEqualToAnalyzer : FluentAssertion
1718
public const string Message = "Use {0} .Should() followed by ### instead.";
1819

1920
protected override DiagnosticDescriptor Rule => new DiagnosticDescriptor(DiagnosticId, Title, Message, Category, DiagnosticSeverity.Info, true);
20-
21-
protected override Diagnostic AnalyzeExpressionStatement(ExpressionStatementSyntax statement)
21+
protected override IEnumerable<(FluentAssertionsCSharpSyntaxVisitor, BecauseArgumentsSyntaxVisitor)> Visitors
2222
{
23-
return null;
24-
var visitor = new CollectionShouldHaveCountGreaterOrEqualToSyntaxVisitor();
25-
statement.Accept(visitor);
26-
27-
if (visitor.IsValid)
23+
get
2824
{
29-
var properties = new Dictionary<string, string>
30-
{
31-
[Constants.DiagnosticProperties.VariableName] = visitor.VariableName,
32-
[Constants.DiagnosticProperties.Title] = Title
33-
}.ToImmutableDictionary();
34-
throw new System.NotImplementedException();
25+
yield return (new CountShouldBeGreaterOrEqualToSyntaxVisitor(), new BecauseArgumentsSyntaxVisitor("BeGreaterOrEqualTo", 1));
26+
}
27+
}
3528

36-
return Diagnostic.Create(
37-
descriptor: Rule,
38-
location: statement.Expression.GetLocation(),
39-
properties: properties,
40-
messageArgs: visitor.VariableName);
29+
private class CountShouldBeGreaterOrEqualToSyntaxVisitor : FluentAssertionsWithArgumentCSharpSyntaxVisitor
30+
{
31+
protected override string MethodContainingArgument => "BeGreaterOrEqualTo";
32+
public CountShouldBeGreaterOrEqualToSyntaxVisitor() : base("Count", "Should", "BeGreaterOrEqualTo")
33+
{
4134
}
42-
return null;
4335
}
4436
}
4537

@@ -49,16 +41,6 @@ public class CollectionShouldHaveCountGreaterOrEqualToCodeFix : FluentAssertions
4941
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(CollectionShouldHaveCountGreaterOrEqualToAnalyzer.DiagnosticId);
5042

5143
protected override StatementSyntax GetNewStatement(FluentAssertionsDiagnosticProperties properties)
52-
{
53-
throw new System.NotImplementedException();
54-
}
55-
}
56-
57-
public class CollectionShouldHaveCountGreaterOrEqualToSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
58-
{
59-
public CollectionShouldHaveCountGreaterOrEqualToSyntaxVisitor() : base("###")
60-
{
61-
throw new System.NotImplementedException();
62-
}
44+
=> SyntaxFactory.ParseStatement($"{properties.VariableName}.Should().HaveCountGreaterOrEqualTo({properties.CombineWithBecauseArgumentsString(properties.ArgumentString)});");
6345
}
6446
}

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

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,13 @@ public class CollectionShouldHaveCountGreaterThanAnalyzer : FluentAssertionsAnal
2626
}
2727
}
2828

29-
private class CountShouldBeGreaterThanSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
29+
private class CountShouldBeGreaterThanSyntaxVisitor : FluentAssertionsWithArgumentCSharpSyntaxVisitor
3030
{
31-
public string CountArgument { get; private set; }
32-
33-
public override bool IsValid => base.IsValid && CountArgument != null;
31+
protected override string MethodContainingArgument => "BeGreaterThan";
3432

3533
public CountShouldBeGreaterThanSyntaxVisitor() : base("Count", "Should", "BeGreaterThan")
3634
{
3735
}
38-
39-
public override ImmutableDictionary<string, string> ToDiagnosticProperties()
40-
=> base.ToDiagnosticProperties().Add(Constants.DiagnosticProperties.CountArgument, CountArgument);
41-
42-
public override void VisitArgumentList(ArgumentListSyntax node)
43-
{
44-
if (!node.Arguments.Any()) return;
45-
if (CurrentMethod != "BeGreaterThan") return;
46-
47-
CountArgument = node.Arguments[0].ToFullString();
48-
}
4936
}
5037
}
5138

@@ -55,6 +42,6 @@ public class CollectionShouldHaveCountGreaterThanCodeFix : FluentAssertionsCodeF
5542
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(CollectionShouldHaveCountGreaterThanAnalyzer.DiagnosticId);
5643

5744
protected override StatementSyntax GetNewStatement(FluentAssertionsDiagnosticProperties properties)
58-
=> SyntaxFactory.ParseStatement($"{properties.VariableName}.Should().HaveCountGreaterThan({properties.CombineWithBecauseArgumentsString(properties.CountArgument)});");
45+
=> SyntaxFactory.ParseStatement($"{properties.VariableName}.Should().HaveCountGreaterThan({properties.CombineWithBecauseArgumentsString(properties.ArgumentString)});");
5946
}
6047
}
Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Microsoft.CodeAnalysis;
22
using Microsoft.CodeAnalysis.CodeFixes;
3+
using Microsoft.CodeAnalysis.CSharp;
34
using Microsoft.CodeAnalysis.CSharp.Syntax;
45
using Microsoft.CodeAnalysis.Diagnostics;
56
using System.Collections.Generic;
@@ -14,32 +15,23 @@ public class CollectionShouldHaveCountLessThanAnalyzer : FluentAssertionsAnalyze
1415
public const string DiagnosticId = Constants.Tips.Collections.CollectionShouldHaveCountLessThan;
1516
public const string Category = Constants.Tips.Category;
1617

17-
public const string Message = "Use {0} .Should() followed by ### instead.";
18+
public const string Message = "Use {0} .Should() followed by HaveCountLessThan() instead.";
1819

1920
protected override DiagnosticDescriptor Rule => new DiagnosticDescriptor(DiagnosticId, Title, Message, Category, DiagnosticSeverity.Info, true);
20-
21-
protected override Diagnostic AnalyzeExpressionStatement(ExpressionStatementSyntax statement)
21+
protected override IEnumerable<(FluentAssertionsCSharpSyntaxVisitor, BecauseArgumentsSyntaxVisitor)> Visitors
2222
{
23-
return null;
24-
var visitor = new CollectionShouldHaveCountLessThanSyntaxVisitor();
25-
statement.Accept(visitor);
26-
27-
if (visitor.IsValid)
23+
get
2824
{
29-
var properties = new Dictionary<string, string>
30-
{
31-
[Constants.DiagnosticProperties.VariableName] = visitor.VariableName,
32-
[Constants.DiagnosticProperties.Title] = Title
33-
}.ToImmutableDictionary();
34-
throw new System.NotImplementedException();
25+
yield return (new CountShouldBeLessThanSyntaxVisitor(), new BecauseArgumentsSyntaxVisitor("BeLessThan", 1));
26+
}
27+
}
3528

36-
return Diagnostic.Create(
37-
descriptor: Rule,
38-
location: statement.Expression.GetLocation(),
39-
properties: properties,
40-
messageArgs: visitor.VariableName);
29+
private class CountShouldBeLessThanSyntaxVisitor : FluentAssertionsWithArgumentCSharpSyntaxVisitor
30+
{
31+
protected override string MethodContainingArgument => "BeLessThan";
32+
public CountShouldBeLessThanSyntaxVisitor() : base("Count", "Should", "BeLessThan")
33+
{
4134
}
42-
return null;
4335
}
4436
}
4537

@@ -49,16 +41,6 @@ public class CollectionShouldHaveCountLessThanCodeFix : FluentAssertionsCodeFixP
4941
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(CollectionShouldHaveCountLessThanAnalyzer.DiagnosticId);
5042

5143
protected override StatementSyntax GetNewStatement(FluentAssertionsDiagnosticProperties properties)
52-
{
53-
throw new System.NotImplementedException();
54-
}
55-
}
56-
57-
public class CollectionShouldHaveCountLessThanSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
58-
{
59-
public CollectionShouldHaveCountLessThanSyntaxVisitor() : base("###")
60-
{
61-
throw new System.NotImplementedException();
62-
}
44+
=> SyntaxFactory.ParseStatement($"{properties.VariableName}.Should().HaveCountLessThan({properties.CombineWithBecauseArgumentsString(properties.ArgumentString)});");
6345
}
6446
}

src/FluentAssertions.BestPractices/Utilities/FluentAssertionsDiagnosticProperties.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public FluentAssertionsDiagnosticProperties(ImmutableDictionary<string, string>
1818
public string PredicateString => Properties[Constants.DiagnosticProperties.PredicateString];
1919
public string ExpectedItemString => Properties[Constants.DiagnosticProperties.ExpectedItemString];
2020
public string UnexpectedItemString => Properties[Constants.DiagnosticProperties.UnexpectedItemString];
21-
public string CountArgument => Properties[Constants.DiagnosticProperties.CountArgument];
21+
public string ArgumentString => Properties[Constants.DiagnosticProperties.ArgumentString];
2222

2323
public string CombineWithBecauseArgumentsString(string validArgument)
2424
{
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System.Collections.Immutable;
2+
using Microsoft.CodeAnalysis.CSharp.Syntax;
3+
4+
namespace FluentAssertions.BestPractices
5+
{
6+
public abstract class FluentAssertionsWithArgumentCSharpSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
7+
{
8+
protected abstract string MethodContainingArgument { get; }
9+
protected string ArgumentString { get; private set; }
10+
11+
protected FluentAssertionsWithArgumentCSharpSyntaxVisitor(params string[] requiredMethods) : base(requiredMethods)
12+
{
13+
}
14+
15+
public override ImmutableDictionary<string, string> ToDiagnosticProperties()
16+
=> base.ToDiagnosticProperties().Add(Constants.DiagnosticProperties.ArgumentString, ArgumentString);
17+
18+
public override bool IsValid => base.IsValid && ArgumentString != null;
19+
20+
public override void VisitArgumentList(ArgumentListSyntax node)
21+
{
22+
if (!node.Arguments.Any()) return;
23+
if (CurrentMethod != MethodContainingArgument) return;
24+
25+
ArgumentString = node.Arguments[0].ToFullString();
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)