diff --git a/src/FluentAssertions.Analyzers.Tests/Tips/CollectionTests.cs b/src/FluentAssertions.Analyzers.Tests/Tips/CollectionTests.cs index 4b756ab9..795b3bb8 100644 --- a/src/FluentAssertions.Analyzers.Tests/Tips/CollectionTests.cs +++ b/src/FluentAssertions.Analyzers.Tests/Tips/CollectionTests.cs @@ -111,7 +111,7 @@ public class CollectionTests [AssertionDiagnostic("actual.AsEnumerable().Where(x => x.BooleanProperty).Should().BeEmpty({0}).And.ToString();")] [AssertionDiagnostic("actual.AsEnumerable().Should().OnlyContain(x => !x.BooleanProperty{0}).And.ToString();", ignore: true)] [Implemented] - public void CollectionShouldNotContainProperty_TestAnalyzer(string assertion) => VerifyCSharpDiagnosticCodeBlock(assertion); + public void CollectionShouldNotContainProperty_TestAnalyzer(string assertion) => VerifyCSharpDiagnosticCodeBlock(assertion); [AssertionDataTestMethod] [AssertionCodeFix( @@ -135,7 +135,7 @@ public class CollectionTests newAssertion: "actual.AsEnumerable().Should().NotContain(x => x.BooleanProperty{0}).And.ToString();", ignore: true)] [Implemented] - public void CollectionShouldNotContainProperty_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFixCodeBlock(oldAssertion, newAssertion); + public void CollectionShouldNotContainProperty_TestCodeFix(string oldAssertion, string newAssertion) => VerifyCSharpFixCodeBlock(oldAssertion, newAssertion); [AssertionDataTestMethod] [AssertionDiagnostic("actual.All(x => x.BooleanProperty).Should().BeTrue({0});")] diff --git a/src/FluentAssertions.Analyzers/Tips/Collections/CollectionAnalyzer.cs b/src/FluentAssertions.Analyzers/Tips/Collections/CollectionAnalyzer.cs index dd5ae60a..9c2d5ed9 100644 --- a/src/FluentAssertions.Analyzers/Tips/Collections/CollectionAnalyzer.cs +++ b/src/FluentAssertions.Analyzers/Tips/Collections/CollectionAnalyzer.cs @@ -71,7 +71,10 @@ protected override IEnumerable Visitors yield return new CollectionShouldNotContainNulls.SelectShouldNotContainNullsSyntaxVisitor(); - // TODO: Add support for CollectionShouldNotContainPropertyAnalyzer + yield return new CollectionShouldNotContainProperty.AnyLambdaShouldBeFalseSyntaxVisitor(); + yield return new CollectionShouldNotContainProperty.WhereShouldBeEmptySyntaxVisitor(); + // TODO: enable this: + // yield return new CollectionShouldNotContainProperty.ShouldOnlyContainNotSyntaxVisitor(); yield return new CollectionShouldNotHaveCount.CountShouldNotBeSyntaxVisitor(); yield return new CollectionShouldNotHaveSameCount.CountShouldNotBeOtherCollectionCountSyntaxVisitor(); @@ -187,6 +190,28 @@ protected override ExpressionSyntax GetNewExpression(ExpressionSyntax expression return GetNewExpression(newExpression, NodeReplacement.PrependArguments("NotContainNulls", remove.Arguments)); } + + case nameof(CollectionShouldNotContainProperty.AnyLambdaShouldBeFalseSyntaxVisitor): + { + var remove = NodeReplacement.RemoveAndExtractArguments("Any"); + var newExpression = GetNewExpression(expression, remove); + + return GetNewExpression(newExpression, NodeReplacement.RenameAndPrependArguments("BeFalse", "NotContain", remove.Arguments)); + } + case nameof(CollectionShouldNotContainProperty.WhereShouldBeEmptySyntaxVisitor): + { + var remove = NodeReplacement.RemoveAndExtractArguments("Where"); + var newExpression = GetNewExpression(expression, remove); + + return GetNewExpression(newExpression, NodeReplacement.RenameAndPrependArguments("BeEmpty", "NotContain", remove.Arguments)); + } + /* + case nameof(CollectionShouldNotContainProperty.ShouldOnlyContainNotSyntaxVisitor): + { + return GetNewExpression(expression, NodeReplacement.RenameAndNegateLambda("OnlyContain", "NotContain")); + } + */ + case nameof(CollectionShouldNotHaveCount.CountShouldNotBeSyntaxVisitor): return GetNewExpression(expression, NodeReplacement.Remove("Count"), NodeReplacement.Rename("NotBe", "NotHaveCount")); ; case nameof(CollectionShouldNotHaveSameCount.CountShouldNotBeOtherCollectionCountSyntaxVisitor): diff --git a/src/FluentAssertions.Analyzers/Tips/Collections/CollectionShouldNotContainProperty.cs b/src/FluentAssertions.Analyzers/Tips/Collections/CollectionShouldNotContainProperty.cs index 387c8621..0008e98a 100644 --- a/src/FluentAssertions.Analyzers/Tips/Collections/CollectionShouldNotContainProperty.cs +++ b/src/FluentAssertions.Analyzers/Tips/Collections/CollectionShouldNotContainProperty.cs @@ -1,35 +1,10 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Diagnostics; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Composition; +namespace FluentAssertions.Analyzers; -namespace FluentAssertions.Analyzers; - -[DiagnosticAnalyzer(LanguageNames.CSharp)] -public class CollectionShouldNotContainPropertyAnalyzer : CollectionAnalyzer +public static class CollectionShouldNotContainProperty { - public const string DiagnosticId = Constants.Tips.Collections.CollectionShouldNotContainProperty; - public const string Category = Constants.Tips.Category; - - public const string Message = "Use .Should().NotContain() instead."; - - protected override DiagnosticDescriptor Rule => new DiagnosticDescriptor(DiagnosticId, Title, Message, Category, DiagnosticSeverity.Info, true); - protected override IEnumerable Visitors - { - get - { - yield return new AnyShouldBeFalseSyntaxVisitor(); - yield return new WhereShouldBeEmptySyntaxVisitor(); - // TODO: yield return new ShouldOnlyContainNotSyntaxVisitor(); - } - } - - public class AnyShouldBeFalseSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor + public class AnyLambdaShouldBeFalseSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor { - public AnyShouldBeFalseSyntaxVisitor() : base(MemberValidator.MethodContainingLambda("Any"), MemberValidator.Should, new MemberValidator("BeFalse")) + public AnyLambdaShouldBeFalseSyntaxVisitor() : base(MemberValidator.MethodContainingLambda("Any"), MemberValidator.Should, new MemberValidator("BeFalse")) { } } @@ -47,35 +22,4 @@ public ShouldOnlyContainSyntaxVisitor() : base(MemberValidator.Should, MemberVal { } } -} - -[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CollectionShouldNotContainPropertyCodeFix)), Shared] -public class CollectionShouldNotContainPropertyCodeFix : FluentAssertionsCodeFixProvider -{ - public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CollectionShouldNotContainPropertyAnalyzer.DiagnosticId); - - protected override ExpressionSyntax GetNewExpression(ExpressionSyntax expression, FluentAssertionsDiagnosticProperties properties) - { - if (properties.VisitorName == nameof(CollectionShouldNotContainPropertyAnalyzer.AnyShouldBeFalseSyntaxVisitor)) - { - var remove = NodeReplacement.RemoveAndExtractArguments("Any"); - var newExpression = GetNewExpression(expression, remove); - - return GetNewExpression(newExpression, NodeReplacement.RenameAndPrependArguments("BeFalse", "NotContain", remove.Arguments)); - } - else if (properties.VisitorName == nameof(CollectionShouldNotContainPropertyAnalyzer.WhereShouldBeEmptySyntaxVisitor)) - { - var remove = NodeReplacement.RemoveAndExtractArguments("Where"); - var newExpression = GetNewExpression(expression, remove); - - return GetNewExpression(newExpression, NodeReplacement.RenameAndPrependArguments("BeEmpty", "NotContain", remove.Arguments)); - } - /* - else if (properties.VisitorName == nameof(CollectionShouldNotContainPropertyAnalyzer.ShouldOnlyContainNotSyntaxVisitor)) - { - return GetNewExpression(expression, NodeReplacement.RenameAndNegateLambda("OnlyContain", "NotContain")); - } - */ - throw new System.InvalidOperationException($"Invalid visitor name - {properties.VisitorName}"); - } -} +} \ No newline at end of file