-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
…in-order-code-fix GH-181 - code fix provider for NS5001
- Loading branch information
Showing
10 changed files
with
563 additions
and
0 deletions.
There are no files selected for viewing
10 changes: 10 additions & 0 deletions
10
...NSubstitute.Analyzers.CSharp/CodeFixProviders/ReceivedInReceivedInOrderCodeFixProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
using NSubstitute.Analyzers.Shared.CodeFixProviders; | ||
|
||
namespace NSubstitute.Analyzers.CSharp.CodeFixProviders; | ||
|
||
[ExportCodeFixProvider(LanguageNames.CSharp)] | ||
internal sealed class ReceivedInReceivedInOrderCodeFixProvider : AbstractReceivedInReceivedInOrderCodeFixProvider | ||
{ | ||
} |
53 changes: 53 additions & 0 deletions
53
...ute.Analyzers.Shared/CodeFixProviders/AbstractReceivedInReceivedInOrderCodeFixProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CodeActions; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
using Microsoft.CodeAnalysis.Operations; | ||
using Document = Microsoft.CodeAnalysis.Document; | ||
|
||
namespace NSubstitute.Analyzers.Shared.CodeFixProviders; | ||
|
||
internal abstract class AbstractReceivedInReceivedInOrderCodeFixProvider : CodeFixProvider | ||
{ | ||
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; | ||
|
||
public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(DiagnosticIdentifiers.ReceivedUsedInReceivedInOrder); | ||
|
||
public override Task RegisterCodeFixesAsync(CodeFixContext context) | ||
{ | ||
var diagnostic = context.Diagnostics.FirstOrDefault(diag => diag.Descriptor.Id == DiagnosticIdentifiers.ReceivedUsedInReceivedInOrder); | ||
if (diagnostic != null) | ||
{ | ||
var codeAction = CodeAction.Create("Remove redundant Received checks", ct => CreateChangedDocument(ct, context, diagnostic), nameof(AbstractReceivedInReceivedInOrderCodeFixProvider)); | ||
context.RegisterCodeFix(codeAction, diagnostic); | ||
} | ||
|
||
return Task.CompletedTask; | ||
} | ||
|
||
private async Task<Document> CreateChangedDocument(CancellationToken cancellationToken, CodeFixContext context, Diagnostic diagnostic) | ||
{ | ||
var root = await context.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); | ||
|
||
var invocation = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); | ||
|
||
var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken); | ||
if (semanticModel.GetOperation(invocation) is not IInvocationOperation invocationOperation) | ||
{ | ||
return context.Document; | ||
} | ||
|
||
var syntax = invocationOperation.Instance != null | ||
? invocationOperation.Instance.Syntax | ||
: invocationOperation.Arguments.Single(arg => arg.Parameter.Ordinal == 0).Value.Syntax; | ||
|
||
var updatedRoot = root.ReplaceNode( | ||
invocation, | ||
syntax.WithTriviaFrom(invocation)); | ||
|
||
return context.Document.WithSyntaxRoot(updatedRoot); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
...titute.Analyzers.VisualBasic/CodeFixProviders/ReceivedInReceivedInOrderCodeFixProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
using NSubstitute.Analyzers.Shared.CodeFixProviders; | ||
|
||
namespace NSubstitute.Analyzers.VisualBasic.CodeFixProviders; | ||
|
||
[ExportCodeFixProvider(LanguageNames.VisualBasic)] | ||
internal sealed class ReceivedInReceivedInOrderCodeFixProvider : AbstractReceivedInReceivedInOrderCodeFixProvider | ||
{ | ||
} |
119 changes: 119 additions & 0 deletions
119
...iderTests/ReceivedInReceivedInOrderCodeFixProviderTests/ReceivedAsExtensionMethodTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
|
||
namespace NSubstitute.Analyzers.Tests.CSharp.CodeFixProviderTests.ReceivedInReceivedInOrderCodeFixProviderTests; | ||
|
||
public class ReceivedAsExtensionMethodTests : ReceivedInReceivedInOrderCodeFixVerifier | ||
{ | ||
[Fact] | ||
public override async Task RemovesReceivedChecks_WhenReceivedChecksHasNoArguments() | ||
{ | ||
var oldSource = @"using NSubstitute; | ||
using NSubstitute.ReceivedExtensions; | ||
namespace MyNamespace | ||
{ | ||
public interface IFoo | ||
{ | ||
int Bar(); | ||
int Bar(int x); | ||
} | ||
public class FooTests | ||
{ | ||
public void Test() | ||
{ | ||
var substitute = NSubstitute.Substitute.For<IFoo>(); | ||
Received.InOrder(() => | ||
{ | ||
substitute.Received().Bar(); | ||
substitute.Received().Bar(Arg.Any<int>()); | ||
substitute.ReceivedWithAnyArgs().Bar(Arg.Any<int>()); | ||
}); | ||
} | ||
} | ||
}"; | ||
|
||
var newSource = @"using NSubstitute; | ||
using NSubstitute.ReceivedExtensions; | ||
namespace MyNamespace | ||
{ | ||
public interface IFoo | ||
{ | ||
int Bar(); | ||
int Bar(int x); | ||
} | ||
public class FooTests | ||
{ | ||
public void Test() | ||
{ | ||
var substitute = NSubstitute.Substitute.For<IFoo>(); | ||
Received.InOrder(() => | ||
{ | ||
substitute.Bar(); | ||
substitute.Bar(Arg.Any<int>()); | ||
substitute.Bar(Arg.Any<int>()); | ||
}); | ||
} | ||
} | ||
}"; | ||
await VerifyFix(oldSource, newSource); | ||
} | ||
|
||
[Fact] | ||
public override async Task RemovesReceivedChecks_WhenReceivedChecksHasArguments() | ||
{ | ||
var oldSource = @"using NSubstitute; | ||
using NSubstitute.ReceivedExtensions; | ||
namespace MyNamespace | ||
{ | ||
public interface IFoo | ||
{ | ||
int Bar(); | ||
int Bar(int x); | ||
} | ||
public class FooTests | ||
{ | ||
public void Test() | ||
{ | ||
var substitute = NSubstitute.Substitute.For<IFoo>(); | ||
Received.InOrder(() => | ||
{ | ||
substitute.Received(1).Bar(); | ||
substitute.Received(1).Bar(Arg.Any<int>()); | ||
}); | ||
} | ||
} | ||
}"; | ||
|
||
var newSource = @"using NSubstitute; | ||
using NSubstitute.ReceivedExtensions; | ||
namespace MyNamespace | ||
{ | ||
public interface IFoo | ||
{ | ||
int Bar(); | ||
int Bar(int x); | ||
} | ||
public class FooTests | ||
{ | ||
public void Test() | ||
{ | ||
var substitute = NSubstitute.Substitute.For<IFoo>(); | ||
Received.InOrder(() => | ||
{ | ||
substitute.Bar(); | ||
substitute.Bar(Arg.Any<int>()); | ||
}); | ||
} | ||
} | ||
}"; | ||
await VerifyFix(oldSource, newSource); | ||
} | ||
} |
119 changes: 119 additions & 0 deletions
119
...viderTests/ReceivedInReceivedInOrderCodeFixProviderTests/ReceivedAsOrdinaryMethodTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
|
||
namespace NSubstitute.Analyzers.Tests.CSharp.CodeFixProviderTests.ReceivedInReceivedInOrderCodeFixProviderTests; | ||
|
||
public class ReceivedAsOrdinaryMethodTests : ReceivedInReceivedInOrderCodeFixVerifier | ||
{ | ||
[Fact] | ||
public override async Task RemovesReceivedChecks_WhenReceivedChecksHasNoArguments() | ||
{ | ||
var oldSource = @"using NSubstitute; | ||
using NSubstitute.ReceivedExtensions; | ||
namespace MyNamespace | ||
{ | ||
public interface IFoo | ||
{ | ||
int Bar(); | ||
int Bar(int x); | ||
} | ||
public class FooTests | ||
{ | ||
public void Test() | ||
{ | ||
var substitute = NSubstitute.Substitute.For<IFoo>(); | ||
Received.InOrder(() => | ||
{ | ||
SubstituteExtensions.Received(substitute).Bar(); | ||
SubstituteExtensions.Received(substitute).Bar(Arg.Any<int>()); | ||
SubstituteExtensions.ReceivedWithAnyArgs(substitute).Bar(Arg.Any<int>()); | ||
}); | ||
} | ||
} | ||
}"; | ||
|
||
var newSource = @"using NSubstitute; | ||
using NSubstitute.ReceivedExtensions; | ||
namespace MyNamespace | ||
{ | ||
public interface IFoo | ||
{ | ||
int Bar(); | ||
int Bar(int x); | ||
} | ||
public class FooTests | ||
{ | ||
public void Test() | ||
{ | ||
var substitute = NSubstitute.Substitute.For<IFoo>(); | ||
Received.InOrder(() => | ||
{ | ||
substitute.Bar(); | ||
substitute.Bar(Arg.Any<int>()); | ||
substitute.Bar(Arg.Any<int>()); | ||
}); | ||
} | ||
} | ||
}"; | ||
await VerifyFix(oldSource, newSource); | ||
} | ||
|
||
[Fact] | ||
public override async Task RemovesReceivedChecks_WhenReceivedChecksHasArguments() | ||
{ | ||
var oldSource = @"using NSubstitute; | ||
using NSubstitute.ReceivedExtensions; | ||
namespace MyNamespace | ||
{ | ||
public interface IFoo | ||
{ | ||
int Bar(); | ||
int Bar(int x); | ||
} | ||
public class FooTests | ||
{ | ||
public void Test() | ||
{ | ||
var substitute = NSubstitute.Substitute.For<IFoo>(); | ||
Received.InOrder(() => | ||
{ | ||
SubstituteExtensions.Received(substitute, 1).Bar(); | ||
SubstituteExtensions.Received(substitute, 1).Bar(Arg.Any<int>()); | ||
}); | ||
} | ||
} | ||
}"; | ||
|
||
var newSource = @"using NSubstitute; | ||
using NSubstitute.ReceivedExtensions; | ||
namespace MyNamespace | ||
{ | ||
public interface IFoo | ||
{ | ||
int Bar(); | ||
int Bar(int x); | ||
} | ||
public class FooTests | ||
{ | ||
public void Test() | ||
{ | ||
var substitute = NSubstitute.Substitute.For<IFoo>(); | ||
Received.InOrder(() => | ||
{ | ||
substitute.Bar(); | ||
substitute.Bar(Arg.Any<int>()); | ||
}); | ||
} | ||
} | ||
}"; | ||
await VerifyFix(oldSource, newSource); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
...ReceivedInReceivedInOrderCodeFixProviderTests/ReceivedInReceivedInOrderCodeFixVerifier.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
using NSubstitute.Analyzers.CSharp.CodeFixProviders; | ||
using NSubstitute.Analyzers.CSharp.DiagnosticAnalyzers; | ||
using NSubstitute.Analyzers.Shared.CodeFixProviders; | ||
using NSubstitute.Analyzers.Tests.Shared.CodeFixProviders; | ||
|
||
namespace NSubstitute.Analyzers.Tests.CSharp.CodeFixProviderTests.ReceivedInReceivedInOrderCodeFixProviderTests; | ||
|
||
public abstract class ReceivedInReceivedInOrderCodeFixVerifier : CSharpCodeFixVerifier, IReceivedInReceivedInOrderCodeFixVerifier | ||
{ | ||
protected override DiagnosticAnalyzer DiagnosticAnalyzer { get; } = new ReceivedInReceivedInOrderAnalyzer(); | ||
|
||
protected override CodeFixProvider CodeFixProvider { get; } = new ReceivedInReceivedInOrderCodeFixProvider(); | ||
|
||
public abstract Task RemovesReceivedChecks_WhenReceivedChecksHasNoArguments(); | ||
|
||
public abstract Task RemovesReceivedChecks_WhenReceivedChecksHasArguments(); | ||
} |
10 changes: 10 additions & 0 deletions
10
...tute.Analyzers.Tests.Shared/CodeFixProviders/IReceivedInReceivedInOrderCodeFixVerifier.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System.Threading.Tasks; | ||
|
||
namespace NSubstitute.Analyzers.Tests.Shared.CodeFixProviders; | ||
|
||
public interface IReceivedInReceivedInOrderCodeFixVerifier | ||
{ | ||
Task RemovesReceivedChecks_WhenReceivedChecksHasNoArguments(); | ||
|
||
Task RemovesReceivedChecks_WhenReceivedChecksHasArguments(); | ||
} |
Oops, something went wrong.