From 97906f92f1c2523bb6d2d0d6791b4407ede6cf2b Mon Sep 17 00:00:00 2001 From: tpodolak Date: Fri, 22 Jul 2022 16:46:12 +0200 Subject: [PATCH 01/10] GH-186 - dropping support for CallInfo as it didnt make it to NSubstitute 4.4 --- libs/nsubstitute-latest/NSubstitute.dll | Bin 154112 -> 160768 bytes .../ReEntrantSetupCodeFixVerifier.cs | 8 ++++---- .../ReturnsAsExtensionMethodTests.cs | 2 +- .../ReturnsAsOrdinaryMethodTests.cs | 2 +- .../CodeFixProviders/CodeFixVerifier.cs | 9 ++++----- .../ReEntrantSetupCodeFixVerifier.cs | 4 ++-- .../ReturnsAsExtensionMethodTests.cs | 2 +- .../ReturnsAsOrdinaryMethodTests.cs | 2 +- .../ReturnsAsOrdinaryMethodTests.cs | 14 +++++++------- 9 files changed, 21 insertions(+), 22 deletions(-) diff --git a/libs/nsubstitute-latest/NSubstitute.dll b/libs/nsubstitute-latest/NSubstitute.dll index 3f77620c9ad8b1a11a6cebf8c265a539d3639a90..83021fb1ace63fcc92040756e8f69783f27281c8 100644 GIT binary patch literal 160768 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 Y(BQ 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 diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/ReEntrantSetupCodeFixProviderTests/ReEntrantSetupCodeFixVerifier.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/ReEntrantSetupCodeFixProviderTests/ReEntrantSetupCodeFixVerifier.cs index 51473f31..10998fb6 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/ReEntrantSetupCodeFixProviderTests/ReEntrantSetupCodeFixVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/ReEntrantSetupCodeFixProviderTests/ReEntrantSetupCodeFixVerifier.cs @@ -21,11 +21,11 @@ protected ReEntrantSetupCodeFixVerifier() [Theory] [InlineData("CreateReEntrantSubstitute(), CreateDefaultValue(), 1", "_ => CreateReEntrantSubstitute(), _ => CreateDefaultValue(), _ => 1")] - [InlineData("CreateReEntrantSubstitute(), new [] { CreateDefaultValue(), 1 }", "_ => CreateReEntrantSubstitute(), new System.Func, int>[] { _ => CreateDefaultValue(), _ => 1 }")] - [InlineData("CreateReEntrantSubstitute(), new int[] { CreateDefaultValue(), 1 }", "_ => CreateReEntrantSubstitute(), new System.Func, int>[] { _ => CreateDefaultValue(), _ => 1 }")] + [InlineData("CreateReEntrantSubstitute(), new [] { CreateDefaultValue(), 1 }", "_ => CreateReEntrantSubstitute(), new System.Func[] { _ => CreateDefaultValue(), _ => 1 }")] + [InlineData("CreateReEntrantSubstitute(), new int[] { CreateDefaultValue(), 1 }", "_ => CreateReEntrantSubstitute(), new System.Func[] { _ => CreateDefaultValue(), _ => 1 }")] [InlineData("returnThis: CreateReEntrantSubstitute()", "returnThis: _ => CreateReEntrantSubstitute()")] - [InlineData("returnThis: CreateReEntrantSubstitute(), returnThese: new [] { CreateDefaultValue(), 1 }", "returnThis: _ => CreateReEntrantSubstitute(), returnThese: new System.Func, int>[] { _ => CreateDefaultValue(), _ => 1 }")] - [InlineData("returnThis: CreateReEntrantSubstitute(), returnThese: new int[] { CreateDefaultValue(), 1 }", "returnThis: _ => CreateReEntrantSubstitute(), returnThese: new System.Func, int>[] { _ => CreateDefaultValue(), _ => 1 }")] + [InlineData("returnThis: CreateReEntrantSubstitute(), returnThese: new [] { CreateDefaultValue(), 1 }", "returnThis: _ => CreateReEntrantSubstitute(), returnThese: new System.Func[] { _ => CreateDefaultValue(), _ => 1 }")] + [InlineData("returnThis: CreateReEntrantSubstitute(), returnThese: new int[] { CreateDefaultValue(), 1 }", "returnThis: _ => CreateReEntrantSubstitute(), returnThese: new System.Func[] { _ => CreateDefaultValue(), _ => 1 }")] public abstract Task ReplacesArgumentExpression_WithLambda(string arguments, string rewrittenArguments); [Fact] diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsExtensionMethodTests.cs index d0a2015f..7b15a9c6 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsExtensionMethodTests.cs @@ -149,7 +149,7 @@ public interface IFoo public void Test() { var secondSubstitute = Substitute.For(); - secondSubstitute.Id.Returns(_ => CreateReEntrantSubstitute(), new Func, int>[] { _ => MyNamespace.FooTests.Value }); + secondSubstitute.Id.Returns(_ => CreateReEntrantSubstitute(), new Func[] { _ => MyNamespace.FooTests.Value }); } private int CreateReEntrantSubstitute() diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsOrdinaryMethodTests.cs index 7e0458c7..0164fb15 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsOrdinaryMethodTests.cs @@ -149,7 +149,7 @@ public interface IFoo public void Test() { var secondSubstitute = Substitute.For(); - SubstituteExtensions.Returns(secondSubstitute.Id, _ => CreateReEntrantSubstitute(), new Func, int>[] { _ => MyNamespace.FooTests.Value }); + SubstituteExtensions.Returns(secondSubstitute.Id, _ => CreateReEntrantSubstitute(), new Func[] { _ => MyNamespace.FooTests.Value }); } private int CreateReEntrantSubstitute() diff --git a/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixVerifier.cs b/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixVerifier.cs index acd6ad60..bcc7ddbe 100644 --- a/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixVerifier.cs @@ -98,12 +98,11 @@ private static Project UpdateNSubstituteMetadataReference(Project project, NSubs project = project.RemoveMetadataReference(RuntimeMetadataReference.NSubstituteLatestReference); - switch (version) + project = version switch { - case NSubstituteVersion.NSubstitute4_2_2: - project = project.AddMetadataReference(RuntimeMetadataReference.NSubstitute422Reference); - break; - } + NSubstituteVersion.NSubstitute4_2_2 => project.AddMetadataReference(RuntimeMetadataReference.NSubstitute422Reference), + _ => throw new ArgumentException($"NSubstitute {version} is not supported", nameof(version)) + }; return project; } diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/ReEntrantSetupCodeFixProviderTests/ReEntrantSetupCodeFixVerifier.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/ReEntrantSetupCodeFixProviderTests/ReEntrantSetupCodeFixVerifier.cs index 12d4bbe5..cdf1445c 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/ReEntrantSetupCodeFixProviderTests/ReEntrantSetupCodeFixVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/ReEntrantSetupCodeFixProviderTests/ReEntrantSetupCodeFixVerifier.cs @@ -16,8 +16,8 @@ public abstract class ReEntrantSetupCodeFixVerifier : VisualBasicCodeFixVerifier [Theory] [InlineData("CreateReEntrantSubstitute(), CreateDefaultValue(), 1", "Function(x) CreateReEntrantSubstitute(), Function(x) CreateDefaultValue(), Function(x) 1")] - [InlineData("CreateReEntrantSubstitute(), { CreateDefaultValue(), 1 }", "Function(x) CreateReEntrantSubstitute(), New System.Func(Of Core.CallInfo(Of Integer), Integer)() {Function(x) CreateDefaultValue(), Function(x) 1}")] - [InlineData("CreateReEntrantSubstitute(), New Integer() {CreateDefaultValue(), 1}", "Function(x) CreateReEntrantSubstitute(), New System.Func(Of Core.CallInfo(Of Integer), Integer)() {Function(x) CreateDefaultValue(), Function(x) 1}")] + [InlineData("CreateReEntrantSubstitute(), { CreateDefaultValue(), 1 }", "Function(x) CreateReEntrantSubstitute(), New System.Func(Of Core.CallInfo, Integer)() {Function(x) CreateDefaultValue(), Function(x) 1}")] + [InlineData("CreateReEntrantSubstitute(), New Integer() {CreateDefaultValue(), 1}", "Function(x) CreateReEntrantSubstitute(), New System.Func(Of Core.CallInfo, Integer)() {Function(x) CreateDefaultValue(), Function(x) 1}")] [InlineData("returnThis:= CreateReEntrantSubstitute()", "returnThis:=Function(x) CreateReEntrantSubstitute()")] public abstract Task ReplacesArgumentExpression_WithLambda(string arguments, string rewrittenArguments); diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsExtensionMethodTests.cs index 96545bc6..409d5baa 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsExtensionMethodTests.cs @@ -125,7 +125,7 @@ End Interface Public Sub Test() Dim secondSubstitute = NSubstitute.Substitute.[For](Of IFoo)() - secondSubstitute.Id.Returns(Function(x) CreateReEntrantSubstitute(), New Func(Of CallInfo(Of Integer), Integer)() {Function(x) MyNamespace.FooTests.Value}) + secondSubstitute.Id.Returns(Function(x) CreateReEntrantSubstitute(), New Func(Of CallInfo, Integer)() {Function(x) MyNamespace.FooTests.Value}) End Sub Private Function CreateReEntrantSubstitute() As Integer diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsOrdinaryMethodTests.cs index 8e5a1a7e..5721567d 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/ReEntrantSetupCodeFixProviderTests/ReturnsAsOrdinaryMethodTests.cs @@ -125,7 +125,7 @@ End Interface Public Sub Test() Dim secondSubstitute = NSubstitute.Substitute.[For](Of IFoo)() - SubstituteExtensions.Returns(secondSubstitute.Id, Function(x) CreateReEntrantSubstitute(), New Func(Of CallInfo(Of Integer), Integer)() {Function(x) MyNamespace.FooTests.Value}) + SubstituteExtensions.Returns(secondSubstitute.Id, Function(x) CreateReEntrantSubstitute(), New Func(Of CallInfo, Integer)() {Function(x) MyNamespace.FooTests.Value}) End Sub Private Function CreateReEntrantSubstitute() As Integer diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/ReEntrantReturnsSetupAnalyzerTests/ReturnsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/ReEntrantReturnsSetupAnalyzerTests/ReturnsAsOrdinaryMethodTests.cs index 04732321..734d3539 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/ReEntrantReturnsSetupAnalyzerTests/ReturnsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/ReEntrantReturnsSetupAnalyzerTests/ReturnsAsOrdinaryMethodTests.cs @@ -312,15 +312,15 @@ Private Function OtherReturn() As Integer Return 1 End Function - Private Function ReturnThisWithCallInfo(ByVal info As CallInfo(Of Integer)) As Integer + Private Function ReturnThisWithCallInfo(ByVal info As CallInfo) As Integer Return OtherReturn() End Function - Private Function MyMethod() As Func(Of CallInfo(Of Integer), Integer) + Private Function MyMethod() As Func(Of CallInfo, Integer) Return AddressOf ReturnThisWithCallInfo End Function - Private ReadOnly Property MyProperty As Func(Of CallInfo(Of Integer), Integer) + Private ReadOnly Property MyProperty As Func(Of CallInfo, Integer) Get Return AddressOf ReturnThisWithCallInfo End Get @@ -362,15 +362,15 @@ Private Function OtherReturn() As Integer Return 1 End Function - Private Function ReturnThisWithCallInfo(ByVal info As CallInfo(Of Integer)) As Integer + Private Function ReturnThisWithCallInfo(ByVal info As CallInfo) As Integer Return OtherReturn() End Function - Private Function MyMethod() As Func(Of CallInfo(Of Integer), Integer) + Private Function MyMethod() As Func(Of CallInfo, Integer) Return AddressOf ReturnThisWithCallInfo End Function - Private ReadOnly Property MyProperty As Func(Of CallInfo(Of Integer), Integer) + Private ReadOnly Property MyProperty As Func(Of CallInfo, Integer) Get Return AddressOf ReturnThisWithCallInfo End Get @@ -747,7 +747,7 @@ End Interface Public Class FooTests Public Sub Test() Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() - {method}(substitute.Bar(), Function(x) 1, New Func(Of CallInfo(Of Integer), Integer)() {{Function(y) OtherReturn()}}) + {method}(substitute.Bar(), Function(x) 1, New Func(Of CallInfo, Integer)() {{Function(y) OtherReturn()}}) End Sub Private Function OtherReturn() As Integer From 2166298afc457798095dcdfccec2317fa7bb4f63 Mon Sep 17 00:00:00 2001 From: tpodolak Date: Fri, 22 Jul 2022 16:46:12 +0200 Subject: [PATCH 02/10] GH-186 - SyncOverAsyncThrowsAnalyzer support for ThrowsAsync --- global.json | 2 +- ...tractSyncOverAsyncThrowsCodeFixProvider.cs | 4 +- .../AbstractSyncOverAsyncThrowsAnalyzer.cs | 2 +- .../Extensions/SubstituteSymbolExtensions.cs | 7 ++- .../MetadataNames.cs | 10 ++++ .../SyncOverAsyncThrowsDiagnosticVerifier.cs | 13 +++++ .../ThrowsAsExtensionMethodTests.cs | 47 ++++++++++++++++ ...sionMethodWithGenericTypeSpecifiedTests.cs | 47 ++++++++++++++++ .../ThrowsAsOrdinaryMethodTests.cs | 53 +++++++++++++++++++ ...naryMethodWithGenericTypeSpecifiedTests.cs | 47 ++++++++++++++++ .../ISyncOverAsyncThrowsDiagnosticVerifier.cs | 2 + .../SyncOverAsyncThrowsDiagnosticVerifier.cs | 13 +++++ .../ThrowsAsExtensionMethodTests.cs | 45 +++++++++++++++- ...sionMethodWithGenericTypeSpecifiedTests.cs | 37 +++++++++++++ .../ThrowsAsOrdinaryMethodTests.cs | 49 +++++++++++++++++ ...naryMethodWithGenericTypeSpecifiedTests.cs | 43 +++++++++++++++ 16 files changed, 414 insertions(+), 7 deletions(-) diff --git a/global.json b/global.json index 572a2a6f..19c87f2a 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "6.0.200" + "version": "6.0.300" } } diff --git a/src/NSubstitute.Analyzers.Shared/CodeFixProviders/AbstractSyncOverAsyncThrowsCodeFixProvider.cs b/src/NSubstitute.Analyzers.Shared/CodeFixProviders/AbstractSyncOverAsyncThrowsCodeFixProvider.cs index 44ff7305..de2d1713 100644 --- a/src/NSubstitute.Analyzers.Shared/CodeFixProviders/AbstractSyncOverAsyncThrowsCodeFixProvider.cs +++ b/src/NSubstitute.Analyzers.Shared/CodeFixProviders/AbstractSyncOverAsyncThrowsCodeFixProvider.cs @@ -45,7 +45,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) return; } - var replacementMethod = methodSymbol.IsThrowsForAnyArgsMethod() + var replacementMethod = methodSymbol.IsThrowsSyncForAnyArgsMethod() ? "ReturnsForAnyArgs" : "Returns"; @@ -93,7 +93,7 @@ private async Task CreateUpdatedInvocationExpression( CreateFromExceptionInvocationExpression(syntaxGenerator, invocationOperation); var returnsMethodName = - invocationSymbol.IsThrowsForAnyArgsMethod() ? "ReturnsForAnyArgs" : "Returns"; + invocationSymbol.IsThrowsSyncForAnyArgsMethod() ? "ReturnsForAnyArgs" : "Returns"; if (invocationSymbol.MethodKind == MethodKind.Ordinary) { diff --git a/src/NSubstitute.Analyzers.Shared/DiagnosticAnalyzers/AbstractSyncOverAsyncThrowsAnalyzer.cs b/src/NSubstitute.Analyzers.Shared/DiagnosticAnalyzers/AbstractSyncOverAsyncThrowsAnalyzer.cs index ae3e3910..bb35fc39 100644 --- a/src/NSubstitute.Analyzers.Shared/DiagnosticAnalyzers/AbstractSyncOverAsyncThrowsAnalyzer.cs +++ b/src/NSubstitute.Analyzers.Shared/DiagnosticAnalyzers/AbstractSyncOverAsyncThrowsAnalyzer.cs @@ -42,7 +42,7 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext) return; } - if (!methodSymbol.IsThrowLikeMethod()) + if (!methodSymbol.IsThrowSyncLikeMethod()) { return; } diff --git a/src/NSubstitute.Analyzers.Shared/Extensions/SubstituteSymbolExtensions.cs b/src/NSubstitute.Analyzers.Shared/Extensions/SubstituteSymbolExtensions.cs index 86d8ba04..b535a8cd 100644 --- a/src/NSubstitute.Analyzers.Shared/Extensions/SubstituteSymbolExtensions.cs +++ b/src/NSubstitute.Analyzers.Shared/Extensions/SubstituteSymbolExtensions.cs @@ -42,7 +42,12 @@ public static bool IsThrowLikeMethod(this ISymbol symbol) return IsMember(symbol, MetadataNames.ThrowsMethodNames); } - public static bool IsThrowsForAnyArgsMethod(this ISymbol symbol) + public static bool IsThrowSyncLikeMethod(this ISymbol symbol) + { + return IsMember(symbol, MetadataNames.ThrowsSyncMethodNames); + } + + public static bool IsThrowsSyncForAnyArgsMethod(this ISymbol symbol) { return IsMember( symbol, diff --git a/src/NSubstitute.Analyzers.Shared/MetadataNames.cs b/src/NSubstitute.Analyzers.Shared/MetadataNames.cs index 4d36d511..1e6d4147 100644 --- a/src/NSubstitute.Analyzers.Shared/MetadataNames.cs +++ b/src/NSubstitute.Analyzers.Shared/MetadataNames.cs @@ -18,7 +18,9 @@ internal class MetadataNames public const string NSubstituteReturnsMethod = "Returns"; public const string NSubstituteReturnsForAnyArgsMethod = "ReturnsForAnyArgs"; public const string NSubstituteThrowsMethod = "Throws"; + public const string NSubstituteThrowsAsyncMethod = "ThrowsAsync"; public const string NSubstituteThrowsForAnyArgsMethod = "ThrowsForAnyArgs"; + public const string NSubstituteThrowsAsyncForAnyArgsMethod = "ThrowsAsyncForAnyArgs"; public const string NSubstituteAndDoesMethod = "AndDoes"; public const string NSubstituteReturnsNullMethod = "ReturnsNull"; public const string NSubstituteReturnsNullForAnyArgsMethod = "ReturnsNullForAnyArgs"; @@ -56,6 +58,14 @@ internal class MetadataNames }; public static readonly IReadOnlyDictionary ThrowsMethodNames = new Dictionary + { + [NSubstituteThrowsMethod] = NSubstituteExceptionExtensionsFullTypeName, + [NSubstituteThrowsAsyncMethod] = NSubstituteExceptionExtensionsFullTypeName, + [NSubstituteThrowsForAnyArgsMethod] = NSubstituteExceptionExtensionsFullTypeName, + [NSubstituteThrowsAsyncForAnyArgsMethod] = NSubstituteExceptionExtensionsFullTypeName + }; + + public static readonly IReadOnlyDictionary ThrowsSyncMethodNames = new Dictionary { [NSubstituteThrowsMethod] = NSubstituteExceptionExtensionsFullTypeName, [NSubstituteThrowsForAnyArgsMethod] = NSubstituteExceptionExtensionsFullTypeName diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/SyncOverAsyncThrowsDiagnosticVerifier.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/SyncOverAsyncThrowsDiagnosticVerifier.cs index 00d77f6a..91aa24ad 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/SyncOverAsyncThrowsDiagnosticVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/SyncOverAsyncThrowsDiagnosticVerifier.cs @@ -21,6 +21,15 @@ public static IEnumerable ThrowsTestCases } } + public static IEnumerable ThrowsAsyncTestCases + { + get + { + yield return new object[] { "ThrowsAsync" }; + yield return new object[] { "ThrowsAsyncForAnyArgs" }; + } + } + protected DiagnosticDescriptor SyncOverAsyncThrowsDescriptor => DiagnosticDescriptors.SyncOverAsyncThrows; protected override DiagnosticAnalyzer DiagnosticAnalyzer { get; } = new SyncOverAsyncThrowsAnalyzer(); @@ -40,4 +49,8 @@ public static IEnumerable ThrowsTestCases [Theory] [MemberData(nameof(ThrowsTestCases))] public abstract Task ReportsNoDiagnostic_WhenUsedWithSyncMember(string method); + + [Theory] + [MemberData(nameof(ThrowsAsyncTestCases))] + public abstract Task ReportsNoDiagnostic_WhenThrowsAsyncUsed(string method); } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodTests.cs index cd607e76..554903e1 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodTests.cs @@ -133,4 +133,51 @@ public void Test() await VerifyNoDiagnostic(source); } + + public override async Task ReportsNoDiagnostic_WhenThrowsAsyncUsed(string method) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + Task FooBar(); + + Task Foo {{ get; set; }} + Task FooBarBar {{ get; set; }} + + Task this[int x] {{ get; set; }} + Task this[int x, int y] {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute.Bar().{method}(new Exception()); + substitute.Bar().{method}(ex: new Exception()); + substitute.FooBar().{method}(new Exception()); + substitute.FooBar().{method}(ex: new Exception()); + + substitute.Foo.{method}(new Exception()); + substitute.Foo.{method}(ex: new Exception()); + substitute.FooBarBar.{method}(new Exception()); + substitute.FooBarBar.{method}(ex: new Exception()); + + substitute[0].{method}(new Exception()); + substitute[0].{method}(ex: new Exception()); + substitute[0, 0].{method}(new Exception()); + substitute[0, 0].{method}(ex: new Exception()); + }} + }} +}}"; + + await VerifyNoDiagnostic(source); + } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs index a2a1839e..8b4b6042 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs @@ -124,4 +124,51 @@ public void Test() await VerifyNoDiagnostic(source); } + + public override async Task ReportsNoDiagnostic_WhenThrowsAsyncUsed(string method) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + Task FooBar(); + + Task Foo {{ get; set; }} + Task FooBarBar {{ get; set; }} + + Task this[int x] {{ get; set; }} + Task this[int x, int y] {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute.Bar().{method}(); + substitute.Bar().{method}(); + substitute.FooBar().{method}(); + substitute.FooBar().{method}(); + + substitute.Foo.{method}(); + substitute.Foo.{method}(); + substitute.FooBarBar.{method}(); + substitute.FooBarBar.{method}(); + + substitute[0].{method}(); + substitute[0].{method}(); + substitute[0, 0].{method}(); + substitute[0, 0].{method}(); + }} + }} +}}"; + + await VerifyNoDiagnostic(source); + } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs index 7f7697ac..0194d8b7 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs @@ -142,4 +142,57 @@ public void Test() await VerifyNoDiagnostic(source); } + + public override async Task ReportsNoDiagnostic_WhenThrowsAsyncUsed(string method) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + Task FooBar(); + + Task Foo {{ get; set; }} + Task FooBarBar {{ get; set; }} + + Task this[int x] {{ get; set; }} + Task this[int x, int y] {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{method}(substitute.Bar(), new Exception()); + ExceptionExtensions.{method}(value: substitute.Bar(), ex: new Exception()); + ExceptionExtensions.{method}(ex: new Exception(), value: substitute.Bar()); + ExceptionExtensions.{method}(substitute.FooBar(), new Exception()); + ExceptionExtensions.{method}(value: substitute.FooBar(), ex: new Exception()); + ExceptionExtensions.{method}(ex: new Exception(), value: substitute.FooBar()); + + ExceptionExtensions.{method}(substitute.Foo, new Exception()); + ExceptionExtensions.{method}(value: substitute.Foo, ex: new Exception()); + ExceptionExtensions.{method}(ex: new Exception(), value: substitute.Foo); + ExceptionExtensions.{method}(substitute.FooBarBar, new Exception()); + ExceptionExtensions.{method}(value: substitute.FooBarBar, ex: new Exception()); + ExceptionExtensions.{method}(ex: new Exception(), value: substitute.FooBarBar); + + ExceptionExtensions.{method}(substitute[0], new Exception()); + ExceptionExtensions.{method}(value: substitute[0], ex: new Exception()); + ExceptionExtensions.{method}(ex: new Exception(), value: substitute[0]); + ExceptionExtensions.{method}(substitute[0, 0], new Exception()); + ExceptionExtensions.{method}(value: substitute[0, 0], ex: new Exception()); + ExceptionExtensions.{method}(ex: new Exception(), value: substitute[0, 0]); + }} + }} +}}"; + + await VerifyNoDiagnostic(source); + } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index e95ba704..5dec06b5 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -133,4 +133,51 @@ public void Test() await VerifyNoDiagnostic(source); } + + public override async Task ReportsNoDiagnostic_WhenThrowsAsyncUsed(string method) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + Task FooBar(); + + Task Foo {{ get; set; }} + Task FooBarBar {{ get; set; }} + + Task this[int x] {{ get; set; }} + Task this[int x, int y] {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{method}(substitute.Bar()); + ExceptionExtensions.{method}(value: substitute.Bar()); + ExceptionExtensions.{method}(substitute.FooBar()); + ExceptionExtensions.{method}(value: substitute.FooBar()); + + ExceptionExtensions.{method}(substitute.Foo); + ExceptionExtensions.{method}(value: substitute.Foo); + ExceptionExtensions.{method}(substitute.FooBarBar); + ExceptionExtensions.{method}(value: substitute.FooBarBar); + + ExceptionExtensions.{method}(substitute[0]); + ExceptionExtensions.{method}(value: substitute[0]); + ExceptionExtensions.{method}(substitute[0, 0]); + ExceptionExtensions.{method}(value: substitute[0, 0]); + }} + }} +}}"; + + await VerifyNoDiagnostic(source); + } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.Shared/DiagnosticAnalyzers/ISyncOverAsyncThrowsDiagnosticVerifier.cs b/tests/NSubstitute.Analyzers.Tests.Shared/DiagnosticAnalyzers/ISyncOverAsyncThrowsDiagnosticVerifier.cs index 5f456c63..87355dc6 100644 --- a/tests/NSubstitute.Analyzers.Tests.Shared/DiagnosticAnalyzers/ISyncOverAsyncThrowsDiagnosticVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.Shared/DiagnosticAnalyzers/ISyncOverAsyncThrowsDiagnosticVerifier.cs @@ -11,4 +11,6 @@ public interface ISyncOverAsyncThrowsDiagnosticVerifier Task ReportsDiagnostic_WhenUsedInTaskReturningIndexer(string method); Task ReportsNoDiagnostic_WhenUsedWithSyncMember(string method); + + Task ReportsNoDiagnostic_WhenThrowsAsyncUsed(string method); } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/SyncOverAsyncThrowsDiagnosticVerifier.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/SyncOverAsyncThrowsDiagnosticVerifier.cs index 725b0bdf..ac5bf796 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/SyncOverAsyncThrowsDiagnosticVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/SyncOverAsyncThrowsDiagnosticVerifier.cs @@ -21,6 +21,15 @@ public static IEnumerable ThrowsTestCases } } + public static IEnumerable ThrowsAsyncTestCases + { + get + { + yield return new object[] { "ThrowsAsync" }; + yield return new object[] { "ThrowsAsyncForAnyArgs" }; + } + } + protected DiagnosticDescriptor SyncOverAsyncThrowsDescriptor => DiagnosticDescriptors.SyncOverAsyncThrows; protected override DiagnosticAnalyzer DiagnosticAnalyzer { get; } = new SyncOverAsyncThrowsAnalyzer(); @@ -40,4 +49,8 @@ public static IEnumerable ThrowsTestCases [Theory] [MemberData(nameof(ThrowsTestCases))] public abstract Task ReportsNoDiagnostic_WhenUsedWithSyncMember(string method); + + [Theory] + [MemberData(nameof(ThrowsAsyncTestCases))] + public abstract Task ReportsNoDiagnostic_WhenThrowsAsyncUsed(string method); } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodTests.cs index 54f5d59f..7262ec27 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodTests.cs @@ -72,8 +72,6 @@ Default Property Item(ByVal x As Integer) As Task Default Property Item(ByVal x As Integer, ByVal y As Integer) As Task(Of Object) End Interface - - Public Class FooTests Public Sub Test() Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() @@ -118,4 +116,47 @@ End Namespace await VerifyNoDiagnostic(source); } + + public override async Task ReportsNoDiagnostic_WhenThrowsAsyncUsed(string method) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + Function FooBar() As Task(Of Object) + + Property Foo As Task + Property FooBarBar As Task(Of Object) + + Default Property Item(ByVal x As Integer) As Task + Default Property Item(ByVal x As Integer, ByVal y As Integer) As Task(Of Object) + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute.Bar().{method}(New Exception()) + substitute.Bar().{method}(ex := New Exception()) + substitute.FooBar().{method}(New Exception()) + substitute.FooBar().{method}(ex := New Exception()) + + substitute.Foo.{method}(New Exception()) + substitute.Foo.{method}(ex := New Exception()) + substitute.FooBarBar.{method}(New Exception()) + substitute.FooBarBar.{method}(ex := New Exception()) + + substitute(0).{method}(New Exception()) + substitute(0).{method}(ex := New Exception()) + substitute(0, 0).{method}(New Exception()) + substitute(0, 0).{method}(ex := New Exception()) + End Sub + End Class +End Namespace"; + + await VerifyNoDiagnostic(source); + } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs index 27661b60..3d7e3b48 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs @@ -107,4 +107,41 @@ End Namespace await VerifyNoDiagnostic(source); } + + public override async Task ReportsNoDiagnostic_WhenThrowsAsyncUsed(string method) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + Function FooBar() As Task(Of Object) + + Property Foo As Task + Property FooBarBar As Task(Of Object) + + Default Property Item(ByVal x As Integer) As Task + Default Property Item(ByVal x As Integer, ByVal y As Integer) As Task(Of Object) + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute.Bar().{method}(Of Exception) + substitute.FooBar().{method}(Of Exception) + + substitute.Foo.{method}(Of Exception) + substitute.FooBarBar.{method}(Of Exception) + + substitute(0).{method}(Of Exception) + substitute(0, 0).{method}(Of Exception) + End Sub + End Class +End Namespace"; + + await VerifyNoDiagnostic(source); + } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs index dab017c1..99e84521 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs @@ -124,4 +124,53 @@ End Namespace await VerifyNoDiagnostic(source); } + + public override async Task ReportsNoDiagnostic_WhenThrowsAsyncUsed(string method) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + Function FooBar() As Task(Of Object) + + Property Foo As Task + Property FooBarBar As Task(Of Object) + + Default Property Item(ByVal x As Integer) As Task + Default Property Item(ByVal x As Integer, ByVal y As Integer) As Task(Of Object) + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{method}(substitute.Bar(), New Exception()) + ExceptionExtensions.{method}(value := substitute.Bar(), ex := New Exception()) + ExceptionExtensions.{method}(ex := New Exception(), value := substitute.Bar()) + ExceptionExtensions.{method}(substitute.FooBar(), New Exception()) + ExceptionExtensions.{method}(value := substitute.FooBar(), ex := New Exception()) + ExceptionExtensions.{method}(ex := New Exception(), value := substitute.FooBar()) + + ExceptionExtensions.{method}(substitute.Foo, New Exception()) + ExceptionExtensions.{method}(value := substitute.Foo, ex := New Exception()) + ExceptionExtensions.{method}(ex := New Exception(), value := substitute.Foo) + ExceptionExtensions.{method}(substitute.FooBarBar, New Exception()) + ExceptionExtensions.{method}(value := substitute.FooBarBar, ex := New Exception()) + ExceptionExtensions.{method}(ex := New Exception(), value := substitute.FooBarBar) + + ExceptionExtensions.{method}(substitute(0), New Exception()) + ExceptionExtensions.{method}(value := substitute(0), ex := New Exception()) + ExceptionExtensions.{method}(ex := New Exception(), value := substitute(0)) + ExceptionExtensions.{method}(substitute(0, 0), New Exception()) + ExceptionExtensions.{method}(value := substitute(0, 0), ex := New Exception()) + ExceptionExtensions.{method}(ex := New Exception(), value := substitute(0, 0)) + End Sub + End Class +End Namespace"; + + await VerifyNoDiagnostic(source); + } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index f9a042ba..90c066ef 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/SyncOverAsyncThrowsAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -115,4 +115,47 @@ End Namespace await VerifyNoDiagnostic(source); } + + public override async Task ReportsNoDiagnostic_WhenThrowsAsyncUsed(string method) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + Function FooBar() As Task(Of Object) + + Property Foo As Task + Property FooBarBar As Task(Of Object) + + Default Property Item(ByVal x As Integer) As Task + Default Property Item(ByVal x As Integer, ByVal y As Integer) As Task(Of Object) + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{method}(Of Exception)(substitute.Bar()) + ExceptionExtensions.{method}(Of Exception)(value := substitute.Bar()) + ExceptionExtensions.{method}(Of Exception)(substitute.FooBar()) + ExceptionExtensions.{method}(Of Exception)(value := substitute.FooBar()) + + ExceptionExtensions.{method}(Of Exception)(substitute.Foo) + ExceptionExtensions.{method}(Of Exception)(value := substitute.Foo) + ExceptionExtensions.{method}(Of Exception)(substitute.FooBarBar) + ExceptionExtensions.{method}(Of Exception)(value := substitute.FooBarBar) + + ExceptionExtensions.{method}(Of Exception)(substitute(0)) + ExceptionExtensions.{method}(Of Exception)(value := substitute(0)) + ExceptionExtensions.{method}(Of Exception)(substitute(0, 0)) + ExceptionExtensions.{method}(Of Exception)(value := substitute(0, 0)) + End Sub + End Class +End Namespace"; + + await VerifyNoDiagnostic(source); + } } \ No newline at end of file From cc5fdfe0a53443c740e3ecc3fab65678c450ba32 Mon Sep 17 00:00:00 2001 From: tpodolak Date: Fri, 22 Jul 2022 16:46:13 +0200 Subject: [PATCH 03/10] GH-186 - NonSubstitableMemberAnalyzer support for ThrowsAsync like methods --- .../ThrowsAsExtensionMethodTests.cs | 230 +++++++++------- ...sionMethodWithGenericTypeSpecifiedTests.cs | 230 +++++++++------- .../ThrowsAsOrdinaryMethodTests.cs | 238 +++++++++------- ...naryMethodWithGenericTypeSpecifiedTests.cs | 238 +++++++++------- .../ThrowsAsExtensionMethodTests.cs | 245 ++++++++++------- .../ThrowsAsOrdinaryMethodTests.cs | 250 ++++++++++------- ...naryMethodWithGenericTypeSpecifiedTests.cs | 253 +++++++++++------- 7 files changed, 996 insertions(+), 688 deletions(-) diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs index 837c1edb..315b1e5f 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs @@ -6,12 +6,13 @@ namespace NSubstitute.Analyzers.Tests.CSharp.DiagnosticAnalyzerTests.NonSubstitutableMemberAnalyzerTests; -[CombinatoryData("Throws", "ThrowsForAnyArgs")] +[CombinatoryData("Throws", "ThrowsAsync", "ThrowsForAnyArgs", "ThrowsAsyncForAnyArgs")] public class ThrowsAsExtensionMethodTests : NonSubstitutableMemberDiagnosticVerifier { public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -19,9 +20,9 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar() + public Task Bar() {{ - return 2; + return Task.FromResult(1); }} }} @@ -61,6 +62,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForStaticMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -68,9 +70,9 @@ namespace MyNamespace {{ public class Foo {{ - public static int Bar() + public static Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} @@ -89,6 +91,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -96,9 +99,9 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} @@ -117,6 +120,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForNonSealedOverrideMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -124,15 +128,15 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} public class Foo2 : Foo {{ - public override int Bar() => 1; + public override Task Bar() => Task.FromResult(1); }} public class FooTests @@ -150,6 +154,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenDataFlowAnalysisIsRequired(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -157,9 +162,9 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} @@ -179,6 +184,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForDelegate(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; using System; @@ -189,7 +195,7 @@ public class FooTests {{ public void Test() {{ - var substitute = Substitute.For>(); + var substitute = Substitute.For>>(); substitute().{method}(new Exception()); }} }} @@ -200,6 +206,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForSealedOverrideMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -207,15 +214,15 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} public class Foo2 : Foo {{ - public sealed override int Bar() => 1; + public sealed override Task Bar() => Task.FromResult(1); }} public class FooTests @@ -234,6 +241,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -241,7 +249,7 @@ namespace MyNamespace {{ public abstract class Foo {{ - public abstract int Bar(); + public abstract Task Bar(); }} public class FooTests @@ -260,6 +268,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -267,7 +276,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(); + Task Bar(); }} public class FooTests @@ -285,6 +294,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -292,7 +302,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar {{ get; }} + Task Bar {{ get; }} }} public class FooTests @@ -310,6 +320,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForGenericInterfaceMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -317,7 +328,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(); + Task Bar(); }} public class FooTests @@ -335,6 +346,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -342,7 +354,7 @@ namespace MyNamespace {{ public abstract class Foo {{ - public abstract int Bar {{ get; }} + public abstract Task Bar {{ get; }} }} public class FooTests @@ -361,6 +373,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceIndexer(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -368,7 +381,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int this[int i] {{ get; }} + Task this[int i] {{ get; }} }} public class FooTests @@ -386,6 +399,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -393,7 +407,7 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar {{ get; }} + public virtual Task Bar {{ get; }} }} public class FooTests @@ -412,6 +426,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -419,7 +434,7 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; }} + public Task Bar {{ get; }} }} public class FooTests @@ -438,6 +453,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualIndexer(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -445,7 +461,7 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int this[int x] => 0; + public virtual Task this[int x] => Task.FromResult(0); }} public class FooTests @@ -463,6 +479,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualIndexer(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -470,7 +487,7 @@ namespace MyNamespace {{ public class Foo {{ - public int this[int x] => 0; + public Task this[int x] => Task.FromResult(0); }} public class FooTests @@ -490,13 +507,14 @@ public override async Task ReportsNoDiagnostics_WhenUsingUnfortunatelyNamedMetho { var source = $@" using System; +using System.Threading.Tasks; namespace NSubstitute {{ public class Foo {{ - public int Bar() + public Task Bar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -507,10 +525,20 @@ public static T Throws(this object value, T ex) where T: Exception return default(T); }} + public static T ThrowsAsync(this Task value, T ex) where T: Exception + {{ + return default(T); + }} + public static T ThrowsForAnyArgs(this object value, T ex) where T: Exception {{ return default(T); }} + + public static T ThrowsAsyncForAnyArgs(this Task value, T ex) where T: Exception + {{ + return default(T); + }} }} public class FooTests @@ -530,6 +558,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Bar", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -537,9 +566,9 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; }} + public Task Bar {{ get; }} - public int FooBar {{ get; }} + public Task FooBar {{ get; }} }} public class FooTests @@ -561,23 +590,24 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Bar", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; namespace MyNamespace {{ - public class Foo + public class Foo where T : Task {{ public T Bar {{ get; }} - public int FooBar {{ get; }} + public Task FooBar {{ get; }} }} public class FooTests {{ public void Test() {{ - var substitute = NSubstitute.Substitute.For>(); + var substitute = NSubstitute.Substitute.For>(); substitute.Bar.{method}(new Exception()); [|substitute.FooBar|].{method}(new Exception()); }} @@ -592,6 +622,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar(System.Int32,System.Int32)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -599,14 +630,14 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar(int x) + public Task Bar(int x) {{ - return 1; + return Task.FromResult(1); }} - public int Bar(int x, int y) + public Task Bar(int x, int y) {{ - return 2; + return Task.FromResult(2); }} }} @@ -629,6 +660,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar``1(``0,``0)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -636,14 +668,14 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar(int x) + public Task Bar(int x) {{ - return 1; + return Task.FromResult(1); }} - public int Bar(T x, T y) + public Task Bar(T x, T y) {{ - return 2; + return Task.FromResult(2); }} }} @@ -666,6 +698,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Item(System.Int32,System.Int32)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -673,8 +706,8 @@ namespace MyNamespace {{ public class Foo {{ - public int this[int x] => 0; - public int this[int x, int y] => 0; + public Task this[int x] => Task.FromResult(0); + public Task this[int x, int y] => Task.FromResult(0); }} public class FooTests @@ -696,6 +729,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Item(`0,`0)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -703,8 +737,8 @@ namespace MyNamespace {{ public class Foo {{ - public int this[T x] => 0; - public int this[T x, T y] => 0; + public Task this[T x] => Task.FromResult(0); + public Task this[T x, T y] => Task.FromResult(0); }} public class FooTests @@ -726,6 +760,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -733,21 +768,21 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} public class FooBarBar {{ - public int Bar {{ get;set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get;set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -787,6 +822,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo`1", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -794,21 +830,21 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} public class FooBarBar {{ - public int Bar {{ get;set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get;set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -848,6 +884,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("N:MyNamespace", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -855,11 +892,11 @@ namespace MyOtherNamespace {{ public class FooBarBar {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} }} @@ -869,11 +906,11 @@ namespace MyNamespace using MyOtherNamespace; public class Foo {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -910,9 +947,10 @@ public void Test() public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressingExtensionMethod(string method) { - Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(System.Object)~System.Int32", NonVirtualSetupSpecificationDescriptor.Id); + Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(System.Object)~System.Threading.Tasks.Task{System.Int32}", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -933,20 +971,20 @@ public static class MyExtensions {{ public static IBar Bar {{ get; set; }} - public static int GetBar(this object @object) + public static Task GetBar(this object @object) {{ return Bar.Foo(@object); }} - public static int GetFooBar(this object @object) + public static Task GetFooBar(this object @object) {{ - return 1; + return Task.FromResult(1); }} }} public interface IBar {{ - int Foo(object @obj); + Task Foo(object @obj); }} }}"; @@ -956,6 +994,7 @@ public interface IBar public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToNotApplied(string method, string call, string message) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -963,16 +1002,16 @@ namespace MyNamespace {{ public class Foo {{ - internal virtual int Bar {{ get; }} + internal virtual Task Bar {{ get; }} - internal virtual int FooBar() + internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - internal virtual int this[int x] + internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} @@ -992,6 +1031,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToApplied(string method, string call) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; using System.Runtime.CompilerServices; @@ -1003,16 +1043,16 @@ namespace MyNamespace {{ public class Foo {{ - internal virtual int Bar {{ get; }} + internal virtual Task Bar {{ get; }} - internal virtual int FooBar() + internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - internal virtual int this[int x] + internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} @@ -1032,6 +1072,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToAppliedToWrongAssembly(string method, string call, string message) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; using System.Runtime.CompilerServices; @@ -1041,16 +1082,16 @@ namespace MyNamespace {{ public class Foo {{ - internal virtual int Bar {{ get; }} + internal virtual Task Bar {{ get; }} - internal virtual int FooBar() + internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - internal virtual int this[int x] + internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} @@ -1070,6 +1111,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForProtectedInternalVirtualMember(string method, string call) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -1077,16 +1119,16 @@ namespace MyNamespace {{ public class Foo {{ - protected internal virtual int Bar {{ get; }} + protected internal virtual Task Bar {{ get; }} - protected internal virtual int FooBar() + protected internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - protected internal virtual int this[int x] + protected internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs index d7dbe5ee..018b8112 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs @@ -6,12 +6,13 @@ namespace NSubstitute.Analyzers.Tests.CSharp.DiagnosticAnalyzerTests.NonSubstitutableMemberAnalyzerTests; -[CombinatoryData("Throws", "ThrowsForAnyArgs")] +[CombinatoryData("Throws", "ThrowsAsync", "ThrowsForAnyArgs", "ThrowsAsyncForAnyArgs")] public class ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests : NonSubstitutableMemberDiagnosticVerifier { public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -19,9 +20,9 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar() + public Task Bar() {{ - return 2; + return Task.FromResult(1); }} }} @@ -61,6 +62,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForStaticMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -68,9 +70,9 @@ namespace MyNamespace {{ public class Foo {{ - public static int Bar() + public static Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} @@ -89,6 +91,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -96,9 +99,9 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} @@ -117,6 +120,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForNonSealedOverrideMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -124,15 +128,15 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} public class Foo2 : Foo {{ - public override int Bar() => 1; + public override Task Bar() => Task.FromResult(1); }} public class FooTests @@ -150,6 +154,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenDataFlowAnalysisIsRequired(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -157,9 +162,9 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} @@ -179,6 +184,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForDelegate(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; using System; @@ -189,7 +195,7 @@ public class FooTests {{ public void Test() {{ - var substitute = Substitute.For>(); + var substitute = Substitute.For>>(); substitute().{method}(); }} }} @@ -200,6 +206,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForSealedOverrideMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -207,15 +214,15 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} public class Foo2 : Foo {{ - public sealed override int Bar() => 1; + public sealed override Task Bar() => Task.FromResult(1); }} public class FooTests @@ -234,6 +241,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -241,7 +249,7 @@ namespace MyNamespace {{ public abstract class Foo {{ - public abstract int Bar(); + public abstract Task Bar(); }} public class FooTests @@ -260,6 +268,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -267,7 +276,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(); + Task Bar(); }} public class FooTests @@ -285,6 +294,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -292,7 +302,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar {{ get; }} + Task Bar {{ get; }} }} public class FooTests @@ -310,6 +320,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForGenericInterfaceMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -317,7 +328,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(); + Task Bar(); }} public class FooTests @@ -335,6 +346,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -342,7 +354,7 @@ namespace MyNamespace {{ public abstract class Foo {{ - public abstract int Bar {{ get; }} + public abstract Task Bar {{ get; }} }} public class FooTests @@ -361,6 +373,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceIndexer(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -368,7 +381,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int this[int i] {{ get; }} + Task this[int i] {{ get; }} }} public class FooTests @@ -386,6 +399,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -393,7 +407,7 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar {{ get; }} + public virtual Task Bar {{ get; }} }} public class FooTests @@ -412,6 +426,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -419,7 +434,7 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; }} + public Task Bar {{ get; }} }} public class FooTests @@ -438,6 +453,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualIndexer(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -445,7 +461,7 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int this[int x] => 0; + public virtual Task this[int x] => Task.FromResult(0); }} public class FooTests @@ -463,6 +479,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualIndexer(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -470,7 +487,7 @@ namespace MyNamespace {{ public class Foo {{ - public int this[int x] => 0; + public Task this[int x] => Task.FromResult(0); }} public class FooTests @@ -490,13 +507,14 @@ public override async Task ReportsNoDiagnostics_WhenUsingUnfortunatelyNamedMetho { var source = $@" using System; +using System.Threading.Tasks; namespace NSubstitute {{ public class Foo {{ - public int Bar() + public Task Bar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -507,10 +525,20 @@ public static T Throws(this object value) where T: Exception return default(T); }} + public static T ThrowsAsync(this Task value) where T: Exception + {{ + return default(T); + }} + public static T ThrowsForAnyArgs(this object value) where T: Exception {{ return default(T); }} + + public static T ThrowsAsyncForAnyArgs(this Task value) where T: Exception + {{ + return default(T); + }} }} public class FooTests @@ -530,6 +558,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Bar", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -537,9 +566,9 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; }} + public Task Bar {{ get; }} - public int FooBar {{ get; }} + public Task FooBar {{ get; }} }} public class FooTests @@ -561,23 +590,24 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Bar", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; namespace MyNamespace {{ - public class Foo + public class Foo where T : Task {{ public T Bar {{ get; }} - public int FooBar {{ get; }} + public Task FooBar {{ get; }} }} public class FooTests {{ public void Test() {{ - var substitute = NSubstitute.Substitute.For>(); + var substitute = NSubstitute.Substitute.For>>(); substitute.Bar.{method}(); [|substitute.FooBar|].{method}(); }} @@ -592,6 +622,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar(System.Int32,System.Int32)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -599,14 +630,14 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar(int x) + public Task Bar(int x) {{ - return 1; + return Task.FromResult(1); }} - public int Bar(int x, int y) + public Task Bar(int x, int y) {{ - return 2; + return Task.FromResult(2); }} }} @@ -629,6 +660,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar``1(``0,``0)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -636,14 +668,14 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar(int x) + public Task Bar(int x) {{ - return 1; + return Task.FromResult(1); }} - public int Bar(T x, T y) + public Task Bar(T x, T y) {{ - return 2; + return Task.FromResult(2); }} }} @@ -666,6 +698,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Item(System.Int32,System.Int32)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -673,8 +706,8 @@ namespace MyNamespace {{ public class Foo {{ - public int this[int x] => 0; - public int this[int x, int y] => 0; + public Task this[int x] => Task.FromResult(0); + public Task this[int x, int y] => Task.FromResult(0); }} public class FooTests @@ -696,6 +729,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Item(`0,`0)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -703,8 +737,8 @@ namespace MyNamespace {{ public class Foo {{ - public int this[T x] => 0; - public int this[T x, T y] => 0; + public Task this[T x] => Task.FromResult(0); + public Task this[T x, T y] => Task.FromResult(0); }} public class FooTests @@ -726,6 +760,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -733,21 +768,21 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} public class FooBarBar {{ - public int Bar {{ get;set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get;set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -787,6 +822,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo`1", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -794,21 +830,21 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} public class FooBarBar {{ - public int Bar {{ get;set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get;set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -848,6 +884,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("N:MyNamespace", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -855,11 +892,11 @@ namespace MyOtherNamespace {{ public class FooBarBar {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} }} @@ -869,11 +906,11 @@ namespace MyNamespace using MyOtherNamespace; public class Foo {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -910,9 +947,10 @@ public void Test() public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressingExtensionMethod(string method) { - Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(System.Object)~System.Int32", NonVirtualSetupSpecificationDescriptor.Id); + Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(System.Object)~System.Threading.Tasks.Task{System.Int32}", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -933,20 +971,20 @@ public static class MyExtensions {{ public static IBar Bar {{ get; set; }} - public static int GetBar(this object @object) + public static Task GetBar(this object @object) {{ return Bar.Foo(@object); }} - public static int GetFooBar(this object @object) + public static Task GetFooBar(this object @object) {{ - return 1; + return Task.FromResult(1); }} }} public interface IBar {{ - int Foo(object @obj); + Task Foo(object @obj); }} }}"; @@ -956,6 +994,7 @@ public interface IBar public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToNotApplied(string method, string call, string message) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -963,16 +1002,16 @@ namespace MyNamespace {{ public class Foo {{ - internal virtual int Bar {{ get; }} + internal virtual Task Bar {{ get; }} - internal virtual int FooBar() + internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - internal virtual int this[int x] + internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} @@ -992,6 +1031,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToApplied(string method, string call) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; using System.Runtime.CompilerServices; @@ -1003,16 +1043,16 @@ namespace MyNamespace {{ public class Foo {{ - internal virtual int Bar {{ get; }} + internal virtual Task Bar {{ get; }} - internal virtual int FooBar() + internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - internal virtual int this[int x] + internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} @@ -1032,6 +1072,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToAppliedToWrongAssembly(string method, string call, string message) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; using System.Runtime.CompilerServices; @@ -1041,16 +1082,16 @@ namespace MyNamespace {{ public class Foo {{ - internal virtual int Bar {{ get; }} + internal virtual Task Bar {{ get; }} - internal virtual int FooBar() + internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - internal virtual int this[int x] + internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} @@ -1070,6 +1111,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForProtectedInternalVirtualMember(string method, string call) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -1077,16 +1119,16 @@ namespace MyNamespace {{ public class Foo {{ - protected internal virtual int Bar {{ get; }} + protected internal virtual Task Bar {{ get; }} - protected internal virtual int FooBar() + protected internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - protected internal virtual int this[int x] + protected internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs index f25e455b..54b9a02f 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using System.Threading.Tasks; using NSubstitute.Analyzers.Shared.Settings; using NSubstitute.Analyzers.Tests.Shared.Extensibility; @@ -6,12 +6,17 @@ namespace NSubstitute.Analyzers.Tests.CSharp.DiagnosticAnalyzerTests.NonSubstitutableMemberAnalyzerTests; -[CombinatoryData("ExceptionExtensions.Throws", "ExceptionExtensions.ThrowsForAnyArgs")] +[CombinatoryData( + "ExceptionExtensions.Throws", + "ExceptionExtensions.ThrowsAsync", + "ExceptionExtensions.ThrowsForAnyArgs", + "ExceptionExtensions.ThrowsAsyncForAnyArgs")] public class ThrowsAsOrdinaryMethodTests : NonSubstitutableMemberDiagnosticVerifier { public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -19,9 +24,9 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar() + public Task Bar() {{ - return 2; + return Task.FromResult(1); }} }} @@ -64,6 +69,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForStaticMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -71,9 +77,9 @@ namespace MyNamespace {{ public class Foo {{ - public static int Bar() + public static Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} @@ -94,6 +100,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -101,9 +108,9 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} @@ -124,6 +131,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForNonSealedOverrideMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -131,15 +139,15 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} public class Foo2 : Foo {{ - public override int Bar() => 1; + public override Task Bar() => Task.FromResult(1); }} public class FooTests @@ -159,6 +167,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenDataFlowAnalysisIsRequired(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -166,9 +175,9 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} @@ -190,6 +199,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForDelegate(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; using System; @@ -200,7 +210,7 @@ public class FooTests {{ public void Test() {{ - var substitute = Substitute.For>(); + var substitute = Substitute.For>>(); {method}(substitute(), new Exception()); {method}(value: substitute(), ex: new Exception()); {method}(ex: new Exception(), value: substitute()); @@ -213,6 +223,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForSealedOverrideMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -220,15 +231,15 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} public class Foo2 : Foo {{ - public sealed override int Bar() => 1; + public sealed override Task Bar() => Task.FromResult(1); }} public class FooTests @@ -249,6 +260,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -256,7 +268,7 @@ namespace MyNamespace {{ public abstract class Foo {{ - public abstract int Bar(); + public abstract Task Bar(); }} public class FooTests @@ -277,6 +289,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -284,7 +297,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(); + Task Bar(); }} public class FooTests @@ -304,6 +317,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -311,7 +325,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar {{ get; }} + Task Bar {{ get; }} }} public class FooTests @@ -331,6 +345,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForGenericInterfaceMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -338,7 +353,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(); + Task Bar(); }} public class FooTests @@ -358,6 +373,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -365,7 +381,7 @@ namespace MyNamespace {{ public abstract class Foo {{ - public abstract int Bar {{ get; }} + public abstract Task Bar {{ get; }} }} public class FooTests @@ -386,6 +402,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceIndexer(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -393,7 +410,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int this[int i] {{ get; }} + Task this[int i] {{ get; }} }} public class FooTests @@ -413,6 +430,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -420,7 +438,7 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar {{ get; }} + public virtual Task Bar {{ get; }} }} public class FooTests @@ -441,6 +459,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -448,7 +467,7 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; }} + public Task Bar {{ get; }} }} public class FooTests @@ -469,6 +488,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualIndexer(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -476,7 +496,7 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int this[int x] => 0; + public virtual Task this[int x] => Task.FromResult(0); }} public class FooTests @@ -496,6 +516,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualIndexer(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -503,7 +524,7 @@ namespace MyNamespace {{ public class Foo {{ - public int this[int x] => 0; + public Task this[int x] => Task.FromResult(0); }} public class FooTests @@ -525,13 +546,14 @@ public override async Task ReportsNoDiagnostics_WhenUsingUnfortunatelyNamedMetho { var source = $@" using System; +using System.Threading.Tasks; namespace NSubstitute {{ public class Foo {{ - public int Bar() + public Task Bar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -542,10 +564,20 @@ public static T Throws(this object value, T ex) where T: Exception return default(T); }} + public static T ThrowsAsync(this Task value, T ex) where T: Exception + {{ + return default(T); + }} + public static T ThrowsForAnyArgs(this object value, T ex) where T: Exception {{ return default(T); }} + + public static T ThrowsAsyncForAnyArgs(this Task value, T ex) where T: Exception + {{ + return default(T); + }} }} public class FooTests @@ -567,6 +599,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Bar", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -574,9 +607,9 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; }} + public Task Bar {{ get; }} - public int FooBar {{ get; }} + public Task FooBar {{ get; }} }} public class FooTests @@ -598,23 +631,24 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Bar", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; namespace MyNamespace {{ - public class Foo + public class Foo where T : Task {{ public T Bar {{ get; }} - public int FooBar {{ get; }} + public Task FooBar {{ get; }} }} public class FooTests {{ public void Test() {{ - var substitute = NSubstitute.Substitute.For>(); + var substitute = NSubstitute.Substitute.For>>(); {method}(substitute.Bar, new Exception()); {method}([|substitute.FooBar|], new Exception()); }} @@ -629,6 +663,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar(System.Int32,System.Int32)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -636,14 +671,14 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar(int x) + public Task Bar(int x) {{ - return 1; + return Task.FromResult(1); }} - public int Bar(int x, int y) + public Task Bar(int x, int y) {{ - return 2; + return Task.FromResult(2); }} }} @@ -666,6 +701,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar``1(``0,``0)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -673,14 +709,14 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar(int x) + public Task Bar(int x) {{ - return 1; + return Task.FromResult(1); }} - public int Bar(T x, T y) + public Task Bar(T x, T y) {{ - return 2; + return Task.FromResult(2); }} }} @@ -703,6 +739,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Item(System.Int32,System.Int32)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -710,8 +747,8 @@ namespace MyNamespace {{ public class Foo {{ - public int this[int x] => 0; - public int this[int x, int y] => 0; + public Task this[int x] => Task.FromResult(0); + public Task this[int x, int y] => Task.FromResult(0); }} public class FooTests @@ -733,6 +770,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Item(`0,`0)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -740,8 +778,8 @@ namespace MyNamespace {{ public class Foo {{ - public int this[T x] => 0; - public int this[T x, T y] => 0; + public Task this[T x] => Task.FromResult(0); + public Task this[T x, T y] => Task.FromResult(0); }} public class FooTests @@ -763,6 +801,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -770,21 +809,21 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} public class FooBarBar {{ - public int Bar {{ get;set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get;set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -824,6 +863,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo`1", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -831,21 +871,21 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} public class FooBarBar {{ - public int Bar {{ get;set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get;set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -885,6 +925,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("N:MyNamespace", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -892,11 +933,11 @@ namespace MyOtherNamespace {{ public class FooBarBar {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} }} @@ -906,11 +947,11 @@ namespace MyNamespace using MyOtherNamespace; public class Foo {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -947,9 +988,10 @@ public void Test() public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressingExtensionMethod(string method) { - Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(System.Object)~System.Int32", NonVirtualSetupSpecificationDescriptor.Id); + Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(System.Object)~System.Threading.Tasks.Task{System.Int32}", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -970,20 +1012,20 @@ public static class MyExtensions {{ public static IBar Bar {{ get; set; }} - public static int GetBar(this object @object) + public static Task GetBar(this object @object) {{ return Bar.Foo(@object); }} - public static int GetFooBar(this object @object) + public static Task GetFooBar(this object @object) {{ - return 1; + return Task.FromResult(1); }} }} public interface IBar {{ - int Foo(object @obj); + Task Foo(object @obj); }} }}"; @@ -993,6 +1035,7 @@ public interface IBar public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToNotApplied(string method, string call, string message) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -1000,16 +1043,16 @@ namespace MyNamespace {{ public class Foo {{ - internal virtual object Bar {{ get; }} + internal virtual Task Bar {{ get; }} - internal virtual object FooBar() + internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - internal virtual object this[int x] + internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} @@ -1031,6 +1074,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToApplied(string method, string call) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; using System.Runtime.CompilerServices; @@ -1042,16 +1086,16 @@ namespace MyNamespace {{ public class Foo {{ - internal virtual object Bar {{ get; }} + internal virtual Task Bar {{ get; }} - internal virtual object FooBar() + internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - internal virtual object this[int x] + internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} @@ -1073,25 +1117,26 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToAppliedToWrongAssembly(string method, string call, string message) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; -using System.Runtime.CompilerServices; using NSubstitute.ExceptionExtensions; +using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo(""OtherAssembly"")] namespace MyNamespace {{ public class Foo {{ - internal virtual object Bar {{ get; }} + internal virtual Task Bar {{ get; }} - internal virtual object FooBar() + internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - internal virtual object this[int x] + internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} @@ -1113,6 +1158,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForProtectedInternalVirtualMember(string method, string call) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -1120,16 +1166,16 @@ namespace MyNamespace {{ public class Foo {{ - protected internal virtual object Bar {{ get; }} + protected internal virtual Task Bar {{ get; }} - protected internal virtual object FooBar() + protected internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - protected internal virtual object this[int x] + protected internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index de11388e..9e274f86 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using System.Threading.Tasks; using NSubstitute.Analyzers.Shared.Settings; using NSubstitute.Analyzers.Tests.Shared.Extensibility; @@ -6,12 +6,17 @@ namespace NSubstitute.Analyzers.Tests.CSharp.DiagnosticAnalyzerTests.NonSubstitutableMemberAnalyzerTests; -[CombinatoryData("ExceptionExtensions.Throws", "ExceptionExtensions.ThrowsForAnyArgs")] +[CombinatoryData( + "ExceptionExtensions.Throws", + "ExceptionExtensions.ThrowsAsync", + "ExceptionExtensions.ThrowsForAnyArgs", + "ExceptionExtensions.ThrowsAsyncForAnyArgs")] public class ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests : NonSubstitutableMemberDiagnosticVerifier { public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -19,9 +24,9 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar() + public Task Bar() {{ - return 2; + return Task.FromResult(1); }} }} @@ -61,6 +66,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForStaticMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -68,9 +74,9 @@ namespace MyNamespace {{ public class Foo {{ - public static int Bar() + public static Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} @@ -89,6 +95,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -96,9 +103,9 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} @@ -117,6 +124,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForNonSealedOverrideMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -124,15 +132,15 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} public class Foo2 : Foo {{ - public override int Bar() => 1; + public override Task Bar() => Task.FromResult(1); }} public class FooTests @@ -150,6 +158,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenDataFlowAnalysisIsRequired(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -157,9 +166,9 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} @@ -179,6 +188,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForDelegate(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; using System; @@ -189,7 +199,7 @@ public class FooTests {{ public void Test() {{ - var substitute = Substitute.For>(); + var substitute = Substitute.For>>(); {method}(substitute()); }} }} @@ -200,6 +210,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForSealedOverrideMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -207,15 +218,15 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar() + public virtual Task Bar() {{ - return 2; + return Task.FromResult(2); }} }} public class Foo2 : Foo {{ - public sealed override int Bar() => 1; + public sealed override Task Bar() => Task.FromResult(1); }} public class FooTests @@ -234,6 +245,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -241,7 +253,7 @@ namespace MyNamespace {{ public abstract class Foo {{ - public abstract int Bar(); + public abstract Task Bar(); }} public class FooTests @@ -260,6 +272,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -267,7 +280,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(); + Task Bar(); }} public class FooTests @@ -285,6 +298,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -292,7 +306,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar {{ get; }} + Task Bar {{ get; }} }} public class FooTests @@ -310,6 +324,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForGenericInterfaceMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -317,7 +332,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(); + Task Bar(); }} public class FooTests @@ -335,6 +350,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -342,7 +358,7 @@ namespace MyNamespace {{ public abstract class Foo {{ - public abstract int Bar {{ get; }} + public abstract Task Bar {{ get; }} }} public class FooTests @@ -361,6 +377,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceIndexer(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -368,7 +385,7 @@ namespace MyNamespace {{ public interface IFoo {{ - int this[int i] {{ get; }} + Task this[int i] {{ get; }} }} public class FooTests @@ -386,6 +403,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -393,7 +411,7 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int Bar {{ get; }} + public virtual Task Bar {{ get; }} }} public class FooTests @@ -412,6 +430,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualProperty(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -419,7 +438,7 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; }} + public Task Bar {{ get; }} }} public class FooTests @@ -438,6 +457,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualIndexer(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -445,7 +465,7 @@ namespace MyNamespace {{ public class Foo {{ - public virtual int this[int x] => 0; + public virtual Task this[int x] => Task.FromResult(0); }} public class FooTests @@ -463,6 +483,7 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualIndexer(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -470,7 +491,7 @@ namespace MyNamespace {{ public class Foo {{ - public int this[int x] => 0; + public Task this[int x] => Task.FromResult(0); }} public class FooTests @@ -490,13 +511,14 @@ public override async Task ReportsNoDiagnostics_WhenUsingUnfortunatelyNamedMetho { var source = $@" using System; +using System.Threading.Tasks; namespace NSubstitute {{ public class Foo {{ - public int Bar() + public Task Bar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -507,10 +529,20 @@ public static T Throws(this object value) where T: Exception return default(T); }} + public static T ThrowsAsync(this Task value) where T: Exception + {{ + return default(T); + }} + public static T ThrowsForAnyArgs(this object value) where T: Exception {{ return default(T); }} + + public static T ThrowsAsyncForAnyArgs(this Task value) where T: Exception + {{ + return default(T); + }} }} public class FooTests @@ -530,6 +562,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Bar", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -537,9 +570,9 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; }} + public Task Bar {{ get; }} - public int FooBar {{ get; }} + public Task FooBar {{ get; }} }} public class FooTests @@ -561,23 +594,24 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Bar", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; namespace MyNamespace {{ - public class Foo + public class Foo where T : Task {{ public T Bar {{ get; }} - public int FooBar {{ get; }} + public Task FooBar {{ get; }} }} public class FooTests {{ public void Test() {{ - var substitute = NSubstitute.Substitute.For>(); + var substitute = NSubstitute.Substitute.For>>(); {method}(substitute.Bar); {method}([|substitute.FooBar|]); }} @@ -592,6 +626,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar(System.Int32,System.Int32)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -599,14 +634,14 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar(int x) + public Task Bar(int x) {{ - return 1; + return Task.FromResult(1); }} - public int Bar(int x, int y) + public Task Bar(int x, int y) {{ - return 2; + return Task.FromResult(2); }} }} @@ -629,6 +664,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar``1(``0,``0)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -636,14 +672,14 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar(int x) + public Task Bar(int x) {{ - return 1; + return Task.FromResult(1); }} - public int Bar(T x, T y) + public Task Bar(T x, T y) {{ - return 2; + return Task.FromResult(2); }} }} @@ -666,6 +702,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Item(System.Int32,System.Int32)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -673,8 +710,8 @@ namespace MyNamespace {{ public class Foo {{ - public int this[int x] => 0; - public int this[int x, int y] => 0; + public Task this[int x] => Task.FromResult(0); + public Task this[int x, int y] => Task.FromResult(0); }} public class FooTests @@ -696,6 +733,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Item(`0,`0)", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -703,8 +741,8 @@ namespace MyNamespace {{ public class Foo {{ - public int this[T x] => 0; - public int this[T x, T y] => 0; + public Task this[T x] => Task.FromResult(0); + public Task this[T x, T y] => Task.FromResult(0); }} public class FooTests @@ -726,6 +764,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -733,21 +772,21 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} public class FooBarBar {{ - public int Bar {{ get;set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get;set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -787,6 +826,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo`1", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -794,21 +834,21 @@ namespace MyNamespace {{ public class Foo {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} public class FooBarBar {{ - public int Bar {{ get;set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get;set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -848,6 +888,7 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("N:MyNamespace", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -855,11 +896,11 @@ namespace MyOtherNamespace {{ public class FooBarBar {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} }} @@ -869,11 +910,11 @@ namespace MyNamespace using MyOtherNamespace; public class Foo {{ - public int Bar {{ get; set; }} - public int this[int x] => 0; - public int FooBar() + public Task Bar {{ get; set; }} + public Task this[int x] => Task.FromResult(0); + public Task FooBar() {{ - return 1; + return Task.FromResult(1); }} }} @@ -910,9 +951,10 @@ public void Test() public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressingExtensionMethod(string method) { - Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(System.Object)~System.Int32", NonVirtualSetupSpecificationDescriptor.Id); + Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(System.Object)~System.Threading.Tasks.Task{System.Int32}", NonVirtualSetupSpecificationDescriptor.Id); var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -933,20 +975,20 @@ public static class MyExtensions {{ public static IBar Bar {{ get; set; }} - public static int GetBar(this object @object) + public static Task GetBar(this object @object) {{ return Bar.Foo(@object); }} - public static int GetFooBar(this object @object) + public static Task GetFooBar(this object @object) {{ - return 1; + return Task.FromResult(1); }} }} public interface IBar {{ - int Foo(object @obj); + Task Foo(object @obj); }} }}"; @@ -956,6 +998,7 @@ public interface IBar public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToNotApplied(string method, string call, string message) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -963,16 +1006,16 @@ namespace MyNamespace {{ public class Foo {{ - internal virtual object Bar {{ get; }} + internal virtual Task Bar {{ get; }} - internal virtual object FooBar() + internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - internal virtual object this[int x] + internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} @@ -992,6 +1035,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToApplied(string method, string call) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; using System.Runtime.CompilerServices; @@ -1003,16 +1047,16 @@ namespace MyNamespace {{ public class Foo {{ - internal virtual object Bar {{ get; }} + internal virtual Task Bar {{ get; }} - internal virtual object FooBar() + internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - internal virtual object this[int x] + internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} @@ -1032,25 +1076,26 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToAppliedToWrongAssembly(string method, string call, string message) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; -using System.Runtime.CompilerServices; using NSubstitute.ExceptionExtensions; +using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo(""OtherAssembly"")] namespace MyNamespace {{ public class Foo {{ - internal virtual object Bar {{ get; }} + internal virtual Task Bar {{ get; }} - internal virtual object FooBar() + internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - internal virtual object this[int x] + internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} @@ -1070,6 +1115,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSettingValueForProtectedInternalVirtualMember(string method, string call) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -1077,16 +1123,16 @@ namespace MyNamespace {{ public class Foo {{ - protected internal virtual object Bar {{ get; }} + protected internal virtual Task Bar {{ get; }} - protected internal virtual object FooBar() + protected internal virtual Task FooBar() {{ - return 1; + return Task.FromResult(1); }} - protected internal virtual object this[int x] + protected internal virtual Task this[int x] {{ - get {{ return 1; }} + get {{ return Task.FromResult(1); }} }} }} diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs index 18835b30..2e0c3f8d 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs @@ -7,21 +7,21 @@ namespace NSubstitute.Analyzers.Tests.VisualBasic.DiagnosticAnalyzersTests.NonSubstitutableMemberAnalyzerTests; -[CombinatoryData("Throws", "ThrowsForAnyArgs")] +[CombinatoryData("Throws", "ThrowsAsync", "ThrowsForAnyArgs", "ThrowsAsyncForAnyArgs")] public class ThrowsAsExtensionMethodTests : NonSubstitutableMemberDiagnosticVerifier { public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - - Public Function Bar() As Integer - Return 2 + Public Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -59,6 +59,7 @@ End Namespace public override async Task ReportsDiagnostics_WhenSettingValueForStaticMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -66,8 +67,8 @@ Namespace MyNamespace Public Class Foo - Public Shared Function Bar() As Integer - Return 2 + Public Shared Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -85,6 +86,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -92,8 +94,8 @@ Namespace MyNamespace Public Class Foo - Public Overridable Function Bar() As Integer - Return 2 + Public Overridable Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -112,6 +114,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForNonSealedOverrideMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -119,16 +122,16 @@ Namespace MyNamespace Public Class Foo - Public Overridable Function Bar() As Integer - Return 2 + Public Overridable Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class Public Class Foo2 Inherits Foo - Public Overrides Function Bar() As Integer - Return 1 + Public Overrides Function Bar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -147,6 +150,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenDataFlowAnalysisIsRequired(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -154,8 +158,8 @@ Namespace MyNamespace Public Class Foo - Public Overridable Function Bar() As Integer - Return 2 + Public Overridable Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -175,6 +179,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForDelegate(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -183,7 +188,7 @@ Namespace MyNamespace Public Class FooTests Public Sub Test() - Dim substitute = NSubstitute.Substitute.[For](Of Func(Of Integer))() + Dim substitute = NSubstitute.Substitute.[For](Of Func(Of Task(Of Integer)))() substitute().{method}(New Exception()) End Sub End Class @@ -195,6 +200,7 @@ End Namespace public override async Task ReportsDiagnostics_WhenSettingValueForSealedOverrideMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -202,16 +208,16 @@ Namespace MyNamespace Public Class Foo - Public Overridable Function Bar() As Integer - Return 2 + Public Overridable Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class Public Class Foo2 Inherits Foo - Public NotOverridable Overrides Function Bar() As Integer - Return 1 + Public NotOverridable Overrides Function Bar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -230,6 +236,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -237,7 +244,7 @@ Namespace MyNamespace Public MustInherit Class Foo - Public MustOverride Function Bar() As Integer + Public MustOverride Function Bar() As Task(Of Integer) End Class Public Class FooTests @@ -256,6 +263,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -263,7 +271,7 @@ Namespace MyNamespace Interface IFoo - Function Bar() As Integer + Function Bar() As Task(Of Integer) End Interface @@ -282,6 +290,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceProperty(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -289,7 +298,7 @@ Namespace MyNamespace Interface IFoo - Property Bar As Integer + Property Bar As Task(Of Integer) End Interface @@ -308,14 +317,14 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForGenericInterfaceMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Interface IFoo(Of T) - - Function Bar(Of T)() As Integer + Function Bar(Of T)()As Task(Of Integer) End Interface Public Class FooTests @@ -333,6 +342,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractProperty(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -340,7 +350,7 @@ Namespace MyNamespace Public MustInherit Class Foo - Public MustOverride ReadOnly Property Bar As Integer + Public MustOverride ReadOnly Property Bar As Task(Of Integer) End Class Public Class FooTests @@ -358,6 +368,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceIndexer(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -365,7 +376,7 @@ Namespace MyNamespace Public Interface IFoo - Default Property Item(ByVal i As Integer) As Integer + Default Property Item(ByVal i As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -382,6 +393,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualProperty(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -389,7 +401,7 @@ Namespace MyNamespace Public Class Foo - Public Overridable ReadOnly Property Bar As Integer + Public Overridable ReadOnly Property Bar As Task(Of Integer) Get End Get End Property @@ -410,6 +422,7 @@ End Class public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualProperty(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -417,8 +430,9 @@ Namespace MyNamespace Public Class Foo - Public ReadOnly Property Bar As Integer + Public ReadOnly Property Bar As Task(Of Integer) Get + Return Nothing End Get End Property End Class @@ -438,6 +452,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualIndexer(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -445,7 +460,7 @@ Namespace MyNamespace Public Class Foo - Public Overridable Default Property Item(ByVal x As Integer) As Integer + Public Overridable Default Property Item(ByVal x As Integer) As Task(Of Integer) Set Throw New NotImplementedException End Set @@ -471,6 +486,7 @@ End Class public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualIndexer(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -478,7 +494,7 @@ Namespace MyNamespace Public Class Foo - Public Default ReadOnly Property Item(ByVal x As Integer) As Integer + Public Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get Throw New NotImplementedException End Get @@ -501,10 +517,12 @@ public override async Task ReportsNoDiagnostics_WhenUsingUnfortunatelyNamedMetho { var source = $@"Imports System.Runtime.CompilerServices Imports System +Imports System.Threading.Tasks + Namespace NSubstitute Public Class Foo - Public Function Bar() As Integer - Return 1 + Public Function Bar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -514,10 +532,20 @@ Function Throws(Of T)(ByVal returnValue As T, ex As Exception) As T Return Nothing End Function + + Function ThrowsAsync(Of T)(ByVal returnValue As Task(Of T), ex As Exception) As T + Return Nothing + End Function + Function ThrowsForAnyArgs(Of T)(ByVal returnValue As T, ex As Exception) As T Return Nothing End Function + + + Function ThrowsAsyncForAnyArgs(Of T)(ByVal returnValue As Task(Of T), ex As Exception) As T + Return Nothing + End Function End Module Public Class FooTests @@ -536,13 +564,14 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Bar", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Public ReadOnly Property Bar As Integer - Public ReadOnly Property FooBar As Integer + Public ReadOnly Property Bar As Task(Of Integer) + Public ReadOnly Property FooBar As Task(Of Integer) End Class Public Class FooTests @@ -563,18 +592,19 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Bar", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace - Public Class Foo(Of T) + Public Class Foo(Of T As Task) Public ReadOnly Property Bar As T - Public ReadOnly Property FooBar As Integer + Public ReadOnly Property FooBar As Task(Of Integer) End Class Public Class FooTests Public Sub Test() - Dim substitute = NSubstitute.Substitute.[For](Of Foo(Of Integer))() + Dim substitute = NSubstitute.Substitute.[For](Of Foo(Of Task))() substitute.Bar.{method}(New Exception()) [|substitute.FooBar|].{method}(New Exception()) End Sub @@ -590,17 +620,18 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar(System.Int32,System.Int32)", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Public Function Bar(ByVal x As Integer) As Integer - Return 1 + Public Function Bar(ByVal x As Integer) As Task(Of Integer) + Return Task.FromResult(0) End Function - Public Function Bar(ByVal x As Integer, ByVal y As Integer) As Integer - Return 2 + Public Function Bar(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) + Return Task.FromResult(0) End Function End Class @@ -622,17 +653,18 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar``1(``0,``0)", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Public Function Bar(ByVal x As Integer) As Integer - Return 1 + Public Function Bar(ByVal x As Integer) As Task(Of Integer) + Return Task.FromResult(0) End Function - Public Function Bar(Of T)(ByVal x As T, ByVal y As T) As Integer - Return 2 + Public Function Bar(Of T)(ByVal x As T, ByVal y As T) As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -654,20 +686,21 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Item(System.Int32,System.Int32)", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Default Public ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property End Class @@ -690,20 +723,21 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Item(`0,`0)", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo(Of T) - Default Public ReadOnly Property Item(ByVal x As T) As Integer + Default Public ReadOnly Property Item(ByVal x As T) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Default Public ReadOnly Property Item(ByVal x As T, ByVal y As T) As Integer + Default Public ReadOnly Property Item(ByVal x As T, ByVal y As T) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property End Class @@ -726,35 +760,36 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class Public Class FooBarBar - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -792,35 +827,36 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo`1", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo(Of T) - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class Public Class FooBarBar(Of T) - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -858,38 +894,39 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("N:MyNamespace", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports MyOtherNamespace Namespace MyOtherNamespace Public Class FooBarBar - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class End Namespace Namespace MyNamespace Public Class Foo - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -924,9 +961,10 @@ End Namespace public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressingExtensionMethod(string method) { - Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(MyNamespace.IFoo)~System.Int32", DiagnosticIdentifiers.NonVirtualSetupSpecification); + Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(MyNamespace.IFoo)~System.Threading.Tasks.Task{System.Int32}", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports System.Runtime.CompilerServices @@ -945,23 +983,22 @@ Module MyExtensions Public Property Bar As IBar - Function GetBar(ByVal foo As IFoo) As Integer + Function GetBar(ByVal foo As IFoo) As Task(Of Integer) Return Bar.Foo() - Return 1 End Function - Function GetFooBar(ByVal foo As IFoo) As Integer - Return 1 + Function GetFooBar(ByVal foo As IFoo) As Task(Of Integer) + Return Task.FromResult(1) End Function End Module Interface IBar - Function Foo() As Integer + Function Foo() As Task(Of Integer) End Interface Interface IFoo - Function Bar() As Integer + Function Bar() As Task(Of Integer) End Interface End Namespace"; @@ -971,18 +1008,19 @@ End Interface public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToNotApplied(string method, string call, string message) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Friend Overridable ReadOnly Property Bar As Foo + Friend Overridable ReadOnly Property Bar As Task(Of Foo) - Friend Overridable Function FooBar() As Foo + Friend Overridable Function FooBar() As Task(Of Foo) Return Nothing End Function - Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Foo + Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Task(Of Foo) Get Return Nothing End Get @@ -1003,6 +1041,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToApplied(string method, string call) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -1012,13 +1051,13 @@ Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Friend Overridable ReadOnly Property Bar As Foo + Friend Overridable ReadOnly Property Bar As Task(Of Foo) - Friend Overridable Function FooBar() As Foo + Friend Overridable Function FooBar() As Task(Of Foo) Return Nothing End Function - Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Foo + Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Task(Of Foo) Get Return Nothing End Get @@ -1039,6 +1078,7 @@ End Class public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToAppliedToWrongAssembly(string method, string call, string message) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -1046,13 +1086,13 @@ Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Friend Overridable ReadOnly Property Bar As Foo + Friend Overridable ReadOnly Property Bar As Task(Of Foo) - Friend Overridable Function FooBar() As Foo + Friend Overridable Function FooBar() As Task(Of Foo) Return Nothing End Function - Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Foo + Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Task(Of Foo) Get Return Nothing End Get @@ -1073,18 +1113,19 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForProtectedInternalVirtualMember(string method, string call) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Protected Friend Overridable ReadOnly Property Bar As Foo + Protected Friend Overridable ReadOnly Property Bar As Task(Of Foo) - Protected Friend Overridable Function FooBar() As Foo + Protected Friend Overridable Function FooBar() As Task(Of Foo) Return Nothing End Function - Default Protected Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Foo + Default Protected Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Task(Of Foo) Get Return Nothing End Get diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs index 02721017..c3ec97d3 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs @@ -7,21 +7,25 @@ namespace NSubstitute.Analyzers.Tests.VisualBasic.DiagnosticAnalyzersTests.NonSubstitutableMemberAnalyzerTests; -[CombinatoryData("ExceptionExtensions.Throws", "ExceptionExtensions.ThrowsForAnyArgs")] +[CombinatoryData( + "ExceptionExtensions.Throws", + "ExceptionExtensions.ThrowsAsync", + "ExceptionExtensions.ThrowsForAnyArgs", + "ExceptionExtensions.ThrowsAsyncForAnyArgs")] public class ThrowsAsOrdinaryMethodTests : NonSubstitutableMemberDiagnosticVerifier { public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - - Public Function Bar() As Integer - Return 2 + Public Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -47,6 +51,7 @@ Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class FooTests + Public Sub Test() {method}([|{literal}|], New Exception()) {method}(value:= [|{literal}|], ex:= New Exception()) @@ -61,6 +66,7 @@ End Namespace public override async Task ReportsDiagnostics_WhenSettingValueForStaticMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -68,8 +74,8 @@ Namespace MyNamespace Public Class Foo - Public Shared Function Bar() As Integer - Return 2 + Public Shared Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -89,6 +95,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -96,8 +103,8 @@ Namespace MyNamespace Public Class Foo - Public Overridable Function Bar() As Integer - Return 2 + Public Overridable Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -117,6 +124,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForNonSealedOverrideMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -124,16 +132,16 @@ Namespace MyNamespace Public Class Foo - Public Overridable Function Bar() As Integer - Return 2 + Public Overridable Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class Public Class Foo2 Inherits Foo - Public Overrides Function Bar() As Integer - Return 1 + Public Overrides Function Bar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -154,6 +162,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenDataFlowAnalysisIsRequired(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -161,8 +170,8 @@ Namespace MyNamespace Public Class Foo - Public Overridable Function Bar() As Integer - Return 2 + Public Overridable Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -184,6 +193,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForDelegate(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -192,7 +202,7 @@ Namespace MyNamespace Public Class FooTests Public Sub Test() - Dim substitute = NSubstitute.Substitute.[For](Of Func(Of Integer))() + Dim substitute = NSubstitute.Substitute.[For](Of Func(Of Task(Of Integer)))() {method}(substitute(), New Exception()) {method}(value:= substitute(), ex:= New Exception()) {method}(ex:= New Exception(), value:= substitute()) @@ -206,6 +216,7 @@ End Namespace public override async Task ReportsDiagnostics_WhenSettingValueForSealedOverrideMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -213,16 +224,16 @@ Namespace MyNamespace Public Class Foo - Public Overridable Function Bar() As Integer - Return 2 + Public Overridable Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class Public Class Foo2 Inherits Foo - Public NotOverridable Overrides Function Bar() As Integer - Return 1 + Public NotOverridable Overrides Function Bar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -243,6 +254,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -250,7 +262,7 @@ Namespace MyNamespace Public MustInherit Class Foo - Public MustOverride Function Bar() As Integer + Public MustOverride Function Bar() As Task(Of Integer) End Class Public Class FooTests @@ -271,6 +283,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -278,7 +291,7 @@ Namespace MyNamespace Interface IFoo - Function Bar() As Integer + Function Bar() As Task(Of Integer) End Interface @@ -299,6 +312,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceProperty(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -306,7 +320,7 @@ Namespace MyNamespace Interface IFoo - Property Bar As Integer + Property Bar As Task(Of Integer) End Interface @@ -327,14 +341,14 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForGenericInterfaceMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Interface IFoo(Of T) - - Function Bar(Of T)() As Integer + Function Bar(Of T)()As Task(Of Integer) End Interface Public Class FooTests @@ -354,6 +368,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractProperty(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -361,7 +376,7 @@ Namespace MyNamespace Public MustInherit Class Foo - Public MustOverride ReadOnly Property Bar As Integer + Public MustOverride ReadOnly Property Bar As Task(Of Integer) End Class Public Class FooTests @@ -381,6 +396,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceIndexer(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -388,7 +404,7 @@ Namespace MyNamespace Public Interface IFoo - Default Property Item(ByVal i As Integer) As Integer + Default Property Item(ByVal i As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -407,6 +423,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualProperty(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -414,7 +431,7 @@ Namespace MyNamespace Public Class Foo - Public Overridable ReadOnly Property Bar As Integer + Public Overridable ReadOnly Property Bar As Task(Of Integer) Get End Get End Property @@ -437,6 +454,7 @@ End Class public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualProperty(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -444,8 +462,9 @@ Namespace MyNamespace Public Class Foo - Public ReadOnly Property Bar As Integer + Public ReadOnly Property Bar As Task(Of Integer) Get + Return Nothing End Get End Property End Class @@ -467,6 +486,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualIndexer(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -474,7 +494,7 @@ Namespace MyNamespace Public Class Foo - Public Overridable Default Property Item(ByVal x As Integer) As Integer + Public Overridable Default Property Item(ByVal x As Integer) As Task(Of Integer) Set Throw New NotImplementedException End Set @@ -502,6 +522,7 @@ End Class public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualIndexer(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -509,7 +530,7 @@ Namespace MyNamespace Public Class Foo - Public Default ReadOnly Property Item(ByVal x As Integer) As Integer + Public Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get Throw New NotImplementedException End Get @@ -534,10 +555,12 @@ public override async Task ReportsNoDiagnostics_WhenUsingUnfortunatelyNamedMetho { var source = $@"Imports System.Runtime.CompilerServices Imports System +Imports System.Threading.Tasks + Namespace NSubstitute Public Class Foo - Public Function Bar() As Integer - Return 1 + Public Function Bar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -547,10 +570,20 @@ Function Throws(Of T)(ByVal returnValue As T, ex As Exception) As T Return Nothing End Function + + Function ThrowsAsync(Of T)(ByVal returnValue As Task(Of T), ex As Exception) As T + Return Nothing + End Function + Function ThrowsForAnyArgs(Of T)(ByVal returnValue As T, ex As Exception) As T Return Nothing End Function + + + Function ThrowsAsyncForAnyArgs(Of T)(ByVal returnValue As Task(Of T), ex As Exception) As T + Return Nothing + End Function End Module Public Class FooTests @@ -569,13 +602,14 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Bar", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Public ReadOnly Property Bar As Integer - Public ReadOnly Property FooBar As Integer + Public ReadOnly Property Bar As Task(Of Integer) + Public ReadOnly Property FooBar As Task(Of Integer) End Class Public Class FooTests @@ -598,18 +632,19 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Bar", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace - Public Class Foo(Of T) + Public Class Foo(Of T As Task) Public ReadOnly Property Bar As T - Public ReadOnly Property FooBar As Integer + Public ReadOnly Property FooBar As Task(Of Integer) End Class Public Class FooTests Public Sub Test() - Dim substitute = NSubstitute.Substitute.[For](Of Foo(Of Integer))() + Dim substitute = NSubstitute.Substitute.[For](Of Foo(Of Task))() {method}(substitute.Bar, New Exception()) {method}([|substitute.FooBar|], New Exception()) {method}(value:= [|substitute.FooBar|], ex:= New Exception()) @@ -627,17 +662,18 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar(System.Int32,System.Int32)", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Public Function Bar(ByVal x As Integer) As Integer - Return 1 + Public Function Bar(ByVal x As Integer) As Task(Of Integer) + Return Task.FromResult(0) End Function - Public Function Bar(ByVal x As Integer, ByVal y As Integer) As Integer - Return 2 + Public Function Bar(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) + Return Task.FromResult(0) End Function End Class @@ -661,17 +697,18 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar``1(``0,``0)", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Public Function Bar(ByVal x As Integer) As Integer - Return 1 + Public Function Bar(ByVal x As Integer) As Task(Of Integer) + Return Task.FromResult(0) End Function - Public Function Bar(Of T)(ByVal x As T, ByVal y As T) As Integer - Return 2 + Public Function Bar(Of T)(ByVal x As T, ByVal y As T) As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -695,20 +732,21 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Item(System.Int32,System.Int32)", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Default Public ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property End Class @@ -733,20 +771,21 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Item(`0,`0)", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo(Of T) - Default Public ReadOnly Property Item(ByVal x As T) As Integer + Default Public ReadOnly Property Item(ByVal x As T) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Default Public ReadOnly Property Item(ByVal x As T, ByVal y As T) As Integer + Default Public ReadOnly Property Item(ByVal x As T, ByVal y As T) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property End Class @@ -771,35 +810,36 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class Public Class FooBarBar - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -838,35 +878,36 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo`1", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo(Of T) - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class Public Class FooBarBar(Of T) - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -905,38 +946,39 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("N:MyNamespace", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports MyOtherNamespace Namespace MyOtherNamespace Public Class FooBarBar - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class End Namespace Namespace MyNamespace Public Class Foo - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -972,9 +1014,10 @@ End Namespace public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressingExtensionMethod(string method) { - Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(MyNamespace.IFoo)~System.Int32", DiagnosticIdentifiers.NonVirtualSetupSpecification); + Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(MyNamespace.IFoo)~System.Threading.Tasks.Task{System.Int32}", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports System.Runtime.CompilerServices @@ -995,23 +1038,22 @@ Module MyExtensions Public Property Bar As IBar - Function GetBar(ByVal foo As IFoo) As Integer + Function GetBar(ByVal foo As IFoo) As Task(Of Integer) Return Bar.Foo() - Return 1 End Function - Function GetFooBar(ByVal foo As IFoo) As Integer - Return 1 + Function GetFooBar(ByVal foo As IFoo) As Task(Of Integer) + Return Task.FromResult(1) End Function End Module Interface IBar - Function Foo() As Integer + Function Foo() As Task(Of Integer) End Interface Interface IFoo - Function Bar() As Integer + Function Bar() As Task(Of Integer) End Interface End Namespace"; @@ -1021,18 +1063,19 @@ End Interface public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToNotApplied(string method, string call, string message) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Friend Overridable ReadOnly Property Bar As Foo + Friend Overridable ReadOnly Property Bar As Task(Of Foo) - Friend Overridable Function FooBar() As Foo + Friend Overridable Function FooBar() As Task(Of Foo) Return Nothing End Function - Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Foo + Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Task(Of Foo) Get Return Nothing End Get @@ -1055,6 +1098,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToApplied(string method, string call) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -1064,13 +1108,13 @@ Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Friend Overridable ReadOnly Property Bar As Foo + Friend Overridable ReadOnly Property Bar As Task(Of Foo) - Friend Overridable Function FooBar() As Foo + Friend Overridable Function FooBar() As Task(Of Foo) Return Nothing End Function - Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Foo + Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Task(Of Foo) Get Return Nothing End Get @@ -1093,6 +1137,7 @@ End Class public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToAppliedToWrongAssembly(string method, string call, string message) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -1100,13 +1145,13 @@ Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Friend Overridable ReadOnly Property Bar As Foo + Friend Overridable ReadOnly Property Bar As Task(Of Foo) - Friend Overridable Function FooBar() As Foo + Friend Overridable Function FooBar() As Task(Of Foo) Return Nothing End Function - Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Foo + Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Task(Of Foo) Get Return Nothing End Get @@ -1129,18 +1174,19 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForProtectedInternalVirtualMember(string method, string call) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Protected Friend Overridable ReadOnly Property Bar As Foo + Protected Friend Overridable ReadOnly Property Bar As Task(Of Foo) - Protected Friend Overridable Function FooBar() As Foo + Protected Friend Overridable Function FooBar() As Task(Of Foo) Return Nothing End Function - Default Protected Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Foo + Default Protected Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Task(Of Foo) Get Return Nothing End Get diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index 254e3974..f4f86020 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -7,21 +7,25 @@ namespace NSubstitute.Analyzers.Tests.VisualBasic.DiagnosticAnalyzersTests.NonSubstitutableMemberAnalyzerTests; -[CombinatoryData("ExceptionExtensions.Throws(Of Exception)", "ExceptionExtensions.ThrowsForAnyArgs(Of Exception)")] +[CombinatoryData( + "ExceptionExtensions.Throws(Of Exception)", + "ExceptionExtensions.ThrowsAsync(Of Exception)", + "ExceptionExtensions.ThrowsForAnyArgs(Of Exception)", + "ExceptionExtensions.ThrowsAsyncForAnyArgs(Of Exception)")] public class ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests : NonSubstitutableMemberDiagnosticVerifier { public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - - Public Function Bar() As Integer - Return 2 + Public Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -46,6 +50,7 @@ Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class FooTests + Public Sub Test() {method}([|{literal}|]) End Sub @@ -58,6 +63,7 @@ End Namespace public override async Task ReportsDiagnostics_WhenSettingValueForStaticMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -65,8 +71,8 @@ Namespace MyNamespace Public Class Foo - Public Shared Function Bar() As Integer - Return 2 + Public Shared Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -84,6 +90,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -91,8 +98,8 @@ Namespace MyNamespace Public Class Foo - Public Overridable Function Bar() As Integer - Return 2 + Public Overridable Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -111,6 +118,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForNonSealedOverrideMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -118,16 +126,16 @@ Namespace MyNamespace Public Class Foo - Public Overridable Function Bar() As Integer - Return 2 + Public Overridable Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class Public Class Foo2 Inherits Foo - Public Overrides Function Bar() As Integer - Return 1 + Public Overrides Function Bar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -146,6 +154,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenDataFlowAnalysisIsRequired(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -153,8 +162,8 @@ Namespace MyNamespace Public Class Foo - Public Overridable Function Bar() As Integer - Return 2 + Public Overridable Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -174,6 +183,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForDelegate(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -182,7 +192,7 @@ Namespace MyNamespace Public Class FooTests Public Sub Test() - Dim substitute = NSubstitute.Substitute.[For](Of Func(Of Integer))() + Dim substitute = NSubstitute.Substitute.[For](Of Func(Of Task(Of Integer)))() {method}(substitute()) End Sub End Class @@ -194,6 +204,7 @@ End Namespace public override async Task ReportsDiagnostics_WhenSettingValueForSealedOverrideMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -201,16 +212,16 @@ Namespace MyNamespace Public Class Foo - Public Overridable Function Bar() As Integer - Return 2 + Public Overridable Function Bar() As Task(Of Integer) + Return Task.FromResult(2) End Function End Class Public Class Foo2 Inherits Foo - Public NotOverridable Overrides Function Bar() As Integer - Return 1 + Public NotOverridable Overrides Function Bar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -229,6 +240,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -236,7 +248,7 @@ Namespace MyNamespace Public MustInherit Class Foo - Public MustOverride Function Bar() As Integer + Public MustOverride Function Bar() As Task(Of Integer) End Class Public Class FooTests @@ -255,6 +267,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -262,7 +275,7 @@ Namespace MyNamespace Interface IFoo - Function Bar() As Integer + Function Bar() As Task(Of Integer) End Interface @@ -281,6 +294,7 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceProperty(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -288,7 +302,7 @@ Namespace MyNamespace Interface IFoo - Property Bar As Integer + Property Bar As Task(Of Integer) End Interface @@ -307,14 +321,14 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSettingValueForGenericInterfaceMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Interface IFoo(Of T) - - Function Bar(Of T)() As Integer + Function Bar(Of T)()As Task(Of Integer) End Interface Public Class FooTests @@ -332,6 +346,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForAbstractProperty(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -339,7 +354,7 @@ Namespace MyNamespace Public MustInherit Class Foo - Public MustOverride ReadOnly Property Bar As Integer + Public MustOverride ReadOnly Property Bar As Task(Of Integer) End Class Public Class FooTests @@ -357,6 +372,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForInterfaceIndexer(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -364,7 +380,7 @@ Namespace MyNamespace Public Interface IFoo - Default Property Item(ByVal i As Integer) As Integer + Default Property Item(ByVal i As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -381,6 +397,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualProperty(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -388,7 +405,7 @@ Namespace MyNamespace Public Class Foo - Public Overridable ReadOnly Property Bar As Integer + Public Overridable ReadOnly Property Bar As Task(Of Integer) Get End Get End Property @@ -409,6 +426,7 @@ End Class public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualProperty(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -416,8 +434,9 @@ Namespace MyNamespace Public Class Foo - Public ReadOnly Property Bar As Integer + Public ReadOnly Property Bar As Task(Of Integer) Get + Return Nothing End Get End Property End Class @@ -437,6 +456,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualIndexer(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -444,7 +464,7 @@ Namespace MyNamespace Public Class Foo - Public Overridable Default Property Item(ByVal x As Integer) As Integer + Public Overridable Default Property Item(ByVal x As Integer) As Task(Of Integer) Set Throw New NotImplementedException End Set @@ -470,6 +490,7 @@ End Class public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualIndexer(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -477,7 +498,7 @@ Namespace MyNamespace Public Class Foo - Public Default ReadOnly Property Item(ByVal x As Integer) As Integer + Public Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get Throw New NotImplementedException End Get @@ -500,10 +521,12 @@ public override async Task ReportsNoDiagnostics_WhenUsingUnfortunatelyNamedMetho { var source = $@"Imports System.Runtime.CompilerServices Imports System +Imports System.Threading.Tasks + Namespace NSubstitute Public Class Foo - Public Function Bar() As Integer - Return 1 + Public Function Bar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -513,10 +536,20 @@ Function Throws(Of T)(ByVal returnValue As Object) As T Return Nothing End Function + + Function ThrowsAsync(Of T)(ByVal returnValue As Task) As T + Return Nothing + End Function + Function ThrowsForAnyArgs(Of T)(ByVal returnValue As Object) As T Return Nothing End Function + + + Function ThrowsAsyncForAnyArgs(Of T)(ByVal returnValue As Task) As T + Return Nothing + End Function End Module Public Class FooTests @@ -535,13 +568,14 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Bar", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Public ReadOnly Property Bar As Integer - Public ReadOnly Property FooBar As Integer + Public ReadOnly Property Bar As Task(Of Integer) + Public ReadOnly Property FooBar As Task(Of Integer) End Class Public Class FooTests @@ -562,18 +596,19 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Bar", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace - Public Class Foo(Of T) + Public Class Foo(Of T As Task) Public ReadOnly Property Bar As T - Public ReadOnly Property FooBar As Integer + Public ReadOnly Property FooBar As Task(Of Integer) End Class Public Class FooTests Public Sub Test() - Dim substitute = NSubstitute.Substitute.[For](Of Foo(Of Integer))() + Dim substitute = NSubstitute.Substitute.[For](Of Foo(Of Task))() {method}(substitute.Bar) {method}([|substitute.FooBar|]) End Sub @@ -589,17 +624,18 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar(System.Int32,System.Int32)", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Public Function Bar(ByVal x As Integer) As Integer - Return 1 + Public Function Bar(ByVal x As Integer) As Task(Of Integer) + Return Task.FromResult(0) End Function - Public Function Bar(ByVal x As Integer, ByVal y As Integer) As Integer - Return 2 + Public Function Bar(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) + Return Task.FromResult(0) End Function End Class @@ -621,17 +657,18 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.Foo.Bar``1(``0,``0)", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Public Function Bar(ByVal x As Integer) As Integer - Return 1 + Public Function Bar(ByVal x As Integer) As Task(Of Integer) + Return Task.FromResult(0) End Function - Public Function Bar(Of T)(ByVal x As T, ByVal y As T) As Integer - Return 2 + Public Function Bar(Of T)(ByVal x As T, ByVal y As T) As Task(Of Integer) + Return Task.FromResult(2) End Function End Class @@ -653,20 +690,21 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo.Item(System.Int32,System.Int32)", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Default Public ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property End Class @@ -689,20 +727,21 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("P:MyNamespace.Foo`1.Item(`0,`0)", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo(Of T) - Default Public ReadOnly Property Item(ByVal x As T) As Integer + Default Public ReadOnly Property Item(ByVal x As T) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Default Public ReadOnly Property Item(ByVal x As T, ByVal y As T) As Integer + Default Public ReadOnly Property Item(ByVal x As T, ByVal y As T) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property End Class @@ -725,35 +764,36 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class Public Class FooBarBar - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -791,35 +831,36 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("T:MyNamespace.Foo`1", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo(Of T) - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class Public Class FooBarBar(Of T) - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -857,38 +898,39 @@ public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressi Settings = AnalyzersSettings.CreateWithSuppressions("N:MyNamespace", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports MyOtherNamespace Namespace MyOtherNamespace Public Class FooBarBar - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class End Namespace Namespace MyNamespace Public Class Foo - Public Property Bar As Integer + Public Property Bar As Task(Of Integer) - Default Public ReadOnly Property Item(ByVal x As Integer) As Integer + Default Public ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) Get - Return 0 + Return Task.FromResult(0) End Get End Property - Public Function FooBar() As Integer - Return 1 + Public Function FooBar() As Task(Of Integer) + Return Task.FromResult(1) End Function End Class @@ -916,17 +958,17 @@ End Namespace "Member FooBar can not be intercepted. Only interface members and overrideable, overriding, and must override members can be intercepted." }; - var diagnostics = textParserResult.Spans.Select((span, idx) => - CreateDiagnostic(NonVirtualSetupSpecificationDescriptor.OverrideMessage(diagnosticMessages[idx]), span)).ToArray(); + var diagnostics = textParserResult.Spans.Select((span, idx) => CreateDiagnostic(NonVirtualSetupSpecificationDescriptor.OverrideMessage(diagnosticMessages[idx]), span)).ToArray(); await VerifyDiagnostic(textParserResult.Text, diagnostics); } public override async Task ReportsNoDiagnosticsForSuppressedMember_WhenSuppressingExtensionMethod(string method) { - Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(MyNamespace.IFoo)~System.Int32", DiagnosticIdentifiers.NonVirtualSetupSpecification); + Settings = AnalyzersSettings.CreateWithSuppressions("M:MyNamespace.MyExtensions.GetBar(MyNamespace.IFoo)~System.Threading.Tasks.Task{System.Int32}", DiagnosticIdentifiers.NonVirtualSetupSpecification); var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports System.Runtime.CompilerServices @@ -945,23 +987,22 @@ Module MyExtensions Public Property Bar As IBar - Function GetBar(ByVal foo As IFoo) As Integer + Function GetBar(ByVal foo As IFoo) As Task(Of Integer) Return Bar.Foo() - Return 1 End Function - Function GetFooBar(ByVal foo As IFoo) As Integer - Return 1 + Function GetFooBar(ByVal foo As IFoo) As Task(Of Integer) + Return Task.FromResult(1) End Function End Module Interface IBar - Function Foo() As Integer + Function Foo() As Task(Of Integer) End Interface Interface IFoo - Function Bar() As Integer + Function Bar() As Task(Of Integer) End Interface End Namespace"; @@ -971,18 +1012,19 @@ End Interface public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToNotApplied(string method, string call, string message) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Friend Overridable ReadOnly Property Bar As Foo + Friend Overridable ReadOnly Property Bar As Task(Of Foo) - Friend Overridable Function FooBar() As Foo + Friend Overridable Function FooBar() As Task(Of Foo) Return Nothing End Function - Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Foo + Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Task(Of Foo) Get Return Nothing End Get @@ -1003,6 +1045,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToApplied(string method, string call) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -1012,13 +1055,13 @@ Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Friend Overridable ReadOnly Property Bar As Foo + Friend Overridable ReadOnly Property Bar As Task(Of Foo) - Friend Overridable Function FooBar() As Foo + Friend Overridable Function FooBar() As Task(Of Foo) Return Nothing End Function - Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Foo + Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Task(Of Foo) Get Return Nothing End Get @@ -1039,6 +1082,7 @@ End Class public override async Task ReportsDiagnostics_WhenSettingValueForInternalVirtualMember_AndInternalsVisibleToAppliedToWrongAssembly(string method, string call, string message) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions @@ -1046,13 +1090,13 @@ Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Friend Overridable ReadOnly Property Bar As Foo + Friend Overridable ReadOnly Property Bar As Task(Of Foo) - Friend Overridable Function FooBar() As Foo + Friend Overridable Function FooBar() As Task(Of Foo) Return Nothing End Function - Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Foo + Default Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Task(Of Foo) Get Return Nothing End Get @@ -1073,18 +1117,19 @@ End Class public override async Task ReportsNoDiagnostics_WhenSettingValueForProtectedInternalVirtualMember(string method, string call) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Public Class Foo - Protected Friend Overridable ReadOnly Property Bar As Foo + Protected Friend Overridable ReadOnly Property Bar As Task(Of Foo) - Protected Friend Overridable Function FooBar() As Foo + Protected Friend Overridable Function FooBar() As Task(Of Foo) Return Nothing End Function - Default Protected Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Foo + Default Protected Friend Overridable ReadOnly Property Item(ByVal x As Integer) As Task(Of Foo) Get Return Nothing End Get From 4d9a70628665eddf60656499600737c173685cb7 Mon Sep 17 00:00:00 2001 From: tpodolak Date: Fri, 22 Jul 2022 16:46:13 +0200 Subject: [PATCH 04/10] GH-186 - CallInfoAnalyzer support for ThrowsAsync like methods --- .../MetadataNames.cs | 2 + .../ThrowsAsExtensionMethodTests.cs | 163 +++++---- .../ThrowsAsOrdinaryMethodTests.cs | 333 ++++++------------ .../ThrowsAsExtensionMethodsTests.cs | 144 ++++---- .../ThrowsAsOrdinaryMethodsTests.cs | 148 ++++---- 5 files changed, 373 insertions(+), 417 deletions(-) diff --git a/src/NSubstitute.Analyzers.Shared/MetadataNames.cs b/src/NSubstitute.Analyzers.Shared/MetadataNames.cs index 1e6d4147..ea8d10a4 100644 --- a/src/NSubstitute.Analyzers.Shared/MetadataNames.cs +++ b/src/NSubstitute.Analyzers.Shared/MetadataNames.cs @@ -128,7 +128,9 @@ internal class MetadataNames [NSubstituteReturnsMethod] = NSubstituteSubstituteExtensionsFullTypeName, [NSubstituteReturnsForAnyArgsMethod] = NSubstituteSubstituteExtensionsFullTypeName, [NSubstituteThrowsMethod] = NSubstituteExceptionExtensionsFullTypeName, + [NSubstituteThrowsAsyncMethod] = NSubstituteExceptionExtensionsFullTypeName, [NSubstituteThrowsForAnyArgsMethod] = NSubstituteExceptionExtensionsFullTypeName, + [NSubstituteThrowsAsyncForAnyArgsMethod] = NSubstituteExceptionExtensionsFullTypeName, [NSubstituteAndDoesMethod] = NSubstituteConfiguredCallFullTypeName, [NSubstituteDoMethod] = NSubstituteWhenCalledType }; diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodTests.cs index 3f628e33..5ab854a1 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodTests.cs @@ -5,12 +5,13 @@ namespace NSubstitute.Analyzers.Tests.CSharp.DiagnosticAnalyzerTests.CallInfoAnalyzerTests; -[CombinatoryData("Throws", "ThrowsForAnyArgs")] +[CombinatoryData("Throws", "ThrowsForAnyArgs", "ThrowsAsync", "ThrowsAsyncForAnyArgs")] public class ThrowsAsExtensionMethodTests : CallInfoDiagnosticVerifier { public override async Task ReportsNoDiagnostics_WhenSubstituteMethodCannotBeInferred(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -18,11 +19,11 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x] {{ get; }} + Task this[int x] {{ get; }} }} public class FooTests @@ -46,17 +47,18 @@ public void Test() public override async Task ReportsDiagnostic_WhenAccessingArgumentOutOfBounds(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x] {{ get; }} + Task this[int x] {{ get; }} }} public class FooTests @@ -78,6 +80,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -85,11 +88,11 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, int y); + Task Bar(int x, int y); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x, int y] {{ get; }} + Task this[int x, int y] {{ get; }} }} public class FooTests @@ -111,6 +114,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAccessingArgumentWithinBounds(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using System; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -119,11 +123,11 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, int y = 1); + Task Bar(int x, int y = 1); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x, int y = 1] {{ get; }} + Task this[int x, int y = 1] {{ get; }} }} public class FooTests @@ -145,6 +149,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAccessingArgumentWithinBoundsForNestedCall(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -152,12 +157,12 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(int x); + Task Bar(int x); }} public interface IFooBar {{ - int FooBaz(int x, int y); + Task FooBaz(int x, int y); }} public class FooTests @@ -192,6 +197,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenManuallyCasting_ToSupportedType(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -199,9 +205,9 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, Bar y); + Task Bar(int x, Bar y); - int this[int x, Bar y] {{ get; }} + Task this[int x, Bar y] {{ get; }} }} public class BarBase @@ -232,6 +238,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenManuallyCasting_ToUnsupportedType(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using System; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -239,17 +246,17 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, double y); + Task Bar(int x, double y); - int Bar(string x, object y); + Task Bar(string x, object y); - int Foo(int x, FooBar bar); + Task Foo(int x, FooBar bar); - int this[int x, double y] {{ get; }} + Task this[int x, double y] {{ get; }} - int this[string x, object y] {{ get; }} + Task this[string x, object y] {{ get; }} - int this[int x, FooBar bar] {{ get; }} + Task this[int x, FooBar bar] {{ get; }} }} public class Bar @@ -279,6 +286,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenCasting_WithArgAt_ToSupportedType(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using System; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -287,13 +295,13 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, Bar y); + Task Bar(int x, Bar y); - int Bar(decimal x, object y, int z = 1); + Task Bar(decimal x, object y, int z = 1); - int this[int x, Bar y] {{ get; }} + Task this[int x, Bar y] {{ get; }} - int this[decimal x, object y] {{ get; }} + Task this[decimal x, object y] {{ get; }} }} public class BarBase @@ -323,24 +331,24 @@ public void Test() public override async Task ReportsDiagnostic_WhenCasting_WithArgAt_ToUnsupportedType(string method, string call, string argAccess, string message) { var source = $@"using System; -using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, double y); + Task Bar(int x, double y); - int Bar(object x, object y); + Task Bar(object x, object y); - int Foo(int x, FooBar bar); + Task Foo(int x, FooBar bar); - int this[int x, double y] {{ get; }} + Task this[int x, double y] {{ get; }} - int this[object x, object y] {{ get; }} + Task this[object x, object y] {{ get; }} - int this[int x, FooBar bar] {{ get; }} + Task this[int x, FooBar bar] {{ get; }} }} public class Bar @@ -370,7 +378,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenCastingElementsFromArgTypes(string method, string callInfo, string argAccess) { var source = $@"using System; -using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -378,9 +386,9 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(Bar x); + Task Bar(Bar x); - int this[Bar x] {{ get; }} + Task this[Bar x] {{ get; }} }} public class Bar @@ -406,7 +414,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAssigningValueToNotRefNorOutArgumentViaIndirectCall(string method, string call, string argAccess) { var source = $@"using System; -using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -414,9 +422,9 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(Bar x); + Task Bar(Bar x); - int this[Bar x] {{ get; }} + Task this[Bar x] {{ get; }} }} public class Bar @@ -442,7 +450,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAccessingArgumentByTypeNotInInvocation(string method, string call, string argAccess, string message) { var source = $@"using System; -using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -450,11 +458,11 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x] {{ get; }} + Task this[int x] {{ get; }} }} public class FooTests @@ -476,6 +484,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAccessingArgumentByTypeNotInInvocationForNestedCall(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -483,12 +492,12 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(int x); + Task Bar(int x); }} public interface IFooBar {{ - int FooBaz(int x); + Task FooBaz(int x); }} public class FooTests @@ -520,6 +529,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAccessingArgumentOutOfBoundsForNestedCall(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -527,12 +537,12 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(int x); + Task Bar(int x); }} public interface IFooBar {{ - int FooBaz(int x, int y); + Task FooBaz(int x, int y); }} public class FooTests @@ -580,7 +590,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAccessingArgumentByTypeInInInvocation(string method, string call, string argAccess) { var source = $@"using System; -using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -588,17 +598,17 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(int x); + Task Bar(int x); - int Bar(Foo x); + Task Bar(Foo x); - int Bar(int x, object y); + Task Bar(int x, object y); - int this[int x] {{ get; }} + Task this[int x] {{ get; }} - int this[Foo x] {{ get; }} + Task this[Foo x] {{ get; }} - int this[int x, object y] {{ get; }} + Task this[int x, object y] {{ get; }} }} public class FooBase @@ -629,6 +639,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAccessingArgumentByTypeInInvocationForNestedCall(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -636,12 +647,12 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(int x); + Task Bar(int x); }} public interface IFooBar {{ - int FooBaz(string x); + Task FooBaz(string x); }} public class FooTests @@ -672,6 +683,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAccessingArgumentByTypeMultipleTimesInInvocation(string method, string call, string argAccess, string message) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -679,13 +691,13 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, int y); + Task Bar(int x, int y); - int Bar(object x, object y); + Task Bar(object x, object y); - int this[int x, int y] {{ get; }} + Task this[int x, int y] {{ get; }} - int this[object x, object y] {{ get; }} + Task this[object x, object y] {{ get; }} }} public class FooBar @@ -712,6 +724,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAccessingArgumentByTypeMultipleDifferentTypesInInvocation(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -719,13 +732,13 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, double y); + Task Bar(int x, double y); - int Bar(object x, FooBar y); + Task Bar(object x, FooBar y); - int this[int x, double y] {{ get; }} + Task this[int x, double y] {{ get; }} - int this[object x, FooBar y] {{ get; }} + Task this[object x, FooBar y] {{ get; }} }} public class FooBar @@ -752,6 +765,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAssigningValueToNotOutNorRefArgument(string method, string call) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -759,9 +773,9 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, double y); + Task Bar(int x, double y); - int this[int x, double y] {{ get; }} + Task this[int x, double y] {{ get; }} }} public class FooTests @@ -783,6 +797,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAssigningValueToRefArgument(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -790,7 +805,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(ref int x); + Task Bar(ref int x); }} public class FooTests @@ -813,6 +828,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAssigningValueToOutArgument(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -820,7 +836,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(out int x); + Task Bar(out int x); }} public class FooTests @@ -843,6 +859,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAssigningValueToOutOfBoundsArgument(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -850,7 +867,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(out int x); + Task Bar(out int x); }} public class FooTests @@ -873,6 +890,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAssigningType_NotAssignableTo_Argument(string method, string left, string right, string expectedMessage) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using System.Collections.Generic; using NSubstitute.ExceptionExtensions; @@ -881,7 +899,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(out {left} x); + Task Bar(out {left} x); }} public class FooTests @@ -905,6 +923,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAssigningType_AssignableTo_Argument(string method, string left, string right) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using System.Collections.Generic; using NSubstitute.ExceptionExtensions; @@ -913,7 +932,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(out {left} x); + Task Bar(out {left} x); }} public class FooTests diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs index 00cb6469..084f4880 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs @@ -5,12 +5,17 @@ namespace NSubstitute.Analyzers.Tests.CSharp.DiagnosticAnalyzerTests.CallInfoAnalyzerTests; -[CombinatoryData("ExceptionExtensions.Throws", "ExceptionExtensions.ThrowsForAnyArgs")] +[CombinatoryData( + "ExceptionExtensions.Throws", + "ExceptionExtensions.ThrowsAsync", + "ExceptionExtensions.ThrowsForAnyArgs", + "ExceptionExtensions.ThrowsAsyncForAnyArgs")] public class ThrowsAsOrdinaryMethodTests : CallInfoDiagnosticVerifier { public override async Task ReportsNoDiagnostics_WhenSubstituteMethodCannotBeInferred(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -18,11 +23,11 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x] {{ get; }} + Task this[int x] {{ get; }} }} public class FooTests @@ -41,11 +46,6 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: returnedValue); }} }} }}"; @@ -56,17 +56,18 @@ public void Test() public override async Task ReportsDiagnostic_WhenAccessingArgumentOutOfBounds(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x] {{ get; }} + Task this[int x] {{ get; }} }} public class FooTests @@ -79,26 +80,16 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(value: {call}, createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; await VerifyDiagnostic(source, CallInfoArgumentOutOfRangeDescriptor, "There is no argument at position 1"); } - public override async Task - ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string method, string call, string argAccess) + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -106,11 +97,11 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, int y); + Task Bar(int x, int y); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x, int y] {{ get; }} + Task this[int x, int y] {{ get; }} }} public class FooTests @@ -128,11 +119,6 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; @@ -142,6 +128,8 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAccessingArgumentWithinBounds(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; +using System; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -149,11 +137,11 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, int y = 1); + Task Bar(int x, int y = 1); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x, int y = 1] {{ get; }} + Task this[int x, int y = 1] {{ get; }} }} public class FooTests @@ -166,16 +154,6 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(value: {call}, createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; @@ -185,6 +163,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAccessingArgumentWithinBoundsForNestedCall(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -192,12 +171,12 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(int x); + Task Bar(int x); }} public interface IFooBar {{ - int FooBaz(int x, int y); + Task FooBaz(int x, int y); }} public class FooTests @@ -213,15 +192,15 @@ public void Test() var x = outerCallInfo.ArgAt(1); var y = outerCallInfo[1]; - var xx = innerCallInfo.ArgAt(0); - var yy = innerCallInfo[0]; + var xx = innerCallInfo.ArgAt(0); + var yy = innerCallInfo[0]; + + return new Exception(); + }}); return new Exception(); }}); - return new Exception(); - }}); - }} }} }}"; @@ -231,6 +210,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenManuallyCasting_ToSupportedType(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -238,9 +218,9 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, Bar y); + Task Bar(int x, Bar y); - int this[int x, Bar y] {{ get; }} + Task this[int x, Bar y] {{ get; }} }} public class BarBase @@ -266,11 +246,6 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; @@ -281,23 +256,25 @@ public void Test() public override async Task ReportsDiagnostic_WhenManuallyCasting_ToUnsupportedType(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; +using System; using NSubstitute; using NSubstitute.ExceptionExtensions; namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, double y); + Task Bar(int x, double y); - int Bar(string x, object y); + Task Bar(string x, object y); - int Foo(int x, FooBar bar); + Task Foo(int x, FooBar bar); - int this[int x, double y] {{ get; }} + Task this[int x, double y] {{ get; }} - int this[string x, object y] {{ get; }} + Task this[string x, object y] {{ get; }} - int this[int x, FooBar bar] {{ get; }} + Task this[int x, FooBar bar] {{ get; }} }} public class Bar @@ -323,11 +300,6 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; @@ -337,6 +309,8 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenCasting_WithArgAt_ToSupportedType(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; +using System; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -344,13 +318,13 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, Bar y); + Task Bar(int x, Bar y); - int Bar(decimal x, object y, int z = 1); + Task Bar(decimal x, object y, int z = 1); - int this[int x, Bar y] {{ get; }} + Task this[int x, Bar y] {{ get; }} - int this[decimal x, object y] {{ get; }} + Task this[decimal x, object y] {{ get; }} }} public class BarBase @@ -371,16 +345,6 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(value: {call}, createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; @@ -390,24 +354,24 @@ public void Test() public override async Task ReportsDiagnostic_WhenCasting_WithArgAt_ToUnsupportedType(string method, string call, string argAccess, string message) { var source = $@"using System; -using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, double y); + Task Bar(int x, double y); - int Bar(object x, object y); + Task Bar(object x, object y); - int Foo(int x, FooBar bar); + Task Foo(int x, FooBar bar); - int this[int x, double y] {{ get; }} + Task this[int x, double y] {{ get; }} - int this[object x, object y] {{ get; }} + Task this[object x, object y] {{ get; }} - int this[int x, FooBar bar] {{ get; }} + Task this[int x, FooBar bar] {{ get; }} }} public class Bar @@ -433,20 +397,16 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; await VerifyDiagnostic(source, CallInfoCouldNotConvertParameterAtPositionDescriptor, message); } - public override async Task ReportsNoDiagnostic_WhenCastingElementsFromArgTypes(string method, string call, string argAccess) + public override async Task ReportsNoDiagnostic_WhenCastingElementsFromArgTypes(string method, string callInfo, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -454,9 +414,9 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(Bar x); + Task Bar(Bar x); - int this[Bar x] {{ get; }} + Task this[Bar x] {{ get; }} }} public class Bar @@ -468,21 +428,11 @@ public class FooTests public void Test() {{ var substitute = NSubstitute.Substitute.For(); - {method}({call}, callInfo => + {method}({callInfo}, callInfo => {{ {argAccess} return new Exception(); }}); - {method}(value: {call}, createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; @@ -492,16 +442,17 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAssigningValueToNotRefNorOutArgumentViaIndirectCall(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; namespace MyNamespace {{ - public interface Foo + public interface Foo {{ - int Bar(Bar x); + Task Bar(Bar x); - int this[Bar x] {{ get; }} + Task this[Bar x] {{ get; }} }} public class Bar @@ -523,11 +474,6 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; @@ -537,6 +483,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAccessingArgumentByTypeNotInInvocation(string method, string call, string argAccess, string message) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -544,11 +491,11 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x] {{ get; }} + Task this[int x] {{ get; }} }} public class FooTests @@ -561,16 +508,6 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(value: {call}, createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; @@ -580,6 +517,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAccessingArgumentByTypeNotInInvocationForNestedCall(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -587,12 +525,12 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(int x); + Task Bar(int x); }} public interface IFooBar {{ - int FooBaz(object x); + Task FooBaz(int x); }} public class FooTests @@ -600,7 +538,7 @@ public class FooTests public void Test() {{ var substitute = NSubstitute.Substitute.For(); - {method}(substitute.FooBaz(Arg.Any()), outerCallInfo => + {method}(substitute.FooBaz(Arg.Any()), outerCallInfo => {{ var otherSubstitute = NSubstitute.Substitute.For(); {method}(otherSubstitute.Bar(Arg.Any()), innerCallInfo => @@ -623,6 +561,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAccessingArgumentOutOfBoundsForNestedCall(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -630,12 +569,12 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(int x); + Task Bar(int x); }} public interface IFooBar {{ - int FooBaz(int x, int y); + Task FooBaz(int x, int y); }} public class FooTests @@ -682,6 +621,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAccessingArgumentByTypeInInInvocation(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -689,17 +629,17 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(int x); + Task Bar(int x); - int Bar(Foo x); + Task Bar(Foo x); - int Bar(int x, object y); + Task Bar(int x, object y); - int this[int x] {{ get; }} + Task this[int x] {{ get; }} - int this[Foo x] {{ get; }} + Task this[Foo x] {{ get; }} - int this[int x, object y] {{ get; }} + Task this[int x, object y] {{ get; }} }} public class FooBase @@ -720,16 +660,6 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(value: {call}, createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; @@ -740,6 +670,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAccessingArgumentByTypeInInvocationForNestedCall(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -747,12 +678,12 @@ namespace MyNamespace {{ public interface IFoo {{ - int Bar(int x); + Task Bar(int x); }} public interface IFooBar {{ - int FooBaz(string x); + Task FooBaz(string x); }} public class FooTests @@ -782,6 +713,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAccessingArgumentByTypeMultipleTimesInInvocation(string method, string call, string argAccess, string message) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -789,13 +721,13 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, int y); + Task Bar(int x, int y); - int Bar(object x, object y); + Task Bar(object x, object y); - int this[int x, int y] {{ get; }} + Task this[int x, int y] {{ get; }} - int this[object x, object y] {{ get; }} + Task this[object x, object y] {{ get; }} }} public class FooBar @@ -817,11 +749,6 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; @@ -832,6 +759,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAccessingArgumentByTypeMultipleDifferentTypesInInvocation(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -839,13 +767,13 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, double y); + Task Bar(int x, double y); - int Bar(object x, FooBar y); + Task Bar(object x, FooBar y); - int this[int x, double y] {{ get; }} + Task this[int x, double y] {{ get; }} - int this[object x, FooBar y] {{ get; }} + Task this[object x, FooBar y] {{ get; }} }} public class FooBar @@ -862,16 +790,6 @@ public void Test() {argAccess} return new Exception(); }}); - {method}(value: {call}, createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}); - {method}(createException: callInfo => - {{ - {argAccess} - return new Exception(); - }}, value: {call}); }} }} }}"; @@ -882,6 +800,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAssigningValueToNotOutNorRefArgument(string method, string call) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -889,9 +808,9 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x, double y); + Task Bar(int x, double y); - int this[int x, double y] {{ get; }} + Task this[int x, double y] {{ get; }} }} public class FooTests @@ -909,21 +828,16 @@ public void Test() [|callInfo[1]|] = 1; return new Exception(); }}); - {method}(createException: callInfo => - {{ - [|callInfo[1]|] = 1; - return new Exception(); - }}, value: {call}); }} }} }}"; - await VerifyDiagnostic(source, CallInfoArgumentIsNotOutOrRefDescriptor, "Could not set argument 1 (double) as it is not an out or ref argument."); } public override async Task ReportsNoDiagnostic_WhenAssigningValueToRefArgument(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -931,7 +845,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(ref int x); + Task Bar(ref int x); }} public class FooTests @@ -950,11 +864,6 @@ public void Test() callInfo[0] = 1; return new Exception(); }}); - {method}(createException: callInfo => - {{ - callInfo[0] = 1; - return new Exception(); - }}, value: substitute.Bar(ref value)); }} }} }}"; @@ -964,6 +873,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAssigningValueToOutArgument(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -971,7 +881,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(out int x); + Task Bar(out int x); }} public class FooTests @@ -985,16 +895,6 @@ public void Test() callInfo[0] = 1; return new Exception(); }}); - {method}(value: substitute.Bar(out value), createException: callInfo => - {{ - callInfo[0] = 1; - return new Exception(); - }}); - {method}(createException: callInfo => - {{ - callInfo[0] = 1; - return new Exception(); - }}, value: substitute.Bar(out value)); }} }} }}"; @@ -1004,6 +904,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAssigningValueToOutOfBoundsArgument(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -1011,7 +912,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(out int x); + Task Bar(out int x); }} public class FooTests @@ -1030,11 +931,6 @@ public void Test() [|callInfo[1]|] = 1; return new Exception(); }}); - {method}(createException: callInfo => - {{ - [|callInfo[1]|] = 1; - return new Exception(); - }}, value: substitute.Bar(out value)); }} }} }}"; @@ -1044,6 +940,7 @@ public void Test() public override async Task ReportsDiagnostic_WhenAssigningType_NotAssignableTo_Argument(string method, string left, string right, string expectedMessage) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using System.Collections.Generic; using NSubstitute.ExceptionExtensions; @@ -1052,7 +949,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(out {left} x); + Task Bar(out {left} x); }} public class FooTests @@ -1066,16 +963,6 @@ public void Test() [|callInfo[0]|] = {right}; return new Exception(); }}); - {method}(value: substitute.Bar(out value), createException: callInfo => - {{ - [|callInfo[0]|] = {right}; - return new Exception(); - }}); - {method}(createException: callInfo => - {{ - [|callInfo[0]|] = {right}; - return new Exception(); - }}, value: substitute.Bar(out value)); }} }} }}"; @@ -1086,6 +973,7 @@ public void Test() public override async Task ReportsNoDiagnostic_WhenAssigningType_AssignableTo_Argument(string method, string left, string right) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using System.Collections.Generic; using NSubstitute.ExceptionExtensions; @@ -1094,7 +982,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(out {left} x); + Task Bar(out {left} x); }} public class FooTests @@ -1113,11 +1001,6 @@ public void Test() callInfo[0] = {right}; return new Exception(); }}); - {method}(createException: callInfo => - {{ - callInfo[0] = {right}; - return new Exception(); - }}, value: substitute.Bar(out value)); }} }} }}"; diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodsTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodsTests.cs index f173d85a..25bfcd64 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodsTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodsTests.cs @@ -5,20 +5,21 @@ namespace NSubstitute.Analyzers.Tests.VisualBasic.DiagnosticAnalyzersTests.CallInfoAnalyzerTests; -[CombinatoryData("Throws", "ThrowsForAnyArgs")] +[CombinatoryData("Throws", "ThrowsAsync", "ThrowsForAnyArgs", "ThrowsAsyncForAnyArgs")] public class ThrowsAsExtensionMethodsTests : CallInfoDiagnosticVerifier { public override async Task ReportsNoDiagnostics_WhenSubstituteMethodCannotBeInferred(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -39,13 +40,14 @@ End Class public override async Task ReportsDiagnostic_WhenAccessingArgumentOutOfBounds(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -65,14 +67,15 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Integer + Function Bar(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -91,14 +94,15 @@ End Class public override async Task ReportsNoDiagnostic_WhenAccessingArgumentWithinBounds(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal Optional y As Integer = 1) As Integer + Function Bar(ByVal x As Integer, ByVal Optional y As Integer = 1) As Task(Of Integer) ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal Optional y As Integer = 1) As Integer + Default ReadOnly Property Item(ByVal x As Integer, ByVal Optional y As Integer = 1) As Task(Of Integer) End Interface Public Class FooTests @@ -118,16 +122,17 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAccessingArgumentWithinBoundsForNestedCall(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface IFoo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Interface IFooBar - Function FooBaz(ByVal x As Integer, ByVal y As Integer) As Integer + Function FooBaz(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -154,16 +159,17 @@ End Class public override async Task ReportsDiagnostic_WhenAccessingArgumentOutOfBoundsForNestedCall(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface IFoo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Interface IFooBar - Function FooBaz(ByVal x As Integer, ByVal y As Integer) As Integer + Function FooBaz(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -202,13 +208,14 @@ End Class public override async Task ReportsNoDiagnostic_WhenManuallyCasting_ToSupportedType(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Bar) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Bar) As Integer + Function Bar(ByVal x As Integer, ByVal y As Bar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Bar) As Task(Of Integer) End Interface Public Class BarBase @@ -235,14 +242,15 @@ End Class public override async Task ReportsDiagnostic_WhenManuallyCasting_ToUnsupportedType(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Double) As Integer - Function Foo(ByVal x As Integer, ByVal bar As FooBar) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal bar As FooBar) As Integer + Function Bar(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Function Foo(ByVal x As Integer, ByVal bar As FooBar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal bar As FooBar) As Task(Of Integer) End Interface Public Class Bar @@ -269,13 +277,14 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenCasting_WithArgAt_ToSupportedType(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Bar) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Bar) As Integer + Function Bar(ByVal x As Integer, ByVal y As Bar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Bar) As Task(Of Integer) End Interface Public Class BarBase @@ -303,14 +312,15 @@ End Namespace public override async Task ReportsDiagnostic_WhenCasting_WithArgAt_ToUnsupportedType(string method, string call, string argAccess, string message) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Double) As Integer - Function Foo(ByVal x As Integer, ByVal bar As FooBar) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal bar As FooBar) As Integer + Function Bar(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Function Foo(ByVal x As Integer, ByVal bar As FooBar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal bar As FooBar) As Task(Of Integer) End Interface Public Class Bar @@ -337,13 +347,14 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenCastingElementsFromArgTypes(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Bar) As Integer - Default ReadOnly Property Item(ByVal x As Bar) As Integer + Function Bar(ByVal x As Bar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Bar) As Task(Of Integer) End Interface Public Class Bar @@ -366,13 +377,14 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAssigningValueToNotRefNorOutArgumentViaIndirectCall(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Bar) As Integer - Default ReadOnly Property Item(ByVal x As Bar) As Integer + Function Bar(ByVal x As Bar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Bar) As Task(Of Integer) End Interface Public Class Bar @@ -395,14 +407,15 @@ End Namespace public override async Task ReportsDiagnostic_WhenAccessingArgumentByTypeNotInInvocation(string method, string call, string argAccess, string message) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface @@ -423,17 +436,18 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAccessingArgumentByTypeInInInvocation(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface IFoo - Function Bar(ByVal x As Integer) As Integer - Function Bar(ByVal x As Foo) As Integer - Function Bar(ByVal x As Integer, ByVal y As Object) As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer - Default ReadOnly Property Item(ByVal x As Foo) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y as Object) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + Function Bar(ByVal x As Foo) As Task(Of Integer) + Function Bar(ByVal x As Integer, ByVal y As Object) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Foo) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y as Object) As Task(Of Integer) End Interface Public Class FooBase @@ -461,16 +475,17 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAccessingArgumentByTypeInInvocationForNestedCall(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface IFoo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Interface IFooBar - Function FooBaz(ByVal x As String) As Integer + Function FooBaz(ByVal x As String) As Task(Of Integer) End Interface Public Class FooTests @@ -495,15 +510,16 @@ End Class public override async Task ReportsDiagnostic_WhenAccessingArgumentByTypeMultipleTimesInInvocation(string method, string call, string argAccess, string message) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Integer) As Integer - Function Bar(ByVal x As Object, ByVal y As Object) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Integer - Default ReadOnly Property Item(ByVal x As Object, ByVal y As Object) As Integer + Function Bar(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) + Function Bar(ByVal x As Object, ByVal y As Object) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Object, ByVal y As Object) As Task(Of Integer) End Interface Public Class FooBar @@ -526,15 +542,16 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAccessingArgumentByTypeMultipleDifferentTypesInInvocation(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Double) As Integer - Function Bar(ByVal x As Object, ByVal y As FooBar) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Integer - Default ReadOnly Property Item(ByVal x As Object, ByVal y As FooBar) As Integer + Function Bar(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Function Bar(ByVal x As Object, ByVal y As FooBar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Object, ByVal y As FooBar) As Task(Of Integer) End Interface Public Class FooBar @@ -558,13 +575,14 @@ End Namespace public override async Task ReportsDiagnostic_WhenAssigningValueToNotOutNorRefArgument(string method, string call) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Double) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Integer + Function Bar(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) End Interface Public Class FooTests @@ -584,12 +602,13 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAssigningValueToRefArgument(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByRef x As Integer) As Integer + Function Bar(ByRef x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -610,13 +629,14 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAssigningValueToOutArgument(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports System.Runtime.InteropServices Namespace MyNamespace Interface Foo - Function Bar( ByRef x As Integer) As Integer + Function Bar( ByRef x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -637,13 +657,14 @@ End Namespace public override async Task ReportsDiagnostic_WhenAssigningValueToOutOfBoundsArgument(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports System.Runtime.InteropServices Namespace MyNamespace Interface Foo - Function Bar( ByRef x As Integer) As Integer + Function Bar( ByRef x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -664,6 +685,7 @@ End Namespace public override async Task ReportsDiagnostic_WhenAssigningType_NotAssignableTo_Argument(string method, string left, string right, string expectedMessage) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports System.Runtime.InteropServices @@ -671,7 +693,7 @@ Imports System.Collections.Generic Namespace MyNamespace Interface Foo - Function Bar( ByRef x As {left}) As Integer + Function Bar( ByRef x As {left}) As Task(Of Integer) End Interface Public Class FooTests @@ -694,6 +716,7 @@ public override async Task ReportsNoDiagnostic_WhenAssigningType_AssignableTo_Ar { var source = $@" Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports System.Runtime.InteropServices @@ -701,7 +724,7 @@ Imports System.Collections.Generic Namespace MyNamespace Interface Foo - Function Bar( ByRef x As {left}) As Integer + Function Bar( ByRef x As {left}) As Task(Of Integer) End Interface Public Class FooTests @@ -723,16 +746,17 @@ End Namespace public override async Task ReportsDiagnostic_WhenAccessingArgumentByTypeNotInInvocationForNestedCall(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface IFoo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Interface IFooBar - Function FooBaz(ByVal x As Integer) As Integer + Function FooBaz(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodsTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodsTests.cs index 5dde1838..12b704de 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodsTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodsTests.cs @@ -5,20 +5,25 @@ namespace NSubstitute.Analyzers.Tests.VisualBasic.DiagnosticAnalyzersTests.CallInfoAnalyzerTests; -[CombinatoryData("ExceptionExtensions.Throws", "ExceptionExtensions.ThrowsForAnyArgs")] +[CombinatoryData( + "ExceptionExtensions.Throws", + "ExceptionExtensions.ThrowsAsync", + "ExceptionExtensions.ThrowsForAnyArgs", + "ExceptionExtensions.ThrowsAsyncForAnyArgs")] public class ThrowsAsOrdinaryMethodsTests : CallInfoDiagnosticVerifier { public override async Task ReportsNoDiagnostics_WhenSubstituteMethodCannotBeInferred(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -47,13 +52,14 @@ End Class public override async Task ReportsDiagnostic_WhenAccessingArgumentOutOfBounds(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -81,14 +87,15 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Integer + Function Bar(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -115,14 +122,15 @@ End Class public override async Task ReportsNoDiagnostic_WhenAccessingArgumentWithinBounds(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal Optional y As Integer = 1) As Integer + Function Bar(ByVal x As Integer, ByVal Optional y As Integer = 1) As Task(Of Integer) ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal Optional y As Integer = 1) As Integer + Default ReadOnly Property Item(ByVal x As Integer, ByVal Optional y As Integer = 1) As Task(Of Integer) End Interface Public Class FooTests @@ -150,16 +158,17 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAccessingArgumentWithinBoundsForNestedCall(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface IFoo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Interface IFooBar - Function FooBaz(ByVal x As Integer, ByVal y As Integer) As Integer + Function FooBaz(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -186,16 +195,17 @@ End Class public override async Task ReportsDiagnostic_WhenAccessingArgumentOutOfBoundsForNestedCall(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface IFoo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Interface IFooBar - Function FooBaz(ByVal x As Integer, ByVal y As Integer) As Integer + Function FooBaz(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -234,13 +244,14 @@ End Class public override async Task ReportsNoDiagnostic_WhenManuallyCasting_ToSupportedType(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Bar) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Bar) As Integer + Function Bar(ByVal x As Integer, ByVal y As Bar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Bar) As Task(Of Integer) End Interface Public Class BarBase @@ -275,14 +286,15 @@ End Class public override async Task ReportsDiagnostic_WhenManuallyCasting_ToUnsupportedType(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Double) As Integer - Function Foo(ByVal x As Integer, ByVal bar As FooBar) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal bar As FooBar) As Integer + Function Bar(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Function Foo(ByVal x As Integer, ByVal bar As FooBar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal bar As FooBar) As Task(Of Integer) End Interface Public Class Bar @@ -317,13 +329,14 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenCasting_WithArgAt_ToSupportedType(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Bar) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Bar) As Integer + Function Bar(ByVal x As Integer, ByVal y As Bar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Bar) As Task(Of Integer) End Interface Public Class BarBase @@ -359,14 +372,15 @@ End Namespace public override async Task ReportsDiagnostic_WhenCasting_WithArgAt_ToUnsupportedType(string method, string call, string argAccess, string message) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Double) As Integer - Function Foo(ByVal x As Integer, ByVal bar As FooBar) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal bar As FooBar) As Integer + Function Bar(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Function Foo(ByVal x As Integer, ByVal bar As FooBar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal bar As FooBar) As Task(Of Integer) End Interface Public Class Bar @@ -401,13 +415,14 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenCastingElementsFromArgTypes(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Bar) As Integer - Default ReadOnly Property Item(ByVal x As Bar) As Integer + Function Bar(ByVal x As Bar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Bar) As Task(Of Integer) End Interface Public Class Bar @@ -438,13 +453,14 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAssigningValueToNotRefNorOutArgumentViaIndirectCall(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Bar) As Integer - Default ReadOnly Property Item(ByVal x As Bar) As Integer + Function Bar(ByVal x As Bar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Bar) As Task(Of Integer) End Interface Public Class Bar @@ -475,14 +491,15 @@ End Namespace public override async Task ReportsDiagnostic_WhenAccessingArgumentByTypeNotInInvocation(string method, string call, string argAccess, string message) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface @@ -511,17 +528,18 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAccessingArgumentByTypeInInInvocation(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface IFoo - Function Bar(ByVal x As Integer) As Integer - Function Bar(ByVal x As Foo) As Integer - Function Bar(ByVal x As Integer, ByVal y As Object) As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer - Default ReadOnly Property Item(ByVal x As Foo) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y as Object) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + Function Bar(ByVal x As Foo) As Task(Of Integer) + Function Bar(ByVal x As Integer, ByVal y As Object) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Foo) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y as Object) As Task(Of Integer) End Interface Public Class FooBase @@ -557,16 +575,17 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAccessingArgumentByTypeInInvocationForNestedCall(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface IFoo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Interface IFooBar - Function FooBaz(ByVal x As String) As Integer + Function FooBaz(ByVal x As String) As Task(Of Integer) End Interface Public Class FooTests @@ -591,15 +610,16 @@ End Class public override async Task ReportsDiagnostic_WhenAccessingArgumentByTypeMultipleTimesInInvocation(string method, string call, string argAccess, string message) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Integer) As Integer - Function Bar(ByVal x As Object, ByVal y As Object) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Integer - Default ReadOnly Property Item(ByVal x As Object, ByVal y As Object) As Integer + Function Bar(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) + Function Bar(ByVal x As Object, ByVal y As Object) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Integer) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Object, ByVal y As Object) As Task(Of Integer) End Interface Public Class FooBar @@ -631,15 +651,16 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAccessingArgumentByTypeMultipleDifferentTypesInInvocation(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Double) As Integer - Function Bar(ByVal x As Object, ByVal y As FooBar) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Integer - Default ReadOnly Property Item(ByVal x As Object, ByVal y As FooBar) As Integer + Function Bar(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Function Bar(ByVal x As Object, ByVal y As FooBar) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Object, ByVal y As FooBar) As Task(Of Integer) End Interface Public Class FooBar @@ -671,13 +692,14 @@ End Namespace public override async Task ReportsDiagnostic_WhenAssigningValueToNotOutNorRefArgument(string method, string call) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer, ByVal y As Double) As Integer - Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Integer + Function Bar(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer, ByVal y As Double) As Task(Of Integer) End Interface Public Class FooTests @@ -705,12 +727,13 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAssigningValueToRefArgument(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByRef x As Integer) As Integer + Function Bar(ByRef x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -739,13 +762,14 @@ End Namespace public override async Task ReportsNoDiagnostic_WhenAssigningValueToOutArgument(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports System.Runtime.InteropServices Namespace MyNamespace Interface Foo - Function Bar( ByRef x As Integer) As Integer + Function Bar( ByRef x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -774,13 +798,14 @@ End Namespace public override async Task ReportsDiagnostic_WhenAssigningValueToOutOfBoundsArgument(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports System.Runtime.InteropServices Namespace MyNamespace Interface Foo - Function Bar( ByRef x As Integer) As Integer + Function Bar( ByRef x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -809,6 +834,7 @@ End Namespace public override async Task ReportsDiagnostic_WhenAssigningType_NotAssignableTo_Argument(string method, string left, string right, string expectedMessage) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports System.Runtime.InteropServices @@ -816,7 +842,7 @@ Imports System.Collections.Generic Namespace MyNamespace Interface Foo - Function Bar( ByRef x As {left}) As Integer + Function Bar( ByRef x As {left}) As Task(Of Integer) End Interface Public Class FooTests @@ -847,6 +873,7 @@ public override async Task ReportsNoDiagnostic_WhenAssigningType_AssignableTo_Ar { var source = $@" Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Imports System.Runtime.InteropServices @@ -854,7 +881,7 @@ Imports System.Collections.Generic Namespace MyNamespace Interface Foo - Function Bar( ByRef x As {left}) As Integer + Function Bar( ByRef x As {left}) As Task(Of Integer) End Interface Public Class FooTests @@ -884,16 +911,17 @@ End Namespace public override async Task ReportsDiagnostic_WhenAccessingArgumentByTypeNotInInvocationForNestedCall(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface IFoo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Interface IFooBar - Function FooBaz(ByVal x As Integer) As Integer + Function FooBaz(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests From f7fcddc70ec32a66ae4bdd54e7c13ec02fe65e27 Mon Sep 17 00:00:00 2001 From: tpodolak Date: Fri, 22 Jul 2022 16:46:13 +0200 Subject: [PATCH 05/10] GH-186 - ConflictingArgumentAssignmentAnalyzer support for ThrowsAsync like methods --- .../ThrowsAsExtensionMethodTests.cs | 39 +++++++++++-------- .../ThrowsAsExtensionMethodTests.cs | 39 +++++++++++-------- .../ThrowsAsOrdinaryMethodTests.cs | 37 +++++++++++------- 3 files changed, 68 insertions(+), 47 deletions(-) diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/ConflictingArgumentAssignmentsAnalyzerTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/ConflictingArgumentAssignmentsAnalyzerTests/ThrowsAsExtensionMethodTests.cs index 41166dc3..695c847e 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/ConflictingArgumentAssignmentsAnalyzerTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/ConflictingArgumentAssignmentsAnalyzerTests/ThrowsAsExtensionMethodTests.cs @@ -3,12 +3,13 @@ namespace NSubstitute.Analyzers.Tests.CSharp.DiagnosticAnalyzerTests.ConflictingArgumentAssignmentsAnalyzerTests; -[CombinatoryData("Throws", "ThrowsForAnyArgs")] +[CombinatoryData("Throws", "ThrowsAsync", "ThrowsForAnyArgs", "ThrowsAsyncForAnyArgs")] public class ThrowsAsExtensionMethodTests : ConflictingArgumentAssignmentsDiagnosticVerifier { public override async Task ReportsDiagnostic_When_AndDoesMethod_SetsSameArgument_AsPreviousSetupMethod(string method, string call, string previousCallArgAccess, string andDoesArgAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -16,11 +17,11 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x] {{ get; }} + Task this[int x] {{ get; }} }} public class FooTests @@ -46,6 +47,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenSubstituteMethodCannotBeInferred(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -53,7 +55,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); }} public class FooTests @@ -80,6 +82,7 @@ public void Test() public override async Task ReportsNoDiagnostics_WhenUsedWithUnfortunatelyNamedMethod(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.Core; using NSubstitute.ExceptionExtensions; @@ -88,7 +91,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); }} public class FooTests @@ -121,6 +124,7 @@ public static void AndDoes(this ConfiguredCall call, Action firstCall, public override async Task ReportsNoDiagnostics_When_AndDoesMethod_SetsDifferentArgument_AsPreviousSetupMethod(string method, string call, string andDoesArgAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -128,11 +132,11 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x] {{ get; }} + Task this[int x] {{ get; }} }} public class FooTests @@ -158,6 +162,7 @@ public void Test() public override async Task ReportsNoDiagnostics_When_AndDoesMethod_AccessSameArguments_AsPreviousSetupMethod(string method, string call, string argAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -165,11 +170,11 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x] {{ get; }} + Task this[int x] {{ get; }} }} public class FooTests @@ -195,6 +200,7 @@ public void Test() public override async Task ReportsNoDiagnostics_When_AndDoesMethod_SetSameArguments_AsPreviousSetupMethod_SetsIndirectly(string method) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -202,7 +208,7 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); }} public class FooTests @@ -230,6 +236,7 @@ public void Test() public override async Task ReportsNoDiagnostic_When_AndDoesMethod_SetArgument_AndPreviousMethod_IsNotUsedWithCallInfo(string method, string call, string andDoesArgAccess) { var source = $@"using System; +using System.Threading.Tasks; using NSubstitute; using NSubstitute.ExceptionExtensions; @@ -237,11 +244,11 @@ namespace MyNamespace {{ public interface Foo {{ - int Bar(int x); + Task Bar(int x); - int Barr {{ get; }} + Task Barr {{ get; }} - int this[int x] {{ get; }} + Task this[int x] {{ get; }} }} public class FooTests diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/ConflictingArgumentAssignmentsAnalyzerTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/ConflictingArgumentAssignmentsAnalyzerTests/ThrowsAsExtensionMethodTests.cs index 65b2f205..37bab9db 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/ConflictingArgumentAssignmentsAnalyzerTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/ConflictingArgumentAssignmentsAnalyzerTests/ThrowsAsExtensionMethodTests.cs @@ -3,20 +3,21 @@ namespace NSubstitute.Analyzers.Tests.VisualBasic.DiagnosticAnalyzersTests.ConflictingArgumentAssignmentsAnalyzerTests; -[CombinatoryData("Throws", "ThrowsForAnyArgs")] +[CombinatoryData("Throws", "ThrowsAsync", "ThrowsForAnyArgs", "ThrowsAsyncForAnyArgs")] public class ThrowsAsExtensionMethodTests : ConflictingArgumentAssignmentsDiagnosticVerifier { public override async Task ReportsDiagnostic_When_AndDoesMethod_SetsSameArgument_AsPreviousSetupMethod(string method, string call, string previousCallArgAccess, string andDoesArgAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -39,12 +40,13 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSubstituteMethodCannotBeInferred(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -67,6 +69,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenUsedWithUnfortunatelyNamedMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports System.Runtime.CompilerServices Imports NSubstitute Imports NSubstitute.Core @@ -74,7 +77,7 @@ Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -107,14 +110,15 @@ End Module public override async Task ReportsNoDiagnostics_When_AndDoesMethod_SetsDifferentArgument_AsPreviousSetupMethod(string method, string call, string andDoesArgAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -136,14 +140,15 @@ End Class public override async Task ReportsNoDiagnostics_When_AndDoesMethod_AccessSameArguments_AsPreviousSetupMethod(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -165,12 +170,13 @@ End Class public override async Task ReportsNoDiagnostics_When_AndDoesMethod_SetSameArguments_AsPreviousSetupMethod_SetsIndirectly(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -195,14 +201,15 @@ End Class public override async Task ReportsNoDiagnostic_When_AndDoesMethod_SetArgument_AndPreviousMethod_IsNotUsedWithCallInfo(string method, string call, string andDoesArgAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/ConflictingArgumentAssignmentsAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/ConflictingArgumentAssignmentsAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs index a4838283..c2126e96 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/ConflictingArgumentAssignmentsAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/ConflictingArgumentAssignmentsAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs @@ -9,14 +9,15 @@ public class ThrowsAsOrdinaryMethodTests : ConflictingArgumentAssignmentsDiagnos public override async Task ReportsDiagnostic_When_AndDoesMethod_SetsSameArgument_AsPreviousSetupMethod(string method, string call, string previousCallArgAccess, string andDoesArgAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -53,12 +54,13 @@ End Namespace public override async Task ReportsNoDiagnostics_WhenSubstituteMethodCannotBeInferred(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -97,6 +99,7 @@ End Class public override async Task ReportsNoDiagnostics_WhenUsedWithUnfortunatelyNamedMethod(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports System.Runtime.CompilerServices Imports NSubstitute Imports NSubstitute.Core @@ -104,7 +107,7 @@ Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -137,14 +140,15 @@ End Module public override async Task ReportsNoDiagnostics_When_AndDoesMethod_SetsDifferentArgument_AsPreviousSetupMethod(string method, string call, string andDoesArgAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -180,14 +184,15 @@ End Class public override async Task ReportsNoDiagnostics_When_AndDoesMethod_AccessSameArguments_AsPreviousSetupMethod(string method, string call, string argAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -223,12 +228,13 @@ End Class public override async Task ReportsNoDiagnostics_When_AndDoesMethod_SetSameArguments_AsPreviousSetupMethod_SetsIndirectly(string method) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests @@ -273,14 +279,15 @@ End Class public override async Task ReportsNoDiagnostic_When_AndDoesMethod_SetArgument_AndPreviousMethod_IsNotUsedWithCallInfo(string method, string call, string andDoesArgAccess) { var source = $@"Imports System +Imports System.Threading.Tasks Imports NSubstitute Imports NSubstitute.ExceptionExtensions Namespace MyNamespace Interface Foo - Function Bar(ByVal x As Integer) As Integer - ReadOnly Property Barr As Integer - Default ReadOnly Property Item(ByVal x As Integer) As Integer + Function Bar(ByVal x As Integer) As Task(Of Integer) + ReadOnly Property Barr As Task(Of Integer) + Default ReadOnly Property Item(ByVal x As Integer) As Task(Of Integer) End Interface Public Class FooTests From 0831c83dd9984a20439ba09bb8a0ecefa398a769 Mon Sep 17 00:00:00 2001 From: tpodolak Date: Fri, 22 Jul 2022 16:46:13 +0200 Subject: [PATCH 06/10] GH-186 - SyncOverAsyncThrowsCodeFixProvider to provide ThrowsAsync fixes for new versions of NSubstitute --- global.json | 2 +- .../SyncOverAsyncThrowsCodeFixProvider.cs | 10 + ...tractSyncOverAsyncThrowsCodeFixProvider.cs | 81 ++++-- .../Extensions/SubstituteSymbolExtensions.cs | 2 +- .../SyncOverAsyncThrowsCodeFixProvider.cs | 12 + .../SyncOverAsyncThrowsCodeFixActionsTests.cs | 37 ++- .../SyncOverAsyncThrowsCodeFixVerifier.cs | 21 ++ .../ThrowsAsExtensionMethodTests.cs | 182 +++++++++++++- ...ionsMethodWithGenericTypeSpecifiedTests.cs | 152 +++++++++++- .../ThrowsAsOrdinaryMethodTests.cs | 200 ++++++++++++++- ...naryMethodWithGenericTypeSpecifiedTests.cs | 158 +++++++++++- .../CodeFixCodeActionsVerifier.cs | 50 ++-- .../CodeFixProviders/CodeFixVerifier.cs | 99 ++++---- ...ncOverAsyncThrowsCodeFixActionsVerifier.cs | 2 + .../ISyncOverAsyncThrowsCodeFixVerifier.cs | 6 + .../CodeVerifier.cs | 19 ++ .../SyncOverAsyncThrowsCodeFixActionsTests.cs | 32 ++- .../SyncOverAsyncThrowsCodeFixVerifier.cs | 21 ++ .../ThrowsAsExtensionMethodTests.cs | 200 ++++++++++++++- ...ionsMethodWithGenericTypeSpecifiedTests.cs | 128 +++++++++- .../ThrowsAsOrdinaryMethodTests.cs | 230 +++++++++++++++++- ...naryMethodWithGenericTypeSpecifiedTests.cs | 15 ++ 22 files changed, 1544 insertions(+), 115 deletions(-) diff --git a/global.json b/global.json index 19c87f2a..572a2a6f 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "6.0.300" + "version": "6.0.200" } } diff --git a/src/NSubstitute.Analyzers.CSharp/CodeFixProviders/SyncOverAsyncThrowsCodeFixProvider.cs b/src/NSubstitute.Analyzers.CSharp/CodeFixProviders/SyncOverAsyncThrowsCodeFixProvider.cs index fc33719c..a1b2f234 100644 --- a/src/NSubstitute.Analyzers.CSharp/CodeFixProviders/SyncOverAsyncThrowsCodeFixProvider.cs +++ b/src/NSubstitute.Analyzers.CSharp/CodeFixProviders/SyncOverAsyncThrowsCodeFixProvider.cs @@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp.Syntax; using NSubstitute.Analyzers.Shared.CodeFixProviders; +using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace NSubstitute.Analyzers.CSharp.CodeFixProviders; @@ -9,4 +10,13 @@ namespace NSubstitute.Analyzers.CSharp.CodeFixProviders; internal sealed class SyncOverAsyncThrowsCodeFixProvider : AbstractSyncOverAsyncThrowsCodeFixProvider { protected override SyntaxNode GetExpression(InvocationExpressionSyntax invocationExpressionSyntax) => ((MemberAccessExpressionSyntax)invocationExpressionSyntax.Expression).Expression; + + protected override SyntaxNode UpdateMemberExpression(InvocationExpressionSyntax invocationExpressionSyntax, SyntaxNode updatedNameSyntax) + { + var expressionSyntax = invocationExpressionSyntax.Expression; + return invocationExpressionSyntax.WithExpression(MemberAccessExpression( + expressionSyntax.Kind(), + ((MemberAccessExpressionSyntax)expressionSyntax).Expression, + (SimpleNameSyntax)updatedNameSyntax)); + } } \ No newline at end of file diff --git a/src/NSubstitute.Analyzers.Shared/CodeFixProviders/AbstractSyncOverAsyncThrowsCodeFixProvider.cs b/src/NSubstitute.Analyzers.Shared/CodeFixProviders/AbstractSyncOverAsyncThrowsCodeFixProvider.cs index de2d1713..976db029 100644 --- a/src/NSubstitute.Analyzers.Shared/CodeFixProviders/AbstractSyncOverAsyncThrowsCodeFixProvider.cs +++ b/src/NSubstitute.Analyzers.Shared/CodeFixProviders/AbstractSyncOverAsyncThrowsCodeFixProvider.cs @@ -39,19 +39,18 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken); var methodSymbol = (IMethodSymbol)semanticModel.GetSymbolInfo(invocation).Symbol; + var supportsThrowsAsync = SupportsThrowsAsync(semanticModel.Compilation); - if (methodSymbol.Parameters.Any(param => param.Type.IsCallInfoDelegate(semanticModel))) + if (!supportsThrowsAsync && methodSymbol.Parameters.Any(param => param.Type.IsCallInfoDelegate(semanticModel))) { return; } - var replacementMethod = methodSymbol.IsThrowsSyncForAnyArgsMethod() - ? "ReturnsForAnyArgs" - : "Returns"; + var replacementMethod = GetReplacementMethodName(methodSymbol, useModernSyntax: supportsThrowsAsync); var codeAction = CodeAction.Create( $"Replace with {replacementMethod}", - ct => CreateChangedDocument(context, semanticModel, invocation, methodSymbol, ct), + ct => CreateChangedDocument(context, semanticModel, invocation, methodSymbol, supportsThrowsAsync, ct), nameof(AbstractSyncOverAsyncThrowsCodeFixProvider)); context.RegisterCodeFix(codeAction, diagnostic); @@ -59,28 +58,56 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) protected abstract SyntaxNode GetExpression(TInvocationExpressionSyntax invocationExpressionSyntax); + protected abstract SyntaxNode UpdateMemberExpression(TInvocationExpressionSyntax invocationExpressionSyntax, SyntaxNode updatedNameSyntax); + private async Task CreateChangedDocument( CodeFixContext context, SemanticModel semanticModel, TInvocationExpressionSyntax currentInvocationExpression, IMethodSymbol invocationSymbol, + bool useModernSyntax, CancellationToken cancellationToken) { var documentEditor = await DocumentEditor.CreateAsync(context.Document, cancellationToken); var invocationOperation = (IInvocationOperation)semanticModel.GetOperation(currentInvocationExpression); - var updatedInvocationExpression = await CreateUpdatedInvocationExpression( - currentInvocationExpression, - invocationOperation, - invocationSymbol, - context); + var updatedInvocationExpression = useModernSyntax + ? await CreateThrowsAsyncInvocationExpression( + currentInvocationExpression, + invocationSymbol, + context) + : await CreateReturnInvocationExpression( + currentInvocationExpression, + invocationOperation, + invocationSymbol, + context); documentEditor.ReplaceNode(currentInvocationExpression, updatedInvocationExpression); return documentEditor.GetChangedDocument(); } - private async Task CreateUpdatedInvocationExpression( + private async Task CreateThrowsAsyncInvocationExpression( + TInvocationExpressionSyntax currentInvocationExpression, + IMethodSymbol invocationSymbol, + CodeFixContext context) + { + var updatedMethodName = + invocationSymbol.IsThrowsSyncForAnyArgsMethod() + ? MetadataNames.NSubstituteThrowsAsyncMethod + : MetadataNames.NSubstituteThrowsAsyncForAnyArgsMethod; + + var documentEditor = await DocumentEditor.CreateAsync(context.Document); + var syntaxGenerator = documentEditor.Generator; + + var nameSyntax = invocationSymbol.IsGenericMethod + ? syntaxGenerator.GenericName(updatedMethodName, invocationSymbol.TypeArguments) + : syntaxGenerator.IdentifierName(updatedMethodName); + + return UpdateMemberExpression(currentInvocationExpression, nameSyntax); + } + + private async Task CreateReturnInvocationExpression( TInvocationExpressionSyntax currentInvocationExpression, IInvocationOperation invocationOperation, IMethodSymbol invocationSymbol, @@ -93,11 +120,11 @@ private async Task CreateUpdatedInvocationExpression( CreateFromExceptionInvocationExpression(syntaxGenerator, invocationOperation); var returnsMethodName = - invocationSymbol.IsThrowsSyncForAnyArgsMethod() ? "ReturnsForAnyArgs" : "Returns"; + invocationSymbol.IsThrowsSyncForAnyArgsMethod() ? "Returns" : "ReturnsForAnyArgs"; if (invocationSymbol.MethodKind == MethodKind.Ordinary) { - return CreateUpdatedOrdinalInvocationExpression( + return CreateReturnOrdinalInvocationExpression( currentInvocationExpression, invocationOperation, syntaxGenerator, @@ -105,14 +132,14 @@ private async Task CreateUpdatedInvocationExpression( returnsMethodName); } - return CreateUpdatedExtensionInvocationExpression( + return CreateReturnExtensionInvocationExpression( currentInvocationExpression, syntaxGenerator, fromExceptionInvocationExpression, returnsMethodName); } - private static SyntaxNode CreateUpdatedOrdinalInvocationExpression( + private static SyntaxNode CreateReturnOrdinalInvocationExpression( TInvocationExpressionSyntax currentInvocationExpression, IInvocationOperation invocationOperation, SyntaxGenerator syntaxGenerator, @@ -126,7 +153,7 @@ private static SyntaxNode CreateUpdatedOrdinalInvocationExpression( fromExceptionInvocationExpression).WithTriviaFrom(currentInvocationExpression); } - private SyntaxNode CreateUpdatedExtensionInvocationExpression( + private SyntaxNode CreateReturnExtensionInvocationExpression( TInvocationExpressionSyntax currentInvocationExpression, SyntaxGenerator syntaxGenerator, SyntaxNode fromExceptionInvocationExpression, @@ -173,4 +200,26 @@ private static SyntaxNode GetExceptionCreationExpression( return invocationOperation.Arguments.OrderBy(arg => arg.Parameter.Ordinal) .First(arg => arg.Parameter.Ordinal > 0).Value.Syntax; } + + private static bool SupportsThrowsAsync(Compilation compilation) + { + var exceptionExtensionsTypeSymbol = compilation.GetTypeByMetadataName("NSubstitute.ExceptionExtensions.ExceptionExtensions"); + + return exceptionExtensionsTypeSymbol != null && + exceptionExtensionsTypeSymbol.GetMembers(MetadataNames.NSubstituteThrowsAsyncMethod).IsEmpty == false; + } + + private static string GetReplacementMethodName(IMethodSymbol methodSymbol, bool useModernSyntax) + { + if (useModernSyntax) + { + return methodSymbol.IsThrowsSyncForAnyArgsMethod() + ? MetadataNames.NSubstituteThrowsAsyncMethod + : MetadataNames.NSubstituteThrowsAsyncForAnyArgsMethod; + } + + return methodSymbol.IsThrowsSyncForAnyArgsMethod() + ? MetadataNames.NSubstituteReturnsMethod + : MetadataNames.NSubstituteReturnsForAnyArgsMethod; + } } \ No newline at end of file diff --git a/src/NSubstitute.Analyzers.Shared/Extensions/SubstituteSymbolExtensions.cs b/src/NSubstitute.Analyzers.Shared/Extensions/SubstituteSymbolExtensions.cs index b535a8cd..7bbfd1f5 100644 --- a/src/NSubstitute.Analyzers.Shared/Extensions/SubstituteSymbolExtensions.cs +++ b/src/NSubstitute.Analyzers.Shared/Extensions/SubstituteSymbolExtensions.cs @@ -51,7 +51,7 @@ public static bool IsThrowsSyncForAnyArgsMethod(this ISymbol symbol) { return IsMember( symbol, - MetadataNames.NSubstituteThrowsForAnyArgsMethod, + MetadataNames.NSubstituteThrowsMethod, MetadataNames.NSubstituteExceptionExtensionsFullTypeName); } diff --git a/src/NSubstitute.Analyzers.VisualBasic/CodeFixProviders/SyncOverAsyncThrowsCodeFixProvider.cs b/src/NSubstitute.Analyzers.VisualBasic/CodeFixProviders/SyncOverAsyncThrowsCodeFixProvider.cs index 8e50f23f..28323f7f 100644 --- a/src/NSubstitute.Analyzers.VisualBasic/CodeFixProviders/SyncOverAsyncThrowsCodeFixProvider.cs +++ b/src/NSubstitute.Analyzers.VisualBasic/CodeFixProviders/SyncOverAsyncThrowsCodeFixProvider.cs @@ -1,7 +1,9 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.VisualBasic; using Microsoft.CodeAnalysis.VisualBasic.Syntax; using NSubstitute.Analyzers.Shared.CodeFixProviders; +using static Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory; namespace NSubstitute.Analyzers.VisualBasic.CodeFixProviders; @@ -9,4 +11,14 @@ namespace NSubstitute.Analyzers.VisualBasic.CodeFixProviders; internal sealed class SyncOverAsyncThrowsCodeFixProvider : AbstractSyncOverAsyncThrowsCodeFixProvider { protected override SyntaxNode GetExpression(InvocationExpressionSyntax invocationExpressionSyntax) => ((MemberAccessExpressionSyntax)invocationExpressionSyntax.Expression).Expression; + + protected override SyntaxNode UpdateMemberExpression(InvocationExpressionSyntax invocationExpressionSyntax, SyntaxNode updatedNameSyntax) + { + var expressionSyntax = invocationExpressionSyntax.Expression; + return invocationExpressionSyntax.WithExpression(MemberAccessExpression( + expressionSyntax.Kind(), + ((MemberAccessExpressionSyntax)expressionSyntax).Expression, + Token(SyntaxKind.DotToken), + (SimpleNameSyntax)updatedNameSyntax)); + } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixActionsTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixActionsTests.cs index 6b6601db..0add03bd 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixActionsTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixActionsTests.cs @@ -1,8 +1,10 @@ +using System.Linq; 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.Tests.Shared; using NSubstitute.Analyzers.Tests.Shared.CodeFixProviders; using Xunit; @@ -40,7 +42,38 @@ public void Test() }} }} }}"; - await VerifyCodeActions(source, expectedCodeActionTitle); + await VerifyCodeActions(source, NSubstituteVersion.NSubstitute4_2_2, expectedCodeActionTitle); + } + + [Theory] + [InlineData("Throws", "Replace with ThrowsAsync")] + [InlineData("ThrowsForAnyArgs", "Replace with ThrowsAsyncForAnyArgs")] + public async Task CreatesCodeAction_ForModernSyntax(string method, string expectedCodeActionTitle) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute.Bar().{method}(new Exception()); + substitute.Bar().{method}(callInfo => new Exception()); + substitute.Bar().{method}(createException: callInfo => new Exception()); + }} + }} +}}"; + await VerifyCodeActions(source, Enumerable.Repeat(expectedCodeActionTitle, 3).ToArray()); } [Theory] @@ -70,6 +103,6 @@ public void Test() }} }} }}"; - await VerifyCodeActions(source); + await VerifyCodeActions(source, NSubstituteVersion.NSubstitute4_2_2); } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixVerifier.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixVerifier.cs index 9027c553..c742c694 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixVerifier.cs @@ -20,6 +20,15 @@ public static IEnumerable ThrowsTestCases } } + public static IEnumerable ThrowsAsyncTestCases + { + get + { + yield return new object[] { "Throws", "ThrowsAsync" }; + yield return new object[] { "ThrowsForAnyArgs", "ThrowsAsyncForAnyArgs" }; + } + } + protected override CodeFixProvider CodeFixProvider { get; } = new SyncOverAsyncThrowsCodeFixProvider(); protected override DiagnosticAnalyzer DiagnosticAnalyzer { get; } = new SyncOverAsyncThrowsAnalyzer(); @@ -35,4 +44,16 @@ public static IEnumerable ThrowsTestCases [Theory] [MemberData(nameof(ThrowsTestCases))] public abstract Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod); + + [Theory] + [MemberData(nameof(ThrowsAsyncTestCases))] + public abstract Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod); + + [Theory] + [MemberData(nameof(ThrowsAsyncTestCases))] + public abstract Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod); + + [Theory] + [MemberData(nameof(ThrowsAsyncTestCases))] + public abstract Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod); } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs index 0d06b40c..7b8e27da 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using NSubstitute.Analyzers.Tests.Shared; namespace NSubstitute.Analyzers.Tests.CSharp.CodeFixProviderTests.SyncOverAsyncThrowsCodeFixProviderTests; @@ -52,7 +53,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -103,7 +104,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -154,6 +155,183 @@ public void Test() }} }}"; + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute.Bar().{method}(new Exception()); + substitute.Bar().{method}(ex: new Exception()); + substitute.Bar().{method}(callInfo => new Exception()); + substitute.Bar().{method}(createException: callInfo => new Exception()); + substitute.Bar().{method}(callInfo => {{ return new Exception(); }}); + substitute.Bar().{method}(createException: callInfo => {{ return new Exception(); }}); + }} + }} +}}"; + + var newSource = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute.Bar().{updatedMethod}(new Exception()); + substitute.Bar().{updatedMethod}(ex: new Exception()); + substitute.Bar().{updatedMethod}(callInfo => new Exception()); + substitute.Bar().{updatedMethod}(createException: callInfo => new Exception()); + substitute.Bar().{updatedMethod}(callInfo => {{ return new Exception(); }}); + substitute.Bar().{updatedMethod}(createException: callInfo => {{ return new Exception(); }}); + }} + }} +}}"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute.Bar.{method}(new Exception()); + substitute.Bar.{method}(ex: new Exception()); + substitute.Bar.{method}(callInfo => new Exception()); + substitute.Bar.{method}(createException: callInfo => new Exception()); + substitute.Bar.{method}(callInfo => {{ return new Exception(); }}); + substitute.Bar.{method}(createException: callInfo => {{ return new Exception(); }}); + }} + }} +}}"; + + var newSource = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute.Bar.{updatedMethod}(new Exception()); + substitute.Bar.{updatedMethod}(ex: new Exception()); + substitute.Bar.{updatedMethod}(callInfo => new Exception()); + substitute.Bar.{updatedMethod}(createException: callInfo => new Exception()); + substitute.Bar.{updatedMethod}(callInfo => {{ return new Exception(); }}); + substitute.Bar.{updatedMethod}(createException: callInfo => {{ return new Exception(); }}); + }} + }} +}}"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task this[int x] {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute[0].{method}(new Exception()); + substitute[0].{method}(ex: new Exception()); + substitute[0].{method}(callInfo => new Exception()); + substitute[0].{method}(createException: callInfo => new Exception()); + substitute[0].{method}(callInfo => {{ return new Exception(); }}); + substitute[0].{method}(createException: callInfo => {{ return new Exception(); }}); + }} + }} +}}"; + + var newSource = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task this[int x] {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute[0].{updatedMethod}(new Exception()); + substitute[0].{updatedMethod}(ex: new Exception()); + substitute[0].{updatedMethod}(callInfo => new Exception()); + substitute[0].{updatedMethod}(createException: callInfo => new Exception()); + substitute[0].{updatedMethod}(callInfo => {{ return new Exception(); }}); + substitute[0].{updatedMethod}(createException: callInfo => {{ return new Exception(); }}); + }} + }} +}}"; + await VerifyFix(source, newSource); } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs index 26a55428..62e96d9f 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using NSubstitute.Analyzers.Tests.Shared; namespace NSubstitute.Analyzers.Tests.CSharp.CodeFixProviderTests.SyncOverAsyncThrowsCodeFixProviderTests; @@ -50,7 +51,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -99,7 +100,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -148,6 +149,153 @@ public void Test() }} }}"; + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute.Bar().{method}(); + }} + }} +}}"; + + var newSource = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute.Bar().{updatedMethod}(); + }} + }} +}}"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute.Bar.{method}(); + }} + }} +}}"; + + var newSource = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute.Bar.{updatedMethod}(); + }} + }} +}}"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task this[int x] {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute[0].{method}(); + }} + }} +}}"; + + var newSource = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task this[int x] {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + substitute[0].{updatedMethod}(); + }} + }} +}}"; + await VerifyFix(source, newSource); } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs index 1e3039e3..43733a51 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using NSubstitute.Analyzers.Tests.Shared; namespace NSubstitute.Analyzers.Tests.CSharp.CodeFixProviderTests.SyncOverAsyncThrowsCodeFixProviderTests; @@ -54,7 +55,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -107,7 +108,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -160,6 +161,201 @@ public void Test() }} }}"; + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{method}(substitute.Bar(), new Exception()); + ExceptionExtensions.{method}(value: substitute.Bar(), ex: new Exception()); + ExceptionExtensions.{method}(ex: new Exception(), value: substitute.Bar()); + ExceptionExtensions.{method}(substitute.Bar(), callInfo => new Exception()); + ExceptionExtensions.{method}(value: substitute.Bar(), createException: callInfo => new Exception()); + ExceptionExtensions.{method}(createException: callInfo => new Exception(), value: substitute.Bar()); + ExceptionExtensions.{method}(substitute.Bar(), callInfo => {{ return new Exception(); }}); + ExceptionExtensions.{method}(value: substitute.Bar(), createException: callInfo => {{ return new Exception(); }}); + ExceptionExtensions.{method}(createException: callInfo => {{ return new Exception(); }}, value: substitute.Bar()); + }} + }} +}}"; + + var newSource = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{updatedMethod}(substitute.Bar(), new Exception()); + ExceptionExtensions.{updatedMethod}(value: substitute.Bar(), ex: new Exception()); + ExceptionExtensions.{updatedMethod}(ex: new Exception(), value: substitute.Bar()); + ExceptionExtensions.{updatedMethod}(substitute.Bar(), callInfo => new Exception()); + ExceptionExtensions.{updatedMethod}(value: substitute.Bar(), createException: callInfo => new Exception()); + ExceptionExtensions.{updatedMethod}(createException: callInfo => new Exception(), value: substitute.Bar()); + ExceptionExtensions.{updatedMethod}(substitute.Bar(), callInfo => {{ return new Exception(); }}); + ExceptionExtensions.{updatedMethod}(value: substitute.Bar(), createException: callInfo => {{ return new Exception(); }}); + ExceptionExtensions.{updatedMethod}(createException: callInfo => {{ return new Exception(); }}, value: substitute.Bar()); + }} + }} +}}"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{method}(substitute.Bar, new Exception()); + ExceptionExtensions.{method}(value: substitute.Bar, ex: new Exception()); + ExceptionExtensions.{method}(ex: new Exception(), value: substitute.Bar); + ExceptionExtensions.{method}(substitute.Bar, callInfo => new Exception()); + ExceptionExtensions.{method}(value: substitute.Bar, createException: callInfo => new Exception()); + ExceptionExtensions.{method}(createException: callInfo => new Exception(), value: substitute.Bar); + ExceptionExtensions.{method}(substitute.Bar, callInfo => {{ return new Exception(); }}); + ExceptionExtensions.{method}(value: substitute.Bar, createException: callInfo => {{ return new Exception(); }}); + ExceptionExtensions.{method}(createException: callInfo => {{ return new Exception(); }}, value: substitute.Bar); + }} + }} +}}"; + + var newSource = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{updatedMethod}(substitute.Bar, new Exception()); + ExceptionExtensions.{updatedMethod}(value: substitute.Bar, ex: new Exception()); + ExceptionExtensions.{updatedMethod}(ex: new Exception(), value: substitute.Bar); + ExceptionExtensions.{updatedMethod}(substitute.Bar, callInfo => new Exception()); + ExceptionExtensions.{updatedMethod}(value: substitute.Bar, createException: callInfo => new Exception()); + ExceptionExtensions.{updatedMethod}(createException: callInfo => new Exception(), value: substitute.Bar); + ExceptionExtensions.{updatedMethod}(substitute.Bar, callInfo => {{ return new Exception(); }}); + ExceptionExtensions.{updatedMethod}(value: substitute.Bar, createException: callInfo => {{ return new Exception(); }}); + ExceptionExtensions.{updatedMethod}(createException: callInfo => {{ return new Exception(); }}, value: substitute.Bar); + }} + }} +}}"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task this[int x] {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{method}(substitute[0], new Exception()); + ExceptionExtensions.{method}(value: substitute[0], ex: new Exception()); + ExceptionExtensions.{method}(ex: new Exception(), value: substitute[0]); + ExceptionExtensions.{method}(substitute[0], callInfo => new Exception()); + ExceptionExtensions.{method}(value: substitute[0], createException: callInfo => new Exception()); + ExceptionExtensions.{method}(createException: callInfo => new Exception(), value: substitute[0]); + ExceptionExtensions.{method}(substitute[0], callInfo => {{ return new Exception(); }}); + ExceptionExtensions.{method}(value: substitute[0], createException: callInfo => {{ return new Exception(); }}); + ExceptionExtensions.{method}(createException: callInfo => {{ return new Exception(); }}, value: substitute[0]); + }} + }} +}}"; + + var newSource = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task this[int x] {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{updatedMethod}(substitute[0], new Exception()); + ExceptionExtensions.{updatedMethod}(value: substitute[0], ex: new Exception()); + ExceptionExtensions.{updatedMethod}(ex: new Exception(), value: substitute[0]); + ExceptionExtensions.{updatedMethod}(substitute[0], callInfo => new Exception()); + ExceptionExtensions.{updatedMethod}(value: substitute[0], createException: callInfo => new Exception()); + ExceptionExtensions.{updatedMethod}(createException: callInfo => new Exception(), value: substitute[0]); + ExceptionExtensions.{updatedMethod}(substitute[0], callInfo => {{ return new Exception(); }}); + ExceptionExtensions.{updatedMethod}(value: substitute[0], createException: callInfo => {{ return new Exception(); }}); + ExceptionExtensions.{updatedMethod}(createException: callInfo => {{ return new Exception(); }}, value: substitute[0]); + }} + }} +}}"; + await VerifyFix(source, newSource); } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index 1f82bed5..17a7d2d3 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using NSubstitute.Analyzers.Tests.Shared; namespace NSubstitute.Analyzers.Tests.CSharp.CodeFixProviderTests.SyncOverAsyncThrowsCodeFixProviderTests; @@ -52,7 +53,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -103,7 +104,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -154,6 +155,159 @@ public void Test() }} }}"; + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{method}(substitute.Bar()); + ExceptionExtensions.{method}(value: substitute.Bar()); + }} + }} +}}"; + + var newSource = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar(); + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{updatedMethod}(substitute.Bar()); + ExceptionExtensions.{updatedMethod}(value: substitute.Bar()); + }} + }} +}}"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{method}(substitute.Bar); + ExceptionExtensions.{method}(value: substitute.Bar); + }} + }} +}}"; + + var newSource = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task Bar {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{updatedMethod}(substitute.Bar); + ExceptionExtensions.{updatedMethod}(value: substitute.Bar); + }} + }} +}}"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod) + { + var source = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task this[int x] {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{method}(substitute[0]); + ExceptionExtensions.{method}(value: substitute[0]); + }} + }} +}}"; + + var newSource = $@"using System; +using System.Threading.Tasks; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface IFoo + {{ + Task this[int x] {{ get; set; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.{updatedMethod}(substitute[0]); + ExceptionExtensions.{updatedMethod}(value: substitute[0]); + }} + }} +}}"; + await VerifyFix(source, newSource); } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixCodeActionsVerifier.cs b/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixCodeActionsVerifier.cs index 141c2cf1..2cda1ede 100644 --- a/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixCodeActionsVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixCodeActionsVerifier.cs @@ -26,42 +26,46 @@ protected CodeFixCodeActionsVerifier(WorkspaceFactory workspaceFactory) protected override string AnalyzerSettings { get; } = Json.Encode(new object()); - protected async Task VerifyCodeActions(string source, params string[] expectedCodeActionTitles) + protected async Task VerifyCodeActions(string source, NSubstituteVersion version, params string[] expectedCodeActionTitles) { - var codeActions = await RegisterCodeFixes(source); + var codeActions = await RegisterCodeFixes(source, version); codeActions.Should().NotBeNull(); codeActions.Select(action => action.Title).Should().BeEquivalentTo(expectedCodeActionTitles ?? Array.Empty()); } - private async Task> RegisterCodeFixes(string source) + protected Task VerifyCodeActions(string source, params string[] expectedCodeActionTitles) { - using (var workspace = new AdhocWorkspace()) - { - var actions = new List(); - var project = AddProject(workspace.CurrentSolution, source); + return VerifyCodeActions(source, NSubstituteVersion.Latest, expectedCodeActionTitles); + } - var document = project.Documents.Single(); + private async Task> RegisterCodeFixes(string source, NSubstituteVersion version) + { + using var workspace = new AdhocWorkspace(); + var actions = new List(); + var project = AddProject(workspace.CurrentSolution, source); + project = UpdateNSubstituteMetadataReference(project, version); - var compilation = await document.Project.GetCompilationAsync(); - var compilationDiagnostics = compilation.GetDiagnostics(); + var document = project.Documents.Single(); - VerifyNoCompilerDiagnosticErrors(compilationDiagnostics); + var compilation = await document.Project.GetCompilationAsync(); + var compilationDiagnostics = compilation.GetDiagnostics(); - var analyzerDiagnostics = await compilation.GetSortedAnalyzerDiagnostics( - DiagnosticAnalyzer, - project.AnalyzerOptions); + VerifyNoCompilerDiagnosticErrors(compilationDiagnostics); - foreach (var context in analyzerDiagnostics.Select(diagnostic => new CodeFixContext( - document, - analyzerDiagnostics[0], - (action, array) => actions.Add(action), - CancellationToken.None))) - { - await CodeFixProvider.RegisterCodeFixesAsync(context); - } + var analyzerDiagnostics = await compilation.GetSortedAnalyzerDiagnostics( + DiagnosticAnalyzer, + project.AnalyzerOptions); - return actions; + foreach (var context in analyzerDiagnostics.Select(diagnostic => new CodeFixContext( + document, + analyzerDiagnostics[0], + (action, array) => actions.Add(action), + CancellationToken.None))) + { + await CodeFixProvider.RegisterCodeFixesAsync(context); } + + return actions; } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixVerifier.cs b/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixVerifier.cs index bcc7ddbe..4f24adf0 100644 --- a/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixVerifier.cs @@ -24,86 +24,71 @@ protected CodeFixVerifier(WorkspaceFactory workspaceFactory) protected abstract DiagnosticAnalyzer DiagnosticAnalyzer { get; } + protected Task VerifyFix( + string oldSource, + string newSource, + NSubstituteVersion version) => VerifyFix(oldSource, newSource, null, version); + protected async Task VerifyFix( string oldSource, string newSource, int? codeFixIndex = null, NSubstituteVersion version = NSubstituteVersion.Latest) { - using (var workspace = new AdhocWorkspace()) - { - var project = AddProject(workspace.CurrentSolution, oldSource); - - project = UpdateNSubstituteMetadataReference(project, version); + using var workspace = new AdhocWorkspace(); + var project = AddProject(workspace.CurrentSolution, oldSource); - var document = project.Documents.Single(); - var compilation = await project.GetCompilationAsync(); + project = UpdateNSubstituteMetadataReference(project, version); - var compilerDiagnostics = compilation.GetDiagnostics(); + var document = project.Documents.Single(); + var compilation = await project.GetCompilationAsync(); - VerifyNoCompilerDiagnosticErrors(compilerDiagnostics); + var compilerDiagnostics = compilation.GetDiagnostics(); - var analyzerDiagnostics = await compilation.GetSortedAnalyzerDiagnostics( - DiagnosticAnalyzer, - project.AnalyzerOptions); + VerifyNoCompilerDiagnosticErrors(compilerDiagnostics); - var previousAnalyzerDiagnostics = analyzerDiagnostics; - var attempts = analyzerDiagnostics.Length; + var analyzerDiagnostics = await compilation.GetSortedAnalyzerDiagnostics( + DiagnosticAnalyzer, + project.AnalyzerOptions); - for (var i = 0; i < attempts; ++i) - { - var actions = new List(); - var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None); - await CodeFixProvider.RegisterCodeFixesAsync(context); + var previousAnalyzerDiagnostics = analyzerDiagnostics; + var attempts = analyzerDiagnostics.Length; - if (!actions.Any()) - { - break; - } + for (var i = 0; i < attempts; ++i) + { + var actions = new List(); + var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None); + await CodeFixProvider.RegisterCodeFixesAsync(context); - document = await document.ApplyCodeAction(actions[codeFixIndex ?? 0]); - compilation = await document.Project.GetCompilationAsync(); + if (!actions.Any()) + { + break; + } - compilerDiagnostics = compilation.GetDiagnostics(); + document = await document.ApplyCodeAction(actions[codeFixIndex ?? 0]); + compilation = await document.Project.GetCompilationAsync(); - VerifyNoCompilerDiagnosticErrors(compilerDiagnostics); + compilerDiagnostics = compilation.GetDiagnostics(); - analyzerDiagnostics = await compilation.GetSortedAnalyzerDiagnostics( - DiagnosticAnalyzer, - project.AnalyzerOptions); + VerifyNoCompilerDiagnosticErrors(compilerDiagnostics); - // check if there are analyzer diagnostics left after the code fix - var newAnalyzerDiagnostics = analyzerDiagnostics.Except(previousAnalyzerDiagnostics).ToList(); - if (analyzerDiagnostics.Length == previousAnalyzerDiagnostics.Length && newAnalyzerDiagnostics.Any()) - { - Execute.Assertion.Fail( - $"Fix didn't fix analyzer diagnostics: {newAnalyzerDiagnostics.ToDebugString()} New document:{Environment.NewLine}{await document.ToFullString()}"); - } + analyzerDiagnostics = await compilation.GetSortedAnalyzerDiagnostics( + DiagnosticAnalyzer, + project.AnalyzerOptions); - previousAnalyzerDiagnostics = analyzerDiagnostics; + // check if there are analyzer diagnostics left after the code fix + var newAnalyzerDiagnostics = analyzerDiagnostics.Except(previousAnalyzerDiagnostics).ToList(); + if (analyzerDiagnostics.Length == previousAnalyzerDiagnostics.Length && newAnalyzerDiagnostics.Any()) + { + Execute.Assertion.Fail( + $"Fix didn't fix analyzer diagnostics: {newAnalyzerDiagnostics.ToDebugString()} New document:{Environment.NewLine}{await document.ToFullString()}"); } - var actual = await document.ToFullString(); - - actual.Should().Be(newSource); - } - } - - private static Project UpdateNSubstituteMetadataReference(Project project, NSubstituteVersion version) - { - if (version == NSubstituteVersion.Latest) - { - return project; + previousAnalyzerDiagnostics = analyzerDiagnostics; } - project = project.RemoveMetadataReference(RuntimeMetadataReference.NSubstituteLatestReference); - - project = version switch - { - NSubstituteVersion.NSubstitute4_2_2 => project.AddMetadataReference(RuntimeMetadataReference.NSubstitute422Reference), - _ => throw new ArgumentException($"NSubstitute {version} is not supported", nameof(version)) - }; + var actual = await document.ToFullString(); - return project; + actual.Should().Be(newSource); } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/ISyncOverAsyncThrowsCodeFixActionsVerifier.cs b/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/ISyncOverAsyncThrowsCodeFixActionsVerifier.cs index bb00f09f..a9654bb4 100644 --- a/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/ISyncOverAsyncThrowsCodeFixActionsVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/ISyncOverAsyncThrowsCodeFixActionsVerifier.cs @@ -6,5 +6,7 @@ public interface ISyncOverAsyncThrowsCodeFixActionsVerifier { Task CreatesCodeAction_WhenOverloadSupported(string method, string expectedCodeActionTitle); + Task CreatesCodeAction_ForModernSyntax(string method, string expectedCodeActionTitle); + Task DoesNotCreateCodeAction_WhenOverloadNotSupported(string method); } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/ISyncOverAsyncThrowsCodeFixVerifier.cs b/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/ISyncOverAsyncThrowsCodeFixVerifier.cs index e0201067..9290be9e 100644 --- a/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/ISyncOverAsyncThrowsCodeFixVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/ISyncOverAsyncThrowsCodeFixVerifier.cs @@ -9,4 +9,10 @@ public interface ISyncOverAsyncThrowsCodeFixVerifier Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod); Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod); + + Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod); + + Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod); + + Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod); } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.Shared/CodeVerifier.cs b/tests/NSubstitute.Analyzers.Tests.Shared/CodeVerifier.cs index 0d598be0..de485b4f 100644 --- a/tests/NSubstitute.Analyzers.Tests.Shared/CodeVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.Shared/CodeVerifier.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Immutable; using System.Globalization; using System.Linq; @@ -45,4 +46,22 @@ protected static void VerifyNoCompilerDiagnosticErrors(ImmutableArray project.AddMetadataReference(RuntimeMetadataReference.NSubstitute422Reference), + _ => throw new ArgumentException($"NSubstitute {version} is not supported", nameof(version)) + }; + + return project; + } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixActionsTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixActionsTests.cs index 2b77e72e..37082437 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixActionsTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixActionsTests.cs @@ -1,6 +1,8 @@ +using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; +using NSubstitute.Analyzers.Tests.Shared; using NSubstitute.Analyzers.Tests.Shared.CodeFixProviders; using NSubstitute.Analyzers.VisualBasic.CodeFixProviders; using NSubstitute.Analyzers.VisualBasic.DiagnosticAnalyzers; @@ -40,6 +42,34 @@ End Class await VerifyCodeActions(source, expectedCodeActionTitle); } + [Theory] + [InlineData("Throws", "Replace with ThrowsAsync")] + [InlineData("ThrowsForAnyArgs", "Replace with ThrowsAsyncForAnyArgs")] + public async Task CreatesCodeAction_ForModernSyntax(string method, string expectedCodeActionTitle) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute.Bar().{method}(New Exception()) + substitute.Bar().{method}(Function(callInfo) New Exception()) + substitute.Bar().{method}(createException:= Function(callInfo) New Exception()) + End Sub + End Class +End Namespace"; + + await VerifyCodeActions(source, Enumerable.Repeat(expectedCodeActionTitle, 3).ToArray()); + } + [Theory] [InlineData("Throws")] [InlineData("ThrowsForAnyArgs")] @@ -64,6 +94,6 @@ End Sub End Class End Namespace"; - await VerifyCodeActions(source); + await VerifyCodeActions(source, NSubstituteVersion.NSubstitute4_2_2); } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixVerifier.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixVerifier.cs index 35a0fcec..bbc1559e 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixVerifier.cs @@ -20,6 +20,15 @@ public static IEnumerable ThrowsTestCases } } + public static IEnumerable ThrowsAsyncTestCases + { + get + { + yield return new object[] { "Throws", "ThrowsAsync" }; + yield return new object[] { "ThrowsForAnyArgs", "ThrowsAsyncForAnyArgs" }; + } + } + protected override CodeFixProvider CodeFixProvider { get; } = new SyncOverAsyncThrowsCodeFixProvider(); protected override DiagnosticAnalyzer DiagnosticAnalyzer { get; } = new SyncOverAsyncThrowsAnalyzer(); @@ -35,4 +44,16 @@ public static IEnumerable ThrowsTestCases [Theory] [MemberData(nameof(ThrowsTestCases))] public abstract Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod); + + [Theory] + [MemberData(nameof(ThrowsAsyncTestCases))] + public abstract Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod); + + [Theory] + [MemberData(nameof(ThrowsAsyncTestCases))] + public abstract Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod); + + [Theory] + [MemberData(nameof(ThrowsAsyncTestCases))] + public abstract Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod); } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs index 536ffa4a..1c0f30b4 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using NSubstitute.Analyzers.Tests.Shared; namespace NSubstitute.Analyzers.Tests.VisualBasic.CodeFixProvidersTests.SyncOverAsyncThrowsCodeFixProviderTests; @@ -44,7 +45,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -87,7 +88,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -130,6 +131,201 @@ End Sub End Class End Namespace"; + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute.Bar().{method}(New Exception()) + substitute.Bar().{method}(ex := New Exception()) + substitute.Bar().{method}(Function(callInfo) New Exception()) + substitute.Bar().{method}(createException:= Function(callInfo) New Exception()) + substitute.Bar().{method}( + Function(callInfo) + Return New Exception() + End Function) + substitute.Bar().{method}( + createException := + Function(callInfo) + Return New Exception() + End Function) + End Sub + End Class +End Namespace"; + + var newSource = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute.Bar().{updatedMethod}(New Exception()) + substitute.Bar().{updatedMethod}(ex := New Exception()) + substitute.Bar().{updatedMethod}(Function(callInfo) New Exception()) + substitute.Bar().{updatedMethod}(createException:= Function(callInfo) New Exception()) + substitute.Bar().{updatedMethod}( + Function(callInfo) + Return New Exception() + End Function) + substitute.Bar().{updatedMethod}( + createException := + Function(callInfo) + Return New Exception() + End Function) + End Sub + End Class +End Namespace"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Property Bar As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute.Bar.{method}(New Exception()) + substitute.Bar.{method}(ex := New Exception()) + substitute.Bar.{method}(Function(callInfo) New Exception()) + substitute.Bar.{method}(createException:= Function(callInfo) New Exception()) + substitute.Bar.{method}( + Function(callInfo) + Return New Exception() + End Function) + substitute.Bar.{method}( + createException := + Function(callInfo) + Return New Exception() + End Function) + End Sub + End Class +End Namespace"; + + var newSource = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Property Bar As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute.Bar.{updatedMethod}(New Exception()) + substitute.Bar.{updatedMethod}(ex := New Exception()) + substitute.Bar.{updatedMethod}(Function(callInfo) New Exception()) + substitute.Bar.{updatedMethod}(createException:= Function(callInfo) New Exception()) + substitute.Bar.{updatedMethod}( + Function(callInfo) + Return New Exception() + End Function) + substitute.Bar.{updatedMethod}( + createException := + Function(callInfo) + Return New Exception() + End Function) + End Sub + End Class +End Namespace"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Default Property Item(ByVal x As Integer) As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute(0).{method}(New Exception()) + substitute(0).{method}(ex := New Exception()) + substitute(0).{method}(Function(callInfo) New Exception()) + substitute(0).{method}(createException:= Function(callInfo) New Exception()) + substitute(0).{method}( + Function(callInfo) + Return New Exception() + End Function) + substitute(0).{method}( + createException := + Function(callInfo) + Return New Exception() + End Function) + End Sub + End Class +End Namespace"; + + var newSource = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Default Property Item(ByVal x As Integer) As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute(0).{updatedMethod}(New Exception()) + substitute(0).{updatedMethod}(ex := New Exception()) + substitute(0).{updatedMethod}(Function(callInfo) New Exception()) + substitute(0).{updatedMethod}(createException:= Function(callInfo) New Exception()) + substitute(0).{updatedMethod}( + Function(callInfo) + Return New Exception() + End Function) + substitute(0).{updatedMethod}( + createException := + Function(callInfo) + Return New Exception() + End Function) + End Sub + End Class +End Namespace"; + await VerifyFix(source, newSource); } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs index 46a98913..67c4c597 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using NSubstitute.Analyzers.Tests.Shared; namespace NSubstitute.Analyzers.Tests.VisualBasic.CodeFixProvidersTests.SyncOverAsyncThrowsCodeFixProviderTests; @@ -42,7 +43,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -83,7 +84,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -124,6 +125,129 @@ End Sub End Class End Namespace"; + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute.Bar().{method}(Of Exception)() + End Sub + End Class +End Namespace"; + + var newSource = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute.Bar().{updatedMethod}(Of Exception)() + End Sub + End Class +End Namespace"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Property Bar As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute.Bar.{method}(Of Exception)() + End Sub + End Class +End Namespace"; + + var newSource = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Property Bar As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute.Bar.{updatedMethod}(Of Exception)() + End Sub + End Class +End Namespace"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Default Property Item(ByVal x As Integer) As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute(0).{method}(Of Exception)() + End Sub + End Class +End Namespace"; + + var newSource = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Default Property Item(ByVal x As Integer) As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + substitute(0).{updatedMethod}(Of Exception)() + End Sub + End Class +End Namespace"; + await VerifyFix(source, newSource); } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs index c7e262cc..9c2897fd 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using NSubstitute.Analyzers.Tests.Shared; namespace NSubstitute.Analyzers.Tests.VisualBasic.CodeFixProvidersTests.SyncOverAsyncThrowsCodeFixProviderTests; @@ -46,7 +47,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -91,7 +92,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -136,6 +137,231 @@ End Sub End Class End Namespace"; + await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{method}(substitute.Bar(), New Exception()) + ExceptionExtensions.{method}(value := substitute.Bar(), ex := New Exception()) + ExceptionExtensions.{method}(ex := New Exception(), value := substitute.Bar()) + ExceptionExtensions.{method}(substitute.Bar(), Function(callInfo) New Exception()) + ExceptionExtensions.{method}(value:= substitute.Bar(), createException:= Function(callInfo) New Exception()) + ExceptionExtensions.{method}(createException:= Function(callInfo) New Exception(), value:= substitute.Bar()) + ExceptionExtensions.{method}(substitute.Bar(), + Function(callInfo) + Return New Exception() + End Function) + ExceptionExtensions.{method}(value:= substitute.Bar(), + createException:= Function(callInfo) + Return New Exception() + End Function) + ExceptionExtensions.{method}( + createException:= Function(callInfo) + Return New Exception() + End Function, value:= substitute.Bar()) + End Sub + End Class +End Namespace"; + + var newSource = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{updatedMethod}(substitute.Bar(), New Exception()) + ExceptionExtensions.{updatedMethod}(value := substitute.Bar(), ex := New Exception()) + ExceptionExtensions.{updatedMethod}(ex := New Exception(), value := substitute.Bar()) + ExceptionExtensions.{updatedMethod}(substitute.Bar(), Function(callInfo) New Exception()) + ExceptionExtensions.{updatedMethod}(value:= substitute.Bar(), createException:= Function(callInfo) New Exception()) + ExceptionExtensions.{updatedMethod}(createException:= Function(callInfo) New Exception(), value:= substitute.Bar()) + ExceptionExtensions.{updatedMethod}(substitute.Bar(), + Function(callInfo) + Return New Exception() + End Function) + ExceptionExtensions.{updatedMethod}(value:= substitute.Bar(), + createException:= Function(callInfo) + Return New Exception() + End Function) + ExceptionExtensions.{updatedMethod}( + createException:= Function(callInfo) + Return New Exception() + End Function, value:= substitute.Bar()) + End Sub + End Class +End Namespace"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Property Bar As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{method}(substitute.Bar, New Exception()) + ExceptionExtensions.{method}(value := substitute.Bar, ex := New Exception()) + ExceptionExtensions.{method}(ex := New Exception(), value := substitute.Bar) + ExceptionExtensions.{method}(substitute.Bar, Function(callInfo) New Exception()) + ExceptionExtensions.{method}(value:= substitute.Bar, createException:= Function(callInfo) New Exception()) + ExceptionExtensions.{method}(createException:= Function(callInfo) New Exception(), value:= substitute.Bar) + ExceptionExtensions.{method}(substitute.Bar, + Function(callInfo) + Return New Exception() + End Function) + ExceptionExtensions.{method}(value:= substitute.Bar, + createException:= Function(callInfo) + Return New Exception() + End Function) + ExceptionExtensions.{method}( + createException:= Function(callInfo) + Return New Exception() + End Function, value:= substitute.Bar) + End Sub + End Class +End Namespace"; + + var newSource = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Property Bar As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{updatedMethod}(substitute.Bar, New Exception()) + ExceptionExtensions.{updatedMethod}(value := substitute.Bar, ex := New Exception()) + ExceptionExtensions.{updatedMethod}(ex := New Exception(), value := substitute.Bar) + ExceptionExtensions.{updatedMethod}(substitute.Bar, Function(callInfo) New Exception()) + ExceptionExtensions.{updatedMethod}(value:= substitute.Bar, createException:= Function(callInfo) New Exception()) + ExceptionExtensions.{updatedMethod}(createException:= Function(callInfo) New Exception(), value:= substitute.Bar) + ExceptionExtensions.{updatedMethod}(substitute.Bar, + Function(callInfo) + Return New Exception() + End Function) + ExceptionExtensions.{updatedMethod}(value:= substitute.Bar, + createException:= Function(callInfo) + Return New Exception() + End Function) + ExceptionExtensions.{updatedMethod}( + createException:= Function(callInfo) + Return New Exception() + End Function, value:= substitute.Bar) + End Sub + End Class +End Namespace"; + + await VerifyFix(source, newSource); + } + + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod) + { + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Default Property Item(ByVal x As Integer) As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{method}(substitute(0), New Exception()) + ExceptionExtensions.{method}(value := substitute(0), ex := New Exception()) + ExceptionExtensions.{method}(ex := New Exception(), value := substitute(0)) + ExceptionExtensions.{method}(substitute(0), Function(callInfo) New Exception()) + ExceptionExtensions.{method}(value:= substitute(0), createException:= Function(callInfo) New Exception()) + ExceptionExtensions.{method}(createException:= Function(callInfo) New Exception(), value:= substitute(0)) + ExceptionExtensions.{method}(substitute(0), + Function(callInfo) + Return New Exception() + End Function) + ExceptionExtensions.{method}(value:= substitute(0), + createException:= Function(callInfo) + Return New Exception() + End Function) + ExceptionExtensions.{method}( + createException:= Function(callInfo) + Return New Exception() + End Function, value:= substitute(0)) + End Sub + End Class +End Namespace"; + + var newSource = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Default Property Item(ByVal x As Integer) As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{updatedMethod}(substitute(0), New Exception()) + ExceptionExtensions.{updatedMethod}(value := substitute(0), ex := New Exception()) + ExceptionExtensions.{updatedMethod}(ex := New Exception(), value := substitute(0)) + ExceptionExtensions.{updatedMethod}(substitute(0), Function(callInfo) New Exception()) + ExceptionExtensions.{updatedMethod}(value:= substitute(0), createException:= Function(callInfo) New Exception()) + ExceptionExtensions.{updatedMethod}(createException:= Function(callInfo) New Exception(), value:= substitute(0)) + ExceptionExtensions.{updatedMethod}(substitute(0), + Function(callInfo) + Return New Exception() + End Function) + ExceptionExtensions.{updatedMethod}(value:= substitute(0), + createException:= Function(callInfo) + Return New Exception() + End Function) + ExceptionExtensions.{updatedMethod}( + createException:= Function(callInfo) + Return New Exception() + End Function, value:= substitute(0)) + End Sub + End Class +End Namespace"; + await VerifyFix(source, newSource); } } \ No newline at end of file diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index ce21b2e3..d1c75fae 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -132,4 +132,19 @@ End Class await VerifyFix(source, newSource); } + + public override Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) + { + throw new System.NotImplementedException(); + } + + public override Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod) + { + throw new System.NotImplementedException(); + } + + public override Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod) + { + throw new System.NotImplementedException(); + } } \ No newline at end of file From ad977614ce8229c3dbc517303bb82614fe902826 Mon Sep 17 00:00:00 2001 From: tpodolak Date: Fri, 22 Jul 2022 16:52:10 +0200 Subject: [PATCH 07/10] GH-186 - fixing build --- appveyor.yml | 2 +- global.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 8e853818..bddd8f66 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,7 +22,7 @@ for: test: off build_script: - move global.json _global.json #workaround for missing AppVeyor images - - dotnet new globaljson --sdk-version 6.0.201 + - dotnet new globaljson --sdk-version 6.0.300 --roll-forward patch - cd Build - set IGNORE_NORMALISATION_GIT_HEAD_MOVE=1 - ps: >- diff --git a/global.json b/global.json index 572a2a6f..6375b8c5 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,6 @@ { "sdk": { - "version": "6.0.200" + "version": "6.0.300", + "rollForward": "patch" } } From a1c04c6dea84518ac19089f101df5d5b3b62e602 Mon Sep 17 00:00:00 2001 From: tpodolak Date: Fri, 22 Jul 2022 17:20:02 +0200 Subject: [PATCH 08/10] GH-186 - fixing overload resolution issues when verifying code fixes. Adding missing tests for SyncOverAsyncThrowsCodeFixProvider --- .../ThrowsAsExtensionMethodTests.cs | 6 +- ...ionsMethodWithGenericTypeSpecifiedTests.cs | 6 +- .../ThrowsAsOrdinaryMethodTests.cs | 6 +- ...naryMethodWithGenericTypeSpecifiedTests.cs | 6 +- .../CodeFixProviders/CodeFixVerifier.cs | 5 - .../SyncOverAsyncThrowsCodeFixActionsTests.cs | 2 +- .../ThrowsAsExtensionMethodTests.cs | 6 +- ...ionsMethodWithGenericTypeSpecifiedTests.cs | 6 +- .../ThrowsAsOrdinaryMethodTests.cs | 6 +- ...naryMethodWithGenericTypeSpecifiedTests.cs | 133 ++++++++++++++++-- 10 files changed, 146 insertions(+), 36 deletions(-) diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs index 7b8e27da..a50c2239 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs @@ -53,7 +53,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -104,7 +104,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -155,7 +155,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs index 62e96d9f..f9afb7d7 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs @@ -51,7 +51,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -100,7 +100,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -149,7 +149,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs index 43733a51..fd2b7e7c 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs @@ -55,7 +55,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -108,7 +108,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -161,7 +161,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index 17a7d2d3..a59bd6a0 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/CodeFixProviderTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -53,7 +53,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -104,7 +104,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -155,7 +155,7 @@ public void Test() }} }}"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) diff --git a/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixVerifier.cs b/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixVerifier.cs index 4f24adf0..5953d621 100644 --- a/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.Shared/CodeFixProviders/CodeFixVerifier.cs @@ -24,11 +24,6 @@ protected CodeFixVerifier(WorkspaceFactory workspaceFactory) protected abstract DiagnosticAnalyzer DiagnosticAnalyzer { get; } - protected Task VerifyFix( - string oldSource, - string newSource, - NSubstituteVersion version) => VerifyFix(oldSource, newSource, null, version); - protected async Task VerifyFix( string oldSource, string newSource, diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixActionsTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixActionsTests.cs index 37082437..3084d811 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixActionsTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/SyncOverAsyncThrowsCodeFixActionsTests.cs @@ -39,7 +39,7 @@ End Sub End Class End Namespace"; - await VerifyCodeActions(source, expectedCodeActionTitle); + await VerifyCodeActions(source, NSubstituteVersion.NSubstitute4_2_2, expectedCodeActionTitle); } [Theory] diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs index 1c0f30b4..b3ca3ade 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionMethodTests.cs @@ -45,7 +45,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -88,7 +88,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -131,7 +131,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs index 67c4c597..32080fbc 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsExtensionsMethodWithGenericTypeSpecifiedTests.cs @@ -43,7 +43,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -84,7 +84,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -125,7 +125,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs index 9c2897fd..e129b64b 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodTests.cs @@ -47,7 +47,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -92,7 +92,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -137,7 +137,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource, NSubstituteVersion.NSubstitute4_2_2); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index d1c75fae..b6520d8d 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/CodeFixProvidersTests/SyncOverAsyncThrowsCodeFixProviderTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using NSubstitute.Analyzers.Tests.Shared; namespace NSubstitute.Analyzers.Tests.VisualBasic.CodeFixProvidersTests.SyncOverAsyncThrowsCodeFixProviderTests; @@ -44,7 +45,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInProperty(string method, string updatedMethod) @@ -87,7 +88,7 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } public override async Task ReplacesThrowsWithReturns_WhenUsedInIndexer(string method, string updatedMethod) @@ -130,21 +131,135 @@ End Sub End Class End Namespace"; - await VerifyFix(source, newSource); + await VerifyFix(source, newSource, null, NSubstituteVersion.NSubstitute4_2_2); } - public override Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInMethod(string method, string updatedMethod) { - throw new System.NotImplementedException(); + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{method}(Of Exception)(substitute.Bar()) + ExceptionExtensions.{method}(Of Exception)(value := substitute.Bar()) + End Sub + End Class +End Namespace"; + + var newSource = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Function Bar() As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{updatedMethod}(Of Exception)(substitute.Bar()) + ExceptionExtensions.{updatedMethod}(Of Exception)(value := substitute.Bar()) + End Sub + End Class +End Namespace"; + + await VerifyFix(source, newSource); } - public override Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod) + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInProperty(string method, string updatedMethod) { - throw new System.NotImplementedException(); + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Property Bar As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{method}(Of Exception)(substitute.Bar) + ExceptionExtensions.{method}(Of Exception)(value := substitute.Bar) + End Sub + End Class +End Namespace"; + + var newSource = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Property Bar As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{updatedMethod}(Of Exception)(substitute.Bar) + ExceptionExtensions.{updatedMethod}(Of Exception)(value := substitute.Bar) + End Sub + End Class +End Namespace"; + + await VerifyFix(source, newSource); } - public override Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod) + public override async Task ReplacesThrowsWithThrowsAsync_WhenUsedInIndexer(string method, string updatedMethod) { - throw new System.NotImplementedException(); + var source = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Default Property Item(ByVal x As Integer) As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{method}(Of Exception)(substitute(0)) + ExceptionExtensions.{method}(Of Exception)(value := substitute(0)) + End Sub + End Class +End Namespace"; + + var newSource = $@"Imports System +Imports System.Threading.Tasks +Imports NSubstitute +Imports NSubstitute.ExceptionExtensions + +Namespace MyNamespace + Interface IFoo + Default Property Item(ByVal x As Integer) As Task + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of IFoo)() + ExceptionExtensions.{updatedMethod}(Of Exception)(substitute(0)) + ExceptionExtensions.{updatedMethod}(Of Exception)(value := substitute(0)) + End Sub + End Class +End Namespace"; + + await VerifyFix(source, newSource); } } \ No newline at end of file From 95d877fd8ec8f213f081ddec68cbf81998ad3f0e Mon Sep 17 00:00:00 2001 From: tpodolak Date: Fri, 22 Jul 2022 18:02:27 +0200 Subject: [PATCH 09/10] GH-186 - manually 'skipping' ThrowsAsync like tests cases for literal expressions --- .../ThrowsAsExtensionMethodTests.cs | 8 ++++++++ ...rowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs | 8 ++++++++ .../ThrowsAsOrdinaryMethodTests.cs | 8 ++++++++ ...hrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs | 8 ++++++++ .../ThrowsAsExtensionMethodTests.cs | 9 +++++++++ .../ThrowsAsOrdinaryMethodTests.cs | 8 ++++++++ ...hrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs | 8 ++++++++ 7 files changed, 57 insertions(+) diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs index 315b1e5f..fcaddb5c 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs @@ -41,6 +41,14 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForLiteral(string method, string literal, string type) { + if (method.Contains("Async")) + { + // ThrowsAsync like methods do not extend literals + // TODO replace with Assert.Skip once xUnit v3 released + // https://github.com/xunit/xunit/issues/2073 + return; + } + var source = $@"using System; using NSubstitute; using NSubstitute.ExceptionExtensions; diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs index 018b8112..57d3850f 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodWithGenericTypeSpecifiedTests.cs @@ -41,6 +41,14 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForLiteral(string method, string literal, string type) { + if (method.Contains("Async")) + { + // ThrowsAsync like methods do not extend literals + // TODO replace with Assert.Skip once xUnit v3 released + // https://github.com/xunit/xunit/issues/2073 + return; + } + var source = $@"using System; using NSubstitute; using NSubstitute.ExceptionExtensions; diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs index 54b9a02f..8d708596 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs @@ -46,6 +46,14 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForLiteral(string method, string literal, string type) { + if (method.Contains("Async")) + { + // ThrowsAsync like methods do not extend literals + // TODO replace with Assert.Skip once xUnit v3 released + // https://github.com/xunit/xunit/issues/2073 + return; + } + var source = $@"using System; using NSubstitute; using NSubstitute.ExceptionExtensions; diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index 9e274f86..459c27b0 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -45,6 +45,14 @@ public void Test() public override async Task ReportsDiagnostics_WhenSettingValueForLiteral(string method, string literal, string type) { + if (method.Contains("Async")) + { + // ThrowsAsync like methods do not extend literals + // TODO replace with Assert.Skip once xUnit v3 released + // https://github.com/xunit/xunit/issues/2073 + return; + } + var source = $@"using System; using NSubstitute; using NSubstitute.ExceptionExtensions; diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs index 2e0c3f8d..eb6ae576 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsExtensionMethodTests.cs @@ -4,6 +4,7 @@ using NSubstitute.Analyzers.Shared.Settings; using NSubstitute.Analyzers.Tests.Shared.Extensibility; using NSubstitute.Analyzers.Tests.Shared.Extensions; +using Xunit; namespace NSubstitute.Analyzers.Tests.VisualBasic.DiagnosticAnalyzersTests.NonSubstitutableMemberAnalyzerTests; @@ -39,6 +40,14 @@ End Namespace public override async Task ReportsDiagnostics_WhenSettingValueForLiteral(string method, string literal, string type) { + if (method.Contains("Async")) + { + // ThrowsAsync like methods do not extend literals + // TODO replace with Assert.Skip once xUnit v3 released + // https://github.com/xunit/xunit/issues/2073 + return; + } + var source = $@"Imports System Imports NSubstitute Imports NSubstitute.ExceptionExtensions diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs index c3ec97d3..8b37df7c 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs @@ -44,6 +44,14 @@ End Namespace public override async Task ReportsDiagnostics_WhenSettingValueForLiteral(string method, string literal, string type) { + if (method.Contains("Async")) + { + // ThrowsAsync like methods do not extend literals + // TODO replace with Assert.Skip once xUnit v3 released + // https://github.com/xunit/xunit/issues/2073 + return; + } + var source = $@"Imports System Imports NSubstitute Imports NSubstitute.ExceptionExtensions diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index f4f86020..9b8a82a8 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/NonSubstitutableMemberAnalyzerTests/ThrowsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -43,6 +43,14 @@ End Namespace public override async Task ReportsDiagnostics_WhenSettingValueForLiteral(string method, string literal, string type) { + if (method.Contains("Async")) + { + // ThrowsAsync like methods do not extend literals + // TODO replace with Assert.Skip once xUnit v3 released + // https://github.com/xunit/xunit/issues/2073 + return; + } + var source = $@"Imports System Imports NSubstitute Imports NSubstitute.ExceptionExtensions From 36da47bc9ab33e225f4a34085482501740d1f0c6 Mon Sep 17 00:00:00 2001 From: tpodolak Date: Sat, 13 Aug 2022 01:17:01 +0200 Subject: [PATCH 10/10] GH-186 - upgrading coveralls.net to fix coverage upload issue --- build/build.cake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build/build.cake b/build/build.cake index e673ec6d..7a5017a6 100644 --- a/build/build.cake +++ b/build/build.cake @@ -9,7 +9,7 @@ // Install tools. #tool "dotnet:https://api.nuget.org/v3/index.json?package=GitVersion.Tool&version=5.8.1" -#tool "dotnet:https://api.nuget.org/v3/index.json?package=coveralls.net&version=1.0.0" +#tool "dotnet:https://api.nuget.org/v3/index.json?package=coveralls.net&version=4.0.1" #tool "nuget:https://www.nuget.org/api/v2?package=ReportGenerator&version=5.0.2" #addin "nuget:https://www.nuget.org/api/v2?package=Cake.Incubator&version=4.0.1" #addin "nuget:https://www.nuget.org/api/v2?package=Newtonsoft.Json&version=9.0.1" @@ -260,11 +260,11 @@ Task("Upload-Coverage-Report") var pathSegments = new [] { "tools", ".store", "coveralls.net", - "1.0.0", + "4.0.1", "coveralls.net", - "1.0.0", + "4.0.1", "tools", - "netcoreapp2.1", + "net6.0", "any" }; var workingDir = pathSegments.Aggregate(Context.Environment.WorkingDirectory, (acc, seed) => acc.Combine(seed));