From 0804465c480095801030c6ea5e92f030353a4d4f Mon Sep 17 00:00:00 2001 From: tpodolak Date: Sun, 26 Aug 2018 00:51:21 +0200 Subject: [PATCH] [GH-30] - additional set of tests for getting position of argument --- .../CallInfoDiagnosticVerifier.cs | 2 + .../ReturnsAsExtensionMethodTests.cs | 45 ++++++++++++++++ ...sionMethodWithGenericTypeSpecifiedTests.cs | 45 ++++++++++++++++ .../ReturnsAsOrdinaryMethodTests.cs | 45 ++++++++++++++++ ...naryMethodWithGenericTypeSpecifiedTests.cs | 45 ++++++++++++++++ ...sionMethodWithGenericTypeSpecifiedTests.cs | 45 ++++++++++++++++ ...eturnsForAnyArgsAsExtensionMethodsTests.cs | 45 ++++++++++++++++ .../ReturnsForAnyArgsAsOrdinaryMethodTests.cs | 45 ++++++++++++++++ ...naryMethodWithGenericTypeSpecifiedTests.cs | 45 ++++++++++++++++ .../ThrowsAsExtensionMethodTests.cs | 46 +++++++++++++++++ .../ThrowsAsOrdinaryMethodTests.cs | 46 +++++++++++++++++ .../ThrowsForAnyArgsAsExtensionMethodTests.cs | 46 +++++++++++++++++ .../ThrowsForAnyArgsAsOrdinaryMethodTests.cs | 46 +++++++++++++++++ .../ICallInfoDiagnosticVerifier.cs | 2 + .../CallInfoDiagnosticVerifier.cs | 2 + .../ReturnsAsExtensionMethodsTests.cs | 50 ++++++++++++++++++ .../ReturnsAsOrdinaryMethodTests.cs | 50 ++++++++++++++++++ ...naryMethodWithGenericTypeSpecifiedTests.cs | 50 ++++++++++++++++++ ...eturnsForAnyArgsAsExtensionMethodsTests.cs | 50 ++++++++++++++++++ .../ReturnsForAnyArgsAsOrdinaryMethodTests.cs | 50 ++++++++++++++++++ ...naryMethodWithGenericTypeSpecifiedTests.cs | 50 ++++++++++++++++++ .../ThrowsAsExtensionMethodsTests.cs | 51 +++++++++++++++++++ .../ThrowsAsOrdinaryMethodsTests.cs | 51 +++++++++++++++++++ ...ThrowsForAnyArgsAsExtensionMethodsTests.cs | 51 +++++++++++++++++++ .../ThrowsForAnyArgsAsOrdinaryMethodsTests.cs | 51 +++++++++++++++++++ 25 files changed, 1054 insertions(+) diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/CallInfoDiagnosticVerifier.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/CallInfoDiagnosticVerifier.cs index cc92c5fd..012f814a 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/CallInfoDiagnosticVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/CallInfoDiagnosticVerifier.cs @@ -10,6 +10,8 @@ public abstract class CallInfoDiagnosticVerifier : CSharpDiagnosticVerifier, ICa { public abstract Task ReportsDiagnostic_WhenAccessingArgumentOutOfBounds(string call, string argAccess, int expectedLine, int expectedColumn); + public abstract Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess); + public abstract Task ReportsNoDiagnostic_WhenAccessingArgumentWithinBounds(string call, string argAccess); public abstract Task ReportsNoDiagnostic_WhenConvertingTypeToAssignableTypeForIndirectCasts(string call, string argAccess); diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsExtensionMethodTests.cs index 953995ac..ed4e527b 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsExtensionMethodTests.cs @@ -70,6 +70,51 @@ public void Test() await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Barr", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"using System; +using NSubstitute; + +namespace MyNamespace +{{ + public interface Foo + {{ + int Bar(int x, int y); + + int Barr {{ get; }} + + int this[int x, int y] {{ get; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + {call}.Returns(callInfo => + {{ + {argAccess} + return 1; + }}); + }} + }} +}}"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(0);")] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(1);")] diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsExtensionMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsExtensionMethodWithGenericTypeSpecifiedTests.cs index 66e905ee..a0c17fdc 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsExtensionMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsExtensionMethodWithGenericTypeSpecifiedTests.cs @@ -70,6 +70,51 @@ public void Test() await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Barr", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"using System; +using NSubstitute; + +namespace MyNamespace +{{ + public interface Foo + {{ + int Bar(int x, int y); + + int Barr {{ get; }} + + int this[int x, int y] {{ get; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + {call}.Returns(callInfo => + {{ + {argAccess} + return 1; + }}); + }} + }} +}}"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(0);")] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(1);")] diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodTests.cs index 5391c29c..692f1ed7 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodTests.cs @@ -70,6 +70,51 @@ public void Test() await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Barr", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"using System; +using NSubstitute; + +namespace MyNamespace +{{ + public interface Foo + {{ + int Bar(int x, int y); + + int Barr {{ get; }} + + int this[int x, int y] {{ get; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + SubstituteExtensions.Returns({call}, callInfo => + {{ + {argAccess} + return 1; + }}); + }} + }} +}}"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(0);")] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(1);")] diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index 0f487916..61ff7e20 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -70,6 +70,51 @@ public void Test() await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Barr", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"using System; +using NSubstitute; + +namespace MyNamespace +{{ + public interface Foo + {{ + int Bar(int x, int y); + + int Barr {{ get; }} + + int this[int x, int y] {{ get; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + SubstituteExtensions.Returns({call}, callInfo => + {{ + {argAccess} + return 1; + }}); + }} + }} +}}"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(0);")] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(1);")] diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsExtensionMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsExtensionMethodWithGenericTypeSpecifiedTests.cs index 4be1a662..ca37d67c 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsExtensionMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsExtensionMethodWithGenericTypeSpecifiedTests.cs @@ -70,6 +70,51 @@ public void Test() await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Barr", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"using System; +using NSubstitute; + +namespace MyNamespace +{{ + public interface Foo + {{ + int Bar(int x, int y); + + int Barr {{ get; }} + + int this[int x, int y] {{ get; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + {call}.ReturnsForAnyArgs(callInfo => + {{ + {argAccess} + return 1; + }}); + }} + }} +}}"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(0);")] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(1);")] diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsExtensionMethodsTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsExtensionMethodsTests.cs index 7f08677f..9d32ec96 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsExtensionMethodsTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsExtensionMethodsTests.cs @@ -70,6 +70,51 @@ public void Test() await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Barr", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"using System; +using NSubstitute; + +namespace MyNamespace +{{ + public interface Foo + {{ + int Bar(int x, int y); + + int Barr {{ get; }} + + int this[int x, int y] {{ get; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + {call}.ReturnsForAnyArgs(callInfo => + {{ + {argAccess} + return 1; + }}); + }} + }} +}}"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(0);")] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(1);")] diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodTests.cs index 490168a9..494d38b3 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodTests.cs @@ -70,6 +70,51 @@ public void Test() await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Barr", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"using System; +using NSubstitute; + +namespace MyNamespace +{{ + public interface Foo + {{ + int Bar(int x, int y); + + int Barr {{ get; }} + + int this[int x, int y] {{ get; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + SubstituteExtensions.ReturnsForAnyArgs({call}, callInfo => + {{ + {argAccess} + return 1; + }}); + }} + }} +}}"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(0);")] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(1);")] diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index ab15794c..677156d1 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -70,6 +70,51 @@ public void Test() await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Barr", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"using System; +using NSubstitute; + +namespace MyNamespace +{{ + public interface Foo + {{ + int Bar(int x, int y); + + int Barr {{ get; }} + + int this[int x, int y] {{ get; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + SubstituteExtensions.ReturnsForAnyArgs({call}, callInfo => + {{ + {argAccess} + return 1; + }}); + }} + }} +}}"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(0);")] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(1);")] diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodTests.cs index f8320c91..91e40dc1 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodTests.cs @@ -71,6 +71,52 @@ public void Test() await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Barr", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"using System; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface Foo + {{ + int Bar(int x, int y); + + int Barr {{ get; }} + + int this[int x, int y] {{ get; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + {call}.Throws(callInfo => + {{ + {argAccess} + return new Exception(); + }}); + }} + }} +}}"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(0);")] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(1);")] diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs index 38c38d7d..d01f006b 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodTests.cs @@ -71,6 +71,52 @@ public void Test() await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Barr", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"using System; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface Foo + {{ + int Bar(int x, int y); + + int Barr {{ get; }} + + int this[int x, int y] {{ get; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.Throws({call}, callInfo => + {{ + {argAccess} + return new Exception(); + }}); + }} + }} +}}"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(0);")] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(1);")] diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsExtensionMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsExtensionMethodTests.cs index 4981d000..121d62bc 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsExtensionMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsExtensionMethodTests.cs @@ -71,6 +71,52 @@ public void Test() await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Barr", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"using System; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface Foo + {{ + int Bar(int x, int y); + + int Barr {{ get; }} + + int this[int x, int y] {{ get; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + {call}.ThrowsForAnyArgs(callInfo => + {{ + {argAccess} + return new Exception(); + }}); + }} + }} +}}"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(0);")] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(1);")] diff --git a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsOrdinaryMethodTests.cs index 4c1f6b11..8fae9eef 100644 --- a/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.CSharp/DiagnosticAnalyzerTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsOrdinaryMethodTests.cs @@ -71,6 +71,52 @@ public void Test() await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute[Arg.Any(), Arg.Any()]", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Barr", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Barr", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; callInfo.ArgAt(x);")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.Args()[x];")] + [InlineData("substitute.Bar(Arg.Any(), Arg.Any())", @"var x = 2; var y = callInfo.ArgTypes()[x];")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"using System; +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace MyNamespace +{{ + public interface Foo + {{ + int Bar(int x, int y); + + int Barr {{ get; }} + + int this[int x, int y] {{ get; }} + }} + + public class FooTests + {{ + public void Test() + {{ + var substitute = NSubstitute.Substitute.For(); + ExceptionExtensions.ThrowsForAnyArgs({call}, callInfo => + {{ + {argAccess} + return new Exception(); + }}); + }} + }} +}}"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(0);")] [InlineData("substitute[Arg.Any(), Arg.Any()]", "callInfo.ArgAt(1);")] diff --git a/tests/NSubstitute.Analyzers.Tests.Shared/DiagnosticAnalyzers/ICallInfoDiagnosticVerifier.cs b/tests/NSubstitute.Analyzers.Tests.Shared/DiagnosticAnalyzers/ICallInfoDiagnosticVerifier.cs index 17b3a884..7b56005e 100644 --- a/tests/NSubstitute.Analyzers.Tests.Shared/DiagnosticAnalyzers/ICallInfoDiagnosticVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.Shared/DiagnosticAnalyzers/ICallInfoDiagnosticVerifier.cs @@ -6,6 +6,8 @@ public interface ICallInfoDiagnosticVerifier { Task ReportsDiagnostic_WhenAccessingArgumentOutOfBounds(string call, string argAccess, int expectedLine, int expectedColumn); + Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess); + Task ReportsNoDiagnostic_WhenAccessingArgumentWithinBounds(string call, string argAccess); Task ReportsNoDiagnostic_WhenConvertingTypeToAssignableTypeForIndirectCasts(string call, string argAccess); diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/CallInfoDiagnosticVerifier.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/CallInfoDiagnosticVerifier.cs index 45d1bd57..fb8987f7 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/CallInfoDiagnosticVerifier.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/CallInfoDiagnosticVerifier.cs @@ -9,6 +9,8 @@ public abstract class CallInfoDiagnosticVerifier : VisualBasicDiagnosticVerifier { public abstract Task ReportsDiagnostic_WhenAccessingArgumentOutOfBounds(string call, string argAccess, int expectedLine, int expectedColumn); + public abstract Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess); + public abstract Task ReportsNoDiagnostic_WhenAccessingArgumentWithinBounds(string call, string argAccess); public abstract Task ReportsNoDiagnostic_WhenConvertingTypeToAssignableTypeForIndirectCasts(string call, string argAccess); diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsAsExtensionMethodsTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsAsExtensionMethodsTests.cs index 2673c6fa..14f045cb 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsAsExtensionMethodsTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsAsExtensionMethodsTests.cs @@ -64,6 +64,56 @@ End Namespace await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"Imports System +Imports NSubstitute + +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 + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of Foo)() + {call}.Returns(Function(callInfo) + {argAccess} + Return 1 + End Function) + End Sub + End Class +End Namespace"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(0)")] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(1)")] diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodTests.cs index 69a4608c..c9b4891e 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodTests.cs @@ -64,6 +64,56 @@ End Namespace await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"Imports System +Imports NSubstitute + +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 + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of Foo)() + SubstituteExtensions.Returns({call}, Function(callInfo) + {argAccess} + Return 1 + End Function) + End Sub + End Class +End Namespace"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(0)")] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(1)")] diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index 1f3d5d8e..402d98dd 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -64,6 +64,56 @@ End Namespace await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"Imports System +Imports NSubstitute + +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 + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of Foo)() + SubstituteExtensions.Returns(Of Integer)({call}, Function(callInfo) + {argAccess} + Return 1 + End Function) + End Sub + End Class +End Namespace"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(0)")] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(1)")] diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsExtensionMethodsTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsExtensionMethodsTests.cs index 2727199f..7bb42039 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsExtensionMethodsTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsExtensionMethodsTests.cs @@ -64,6 +64,56 @@ End Namespace await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"Imports System +Imports NSubstitute + +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 + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of Foo)() + {call}.ReturnsForAnyArgs(Function(callInfo) + {argAccess} + Return 1 + End Function) + End Sub + End Class +End Namespace"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(0)")] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(1)")] diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodTests.cs index d5c7f664..3768dd2c 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodTests.cs @@ -64,6 +64,56 @@ End Namespace await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"Imports System +Imports NSubstitute + +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 + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of Foo)() + SubstituteExtensions.ReturnsForAnyArgs({call}, Function(callInfo) + {argAccess} + Return 1 + End Function) + End Sub + End Class +End Namespace"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(0)")] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(1)")] diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs index 448b7cb2..e8168721 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ReturnsForAnyArgsAsOrdinaryMethodWithGenericTypeSpecifiedTests.cs @@ -64,6 +64,56 @@ End Namespace await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"Imports System +Imports NSubstitute + +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 + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of Foo)() + SubstituteExtensions.ReturnsForAnyArgs(Of Integer)({call}, Function(callInfo) + {argAccess} + Return 1 + End Function) + End Sub + End Class +End Namespace"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(0)")] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(1)")] diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodsTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodsTests.cs index cce59054..11359e69 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodsTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsExtensionMethodsTests.cs @@ -65,6 +65,57 @@ End Namespace await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"Imports System +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 + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of Foo)() + {call}.Throws(Function(callInfo) + {argAccess} + Return New Exception() + End Function) + End Sub + End Class +End Namespace"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(0)")] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(1)")] diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodsTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodsTests.cs index 7127c35b..0405f92b 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodsTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsAsOrdinaryMethodsTests.cs @@ -65,6 +65,57 @@ End Namespace await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"Imports System +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 + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of Foo)() + ExceptionExtensions.Throws({call}, Function(callInfo) + {argAccess} + Return New Exception() + End Function) + End Sub + End Class +End Namespace"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(0)")] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(1)")] diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsExtensionMethodsTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsExtensionMethodsTests.cs index 8d217ae5..cf43ae47 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsExtensionMethodsTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsExtensionMethodsTests.cs @@ -65,6 +65,57 @@ End Namespace await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"Imports System +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 + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of Foo)() + {call}.ThrowsForAnyArgs(Function(callInfo) + {argAccess} + Return New Exception() + End Function) + End Sub + End Class +End Namespace"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(0)")] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(1)")] diff --git a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsOrdinaryMethodsTests.cs b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsOrdinaryMethodsTests.cs index 09ba691c..9115e23e 100644 --- a/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsOrdinaryMethodsTests.cs +++ b/tests/NSubstitute.Analyzers.Tests.VisualBasic/DiagnosticAnalyzersTests/CallInfoAnalyzerTests/ThrowsForAnyArgsAsOrdinaryMethodsTests.cs @@ -65,6 +65,57 @@ End Namespace await VerifyDiagnostic(source, expectedDiagnostic); } + [Theory] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Barr", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + callInfo.ArgAt(Of Integer)(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.Args()(x)")] + [InlineData("substitute.Bar(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", @"Dim x = 2 + Dim y = callInfo.ArgTypes()(x)")] + public override async Task ReportsNoDiagnostic_WhenAccessingArgumentOutOfBound_AndPositionIsNotLiteralExpression(string call, string argAccess) + { + var source = $@"Imports System +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 + End Interface + + Public Class FooTests + Public Sub Test() + Dim substitute = NSubstitute.Substitute.[For](Of Foo)() + ExceptionExtensions.ThrowsForAnyArgs({call}, Function(callInfo) + {argAccess} + Return New Exception() + End Function) + End Sub + End Class +End Namespace"; + await VerifyDiagnostic(source); + } + [Theory] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(0)")] [InlineData("substitute(Arg.Any(Of Integer)(), Arg.Any(Of Integer)())", "callInfo.ArgAt(Of Integer)(1)")]