Skip to content

Commit 611cf40

Browse files
committed
bugfix: improve CollectionShouldHaveCountGreaterOrEqualTo_CountShouldBeGreaterOrEqualTo detection
1 parent 7407627 commit 611cf40

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,18 +451,44 @@ public void CollectionShouldHaveCount_LengthShouldBe_TestNoAnalyzer(string asser
451451
[DataTestMethod]
452452
[AssertionDiagnostic("actual.Count().Should().BeGreaterOrEqualTo(k{0});")]
453453
[AssertionDiagnostic("actual.Count().Should().BeGreaterOrEqualTo(6{0});")]
454+
[AssertionDiagnostic("actual.Count.Should().BeGreaterOrEqualTo(k{0});")]
455+
[AssertionDiagnostic("actual.Count.Should().BeGreaterOrEqualTo(6{0});")]
456+
[AssertionDiagnostic("actual.ToArray().Length.Should().BeGreaterOrEqualTo(k{0});")]
457+
[AssertionDiagnostic("actual.ToArray().Length.Should().BeGreaterOrEqualTo(6{0});")]
454458
[AssertionDiagnostic("actual.AsEnumerable().Count().Should().BeGreaterOrEqualTo(k{0}).And.ToString();")]
455459
[AssertionDiagnostic("actual.AsEnumerable().Count().Should().BeGreaterOrEqualTo(6{0}).And.ToString();")]
456460
[Implemented]
457461
public void CollectionShouldHaveCountGreaterOrEqualTo_TestAnalyzer(string assertion) => VerifyCSharpDiagnosticCodeBlock(assertion, DiagnosticMetadata.CollectionShouldHaveCountGreaterOrEqualTo_CountShouldBeGreaterOrEqualTo);
458462

463+
[DataTestMethod]
464+
[AssertionDiagnostic("(actual.Count() + 1).Should().BeGreaterOrEqualTo(k{0});")]
465+
[AssertionDiagnostic("(actual.Count() + 1).Should().BeGreaterOrEqualTo(6{0});")]
466+
[AssertionDiagnostic("(actual.Count + 1).Should().BeGreaterOrEqualTo(k{0});")]
467+
[AssertionDiagnostic("(actual.Count + 1).Should().BeGreaterOrEqualTo(6{0});")]
468+
[AssertionDiagnostic("(actual.ToArray().Length + 1).Should().BeGreaterOrEqualTo(k{0});")]
469+
[AssertionDiagnostic("(actual.ToArray().Length + 1).Should().BeGreaterOrEqualTo(6{0});")]
470+
[Implemented]
471+
public void CollectionShouldHaveCountGreaterOrEqualTo_TestNoAnalyzer(string assertion) => DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(GenerateCode.GenericIListCodeBlockAssertion(assertion));
472+
459473
[DataTestMethod]
460474
[AssertionCodeFix(
461475
oldAssertion: "actual.Count().Should().BeGreaterOrEqualTo(k{0});",
462476
newAssertion: "actual.Should().HaveCountGreaterOrEqualTo(k{0});")]
463477
[AssertionCodeFix(
464478
oldAssertion: "actual.Count().Should().BeGreaterOrEqualTo(6{0});",
465479
newAssertion: "actual.Should().HaveCountGreaterOrEqualTo(6{0});")]
480+
[AssertionCodeFix(
481+
oldAssertion: "actual.Count.Should().BeGreaterOrEqualTo(k{0});",
482+
newAssertion: "actual.Should().HaveCountGreaterOrEqualTo(k{0});")]
483+
[AssertionCodeFix(
484+
oldAssertion: "actual.Count.Should().BeGreaterOrEqualTo(6{0});",
485+
newAssertion: "actual.Should().HaveCountGreaterOrEqualTo(6{0});")]
486+
[AssertionCodeFix(
487+
oldAssertion: "actual.ToArray().Length.Should().BeGreaterOrEqualTo(k{0});",
488+
newAssertion: "actual.ToArray().Should().HaveCountGreaterOrEqualTo(k{0});")]
489+
[AssertionCodeFix(
490+
oldAssertion: "actual.ToArray().Length.Should().BeGreaterOrEqualTo(6{0});",
491+
newAssertion: "actual.ToArray().Should().HaveCountGreaterOrEqualTo(6{0});")]
466492
[AssertionCodeFix(
467493
oldAssertion: "actual.AsEnumerable().Count().Should().BeGreaterOrEqualTo(k{0}).And.ToString();",
468494
newAssertion: "actual.AsEnumerable().Should().HaveCountGreaterOrEqualTo(k{0}).And.ToString();")]

src/FluentAssertions.Analyzers/Tips/FluentAssertionsAnalyzer.Utils.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ public FluentAssertionsMetadata(Compilation compilation)
7272
IReadonlyDictionaryOfT2 = compilation.GetTypeByMetadataName(typeof(IReadOnlyDictionary<,>).FullName);
7373
IListOfT = compilation.GetTypeByMetadataName(typeof(IList<>).FullName);
7474
IReadonlyListOfT = compilation.GetTypeByMetadataName(typeof(IReadOnlyList<>).FullName);
75+
ICollectionOfT = compilation.GetTypeByMetadataName(typeof(ICollection<>).FullName);
76+
IReadonlyCollectionOfT = compilation.GetTypeByMetadataName(typeof(IReadOnlyCollection<>).FullName);
7577
Enumerable = compilation.GetTypeByMetadataName(typeof(Enumerable).FullName);
7678
IEnumerable = compilation.GetTypeByMetadataName(typeof(IEnumerable).FullName);
7779
Math = compilation.GetTypeByMetadataName(typeof(Math).FullName);
@@ -91,6 +93,8 @@ public FluentAssertionsMetadata(Compilation compilation)
9193
public INamedTypeSymbol IReadonlyDictionaryOfT2 { get; }
9294
public INamedTypeSymbol IListOfT { get; }
9395
public INamedTypeSymbol IReadonlyListOfT { get; }
96+
public INamedTypeSymbol ICollectionOfT { get; }
97+
public INamedTypeSymbol IReadonlyCollectionOfT { get; }
9498
public INamedTypeSymbol BooleanAssertionsOfT1 { get; }
9599
public INamedTypeSymbol NumericAssertionsOfT2 { get; }
96100
public INamedTypeSymbol Enumerable { get; }

src/FluentAssertions.Analyzers/Tips/FluentAssertionsAnalyzer.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ private static void AnalyzeInvocation(OperationAnalysisContext context, FluentAs
423423
return;
424424
case "BeGreaterOrEqualTo" when assertion.IsContainedInType(metadata.NumericAssertionsOfT2):
425425
{
426-
if (invocation.TryGetFirstDescendent<IInvocationOperation>(out var invocationBeforeShould))
426+
if (invocation.TryGetSingleArgumentAs<IInvocationOperation>(out var invocationBeforeShould))
427427
{
428428
switch (invocationBeforeShould.TargetMethod.Name)
429429
{
@@ -434,6 +434,17 @@ private static void AnalyzeInvocation(OperationAnalysisContext context, FluentAs
434434
}
435435
}
436436

437+
if (invocation.TryGetSingleArgumentAs<IPropertyReferenceOperation>(out var propertyBeforeShould))
438+
{
439+
switch (propertyBeforeShould.Property.Name)
440+
{
441+
case nameof(Array.Length) when propertyBeforeShould.IsContainedInType(SpecialType.System_Array):
442+
case nameof(List<object>.Count) when propertyBeforeShould.ImplementsOrIsInterface(SpecialType.System_Collections_Generic_ICollection_T):
443+
context.ReportDiagnostic(CreateDiagnostic(assertion, DiagnosticMetadata.CollectionShouldHaveCountGreaterOrEqualTo_CountShouldBeGreaterOrEqualTo));
444+
return;
445+
}
446+
}
447+
437448
if (assertion.TryGetChainedInvocationAfterAndConstraint("BeLessOrEqualTo", out var chainedInvocation))
438449
{
439450
if (!assertion.HasEmptyBecauseAndReasonArgs(startingIndex: 1) && !chainedInvocation.HasEmptyBecauseAndReasonArgs(startingIndex: 1)) return;

0 commit comments

Comments
 (0)