1+ using System . Collections . Generic ;
2+ using System . Collections . Immutable ;
3+ using System . Composition ;
4+ using Microsoft . CodeAnalysis ;
5+ using Microsoft . CodeAnalysis . CodeFixes ;
6+ using Microsoft . CodeAnalysis . CSharp . Syntax ;
7+ using Microsoft . CodeAnalysis . Diagnostics ;
8+ using TypeSelector = FluentAssertions . Analyzers . Utilities . SemanticModelTypeExtensions ;
9+
10+ namespace FluentAssertions . Analyzers . Xunit ;
11+
12+ [ DiagnosticAnalyzer ( LanguageNames . CSharp ) ]
13+ public class AssertContainsAnalyzer : XunitAnalyzer
14+ {
15+ public const string DiagnosticId = Constants . Tips . Xunit . AssertContains ;
16+ public const string Category = Constants . Tips . Category ;
17+
18+ public const string Message = "Use .Should().Contain()." ;
19+
20+ protected override DiagnosticDescriptor Rule => new ( DiagnosticId , Title , Message , Category , DiagnosticSeverity . Info , true ) ;
21+
22+ protected override IEnumerable < FluentAssertionsCSharpSyntaxVisitor > Visitors => new FluentAssertionsCSharpSyntaxVisitor [ ]
23+ {
24+ new AssertContainsStringSyntaxVisitor ( )
25+ } ;
26+
27+ //public static void Contains(string expectedSubstring, string? actualString)
28+ public class AssertContainsStringSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor
29+ {
30+ public AssertContainsStringSyntaxVisitor ( ) : base (
31+ MemberValidator . ArgumentsMatch ( "Contains" ,
32+ ArgumentValidator . IsType ( TypeSelector . GetStringType ) ,
33+ ArgumentValidator . IsType ( TypeSelector . GetStringType ) )
34+ )
35+ {
36+ }
37+ }
38+ }
39+
40+ [ ExportCodeFixProvider ( LanguageNames . CSharp , Name = nameof ( AssertContainsCodeFix ) ) , Shared ]
41+ public class AssertContainsCodeFix : XunitCodeFixProvider
42+ {
43+ public override ImmutableArray < string > FixableDiagnosticIds => ImmutableArray . Create ( AssertContainsAnalyzer . DiagnosticId ) ;
44+
45+ protected override ExpressionSyntax GetNewExpression (
46+ ExpressionSyntax expression ,
47+ FluentAssertionsDiagnosticProperties properties )
48+ {
49+ switch ( properties . VisitorName )
50+ {
51+ case nameof ( AssertContainsAnalyzer . AssertContainsStringSyntaxVisitor ) :
52+ return RenameMethodAndReorderActualExpectedAndReplaceWithSubjectShould ( expression , "Contains" , "Contain" ) ;
53+ default :
54+ throw new System . InvalidOperationException ( $ "Invalid visitor name - { properties . VisitorName } ") ;
55+ }
56+ }
57+ }
0 commit comments