Skip to content

Commit e5691f7

Browse files
committed
{EnumerableAnalyzer} - added more assertions
1 parent 29457fb commit e5691f7

File tree

10 files changed

+111
-158
lines changed

10 files changed

+111
-158
lines changed

build.cake

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@ var version = GetCurrentVersion(Context);
2222
// TASKS
2323
//////////////////////////////////////////////////////////////////////
2424

25-
Task("GitVersion")
25+
Task("Update-Version")
2626
.WithCriteria(AppVeyor.IsRunningOnAppVeyor)
2727
.Does(() =>
2828
{
29-
var gitVersion = GitVersion();
30-
version += $"-preview{gitVersion.BuildMetaData}";
29+
version += $"-preview{AppVeyor.Environment.Build.Number}";
3130

3231
Information($"Version: {version}");
3332
});
@@ -78,21 +77,15 @@ Task("Pack")
7877
NuGetPack(nuspecFile, nuGetPackSettings);
7978
});
8079

81-
Task("Publish-Nuget")
80+
Task("Publish-NuGet")
8281
.WithCriteria(AppVeyor.IsRunningOnAppVeyor)
82+
.WithCriteria(HasEnvironmentVariable("NUGET_API_KEY"))
83+
.WithCriteria(HasEnvironmentVariable("NUGET_API_URL"))
8384
.Does(() =>
8485
{
8586
var apiKey = EnvironmentVariable("NUGET_API_KEY");
86-
if(string.IsNullOrEmpty(apiKey))
87-
{
88-
throw new InvalidOperationException("Could not resolve NuGet API key.");
89-
}
9087
var apiUrl = EnvironmentVariable("NUGET_API_URL");
91-
if(string.IsNullOrEmpty(apiUrl))
92-
{
93-
throw new InvalidOperationException("Could not resolve NuGet API url.");
94-
}
95-
88+
9689
var nupkgFile = File($"{buildDir}/FluentAssertions.BestPractices.{version}.nupkg");
9790
Information($"Publishing nupkg file '{nupkgFile}'...");
9891

@@ -108,11 +101,11 @@ Task("Publish-Nuget")
108101
//////////////////////////////////////////////////////////////////////
109102

110103
Task("Default")
111-
.IsDependentOn("GitVersion")
104+
.IsDependentOn("Update-Version")
112105
.IsDependentOn("Build")
113106
.IsDependentOn("Run-Unit-Tests")
114107
.IsDependentOn("Pack")
115-
.IsDependentOn("Publish-Nuget");
108+
.IsDependentOn("Publish-NuGet");
116109

117110
//////////////////////////////////////////////////////////////////////
118111
// EXECUTION

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

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public class CollectionTests
131131
oldAssertion: "actual.Count().Should().BeGreaterThan(6{0});",
132132
newAssertion: "actual.Should().HaveCountGreaterThan(6{0});")]
133133
[Implemented]
134-
[Ignore("Waiting for official FluentAssertions 5.0")]
134+
[Ignore("Will be available in Fluent Assertions 5.0")]
135135
public void CollectionShouldHaveCountGreaterThan_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldHaveCountGreaterThanCodeFix, CollectionShouldHaveCountGreaterThanAnalyzer>(oldAssertion, newAssertion);
136136

137137
[AssertionDataTestMethod]
@@ -148,7 +148,7 @@ public class CollectionTests
148148
oldAssertion: "actual.Count().Should().BeGreaterOrEqualTo(6{0});",
149149
newAssertion: "actual.Should().HaveCountGreaterOrEqualTo(6{0});")]
150150
[Implemented]
151-
[Ignore("Waiting for official FluentAssertions 5.0")]
151+
[Ignore("Will be available in Fluent Assertions 5.0")]
152152
public void CollectionShouldHaveCountGreaterOrEqualTo_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldHaveCountGreaterOrEqualToCodeFix, CollectionShouldHaveCountGreaterOrEqualToAnalyzer>(oldAssertion, newAssertion);
153153

154154
[AssertionDataTestMethod]
@@ -165,54 +165,64 @@ public class CollectionTests
165165
oldAssertion: "actual.Count().Should().BeLessThan(6{0});",
166166
newAssertion: "actual.Should().HaveCountLessThan(6{0});")]
167167
[Implemented]
168-
[Ignore("Waiting for official FluentAssertions 5.0")]
168+
[Ignore("Will be available in Fluent Assertions 5.0")]
169169
public void CollectionShouldHaveCountLessThan_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldHaveCountLessThanCodeFix, CollectionShouldHaveCountLessThanAnalyzer>(oldAssertion, newAssertion);
170170

171171
[AssertionDataTestMethod]
172172
[AssertionDiagnostic("actual.Count().Should().BeLessOrEqualTo(k{0});")]
173-
[NotImplemented]
173+
[AssertionDiagnostic("actual.Count().Should().BeLessOrEqualTo(6{0});")]
174+
[Implemented]
174175
public void CollectionShouldHaveCountLessOrEqualTo_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<CollectionShouldHaveCountLessOrEqualToAnalyzer>(assertion);
175176

