Skip to content

Commit 70324b5

Browse files
authored
bugfix: improve CollectionShouldHaveElementAt_IndexerShouldBe detection (#390)
1 parent 8c1b012 commit 70324b5

File tree

4 files changed

+13
-1
lines changed

4 files changed

+13
-1
lines changed

src/FluentAssertions.Analyzers.TestUtils/GenerateCode.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ public static string GenericIListExpressionBodyAssertion(string assertion) => Ge
5555
.AppendLine(" {")
5656
.AppendLine(" public bool BooleanProperty { get; set; }")
5757
.AppendLine(" public string Message { get; set; }")
58+
.AppendLine(" public TestComplexClass this[int index] => throw new NotImplementedException();")
5859
.AppendLine(" }")
60+
.AppendLine()
5961
.AppendLine("}")
6062
.ToString();
6163

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ public void CollectionShouldContainSingle_TestAnalyzer_GenericIEnumerableShouldR
773773
[AssertionDiagnostic("actual.ElementAt(k).BooleanProperty.Should().Be(expectedItem.BooleanProperty{0});")]
774774
[AssertionDiagnostic("actual.ElementAt(6).BooleanProperty.Should().Be(expectedItem.BooleanProperty{0});")]
775775
[AssertionDiagnostic("actual.AsEnumerable().ElementAt(k).BooleanProperty.Should().Be(expectedItem.BooleanProperty{0}).And.ToString();")]
776-
[AssertionDiagnostic("actual.AsEnumerable().ElementAt(6).BooleanProperty.Should().Be(expectedItem.BooleanProperty{0}).And.ToString();")]
776+
[AssertionDiagnostic("actual.AsEnumerable().ElementAt(6).BooleanProperty.Should().Be(expectedItem.BooleanProperty{0}).And.ToString();")]
777777
[Implemented]
778778
public void CollectionShouldHaveElementAt_ElementAtIndexShouldBe_TestNoAnalyzer(string assertion) => DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(GenerateCode.GenericIListCodeBlockAssertion(assertion));
779779

@@ -793,6 +793,11 @@ public void CollectionShouldContainSingle_TestAnalyzer_GenericIEnumerableShouldR
793793
[Implemented]
794794
public void CollectionShouldHaveElementAt_IndexerShouldBe_TestAnalyzer(string assertion) => VerifyCSharpDiagnosticCodeBlock(assertion, DiagnosticMetadata.CollectionShouldHaveElementAt_IndexerShouldBe);
795795

796+
[DataTestMethod]
797+
[AssertionDiagnostic("var first = actual[0]; first[6].Should().Be(expectedItem{0});")]
798+
[Implemented]
799+
public void CollectionShouldHaveElementAt_IndexerShouldBe_TestNoAnalyzer(string assertion) => DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(GenerateCode.GenericIListCodeBlockAssertion(assertion));
800+
796801
[DataTestMethod]
797802
[AssertionDiagnostic("actual.Skip(k).First().Should().Be(expectedItem{0});")]
798803
[AssertionDiagnostic("actual.Skip(6).First().Should().Be(expectedItem{0});")]

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ public FluentAssertionsMetadata(Compilation compilation)
7070
IDictionaryOfT2 = compilation.GetTypeByMetadataName(typeof(IDictionary<,>).FullName);
7171
DictionaryOfT2 = compilation.GetTypeByMetadataName(typeof(Dictionary<,>).FullName);
7272
IReadonlyDictionaryOfT2 = compilation.GetTypeByMetadataName(typeof(IReadOnlyDictionary<,>).FullName);
73+
IListOfT = compilation.GetTypeByMetadataName(typeof(IList<>).FullName);
74+
IReadonlyListOfT = compilation.GetTypeByMetadataName(typeof(IReadOnlyList<>).FullName);
7375
Enumerable = compilation.GetTypeByMetadataName(typeof(Enumerable).FullName);
7476
IEnumerable = compilation.GetTypeByMetadataName(typeof(IEnumerable).FullName);
7577
Math = compilation.GetTypeByMetadataName(typeof(Math).FullName);
@@ -87,6 +89,8 @@ public FluentAssertionsMetadata(Compilation compilation)
8789
public INamedTypeSymbol IDictionaryOfT2 { get; }
8890
public INamedTypeSymbol DictionaryOfT2 { get; }
8991
public INamedTypeSymbol IReadonlyDictionaryOfT2 { get; }
92+
public INamedTypeSymbol IListOfT { get; }
93+
public INamedTypeSymbol IReadonlyListOfT { get; }
9094
public INamedTypeSymbol BooleanAssertionsOfT1 { get; }
9195
public INamedTypeSymbol NumericAssertionsOfT2 { get; }
9296
public INamedTypeSymbol Enumerable { get; }

src/FluentAssertions.Analyzers/Tips/FluentAssertionsAnalyzer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ private static void AnalyzeInvocation(OperationAnalysisContext context, FluentAs
394394
}
395395
else if (subject.TryGetFirstDescendent<IPropertyReferenceOperation>(out var propertyReference) && propertyReference.Property.IsIndexer)
396396
{
397+
if (!propertyReference.Instance.Type.ImplementsOrIsInterface(metadata.IListOfT) && !propertyReference.Instance.Type.ImplementsOrIsInterface(metadata.IReadonlyListOfT)) return;
397398
if (propertyReference.Instance.Type.ImplementsOrIsInterface(metadata.IDictionaryOfT2) || propertyReference.Instance.Type.ImplementsOrIsInterface(metadata.IReadonlyDictionaryOfT2)) return;
398399

399400
context.ReportDiagnostic(CreateDiagnostic(assertion, DiagnosticMetadata.CollectionShouldHaveElementAt_IndexerShouldBe));

0 commit comments

Comments
 (0)