Skip to content

Commit

Permalink
Fix codefix test
Browse files Browse the repository at this point in the history
  • Loading branch information
Duke committed Jan 8, 2024
1 parent 7ed3ee3 commit fc7a9d6
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 16 deletions.
79 changes: 77 additions & 2 deletions src/Immediate.Handlers.CodeFixes/HandlerClassCodeFixProvider.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Formatting;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using SyntaxKind = Microsoft.CodeAnalysis.CSharp.SyntaxKind;

namespace Immediate.Handlers.CodeFixes;

Expand All @@ -9,8 +15,77 @@ public class HandlerClassCodeFixProvider : CodeFixProvider

public override FixAllProvider? GetFixAllProvider() => null;

public override Task RegisterCodeFixesAsync(CodeFixContext context)
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
throw new NotImplementedException();
// We link only one diagnostic and assume there is only one diagnostic in the context.
var diagnostic = context.Diagnostics.Single();

// 'SourceSpan' of 'Location' is the highlighted area. We're going to use this area to find the 'SyntaxNode' to rename.
var diagnosticSpan = diagnostic.Location.SourceSpan;

var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

if (root?.FindNode(diagnosticSpan) is ClassDeclarationSyntax classDeclarationSyntax)
{
context.RegisterCodeFix(
CodeAction.Create(
title: "Add HandleAsync method",
createChangedDocument: _ => AddHandleAsyncMethodAsync(context.Document, root, classDeclarationSyntax),
equivalenceKey: nameof(HandlerClassCodeFixProvider)
),
diagnostic);
}
}

private static Task<Document> AddHandleAsyncMethodAsync(Document document,
SyntaxNode root,
ClassDeclarationSyntax classDeclarationSyntax)
{
var methodDeclaration = MethodDeclaration(
GenericName(
Identifier("Task"))
.WithTypeArgumentList(
TypeArgumentList(
SingletonSeparatedList<TypeSyntax>(
PredefinedType(
Token(SyntaxKind.IntKeyword))))),
Identifier("HandleAsync"))
.WithModifiers(
TokenList(
[
Token(SyntaxKind.PrivateKeyword),
Token(SyntaxKind.StaticKeyword),
]))
.WithParameterList(
ParameterList(
SeparatedList<ParameterSyntax>(
new SyntaxNodeOrToken[]
{
Parameter(
Identifier(
TriviaList(),
SyntaxKind.UnderscoreToken,
"_",
"_",
TriviaList()))
.WithType(
IdentifierName("Query")),
Token(SyntaxKind.CommaToken),
Parameter(
Identifier("token"))
.WithType(
IdentifierName("CancellationToken")),
})))
.WithBody(
Block(
SingletonList<StatementSyntax>(
ReturnStatement(
LiteralExpression(
SyntaxKind.NullLiteralExpression)))))
.WithAdditionalAnnotations(Formatter.Annotation);

var newClassDecl = classDeclarationSyntax.AddMembers(methodDeclaration);

return Task.FromResult(document.WithSyntaxRoot(root.ReplaceNode(classDeclarationSyntax, newClassDecl)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public static CSharpCodeFixTest<TAnalyzer, TCodeFix, DefaultVerifier> CreateCode
string inputSource,
string fixedSource,
DriverReferenceAssemblies assemblies,
IEnumerable<DiagnosticResult> expectedDiagnostics
)
IEnumerable<DiagnosticResult> expectedDiagnostics,
IEnumerable<DiagnosticResult> expectedFixedDiagnostics)
where TAnalyzer : DiagnosticAnalyzer, new()
where TCodeFix : CodeFixProvider, new()
{
Expand All @@ -35,6 +35,9 @@ IEnumerable<DiagnosticResult> expectedDiagnostics
csTest.TestState.ExpectedDiagnostics
.AddRange(expectedDiagnostics);

csTest.FixedState.ExpectedDiagnostics
.AddRange(expectedFixedDiagnostics);

return csTest;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
Immediate.Handlers.Analyzers.HandlerClassAnalyzer,
Immediate.Handlers.CodeFixes.HandlerClassCodeFixProvider>;

namespace Immediate.Handlers.Tests.CodeFixTests;
namespace Immediate.Handlers.Tests.CodeFixTests.HandlerClassCodeFixTests;

public class HandlerClassCodeFixTests
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1724:Type names should not match namespaces", Justification = "Not being consumed by other code")]
public class Tests
{
[Fact]
public async Task CodeFixTest()
public async Task HandleMethodDoesNotExist()
{
var input = @"
using System;
Expand All @@ -21,6 +22,7 @@ public async Task CodeFixTest()
using System.Threading;
using System.Threading.Tasks;
using Immediate.Handlers.Shared;
[Handler]
public static class GetUsersQuery
{
Expand All @@ -35,20 +37,25 @@ public record Query;
using System.Threading;
using System.Threading.Tasks;
using Immediate.Handlers.Shared;
[Handler]
public static class GetUsersQuery
{
public record Query;
private static Task HandleAsync(
Query _,
CancellationToken token)
{
return null;
}
}
";
var test = CodeFixTestHelper.CreateCodeFixTest<HandlerClassAnalyzer, HandlerClassCodeFixProvider>(input, fixedSource, DriverReferenceAssemblies.Normal, [Verifier.Diagnostic("IH0001")]);
private static Task<int> HandleAsync(Query _, CancellationToken token)
{
return null;
}
}";

var expected = Verifier.Diagnostic("IH0001")
.WithLocation(12, 21)
.WithArguments("GetUsersQuery");

//var expectedFixed = DiagnosticResult.CompilerError("CS7003").WithSpan(15, 17, 15, 23);

var test = CodeFixTestHelper.CreateCodeFixTest<HandlerClassAnalyzer, HandlerClassCodeFixProvider>(input, fixedSource, DriverReferenceAssemblies.Normal, [expected], []);

await test.RunAsync();
}
Expand Down

0 comments on commit fc7a9d6

Please sign in to comment.