176177
[AssertionDataTestMethod]
177178
[AssertionCodeFix(
178179
oldAssertion: "actual.Count().Should().BeLessOrEqualTo(k{0});",
179180
newAssertion: "actual.Should().HaveCountLessOrEqualTo(k{0});")]
180-
[NotImplemented]
181+
[AssertionCodeFix(
182+
oldAssertion: "actual.Count().Should().BeLessOrEqualTo(6{0});",
183+
newAssertion: "actual.Should().HaveCountLessOrEqualTo(6{0});")]
184+
[Implemented]
185+
[Ignore("Will be available in Fluent Assertions 5.0")]
181186
public void CollectionShouldHaveCountLessOrEqualTo_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldHaveCountLessOrEqualToCodeFix, CollectionShouldHaveCountLessOrEqualToAnalyzer>(oldAssertion, newAssertion);
182187

183188
[AssertionDataTestMethod]
184189
[AssertionDiagnostic("actual.Count().Should().NotBe(k{0});")]
185-
[NotImplemented]
190+
[AssertionDiagnostic("actual.Count().Should().NotBe(6{0});")]
191+
[Implemented]
186192
public void CollectionShouldNotHaveCount_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<CollectionShouldNotHaveCountAnalyzer>(assertion);
187193

188194
[AssertionDataTestMethod]
189195
[AssertionCodeFix(
190196
oldAssertion: "actual.Count().Should().NotBe(k{0});",
191197
newAssertion: "actual.Should().NotHaveCount(k{0});")]
192-
[NotImplemented]
198+
[AssertionCodeFix(
199+
oldAssertion: "actual.Count().Should().NotBe(6{0});",
200+
newAssertion: "actual.Should().NotHaveCount(6{0});")]
201+
[Implemented]
202+
[Ignore("Will be available in Fluent Assertions 5.0")]
193203
public void CollectionShouldNotHaveCount_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldNotHaveCountCodeFix, CollectionShouldNotHaveCountAnalyzer>(oldAssertion, newAssertion);
194204

195205
[AssertionDataTestMethod]
196206
[AssertionDiagnostic("actual.Should().HaveCount(1{0});")]
197-
[NotImplemented]
207+
[Implemented]
198208
public void CollectionShouldContainSingle_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<CollectionShouldContainSingleAnalyzer>(assertion);
199209

200210
[AssertionDataTestMethod]
201211
[AssertionCodeFix(oldAssertion: "actual.Should().HaveCount(1{0});",
202212
newAssertion: "actual.Should().ContainSingle({0});")]
203-
[NotImplemented]
213+
[Implemented]
204214
public void CollectionShouldContainSingle_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldContainSingleCodeFix, CollectionShouldContainSingleAnalyzer>(oldAssertion, newAssertion);
205215

206216
[AssertionDataTestMethod]
207217
[AssertionDiagnostic("actual.Should().HaveCount(expected.Count(){0});")]
208-
[NotImplemented]
218+
[Implemented]
209219
public void CollectionShouldHaveSameCount_TestAnalyzer(string assertion) => VerifyCSharpDiagnostic<CollectionShouldHaveSameCountAnalyzer>(assertion);
210220

211221
[AssertionDataTestMethod]
212222
[AssertionCodeFix(
213223
oldAssertion: "actual.Should().HaveCount(expected.Count(){0});",
214224
newAssertion: "actual.Should().HaveSameCount(expected{0});")]
215-
[NotImplemented]
225+
[Implemented]
216226
public void CollectionShouldHaveSameCount_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFix<CollectionShouldHaveSameCountCodeFix, CollectionShouldHaveSameCountAnalyzer>(oldAssertion, newAssertion);
217227

218228
[AssertionDataTestMethod]

src/FluentAssertions.BestPractices.sln

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionIt
1515
..\comparable.yml = ..\comparable.yml
1616
..\dictionaries.yml = ..\dictionaries.yml
1717
..\exceptions.yml = ..\exceptions.yml
18-
FluentAssertions.BestPractices.nuspec = FluentAssertions.BestPractices.nuspec
1918
..\LICENSE = ..\LICENSE
2019
..\nullables.yml = ..\nullables.yml
2120
..\README.md = ..\README.md

src/FluentAssertions.BestPractices/FluentAssertions.BestPractices.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>netstandard1.3</TargetFramework>
5-
<RootNamespace>FluentAssertions.BestPractices</RootNamespace>
5+
<RootNamespace>FluentAssertions.BestPractices</RootNamespace>
66
</PropertyGroup>
77

88
<ItemGroup>
@@ -22,9 +22,9 @@
2222
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
2323
</None>
2424
</ItemGroup>
25-
25+
2626
<PropertyGroup>
2727
<NuspecFile>.\FluentAssertions.BestPractices</NuspecFile>
2828
</PropertyGroup>
29-
29+
3030
</Project>

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.1</version>
6+
<version>0.2.0</version>
77
<owners>Meir Blachman</owners>
88
<authors>Meir Blachman</authors>
99
<summary>
Lines changed: 24 additions & 29 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,36 @@ public class CollectionShouldContainSingleAnalyzer : FluentAssertionsAnalyzer
1415
public const string DiagnosticId = Constants.Tips.Collections.CollectionShouldContainSingle;
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 ContainSingle() instead.";
1819

1920
protected override DiagnosticDescriptor Rule => new DiagnosticDescriptor(DiagnosticId, Title, Message, Category, DiagnosticSeverity.Info, true);
21+
protected override IEnumerable<(FluentAssertionsCSharpSyntaxVisitor, BecauseArgumentsSyntaxVisitor)> Visitors {
22+
get
23+
{
24+
yield return (new ShouldHaveCount1SyntaxVisitor(), new BecauseArgumentsSyntaxVisitor("HaveCount", 1));
25+
}
26+
}
2027

21-
protected override Diagnostic AnalyzeExpressionStatement(ExpressionStatementSyntax statement)
28+
private class ShouldHaveCount1SyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
2229
{
23-
return null;
24-
var visitor = new CollectionShouldContainSingleSyntaxVisitor();
25-
statement.Accept(visitor);
30+
private bool _haveCountMethodHas0Argument;
31+
32+
public override bool IsValid => base.IsValid && _haveCountMethodHas0Argument;
33+
34+
public ShouldHaveCount1SyntaxVisitor() : base("Should", "HaveCount")
35+
{
36+
}
2637

27-
if (visitor.IsValid)
38+
public override void VisitArgumentList(ArgumentListSyntax node)
2839
{
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();
40+
if (!node.Arguments.Any()) return;
41+
if (CurrentMethod != "HaveCount") return;
3542

36-
return Diagnostic.Create(
37-
descriptor: Rule,
38-
location: statement.Expression.GetLocation(),
39-
properties: properties,
40-
messageArgs: visitor.VariableName);
43+
_haveCountMethodHas0Argument =
44+
node.Arguments[0].Expression is LiteralExpressionSyntax literal
45+
&& literal.Token.Value is int argument
46+
&& argument == 1;
4147
}
42-
return null;
4348
}
4449
}
4550

@@ -49,16 +54,6 @@ public class CollectionShouldContainSingleCodeFix : FluentAssertionsCodeFixProvi
4954
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(CollectionShouldContainSingleAnalyzer.DiagnosticId);
5055

5156
protected override StatementSyntax GetNewStatement(FluentAssertionsDiagnosticProperties properties)
52-
{
53-
throw new System.NotImplementedException();
54-
}
55-
}
56-
57-
public class CollectionShouldContainSingleSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
58-
{
59-
public CollectionShouldContainSingleSyntaxVisitor() : base("###")
60-
{
61-
throw new System.NotImplementedException();
62-
}
57+
=> SyntaxFactory.ParseStatement($"{properties.VariableName}.Should().ContainSingle({properties.BecauseArgumentsString});");
6358
}
6459
}
Lines changed: 14 additions & 32 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 CollectionShouldHaveCountLessOrEqualToAnalyzer : FluentAssertionsAn
1415
public const string DiagnosticId = Constants.Tips.Collections.CollectionShouldHaveCountLessOrEqualTo;
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 HaveCountLessOrEqualTo instead.";
1819

1920
protected override DiagnosticDescriptor Rule => new DiagnosticDescriptor(DiagnosticId, Title, Message, Category, DiagnosticSeverity.Info, true);
2021

21-
protected override Diagnostic AnalyzeExpressionStatement(ExpressionStatementSyntax statement)
22+
protected override IEnumerable<(FluentAssertionsCSharpSyntaxVisitor, BecauseArgumentsSyntaxVisitor)> Visitors
2223
{
23-
return null;
24-
var visitor = new CollectionShouldHaveCountLessOrEqualToSyntaxVisitor();
25-
statement.Accept(visitor);
26-
27-
if (visitor.IsValid)
24+
get
25+
{
26+
yield return (new CountShouldBeLessOrEqualToSyntaxVisitor(), new BecauseArgumentsSyntaxVisitor("BeLessOrEqualTo", 1));
27+
}
28+
}
29+
private class CountShouldBeLessOrEqualToSyntaxVisitor : FluentAssertionsWithArgumentCSharpSyntaxVisitor
30+
{
31+
protected override string MethodContainingArgument => "BeLessOrEqualTo";
32+
public CountShouldBeLessOrEqualToSyntaxVisitor() : base("Count", "Should", "BeLessOrEqualTo")
2833
{
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();
35-
36-
return Diagnostic.Create(
37-
descriptor: Rule,
38-
location: statement.Expression.GetLocation(),
39-
properties: properties,
40-
messageArgs: visitor.VariableName);
4134
}
42-
return null;
4335
}
4436
}
4537

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

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

0 commit comments

Comments
 (0)