From a07fbd22c4e44bf61037f24d3dacf4171110b271 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Tue, 16 Jul 2024 22:07:59 -0700 Subject: [PATCH] Convert to use raw strings and /* lang=c#-test */ --- .editorconfig | 4 + src/Directory.Build.props | 6 +- ...DataAttributeMustPointAtValidClassTests.cs | 688 +++--- ...ctionDefinitionClassesMustBePublicTests.cs | 52 +- ...actAttributeSubclassShouldBePublicTests.cs | 221 +- ...DataAttributeShouldBeUsedOnATheoryTests.cs | 62 +- .../DoNotUseAsyncVoidForTestMethodsTests.cs | 103 +- .../DoNotUseBlockingTaskOperationsTests.cs | 1029 ++++----- .../X1000/DoNotUseConfigureAwaitTests.cs | 461 ++--- .../X1000/EnsureFixturesHaveASourceTests.cs | 418 ++-- .../FactMethodMustNotHaveParametersTests.cs | 45 +- .../FactMethodShouldNotHaveTestDataTests.cs | 68 +- ...nlineDataMustMatchTheoryParametersTests.cs | 1349 ++++++------ ...lineDataShouldBeUniqueWithinTheoryTests.cs | 745 +++---- ...ocalFunctionsCannotBeTestFunctionsTests.cs | 53 +- ...mberDataShouldReferenceValidMemberTests.cs | 1837 ++++++++--------- .../PublicMethodShouldBeMarkedAsTestTests.cs | 377 ++-- ...tClassCannotBeNestedInGenericClassTests.cs | 112 +- .../X1000/TestClassMustBePublicTests.cs | 157 +- ...estClassShouldHaveTFixtureArgumentTests.cs | 70 +- .../TestMethodCannotHaveOverloadsTests.cs | 158 +- ...dMustNotHaveMultipleFactAttributesTests.cs | 59 +- .../TestMethodShouldNotBeSkippedTests.cs | 34 +- .../TestMethodSupportedReturnTypeTests.cs | 116 +- ...taRowArgumentsShouldBeSerializableTests.cs | 359 ++-- ...aTypeArgumentsShouldBeSerializableTests.cs | 396 ++-- ...ryMethodCannotHaveDefaultParameterTests.cs | 33 +- .../TheoryMethodCannotHaveParamsArrayTests.cs | 59 +- .../TheoryMethodMustHaveTestDataTests.cs | 47 +- .../TheoryMethodShouldHaveParametersTests.cs | 45 +- ...TheoryMethodShouldUseAllParametersTests.cs | 264 ++- .../X1000/UseCancellationTokenTests.cs | 129 +- ...ctionContainsShouldNotUseBoolCheckTests.cs | 256 ++- ...mptyCollectionCheckShouldNotBeUsedTests.cs | 40 +- ...edForCollectionDoesNotContainCheckTests.cs | 97 +- ...otBeUsedForCollectionContainsCheckTests.cs | 23 +- ...nericShouldNotBeUsedForStringValueTests.cs | 60 +- ...sertEqualLiteralValueShouldBeFirstTests.cs | 126 +- ...AssertEqualPrecisionShouldBeInRangeTest.cs | 32 +- ...ShouldNotBeUsedForBoolLiteralCheckTests.cs | 106 +- ...uldNotBeUsedForCollectionSizeCheckTests.cs | 272 ++- ...rtEqualShouldNotBeUsedForNullCheckTests.cs | 185 +- .../X2000/AssertEqualsShouldNotBeUsedTests.cs | 18 +- ...TypeShouldNotBeUsedForAbstractTypeTests.cs | 96 +- ...sertIsTypeShouldUseGenericOverloadTests.cs | 44 +- ...IsTypeShouldUseGenericOverloadTypeTests.cs | 100 +- ...tNullShouldNotBeCalledOnValueTypesTests.cs | 165 +- ...xMatchShouldNotUseBoolLiteralCheckTests.cs | 69 +- ...tSameShouldNotBeCalledOnValueTypesTests.cs | 178 +- ...ngleShouldBeUsedForSingleParameterTests.cs | 49 +- ...gEqualityCheckShouldNotUseBoolCheckTest.cs | 167 +- ...ubstringCheckShouldNotUseBoolCheckTests.cs | 312 ++- ...ShouldNotBeUsedForAsyncThrowsCheckTests.cs | 319 ++- ...hrowsShouldUseGenericOverloadCheckTests.cs | 175 +- .../X2000/AsyncAssertsShouldBeAwaitedTests.cs | 117 +- .../BooleanAssertsShouldNotBeNegatedTests.cs | 27 +- ...uldNotBeUsedForSimpleEqualityCheckTests.cs | 212 +- ...UseAssertEmptyWithProblematicTypesTests.cs | 89 +- .../X2000/SetEqualityAnalyzerTests.cs | 419 ++-- ...seAssertFailInsteadOfBooleanAssertTests.cs | 68 +- ...sMustBeLongLivedMarshalByRefObjectTests.cs | 167 +- ...ssMustHaveParameterlessConstructorTests.cs | 85 +- ...ttributeMustPointAtValidClassFixerTests.cs | 262 +-- ...DefinitionClassesMustBePublicFixerTests.cs | 38 +- .../Fixes/X1000/ConvertToFactFixTests.cs | 62 +- .../Fixes/X1000/ConvertToTheoryFixTests.cs | 66 +- ...ttributeShouldBeUsedOnATheoryFixerTests.cs | 62 +- ...NotUseAsyncVoidForTestMethodsFixerTests.cs | 181 +- .../X1000/DoNotUseConfigureAwaitFixerTests.cs | 660 +++--- ...ctMethodMustNotHaveParametersFixerTests.cs | 27 +- ...ctMethodShouldNotHaveTestDataFixerTests.cs | 29 +- ...chTheoryParameters_ExtraValueFixerTests.cs | 93 +- ...eUsedForIncompatibleParameterFixerTests.cs | 78 +- ...TheoryParameters_TooFewValuesFixerTests.cs | 35 +- ...ataShouldBeUniqueWithinTheoryFixerTests.cs | 33 +- ...unctionsCannotBeTestFunctionsFixerTests.cs | 36 +- ...ferenceValidMember_ExtraValueFixerTests.cs | 113 +- ...ldReferenceValidMember_NameOfFixerTests.cs | 43 +- ...eUsedForIncompatibleParameterFixerTests.cs | 74 +- ...alidMember_ParamsForNonMethodFixerTests.cs | 47 +- ...ferenceValidMember_ReturnTypeFixerTests.cs | 78 +- ...ldReferenceValidMember_StaticFixerTests.cs | 39 +- ...ferenceValidMember_VisibilityFixerTests.cs | 39 +- ...licMethodShouldBeMarkedAsTestFixerTests.cs | 66 +- .../X1000/RemoveMethodParameterFixTests.cs | 136 +- ...sCannotBeNestedInGenericClassFixerTests.cs | 38 +- .../X1000/TestClassMustBePublicFixerTests.cs | 68 +- ...assShouldHaveTFixtureArgumentFixerTests.cs | 74 +- ...NotHaveMultipleFactAttributesFixerTests.cs | 33 +- .../TestMethodShouldNotBeSkippedFixerTests.cs | 27 +- ...hodCannotHaveDefaultParameterFixerTests.cs | 31 +- ...ContainsShouldNotUseBoolCheckFixerTests.cs | 39 +- ...ollectionCheckShouldNotBeUsedFixerTests.cs | 61 +- ...CollectionDoesNotContainCheckFixerTests.cs | 35 +- ...sedForCollectionContainsCheckFixerTests.cs | 29 +- ...ShouldNotBeUsedForStringValueFixerTests.cs | 19 +- ...qualLiteralValueShouldBeFirstFixerTests.cs | 44 +- ...EqualPrecisionShouldBeInRangeFixerTests.cs | 33 +- ...dNotBeUsedForBoolLiteralCheckFixerTests.cs | 51 +- ...tBeUsedForCollectionSizeCheckFixerTests.cs | 33 +- ...alShouldNotBeUsedForNullCheckFixerTests.cs | 35 +- .../AssertEqualsShouldNotBeUsedFixerTests.cs | 27 +- ...houldNotBeUsedForAbstractTypeFixerTests.cs | 37 +- ...ShouldNotBeCalledOnValueTypesFixerTests.cs | 98 +- ...hShouldNotUseBoolLiteralCheckFixerTests.cs | 29 +- ...ShouldNotBeCalledOnValueTypesFixerTests.cs | 27 +- ...houldBeUsedForSingleParameterFixerTests.cs | 210 +- ...ityCheckShouldNotUseBoolCheckFixerTests.cs | 53 +- ...ingCheckShouldNotUseBoolCheckFixerTests.cs | 45 +- ...dNotBeUsedForAsyncThrowsCheckFixerTests.cs | 739 +++---- .../AsyncAssertsShouldBeAwaitedFixerTests.cs | 53 +- ...leanAssertsShouldNotBeNegatedFixerTests.cs | 19 +- ...ForSimpleEqualityCheckBooleanFixerTests.cs | 51 +- ...SimpleEqualityCheckNonBooleanFixerTests.cs | 33 +- ...ertFailInsteadOfBooleanAssertFixerTests.cs | 22 +- .../Fixes/X2000/UseGenericOverloadFixTests.cs | 82 +- ...BeLongLivedMarshalByRefObjectFixerTests.cs | 60 +- ...tHaveParameterlessConstructorFixerTests.cs | 166 +- ...derCallingConfigureAwaitSuppressorTests.cs | 92 +- .../MakeTypesInternalSuppressorTests.cs | 38 +- .../Utility/CodeAnalyzerHelper.cs | 6 +- .../xunit.analyzers.tests.csproj | 4 +- .../X1000/PublicMethodShouldBeMarkedAsTest.cs | 2 +- tools/builder/common | 2 +- 124 files changed, 8914 insertions(+), 9557 deletions(-) diff --git a/.editorconfig b/.editorconfig index 4c91d0bf..02820dae 100644 --- a/.editorconfig +++ b/.editorconfig @@ -232,4 +232,8 @@ dotnet_diagnostic.CA1707.severity = none # Remove the underscores from type na dotnet_diagnostic.CA1720.severity = none # Identifier contains type name dotnet_diagnostic.CA1724.severity = none # Type names should not match namespaces dotnet_diagnostic.CA1859.severity = none # Use concrete types when possible for improved performance +dotnet_diagnostic.CA1861.severity = none # Avoid constant arrays as arguments +dotnet_diagnostic.CA2211.severity = none # Non-constant fields should not be visible +dotnet_diagnostic.CA2241.severity = error # Provide correct arguments to formatting methods/The format argument is not a valid string +dotnet_diagnostic.IDE0040.severity = none # Add accessibility modifiers dotnet_diagnostic.IDE1006.severity = none # Naming rule violation diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 6f830b21..a6302259 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -77,9 +77,9 @@ - - - + + + diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/ClassDataAttributeMustPointAtValidClassTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/ClassDataAttributeMustPointAtValidClassTests.cs index 1756da84..3e92eb8d 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/ClassDataAttributeMustPointAtValidClassTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/ClassDataAttributeMustPointAtValidClassTests.cs @@ -1,35 +1,36 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Xunit; using Verify = CSharpVerifier; public class ClassDataAttributeMustPointAtValidClassTests { - static string TestMethodSource(string testMethodParams = "(int n)") => @$" -#nullable enable + static string TestMethodSource(string testMethodParams = "(int n)") => string.Format(/* lang=c#-test */ """ + #nullable enable -using Xunit; + using Xunit; -public class TestClass {{ - [Theory] - [ClassData(typeof(DataClass))] - public void TestMethod{testMethodParams} {{ }} -}}"; + public class TestClass {{ + [Theory] + [ClassData(typeof(DataClass))] + public void TestMethod{0} {{ }} + }} + """, testMethodParams); public class SuccessCases { [Fact] public async Task SuccessCaseV2() { - var dataClassSource = @" -using System.Collections; -using System.Collections.Generic; + var dataClassSource = /* lang=c#-test */ """ + using System.Collections; + using System.Collections.Generic; -class DataClass: IEnumerable { - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -}"; + class DataClass: IEnumerable { + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + """; await Verify.VerifyAnalyzerV2(LanguageVersion.CSharp9, [TestMethodSource(), dataClassSource]); } @@ -37,105 +38,150 @@ class DataClass: IEnumerable { public static TheoryData SuccessCasesV3Data = new() { // IEnumerable> maps to int - { "(int n)", @" -using System.Collections; -using System.Collections.Generic; -using Xunit; - -class DataClass: IEnumerable> { - public IEnumerator> GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -}" }, + { + /* lang=c#-test */ "(int n)", + /* lang=c#-test */ """ + using System.Collections; + using System.Collections.Generic; + using Xunit; + + class DataClass: IEnumerable> { + public IEnumerator> GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + """ + }, // IAsyncEnumerable> maps to int - { "(int n)", @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}" }, + { + /* lang=c#-test */ "(int n)", + /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """ + }, // IAsyncEnumerable> with optional parameter - { "(int n, int p = 0)", @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}" }, + { + /* lang=c#-test */ "(int n, int p = 0)", + /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """ + }, // IAsyncEnumerable> with params array (no values) - { "(int n, params int[] a)", @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}" }, + { + /* lang=c#-test */ "(int n, params int[] a)", + /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """ + }, // IAsyncEnumerable> with params array (one value) - { "(int n, params string[] a)", @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}" }, + { + /* lang=c#-test */ "(int n, params string[] a)", + /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """ + }, // IAsyncEnumerable> with params array (multiple values) - { "(int n, params string[] a)", @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}" }, + { + /* lang=c#-test */ "(int n, params string[] a)", + /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """ + }, // IAsyncEnumerable> with params array (array for params array) - { "(int n, params string[] a)", @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}" }, + { + /* lang=c#-test */ "(int n, params string[] a)", + /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """ + }, // IAsyncEnumerable> maps to generic T - { "(T t)", @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}" }, + { + /* lang=c#-test */ "(T t)", + /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """ + }, // IAsyncEnumerable> maps to generic T? - { "(T? t)", @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}" }, + { + /* lang=c#-test */ "(T? t)", + /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """ + }, // IAsyncEnumerable> maps unnamed tuple to named tuple - { "((int x, int y) point)", @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}" }, + { + /* lang=c#-test */ "((int x, int y) point)", + /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """ + }, // IAsyncEnumerable> maps tuples with mismatched names - { "((int x, int y) point)", @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}" }, + { + /* lang=c#-test */ "((int x, int y) point)", + /* lang=c#-test */ """ + + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """ + }, }; [Theory] @@ -150,72 +196,78 @@ public async Task SuccessCasesV3( public class X1007_ClassDataAttributeMustPointAtValidClass { - public static TheoryData FailureCasesData = new() - { + public static TheoryData FailureCasesData = + [ // Incorrect enumeration type (object instead of object[]) - @" -using System.Collections; -using System.Collections.Generic; - -class DataClass: IEnumerable { - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -}", + /* lang=c#-test */ + """ + using System.Collections; + using System.Collections.Generic; + + class DataClass: IEnumerable { + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + """, + // Abstract class - @" -using System.Collections; -using System.Collections.Generic; - -abstract class DataClass: IEnumerable { - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -}", + /* lang=c#-test */ + """ + using System.Collections; + using System.Collections.Generic; + + abstract class DataClass: IEnumerable { + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + """, + // Missing parameterless constructor - @" -using System.Collections; -using System.Collections.Generic; - -class DataClass: IEnumerable { - public DataClass(string parameter) { } - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -}", + /* lang=c#-test */ + """ + using System.Collections; + using System.Collections.Generic; + + class DataClass: IEnumerable { + public DataClass(string parameter) { } + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + """, + // Parameterless constructor is internal - @" -using System.Collections; -using System.Collections.Generic; - -class DataClass: IEnumerable { - internal DataClass() { } - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -}", + /* lang=c#-test */ + """ + using System.Collections; + using System.Collections.Generic; + + class DataClass: IEnumerable { + internal DataClass() { } + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + """, + // Parameterless constructor is private - @" -using System.Collections; -using System.Collections.Generic; - -class DataClass: IEnumerable { - private DataClass() { } - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -}", - }; + /* lang=c#-test */ + """ + using System.Collections; + using System.Collections.Generic; + + class DataClass: IEnumerable { + private DataClass() { } + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + """, + ]; [Theory] [MemberData(nameof(FailureCasesData))] public async Task FailureCases(string dataClassSource) { - var expectedV2 = - Verify - .Diagnostic("xUnit1007") - .WithSpan(8, 6, 8, 34) - .WithArguments("DataClass", "IEnumerable"); - var expectedV3 = - Verify - .Diagnostic("xUnit1007") - .WithSpan(8, 6, 8, 34) - .WithArguments("DataClass", "IEnumerable, IAsyncEnumerable, IEnumerable, or IAsyncEnumerable"); + var expectedV2 = Verify.Diagnostic("xUnit1007").WithSpan(7, 6, 7, 34).WithArguments("DataClass", "IEnumerable"); + var expectedV3 = Verify.Diagnostic("xUnit1007").WithSpan(7, 6, 7, 34).WithArguments("DataClass", "IEnumerable, IAsyncEnumerable, IEnumerable, or IAsyncEnumerable"); await Verify.VerifyAnalyzerV2(LanguageVersion.CSharp9, [TestMethodSource(), dataClassSource], expectedV2); await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource(), dataClassSource], expectedV3); @@ -224,18 +276,15 @@ public async Task FailureCases(string dataClassSource) [Fact] public async Task IAsyncEnumerableNotSupportedInV2() { - var dataClassSource = @" -using System.Collections.Generic; -using System.Threading; - -public class DataClass : IAsyncEnumerable { - public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}"; - var expected = - Verify - .Diagnostic("xUnit1007") - .WithSpan(8, 6, 8, 34) - .WithArguments("DataClass", "IEnumerable"); + var dataClassSource = /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + + public class DataClass : IAsyncEnumerable { + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """; + var expected = Verify.Diagnostic("xUnit1007").WithSpan(7, 6, 7, 34).WithArguments("DataClass", "IEnumerable"); await Verify.VerifyAnalyzerV2(LanguageVersion.CSharp9, [TestMethodSource(), dataClassSource], expected); } @@ -246,23 +295,18 @@ public class X1037_TheoryDataTypeArgumentsMustMatchTestMethodParameters_TooFewTy [Fact] public async Task NotEnoughTypeParameters_Triggers() { - var source = @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}"; - - var expected = - Verify - .Diagnostic("xUnit1037") - .WithSpan(8, 6, 8, 34) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Xunit.TheoryDataRow"); - - await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource("(int n, string f)"), source], expected); + var dataClassSource = /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """; + var expected = Verify.Diagnostic("xUnit1037").WithSpan(7, 6, 7, 34).WithArguments("Xunit.TheoryDataRow"); + + await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource("(int n, string f)"), dataClassSource], expected); } } @@ -271,45 +315,35 @@ public class X1038_TheoryDataTypeArgumentsMustMatchTestMethodParameters_ExtraTyp [Fact] public async Task TooManyTypeParameters_Triggers() { - var source = @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}"; - - var expected = - Verify - .Diagnostic("xUnit1038") - .WithSpan(8, 6, 8, 34) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Xunit.TheoryDataRow"); - - await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource("(int n)"), source], expected); + var dataClassSource = /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """; + var expected = Verify.Diagnostic("xUnit1038").WithSpan(7, 6, 7, 34).WithArguments("Xunit.TheoryDataRow"); + + await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource("(int n)"), dataClassSource], expected); } [Fact] public async Task ExtraDataPastParamsArray_Triggers() { - var source = $@" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> {{ - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}}"; - - var expected = - Verify - .Diagnostic("xUnit1038") - .WithSpan(8, 6, 8, 34) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Xunit.TheoryDataRow"); - - await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource("(int n, params double[] d)"), source], expected); + var dataClassSource = /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """; + var expected = Verify.Diagnostic("xUnit1038").WithSpan(7, 6, 7, 34).WithArguments("Xunit.TheoryDataRow"); + + await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource("(int n, params double[] d)"), dataClassSource], expected); } } @@ -318,45 +352,35 @@ public class X1039_TheoryDataTypeArgumentsMustMatchTestMethodParameters_Incompat [Fact] public async Task WithIncompatibleType_Triggers() { - var source = @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}"; - - var expected = - Verify - .Diagnostic("xUnit1039") - .WithSpan(9, 35, 9, 41) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("string", "DataClass", "d"); - - await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource("(int n, double d)"), source], expected); + var dataClassSource = /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """; + var expected = Verify.Diagnostic("xUnit1039").WithSpan(8, 35, 8, 41).WithArguments("string", "DataClass", "d"); + + await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource("(int n, double d)"), dataClassSource], expected); } [Fact] public async Task WithExtraValueNotCompatibleWithParamsArray_Triggers() { - var source = @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}"; - - var expected = - Verify - .Diagnostic("xUnit1039") - .WithSpan(9, 42, 9, 50) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("int", "DataClass", "s"); - - await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource("(int n, params string[] s)"), source], expected); + var dataClassSource = /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """; + var expected = Verify.Diagnostic("xUnit1039").WithSpan(8, 42, 8, 50).WithArguments("int", "DataClass", "s"); + + await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource("(int n, params string[] s)"), dataClassSource], expected); } } @@ -365,97 +389,105 @@ public class X1040_TheoryDataTypeArgumentsMustMatchTestMethodParameters_Incompat [Fact] public async Task ValidTheoryDataRowMemberWithMismatchedNullability_Triggers() { - var source = @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable> { - public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}"; - - var expected = - Verify - .Diagnostic("xUnit1040") - .WithSpan(9, 28, 9, 34) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("string?", "DataClass", "s"); - - await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource("(string s)"), source], expected); + var dataClassSource = /* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable> { + public IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """; + var expected = Verify.Diagnostic("xUnit1040").WithSpan(8, 28, 8, 34).WithArguments("string?", "DataClass", "s"); + + await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource("(string s)"), dataClassSource], expected); } } public class X1050_ClassDataTheoryDataRowIsRecommendedForStronglyTypedAnalysis { - public static TheoryData FailureCasesData = new() - { + public static TheoryData FailureCasesData = + [ // IEnumerable - @" -using System.Collections; -using System.Collections.Generic; -using Xunit; + /* lang=c#-test */ """ + using System.Collections; + using System.Collections.Generic; + using Xunit; + + public class DataClass : IEnumerable { + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + """, -public class DataClass : IEnumerable { - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -}", // IAsyncEnumerable - @" -using System.Collections.Generic; -using System.Threading; -using Xunit; + /* lang=c#-test */ + """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable { + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """, -public class DataClass : IAsyncEnumerable { - public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}", // IEnumerable - @" -using System.Collections; -using System.Collections.Generic; -using Xunit; + /* lang=c#-test */ + """ + using System.Collections; + using System.Collections.Generic; + using Xunit; + + public class DataClass : IEnumerable { + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + """, -public class DataClass : IEnumerable { - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -}", // IAsyncEnumerable - @" -using System.Collections.Generic; -using System.Threading; -using Xunit; + /* lang=c#-test */ + """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable { + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """, -public class DataClass : IAsyncEnumerable { - public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}", // IEnumerable - @" -using System.Collections; -using System.Collections.Generic; -using Xunit; + /* lang=c#-test */ + """ + using System.Collections; + using System.Collections.Generic; + using Xunit; + + public class DataClass : IEnumerable { + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + """, -public class DataClass : IEnumerable { - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -}", // IAsyncEnumerable - @" -using System.Collections.Generic; -using System.Threading; -using Xunit; - -public class DataClass : IAsyncEnumerable { - public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; -}", - }; + /* lang=c#-test */ + """ + using System.Collections.Generic; + using System.Threading; + using Xunit; + + public class DataClass : IAsyncEnumerable { + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => null; + } + """, + ]; [Theory] [MemberData(nameof(FailureCasesData))] public async Task FailureCases(string dataClassSource) { - var expected = - Verify - .Diagnostic("xUnit1050") - .WithSpan(8, 6, 8, 34); + var expected = Verify.Diagnostic("xUnit1050").WithSpan(7, 6, 7, 34); await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, [TestMethodSource(), dataClassSource], expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/CollectionDefinitionClassesMustBePublicTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/CollectionDefinitionClassesMustBePublicTests.cs index 0db73515..550a2c9d 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/CollectionDefinitionClassesMustBePublicTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/CollectionDefinitionClassesMustBePublicTests.cs @@ -5,11 +5,12 @@ public class CollectionDefinitionClassesMustBePublicTests { [Fact] - public async Task ForPublicClass_DoesNotFindError() + public async Task ForPublicClass_DoesNotTrigger() { - var source = @" -[Xunit.CollectionDefinition(""MyCollection"")] -public class CollectionDefinitionClass { }"; + var source = /* lang=c#-test */ """ + [Xunit.CollectionDefinition("MyCollection")] + public class CollectionDefinitionClass { } + """; await Verify.VerifyAnalyzer(source); } @@ -17,28 +18,26 @@ public class CollectionDefinitionClass { }"; [Theory] [InlineData("")] [InlineData("internal ")] - public async Task ForFriendOrInternalClass_FindsError(string classAccessModifier) + public async Task ForFriendOrInternalClass_Triggers(string classAccessModifier) { - var source = $@" -[Xunit.CollectionDefinition(""MyCollection"")] -{classAccessModifier}class CollectionDefinitionClass {{ }}"; - var expected = - Verify - .Diagnostic() - .WithSpan(3, 7 + classAccessModifier.Length, 3, 32 + classAccessModifier.Length); + var source = string.Format(/* lang=c#-test */ """ + [Xunit.CollectionDefinition("MyCollection")] + {0}class [|CollectionDefinitionClass|] {{ }} + """, classAccessModifier); - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } [Theory] [InlineData("")] [InlineData("public ")] - public async Task ForPartialClassInSameFile_WhenClassIsPublic_DoesNotFindError(string otherPartAccessModifier) + public async Task ForPartialClassInSameFile_WhenClassIsPublic_DoesNotTrigger(string otherPartAccessModifier) { - var source = $@" -[Xunit.CollectionDefinition(""MyCollection"")] -public partial class CollectionDefinitionClass {{ }} -{otherPartAccessModifier}partial class CollectionDefinitionClass {{ }}"; + var source = string.Format(/* lang=c#-test */ """ + [Xunit.CollectionDefinition("MyCollection")] + public partial class CollectionDefinitionClass {{ }} + {0}partial class CollectionDefinitionClass {{ }} + """, otherPartAccessModifier); await Verify.VerifyAnalyzer(source); } @@ -47,19 +46,16 @@ public partial class CollectionDefinitionClass {{ }} [InlineData("", "")] [InlineData("", "internal ")] [InlineData("internal ", "internal ")] - public async Task ForPartialClassInSameFile_WhenClassIsNonPublic_FindsError( + public async Task ForPartialClassInSameFile_WhenClassIsNonPublic_Triggers( string part1AccessModifier, string part2AccessModifier) { - var source = $@" -[Xunit.CollectionDefinition(""MyCollection"")] -{part1AccessModifier}partial class CollectionDefinitionClass {{ }} -{part2AccessModifier}partial class CollectionDefinitionClass {{ }}"; - var expected = - Verify - .Diagnostic() - .WithSpan(3, 15 + part1AccessModifier.Length, 3, 40 + part1AccessModifier.Length) - .WithSpan(4, 15 + part2AccessModifier.Length, 4, 40 + part2AccessModifier.Length); + var source = string.Format(/* lang=c#-test */ """ + [Xunit.CollectionDefinition("MyCollection")] + {0}partial class {{|#0:CollectionDefinitionClass|}} {{ }} + {1}partial class {{|#1:CollectionDefinitionClass|}} {{ }} + """, part1AccessModifier, part2AccessModifier); + var expected = Verify.Diagnostic().WithLocation(0).WithLocation(1); await Verify.VerifyAnalyzer(source, expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/ConstructorsOnFactAttributeSubclassShouldBePublicTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/ConstructorsOnFactAttributeSubclassShouldBePublicTests.cs index 378a95c0..76a67055 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/ConstructorsOnFactAttributeSubclassShouldBePublicTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/ConstructorsOnFactAttributeSubclassShouldBePublicTests.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Verify = CSharpVerifier; @@ -8,20 +7,21 @@ public class ConstructorsOnFactAttributeSubclassShouldBePublicTests [Fact] public async Task DefaultConstructor_DoesNotTrigger() { - var source = @" -using System; -using Xunit; + var source = /* lang=c#-test */ """ + using System; + using Xunit; -[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] -internal sealed class CustomFactAttribute : FactAttribute { } + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] + internal sealed class CustomFactAttribute : FactAttribute { } -public class Tests { - [CustomFact] - public void TestCustomFact() { } + public class Tests { + [CustomFact] + public void TestCustomFact() { } - [Fact] - public void TestFact() { } -}"; + [Fact] + public void TestFact() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -29,24 +29,25 @@ public void TestFact() { } [Fact] public async Task ParameterlessPublicConstructor_DoesNotTrigger() { - var source = @" -using System; -using Xunit; - -[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] -internal sealed class CustomFactAttribute : FactAttribute { - public CustomFactAttribute() { - this.Skip = ""xxx""; - } -} - -public class Tests { - [CustomFact] - public void TestCustomFact() { } - - [Fact] - public void TestFact() { } -}"; + var source = /* lang=c#-test */ """ + using System; + using Xunit; + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] + internal sealed class CustomFactAttribute : FactAttribute { + public CustomFactAttribute() { + this.Skip = "xxx"; + } + } + + public class Tests { + [CustomFact] + public void TestCustomFact() { } + + [Fact] + public void TestFact() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -54,24 +55,25 @@ public void TestFact() { } [Fact] public async Task PublicConstructorWithParameters_DoesNotTrigger() { - var source = @" -using System; -using Xunit; - -[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] -internal sealed class CustomFactAttribute : FactAttribute { - public CustomFactAttribute(string skip) { - this.Skip = skip; - } -} - -public class Tests { - [CustomFact(""blah"")] - public void TestCustomFact() { } - - [Fact] - public void TestFact() { } -}"; + var source = /* lang=c#-test */ """ + using System; + using Xunit; + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] + internal sealed class CustomFactAttribute : FactAttribute { + public CustomFactAttribute(string skip) { + this.Skip = skip; + } + } + + public class Tests { + [CustomFact("blah")] + public void TestCustomFact() { } + + [Fact] + public void TestFact() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -79,28 +81,29 @@ public void TestFact() { } [Fact] public async Task PublicConstructorWithOtherConstructors_DoesNotTrigger() { - var source = @" -using System; -using Xunit; - -[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] -internal sealed class CustomFactAttribute : FactAttribute { - public CustomFactAttribute() { - this.Skip = ""xxx""; - } - - internal CustomFactAttribute(string skip) { - this.Skip = skip; - } -} - -public class Tests { - [CustomFact] - public void TestCustomFact() { } - - [Fact] - public void TestFact() { } -}"; + var source = /* lang=c#-test */ """ + using System; + using Xunit; + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] + internal sealed class CustomFactAttribute : FactAttribute { + public CustomFactAttribute() { + this.Skip = "xxx"; + } + + internal CustomFactAttribute(string skip) { + this.Skip = skip; + } + } + + public class Tests { + [CustomFact] + public void TestCustomFact() { } + + [Fact] + public void TestFact() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -108,28 +111,24 @@ public void TestFact() { } [Fact] public async Task InternalConstructor_Triggers() { - var source = @" -using System; -using Xunit; + var source = /* lang=c#-test */ """ + using System; + using Xunit; -[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] -internal sealed class CustomFactAttribute : FactAttribute { - internal CustomFactAttribute(string skip, params int[] values) { } -} + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] + internal sealed class CustomFactAttribute : FactAttribute { + internal CustomFactAttribute(string skip, params int[] values) { } + } -public class Tests { - [CustomFact(""Skip"", 42)] - public void TestCustomFact() { } + public class Tests { + [{|#0:CustomFact("Skip", 42)|}] + public void TestCustomFact() { } - [Fact] - public void TestFact() { } -}"; - var expected = - Verify - .Diagnostic() - .WithSeverity(DiagnosticSeverity.Error) - .WithSpan(11, 6, 11, 28) - .WithArguments("CustomFactAttribute.CustomFactAttribute(string, params int[])"); + [Fact] + public void TestFact() { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("CustomFactAttribute.CustomFactAttribute(string, params int[])"); await Verify.VerifyAnalyzer(source, expected); } @@ -137,30 +136,26 @@ public void TestFact() { } [Fact] public async Task ProtectedInternalConstructor_Triggers() { - var source = @" -using System; -using Xunit; - -[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] -internal sealed class CustomFactAttribute : FactAttribute { - protected internal CustomFactAttribute() { - this.Skip = ""xxx""; - } -} - -public class Tests { - [CustomFact] - public void TestCustomFact() { } - - [Fact] - public void TestFact() { } -}"; - var expected = - Verify - .Diagnostic() - .WithSeverity(DiagnosticSeverity.Error) - .WithSpan(13, 6, 13, 16) - .WithArguments("CustomFactAttribute.CustomFactAttribute()"); + var source = /* lang=c#-test */ """ + using System; + using Xunit; + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] + internal sealed class CustomFactAttribute : FactAttribute { + protected internal CustomFactAttribute() { + this.Skip = "xxx"; + } + } + + public class Tests { + [{|#0:CustomFact|}] + public void TestCustomFact() { } + + [Fact] + public void TestFact() { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("CustomFactAttribute.CustomFactAttribute()"); await Verify.VerifyAnalyzer(source, expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/DataAttributeShouldBeUsedOnATheoryTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/DataAttributeShouldBeUsedOnATheoryTests.cs index 6d49dfbc..c314db68 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/DataAttributeShouldBeUsedOnATheoryTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/DataAttributeShouldBeUsedOnATheoryTests.cs @@ -5,13 +5,14 @@ public class DataAttributeShouldBeUsedOnATheoryTests { [Fact] - public async Task DoesNotFindErrorForFactMethodWithNoDataAttributes() + public async Task FactMethodWithNoDataAttributes_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Fact] - public void TestMethod() { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -20,14 +21,15 @@ public void TestMethod() { } [InlineData("InlineData")] [InlineData("MemberData(\"\")")] [InlineData("ClassData(typeof(string))")] - public async Task DoesNotFindErrorForFactMethodWithDataAttributes(string dataAttribute) + public async Task FactMethodWithDataAttributes_DoesNotTrigger(string dataAttribute) { - var source = $@" -public class TestClass {{ - [Xunit.Fact] - [Xunit.{dataAttribute}] - public void TestMethod() {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Fact] + [Xunit.{0}] + public void TestMethod() {{ }} + }} + """, dataAttribute); await Verify.VerifyAnalyzer(source); } @@ -36,14 +38,15 @@ public void TestMethod() {{ }} [InlineData("InlineData")] [InlineData("MemberData(\"\")")] [InlineData("ClassData(typeof(string))")] - public async Task DoesNotFindErrorForTheoryMethodWithDataAttributes(string dataAttribute) + public async Task TheoryMethodWithDataAttributes_DoesNotTrigger(string dataAttribute) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.{dataAttribute}] - public void TestMethod() {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.{0}] + public void TestMethod() {{ }} + }} + """, dataAttribute); await Verify.VerifyAnalyzer(source); } @@ -52,18 +55,15 @@ public void TestMethod() {{ }} [InlineData("InlineData")] [InlineData("MemberData(\"\")")] [InlineData("ClassData(typeof(string))")] - public async Task FindsErrorForMethodsWithDataAttributesButNotFactOrTheory(string dataAttribute) + public async Task MethodsWithDataAttributesButNotFactOrTheory_Triggers(string dataAttribute) { - var source = $@" -public class TestClass {{ - [Xunit.{dataAttribute}] - public void TestMethod() {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 17, 4, 27); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.{0}] + public void [|TestMethod|]() {{ }} + }} + """, dataAttribute); - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/DoNotUseAsyncVoidForTestMethodsTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/DoNotUseAsyncVoidForTestMethodsTests.cs index c117a595..a325a6f6 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/DoNotUseAsyncVoidForTestMethodsTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/DoNotUseAsyncVoidForTestMethodsTests.cs @@ -7,14 +7,15 @@ public class DoNotUseAsyncVoidForTestMethodsTests [Fact] public async Task NonTestMethod_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; -public class MyClass { - public async void MyMethod() { - await Task.Yield(); - } -}"; + public class MyClass { + public async void MyMethod() { + await Task.Yield(); + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -22,13 +23,14 @@ public async void MyMethod() { [Fact] public async Task NonAsyncTestMethod_DoesNotTrigger() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Fact] - public void TestMethod() { } -}"; + public class TestClass { + [Fact] + public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -36,16 +38,17 @@ public void TestMethod() { } [Fact] public async Task AsyncTaskMethod_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - await Task.Yield(); - } -}"; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + await Task.Yield(); + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -53,43 +56,37 @@ public async Task TestMethod() { [Fact] public async Task AsyncValueTaskMethod_V3_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async ValueTask TestMethod() { - await Task.Yield(); - } -}"; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async ValueTask TestMethod() { + await Task.Yield(); + } + } + """; await Verify.VerifyAnalyzerV3(source); } - [Fact] public async Task AsyncVoidMethod_Triggers() { - var source = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async void TestMethod() { - await Task.Yield(); - } -}"; - - var expectedV2 = - Verify - .Diagnostic("xUnit1048") - .WithSpan(7, 23, 7, 33); - var expectedV3 = - Verify - .Diagnostic("xUnit1049") - .WithSpan(7, 23, 7, 33); + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async void {|#0:TestMethod|}() { + await Task.Yield(); + } + } + """; + var expectedV2 = Verify.Diagnostic("xUnit1048").WithLocation(0); + var expectedV3 = Verify.Diagnostic("xUnit1049").WithLocation(0); await Verify.VerifyAnalyzerV2(source, expectedV2); await Verify.VerifyAnalyzerV3(source, expectedV3); diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/DoNotUseBlockingTaskOperationsTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/DoNotUseBlockingTaskOperationsTests.cs index decb6b9d..276128a6 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/DoNotUseBlockingTaskOperationsTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/DoNotUseBlockingTaskOperationsTests.cs @@ -8,16 +8,17 @@ public class DoNotUseBlockingTaskOperationsTests [Fact] public async Task SuccessCase() { - var source = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - await Task.Delay(1); - } -}"; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + await Task.Delay(1); + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -25,23 +26,24 @@ public async Task TestMethod() { public class IValueTaskSource_NonGeneric { [Fact] - public async Task FailureCase_GetResult() + public async Task GetResult_Triggers() { - var source = @" -using System; -using System.Threading.Tasks.Sources; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - default(IValueTaskSource).[|GetResult(0)|]; - Action _ = vts => vts.GetResult(0); - void LocalFunction() { - default(IValueTaskSource).GetResult(0); - } - } -}"; + var source = /* lang=c#-test */ """ + using System; + using System.Threading.Tasks.Sources; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + default(IValueTaskSource).[|GetResult(0)|]; + Action _ = vts => vts.GetResult(0); + void LocalFunction() { + default(IValueTaskSource).GetResult(0); + } + } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, source); } @@ -50,23 +52,24 @@ void LocalFunction() { public class IValueTaskSource_Generic { [Fact] - public async Task FailureCase_GetResult() + public async Task GetResult_Triggers() { - var source = @" -using System; -using System.Threading.Tasks.Sources; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - default(IValueTaskSource).[|GetResult(0)|]; - Func, int> _ = vts => vts.GetResult(0); - void LocalFunction() { - default(IValueTaskSource).GetResult(0); - } - } -}"; + var source = /* lang=c#-test */ """ + using System; + using System.Threading.Tasks.Sources; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + default(IValueTaskSource).[|GetResult(0)|]; + Func, int> _ = vts => vts.GetResult(0); + void LocalFunction() { + default(IValueTaskSource).GetResult(0); + } + } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, source); } @@ -77,129 +80,135 @@ public class Task_NonGeneric public class Wait { [Fact] - public async Task FailureCase() + public async Task Wait_Triggers() { - var source = @" -using System; -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - Task.Delay(1).[|Wait()|]; - Action _ = t => t.Wait(); - void LocalFunction() { - Task.Delay(1).Wait(); - } - } -}"; + var source = /* lang=c#-test */ """ + using System; + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + Task.Delay(1).[|Wait()|]; + Action _ = t => t.Wait(); + void LocalFunction() { + Task.Delay(1).Wait(); + } + } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, source); } [Fact] - public async Task FailureCase_BeforeWhenAll() + public async Task Wait_BeforeWhenAll_Triggers() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task = Task.Delay(1); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task = Task.Delay(1); - task.[|Wait()|]; + task.[|Wait()|]; - await Task.WhenAll(task); - } -}"; + await Task.WhenAll(task); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FailureCase_WhenAllForOtherTask() + public async Task Wait_ForUnawaitedTask_Triggers() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task1 = Task.Delay(1); - var task2 = Task.Delay(2); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task1 = Task.Delay(1); + var task2 = Task.Delay(2); - await Task.WhenAll(new[] { task1 }); + await Task.WhenAll(new[] { task1 }); - task1.Wait(); - task2.[|Wait()|]; - } -}"; + task1.Wait(); + task2.[|Wait()|]; + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task SuccessCase_InContinueWithLambda() + public async Task Wait_InLambda_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - Task.CompletedTask.ContinueWith(x => x.Wait()); - } -}"; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + Task.CompletedTask.ContinueWith(x => x.Wait()); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task SuccessCase_AfterWhenAll() + public async Task Wait_AfterWhenAll_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task1 = Task.Delay(1); - var task2 = Task.Delay(2); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task1 = Task.Delay(1); + var task2 = Task.Delay(2); - await Task.WhenAll(task1, task2); + await Task.WhenAll(task1, task2); - task1.Wait(); - task2.Wait(); - } -}"; + task1.Wait(); + task2.Wait(); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task SuccessCase_AfterWhenAny() + public async Task Wait_AfterWhenAny_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task1 = Task.Delay(1); - var task2 = Task.Delay(2); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task1 = Task.Delay(1); + var task2 = Task.Delay(2); - var finishedTask = await Task.WhenAny(task1, task2); + var finishedTask = await Task.WhenAny(task1, task2); - finishedTask.Wait(); - } -}"; + finishedTask.Wait(); + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -210,23 +219,24 @@ public class WaitAny_WaitAll [Theory] [InlineData("WaitAny")] [InlineData("WaitAll")] - public async Task FailureCase(string waitMethod) + public async Task WaitMethod_Triggers(string waitMethod) { - var source = @$" -using System; -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - Task.[|{waitMethod}(Task.Delay(1))|]; - Action _ = t => Task.{waitMethod}(t); - void LocalFunction() {{ - Task.{waitMethod}(Task.Delay(1)); - }} - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System; + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + Task.[|{0}(Task.Delay(1))|]; + Action _ = t => Task.{0}(t); + void LocalFunction() {{ + Task.{0}(Task.Delay(1)); + }} + }} + }} + """, waitMethod); await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, source); } @@ -234,22 +244,23 @@ void LocalFunction() {{ [Theory] [InlineData("WaitAny")] [InlineData("WaitAll")] - public async Task FailureCase_BeforeWhenAll(string waitMethod) + public async Task WaitMethod_BeforeWhenAll_Triggers(string waitMethod) { - var source = @$" -using System.Threading.Tasks; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var task = Task.Delay(1); + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var task = Task.Delay(1); - Task.[|{waitMethod}(task)|]; + Task.[|{0}(task)|]; - await Task.WhenAll(task); - }} -}}"; + await Task.WhenAll(task); + }} + }} + """, waitMethod); await Verify.VerifyAnalyzer(source); } @@ -257,25 +268,26 @@ public async Task TestMethod() {{ [Theory] [InlineData("WaitAny")] [InlineData("WaitAll")] - public async Task FailureCase_WhenAllForOtherTask(string waitMethod) + public async Task WaitMethod_ForUnawaitedTask_Triggers(string waitMethod) { - var source = @$" -using System.Threading.Tasks; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var task1 = Task.Delay(1); - var task2 = Task.Delay(2); + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var task1 = Task.Delay(1); + var task2 = Task.Delay(2); - await Task.WhenAll(new[] {{ task1 }}); + await Task.WhenAll(new[] {{ task1 }}); - Task.{waitMethod}(task1); - Task.[|{waitMethod}(task2)|]; - Task.[|{waitMethod}(task1, task2)|]; - }} -}}"; + Task.{0}(task1); + Task.[|{0}(task2)|]; + Task.[|{0}(task1, task2)|]; + }} + }} + """, waitMethod); await Verify.VerifyAnalyzer(source); } @@ -283,18 +295,19 @@ public async Task TestMethod() {{ [Theory] [InlineData("WaitAny")] [InlineData("WaitAll")] - public async Task SuccessCase_InContinueWithLambda(string waitMethod) + public async Task WaitMethod_InLambda_DoesNotTrigger(string waitMethod) { - var source = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - Task.CompletedTask.ContinueWith(x => Task.{waitMethod}(x)); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + Task.CompletedTask.ContinueWith(x => Task.{0}(x)); + }} + }} + """, waitMethod); await Verify.VerifyAnalyzer(source); } @@ -302,25 +315,26 @@ public void TestMethod() {{ [Theory] [InlineData("WaitAny")] [InlineData("WaitAll")] - public async Task SuccessCase_AfterWhenAll(string waitMethod) + public async Task WaitMethod_AfterWhenAll_DoesNotTrigger(string waitMethod) { - var source = @$" -using System.Threading.Tasks; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var task1 = Task.Delay(1); - var task2 = Task.Delay(2); + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var task1 = Task.Delay(1); + var task2 = Task.Delay(2); - await Task.WhenAll(task1, task2); + await Task.WhenAll(task1, task2); - Task.{waitMethod}(task1); - Task.{waitMethod}(task2); - Task.{waitMethod}(task1, task2); - }} -}}"; + Task.{0}(task1); + Task.{0}(task2); + Task.{0}(task1, task2); + }} + }} + """, waitMethod); await Verify.VerifyAnalyzer(source); } @@ -328,23 +342,24 @@ public async Task TestMethod() {{ [Theory] [InlineData("WaitAny")] [InlineData("WaitAll")] - public async Task SuccessCase_AfterWhenAny(string waitMethod) + public async Task WaitMethod_AfterWhenAny_DoesNotTrigger(string waitMethod) { - var source = @$" -using System.Threading.Tasks; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var task1 = Task.Delay(1); - var task2 = Task.Delay(2); + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var task1 = Task.Delay(1); + var task2 = Task.Delay(2); - var finishedTask = await Task.WhenAny(task1, task2); + var finishedTask = await Task.WhenAny(task1, task2); - Task.{waitMethod}(finishedTask); - }} -}}"; + Task.{0}(finishedTask); + }} + }} + """, waitMethod); await Verify.VerifyAnalyzer(source); } @@ -353,129 +368,135 @@ public async Task TestMethod() {{ public class GetAwaiterGetResult { [Fact] - public async Task FailureCase() + public async Task GetResult_Triggers() { - var source = @" -using System; -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - Task.CompletedTask.GetAwaiter().[|GetResult()|]; - Action _ = t => t.GetAwaiter().GetResult(); - void LocalFunction() { - Task.CompletedTask.GetAwaiter().GetResult(); - } - } -}"; + var source = /* lang=c#-test */ """ + using System; + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + Task.CompletedTask.GetAwaiter().[|GetResult()|]; + Action _ = t => t.GetAwaiter().GetResult(); + void LocalFunction() { + Task.CompletedTask.GetAwaiter().GetResult(); + } + } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, source); } [Fact] - public async Task FailureCase_BeforeWhenAll() + public async Task GetResult_BeforeWhenAll_Triggers() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task = Task.Delay(1); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task = Task.Delay(1); - task.GetAwaiter().[|GetResult()|]; + task.GetAwaiter().[|GetResult()|]; - await Task.WhenAll(task); - } -}"; + await Task.WhenAll(task); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FailureCase_WhenAllForOtherTask() + public async Task GetResult_OnUnawaitedTask_Triggers() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task1 = Task.Delay(1); - var task2 = Task.Delay(2); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task1 = Task.Delay(1); + var task2 = Task.Delay(2); - await Task.WhenAll(new[] { task1 }); + await Task.WhenAll(new[] { task1 }); - task1.GetAwaiter().GetResult(); - task2.GetAwaiter().[|GetResult()|]; - } -}"; + task1.GetAwaiter().GetResult(); + task2.GetAwaiter().[|GetResult()|]; + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task SuccessCase_InContinueWithLambda() + public async Task GetResult_InLambda_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - Task.CompletedTask.ContinueWith(x => x.GetAwaiter().GetResult()); - } -}"; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + Task.CompletedTask.ContinueWith(x => x.GetAwaiter().GetResult()); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task SuccessCase_AfterWhenAll() + public async Task GetResult_AfterWhenAll_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task1 = Task.Delay(1); - var task2 = Task.Delay(2); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task1 = Task.Delay(1); + var task2 = Task.Delay(2); - await Task.WhenAll(task1, task2); + await Task.WhenAll(task1, task2); - task1.GetAwaiter().GetResult(); - task2.GetAwaiter().GetResult(); - } -}"; + task1.GetAwaiter().GetResult(); + task2.GetAwaiter().GetResult(); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task SuccessCase_AfterWhenAny() + public async Task GetResult_AfterWhenAny_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task1 = Task.Delay(1); - var task2 = Task.Delay(2); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task1 = Task.Delay(1); + var task2 = Task.Delay(2); - var finishedTask = await Task.WhenAny(task1, task2); + var finishedTask = await Task.WhenAny(task1, task2); - finishedTask.GetAwaiter().GetResult(); - } -}"; + finishedTask.GetAwaiter().GetResult(); + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -487,131 +508,137 @@ public class Task_Generic public class Result { [Fact] - public async Task FailureCase() + public async Task Result_Triggers() { - var source = @" -using System; -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - var _ = Task.FromResult(42).[|Result|]; - Func, int> _2 = t => t.Result; - void LocalFunction() { - var _3 = Task.FromResult(42).Result; - } - } -}"; + var source = /* lang=c#-test */ """ + using System; + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + var _ = Task.FromResult(42).[|Result|]; + Func, int> _2 = t => t.Result; + void LocalFunction() { + var _3 = Task.FromResult(42).Result; + } + } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, source); } [Fact] - public async Task FailureCase_BeforeWhenAll() + public async Task Result_BeforeWhenAll_Triggers() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task = Task.FromResult(42); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task = Task.FromResult(42); - Assert.Equal(42, task.[|Result|]); + Assert.Equal(42, task.[|Result|]); - await Task.WhenAll(task); - } -}"; + await Task.WhenAll(task); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FailureCase_WhenAllForOtherTask() + public async Task Result_ForUnawaitedTask_Triggers() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task1 = Task.FromResult(42); - var task2 = Task.FromResult(2112); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task1 = Task.FromResult(42); + var task2 = Task.FromResult(2112); - await Task.WhenAll(new[] { task1 }); + await Task.WhenAll(new[] { task1 }); - Assert.Equal(42, task1.Result); - Assert.Equal(2112, task2.[|Result|]); - Assert.Equal(2154, task1.Result + task2.[|Result|]); - } -}"; + Assert.Equal(42, task1.Result); + Assert.Equal(2112, task2.[|Result|]); + Assert.Equal(2154, task1.Result + task2.[|Result|]); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task SuccessCase_InContinueWithLambda() + public async Task Result_InLambda_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - var _ = Task.FromResult(42).ContinueWith(x => x.Result); - } -}"; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + var _ = Task.FromResult(42).ContinueWith(x => x.Result); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task SuccessCase_AfterWhenAll() + public async Task Result_AfterWhenAll_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task1 = Task.FromResult(42); - var task2 = Task.FromResult(2112); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task1 = Task.FromResult(42); + var task2 = Task.FromResult(2112); - await Task.WhenAll(task1, task2); + await Task.WhenAll(task1, task2); - Assert.Equal(42, task1.Result); - Assert.Equal(2112, task2.Result); - Assert.Equal(2154, task1.Result + task2.Result); - } -}"; + Assert.Equal(42, task1.Result); + Assert.Equal(2112, task2.Result); + Assert.Equal(2154, task1.Result + task2.Result); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task SuccessCase_AfterWhenAny() + public async Task Result_AfterWhenAny_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task1 = Task.FromResult(42); - var task2 = Task.FromResult(2112); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task1 = Task.FromResult(42); + var task2 = Task.FromResult(2112); - var finishedTask = await Task.WhenAny(task1, task2); + var finishedTask = await Task.WhenAny(task1, task2); - Assert.Equal(2600, finishedTask.Result); - } -}"; + Assert.Equal(2600, finishedTask.Result); + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -620,131 +647,138 @@ public async Task TestMethod() { public class GetAwaiterGetResult { [Fact] - public async Task FailureCase() + public async Task GetResult_Triggers() { - var source = @" -using System; -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - var _ = Task.FromResult(42).GetAwaiter().[|GetResult()|]; - Func, int> _2 = t => t.GetAwaiter().GetResult(); - void LocalFunction() { - var _3 = Task.FromResult(42).GetAwaiter().GetResult(); - } - } -}"; + var source = /* lang=c#-test */ """ + using System; + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + var _ = Task.FromResult(42).GetAwaiter().[|GetResult()|]; + Func, int> _2 = t => t.GetAwaiter().GetResult(); + void LocalFunction() { + var _3 = Task.FromResult(42).GetAwaiter().GetResult(); + } + } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, source); } [Fact] - public async Task FailureCase_BeforeWhenAll() + public async Task GetResult_BeforeWhenAll_Triggers() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ -public class TestClass { - [Fact] - public async Task TestMethod() { - var task = Task.FromResult(42); + using System.Threading.Tasks; + using Xunit; - Assert.Equal(42, task.GetAwaiter().[|GetResult()|]); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task = Task.FromResult(42); - await Task.WhenAll(task); - } -}"; + Assert.Equal(42, task.GetAwaiter().[|GetResult()|]); + + await Task.WhenAll(task); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FailureCase_WhenAllForOtherTask() + public async Task GetResult_OnUnawaitedTask_Triggers() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task1 = Task.FromResult(42); - var task2 = Task.FromResult(2112); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task1 = Task.FromResult(42); + var task2 = Task.FromResult(2112); - await Task.WhenAll(new[] { task1 }); + await Task.WhenAll(new[] { task1 }); - Assert.Equal(42, task1.GetAwaiter().GetResult()); - Assert.Equal(2112, task2.GetAwaiter().[|GetResult()|]); - Assert.Equal(2154, task1.GetAwaiter().GetResult() + task2.GetAwaiter().[|GetResult()|]); - } -}"; + Assert.Equal(42, task1.GetAwaiter().GetResult()); + Assert.Equal(2112, task2.GetAwaiter().[|GetResult()|]); + Assert.Equal(2154, task1.GetAwaiter().GetResult() + task2.GetAwaiter().[|GetResult()|]); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task SuccessCase_InContinueWithLambda() + public async Task GetResult_InLambda_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - var _ = Task.FromResult(42).ContinueWith(x => x.GetAwaiter().GetResult()); - } -}"; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + var _ = Task.FromResult(42).ContinueWith(x => x.GetAwaiter().GetResult()); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task SuccessCase_AfterWhenAll() + public async Task GetResult_AfterWhenAll_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task1 = Task.FromResult(42); - var task2 = Task.FromResult(2112); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task1 = Task.FromResult(42); + var task2 = Task.FromResult(2112); - await Task.WhenAll(task1, task2); + await Task.WhenAll(task1, task2); - Assert.Equal(42, task1.GetAwaiter().GetResult()); - Assert.Equal(2112, task2.GetAwaiter().GetResult()); - Assert.Equal(2154, task1.GetAwaiter().GetResult() + task2.GetAwaiter().GetResult()); - } -}"; + Assert.Equal(42, task1.GetAwaiter().GetResult()); + Assert.Equal(2112, task2.GetAwaiter().GetResult()); + Assert.Equal(2154, task1.GetAwaiter().GetResult() + task2.GetAwaiter().GetResult()); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task SuccessCase_AfterWhenAny() + public async Task GetResult_AfterWhenAny_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class TestClass { - [Fact] - public async Task TestMethod() { - var task1 = Task.FromResult(42); - var task2 = Task.FromResult(2112); + public class TestClass { + [Fact] + public async Task TestMethod() { + var task1 = Task.FromResult(42); + var task2 = Task.FromResult(2112); - var finishedTask = await Task.WhenAny(task1, task2); + var finishedTask = await Task.WhenAny(task1, task2); - Assert.Equal(2600, finishedTask.GetAwaiter().GetResult()); - } -}"; + Assert.Equal(2600, finishedTask.GetAwaiter().GetResult()); + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -754,23 +788,24 @@ public async Task TestMethod() { public class ValueTask_NonGeneric { [Fact] - public async Task FailureCase_GetAwaiterGetResult() + public async Task GetResult_Triggers() { - var source = @" -using System; -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - default(ValueTask).GetAwaiter().[|GetResult()|]; - Action _ = vt => vt.GetAwaiter().GetResult(); - void LocalFunction() { - default(ValueTask).GetAwaiter().GetResult(); - } - } -}"; + var source = /* lang=c#-test */ """ + using System; + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + default(ValueTask).GetAwaiter().[|GetResult()|]; + Action _ = vt => vt.GetAwaiter().GetResult(); + void LocalFunction() { + default(ValueTask).GetAwaiter().GetResult(); + } + } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, source); } @@ -779,45 +814,47 @@ void LocalFunction() { public class ValueTask_Generic { [Fact] - public async Task FailureCase_Result() + public async Task Result_Triggers() { - var source = @" -using System; -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - var _ = new ValueTask(42).[|Result|]; - Func, int> _2 = vt => vt.Result; - void LocalFunction() { - var _3 = new ValueTask(42).Result; - } - } -}"; + var source = /* lang=c#-test */ """ + using System; + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + var _ = new ValueTask(42).[|Result|]; + Func, int> _2 = vt => vt.Result; + void LocalFunction() { + var _3 = new ValueTask(42).Result; + } + } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, source); } [Fact] - public async Task FailureCase_GetAwaiterGetResult() + public async Task GetResult_Triggers() { - var source = @" -using System; -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - var _ = new ValueTask(42).GetAwaiter().[|GetResult()|]; - Func, int> _2 = vt => vt.GetAwaiter().GetResult(); - void LocalFunction() { - var _3 = new ValueTask(42).GetAwaiter().GetResult(); - } - } -}"; + var source = /* lang=c#-test */ """ + using System; + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + var _ = new ValueTask(42).GetAwaiter().[|GetResult()|]; + Func, int> _2 = vt => vt.GetAwaiter().GetResult(); + void LocalFunction() { + var _3 = new ValueTask(42).GetAwaiter().GetResult(); + } + } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/DoNotUseConfigureAwaitTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/DoNotUseConfigureAwaitTests.cs index f2323167..9a55c7d4 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/DoNotUseConfigureAwaitTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/DoNotUseConfigureAwaitTests.cs @@ -8,16 +8,17 @@ public class DoNotUseConfigureAwaitTests [Fact] public async Task NoCall_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - await Task.Delay(1); - } -}"; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + await Task.Delay(1); + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -27,15 +28,16 @@ public class ConfigureAwait_Boolean [Fact] public async Task NonTestMethod_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class NonTestClass { - public async Task NonTestMethod() { - await Task.Delay(1).ConfigureAwait(false); - } -}"; + public class NonTestClass { + public async Task NonTestMethod() { + await Task.Delay(1).ConfigureAwait(false); + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -43,46 +45,48 @@ public async Task NonTestMethod() { [Fact] public async Task True_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - await Task.Delay(1).ConfigureAwait(true); - } -}"; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + await Task.Delay(1).ConfigureAwait(true); + } + } + """; await Verify.VerifyAnalyzer(source); } - public static TheoryData InvalidValues = new() - { + public static TheoryData InvalidValues = + [ "false", // Literal false "1 == 2", // Logical false (we don't compute) "1 == 1", // Logical true (we don't compute) "booleanVar", // Reference value (we don't do lookup) - }; + ]; [Theory] [MemberData(nameof(InvalidValues))] public async Task InvalidValue_InsideLambda_DoesNotTrigger(string argumentValue) { - var source = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - var t = Task.Run(async () => {{ - await Task.Delay(1).ConfigureAwait({argumentValue}); - }}); - await t; - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + var t = Task.Run(async () => {{ + await Task.Delay(1).ConfigureAwait({0}); + }}); + await t; + }} + }} + """, argumentValue); await Verify.VerifyAnalyzer(source); } @@ -91,19 +95,20 @@ public async Task TestMethod() {{ [MemberData(nameof(InvalidValues))] public async Task InvalidValue_InsideLocalFunction_DoesNotTrigger(string argumentValue) { - var source = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - async Task AssertEventStateAsync() {{ - await Task.Delay(1).ConfigureAwait({argumentValue}); - }} - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + async Task AssertEventStateAsync() {{ + await Task.Delay(1).ConfigureAwait({0}); + }} + }} + }} + """, argumentValue); await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, source); } @@ -112,22 +117,19 @@ async Task AssertEventStateAsync() {{ [MemberData(nameof(InvalidValues))] public async Task InvalidValue_TaskWithAwait_Triggers(string argumentValue) { - var source = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - await Task.Delay(1).ConfigureAwait({argumentValue}); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(9, 29, 9, 45 + argumentValue.Length) - .WithArguments(argumentValue, "Omit ConfigureAwait, or use ConfigureAwait(true) to avoid CA2007."); + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + await Task.Delay(1).{{|#0:ConfigureAwait({0})|}}; + }} + }} + """, argumentValue); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(argumentValue, "Omit ConfigureAwait, or use ConfigureAwait(true) to avoid CA2007."); await Verify.VerifyAnalyzer(source, expected); } @@ -136,22 +138,19 @@ public async Task TestMethod() {{ [MemberData(nameof(InvalidValues))] public async Task InvalidValue_TaskWithoutAwait_Triggers(string argumentValue) { - var source = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var booleanVar = true; - Task.Delay(1).ConfigureAwait({argumentValue}).GetAwaiter().GetResult(); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(9, 23, 9, 39 + argumentValue.Length) - .WithArguments(argumentValue, "Omit ConfigureAwait, or use ConfigureAwait(true) to avoid CA2007."); + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var booleanVar = true; + Task.Delay(1).{{|#0:ConfigureAwait({0})|}}.GetAwaiter().GetResult(); + }} + }} + """, argumentValue); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(argumentValue, "Omit ConfigureAwait, or use ConfigureAwait(true) to avoid CA2007."); await Verify.VerifyAnalyzer(source, expected); } @@ -160,23 +159,20 @@ public void TestMethod() {{ [MemberData(nameof(InvalidValues))] public async Task InvalidValue_TaskOfT_Triggers(string argumentValue) { - var source = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - var task = Task.FromResult(42); - await task.ConfigureAwait({argumentValue}); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(10, 20, 10, 36 + argumentValue.Length) - .WithArguments(argumentValue, "Omit ConfigureAwait, or use ConfigureAwait(true) to avoid CA2007."); + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + var task = Task.FromResult(42); + await task.{{|#0:ConfigureAwait({0})|}}; + }} + }} + """, argumentValue); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(argumentValue, "Omit ConfigureAwait, or use ConfigureAwait(true) to avoid CA2007."); await Verify.VerifyAnalyzer(source, expected); } @@ -185,23 +181,20 @@ public async Task TestMethod() {{ [MemberData(nameof(InvalidValues))] public async Task InvalidValue_ValueTask_Triggers(string argumentValue) { - var source = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - var valueTask = default(ValueTask); - await valueTask.ConfigureAwait({argumentValue}); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(10, 25, 10, 41 + argumentValue.Length) - .WithArguments(argumentValue, "Omit ConfigureAwait, or use ConfigureAwait(true) to avoid CA2007."); + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + var valueTask = default(ValueTask); + await valueTask.{{|#0:ConfigureAwait({0})|}}; + }} + }} + """, argumentValue); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(argumentValue, "Omit ConfigureAwait, or use ConfigureAwait(true) to avoid CA2007."); await Verify.VerifyAnalyzer(source, expected); } @@ -210,23 +203,20 @@ public async Task TestMethod() {{ [MemberData(nameof(InvalidValues))] public async Task InvalidValue_ValueTaskOfT_Triggers(string argumentValue) { - var source = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - var valueTask = default(ValueTask); - await valueTask.ConfigureAwait({argumentValue}); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(10, 25, 10, 41 + argumentValue.Length) - .WithArguments(argumentValue, "Omit ConfigureAwait, or use ConfigureAwait(true) to avoid CA2007."); + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + var valueTask = default(ValueTask); + await valueTask.{{|#0:ConfigureAwait({0})|}}; + }} + }} + """, argumentValue); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(argumentValue, "Omit ConfigureAwait, or use ConfigureAwait(true) to avoid CA2007."); await Verify.VerifyAnalyzer(source, expected); } @@ -239,15 +229,16 @@ public class ConfigureAwait_ConfigureAwaitOptions [Fact] public async Task NonTestMethod_DoesNotTrigger() { - var source = @" -using System.Threading.Tasks; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -public class NonTestClass { - public async Task NonTestMethod() { - await Task.Delay(1).ConfigureAwait(ConfigureAwaitOptions.None); - } -}"; + public class NonTestClass { + public async Task NonTestMethod() { + await Task.Delay(1).ConfigureAwait(ConfigureAwaitOptions.None); + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -258,48 +249,50 @@ public async Task NonTestMethod() { [InlineData("ConfigureAwaitOptions.ForceYielding | ConfigureAwaitOptions.SuppressThrowing | ConfigureAwaitOptions.ContinueOnCapturedContext")] public async Task ValidValue_DoesNotTrigger(string enumValue) { - var source = $@" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - await Task.Delay(1).ConfigureAwait({enumValue}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + await Task.Delay(1).ConfigureAwait({0}); + }} + }} + """, enumValue); await Verify.VerifyAnalyzer(source); } - public static TheoryData InvalidValues = new() - { + public static TheoryData InvalidValues = + [ // Literal values "ConfigureAwaitOptions.None", "ConfigureAwaitOptions.SuppressThrowing", "ConfigureAwaitOptions.ForceYielding | ConfigureAwaitOptions.SuppressThrowing", // Reference values (we don't do lookup) "enumVar", - }; + ]; [Theory] [MemberData(nameof(InvalidValues))] public async Task InvalidValue_InsideLambda_DoesNotTrigger(string argumentValue) { - var source = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; - var t = Task.Run(async () => {{ - await Task.Delay(1).ConfigureAwait({argumentValue}); - }}); - await t; - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; + var t = Task.Run(async () => {{ + await Task.Delay(1).ConfigureAwait({0}); + }}); + await t; + }} + }} + """, argumentValue); await Verify.VerifyAnalyzer(source); } @@ -308,19 +301,20 @@ public async Task TestMethod() {{ [MemberData(nameof(InvalidValues))] public async Task InvalidValue_InsideLocalFunction_DoesNotTrigger(string argumentValue) { - var source = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; - async Task AssertEventStateAsync() {{ - await Task.Delay(1).ConfigureAwait({argumentValue}); - }} - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; + async Task AssertEventStateAsync() {{ + await Task.Delay(1).ConfigureAwait({0}); + }} + }} + }} + """, argumentValue); await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, source); } @@ -329,22 +323,19 @@ async Task AssertEventStateAsync() {{ [MemberData(nameof(InvalidValues))] public async Task InvalidValue_TaskWithAwait_Triggers(string enumValue) { - var source = $@" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; - await Task.Delay(1).ConfigureAwait({enumValue}); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(9, 29, 9, 45 + enumValue.Length) - .WithArguments(enumValue, "Ensure ConfigureAwaitOptions.ContinueOnCapturedContext in the flags."); + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; + await Task.Delay(1).{{|#0:ConfigureAwait({0})|}}; + }} + }} + """, enumValue); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(enumValue, "Ensure ConfigureAwaitOptions.ContinueOnCapturedContext in the flags."); await Verify.VerifyAnalyzer(source, expected); } @@ -353,22 +344,19 @@ public async Task TestMethod() {{ [MemberData(nameof(InvalidValues))] public async Task InvalidValue_TaskWithoutAwait_Triggers(string argumentValue) { - var source = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; - Task.Delay(1).ConfigureAwait({argumentValue}).GetAwaiter().GetResult(); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(9, 23, 9, 39 + argumentValue.Length) - .WithArguments(argumentValue, "Ensure ConfigureAwaitOptions.ContinueOnCapturedContext in the flags."); + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; + Task.Delay(1).{{|#0:ConfigureAwait({0})|}}.GetAwaiter().GetResult(); + }} + }} + """, argumentValue); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(argumentValue, "Ensure ConfigureAwaitOptions.ContinueOnCapturedContext in the flags."); await Verify.VerifyAnalyzer(source, expected); } @@ -377,23 +365,20 @@ public void TestMethod() {{ [MemberData(nameof(InvalidValues))] public async Task InvalidValue_TaskOfT_Triggers(string argumentValue) { - var source = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; - var task = Task.FromResult(42); - await task.ConfigureAwait({argumentValue}); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(10, 20, 10, 36 + argumentValue.Length) - .WithArguments(argumentValue, "Ensure ConfigureAwaitOptions.ContinueOnCapturedContext in the flags."); + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; + var task = Task.FromResult(42); + await task.{{|#0:ConfigureAwait({0})|}}; + }} + }} + """, argumentValue); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(argumentValue, "Ensure ConfigureAwaitOptions.ContinueOnCapturedContext in the flags."); await Verify.VerifyAnalyzer(source, expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/EnsureFixturesHaveASourceTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/EnsureFixturesHaveASourceTests.cs index 1b330201..ba1cb0c4 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/EnsureFixturesHaveASourceTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/EnsureFixturesHaveASourceTests.cs @@ -9,10 +9,11 @@ public class NonTestClass [Fact] public async Task DoesNotTrigger() { - var source = @" -public class NonTestClass { - public NonTestClass(object _) { } -}"; + var source = /* lang=c#-test */ """ + public class NonTestClass { + public NonTestClass(object _) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -23,17 +24,18 @@ public class SupportedNonFixtureData [Theory] [InlineData("")] [InlineData("[Collection(\"TestCollection\")]")] - public async Task V2SupportedTypes(string attribute) + public async Task SupportedTypes_V2_DoesNotTrigger(string attribute) { - var source = $@" -using Xunit; -using Xunit.Abstractions; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; + using Xunit.Abstractions; -{attribute} public class TestClass {{ - public TestClass(ITestOutputHelper _) {{ }} + {0} public class TestClass {{ + public TestClass(ITestOutputHelper _) {{ }} - [Fact] public void TestMethod() {{ }} -}}"; + [Fact] public void TestMethod() {{ }} + }} + """, attribute); await Verify.VerifyAnalyzerV2(source); } @@ -41,18 +43,18 @@ [Fact] public void TestMethod() {{ }} [Theory] [InlineData("")] [InlineData("[Collection(\"TestCollection\")]")] - public async Task V3SupportedTypes(string attribute) + public async Task SupportedTypes_V3_DoesNotTrigger(string attribute) { - // TODO: This will need to be updated when v3 names are finalized - var source = $@" -using Xunit; -using Xunit.v3; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; + using Xunit.v3; -{attribute} public class TestClass {{ - public TestClass(ITestOutputHelper _1, ITestContextAccessor _2) {{ }} + {0} public class TestClass {{ + public TestClass(ITestOutputHelper _1, ITestContextAccessor _2) {{ }} - [Fact] public void TestMethod() {{ }} -}}"; + [Fact] public void TestMethod() {{ }} + }} + """, attribute); await Verify.VerifyAnalyzerV3(source); } @@ -60,14 +62,15 @@ [Fact] public void TestMethod() {{ }} [Fact] public async Task OptionalParameter_DoesNotTrigger() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - public TestClass(bool value = true) { } + public class TestClass { + public TestClass(bool value = true) { } - [Fact] public void TestMethod() { } -}"; + [Fact] public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -92,25 +95,25 @@ public class ClassFixtures [InlineData( "[Collection(\"TestCollection\")]", "", "", ", IClassFixture")] - public async Task SupportsDerivation( + public async Task BaseClassParameter_DerivedClassFixture_DoesNotTrigger( string baseAttribute, string baseInterface, string derivedAttribute, string derivedInterface) { - var source = @$" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -{baseAttribute} -public abstract class BaseClass {baseInterface} {{ -}} + {0} + public abstract class BaseClass {1} {{ }} -{derivedAttribute} -public class TestClass : BaseClass {derivedInterface} {{ - public TestClass(object _) {{ }} + {2} + public class TestClass : BaseClass {3} {{ + public TestClass(object _) {{ }} - [Fact] public void TestMethod() {{ }} -}}"; + [Fact] public void TestMethod() {{ }} + }} + """, baseAttribute, baseInterface, derivedAttribute, derivedInterface); await Verify.VerifyAnalyzer(source); } @@ -118,18 +121,19 @@ [Fact] public void TestMethod() {{ }} [Fact] public async Task ClassFixtureOnCollectionDefinition_DoesNotTrigger() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -[CollectionDefinition(nameof(TestCollection))] -public class TestCollection : IClassFixture { } + [CollectionDefinition(nameof(TestCollection))] + public class TestCollection : IClassFixture { } -[Collection(nameof(TestCollection))] -public class TestClass { - public TestClass(object _) { } + [Collection(nameof(TestCollection))] + public class TestClass { + public TestClass(object _) { } - [Fact] public void TestMethod() { } -}"; + [Fact] public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -137,21 +141,17 @@ [Fact] public void TestMethod() { } [Fact] public async Task MissingClassFixtureDefinition_Triggers() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - public TestClass(object _) { } + public class TestClass { + public TestClass(object [|_|]) { } - [Fact] public void TestMethod() { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 29, 5, 30) - .WithArguments("_"); + [Fact] public void TestMethod() { } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } @@ -162,16 +162,17 @@ public class CollectionFixtures [InlineData("[CollectionDefinition(nameof(TestCollection))]")] public async Task NoFixture_DoesNotTrigger(string definitionAttribute) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -{definitionAttribute} -public class TestCollection {{ }} + {0} + public class TestCollection {{ }} -[Collection(nameof(TestCollection))] -public class TestClass {{ - [Fact] public void TestMethod() {{ }} -}}"; + [Collection(nameof(TestCollection))] + public class TestClass {{ + [Fact] public void TestMethod() {{ }} + }} + """, definitionAttribute); await Verify.VerifyAnalyzer(source); } @@ -179,25 +180,26 @@ [Fact] public void TestMethod() {{ }} [Fact] public async Task WithInheritedFixture_DoesNotTrigger() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class Fixture { } + public class Fixture { } -[CollectionDefinition(""test"")] -public class TestCollection : ICollectionFixture { } + [CollectionDefinition("test")] + public class TestCollection : ICollectionFixture { } -public abstract class TestContext { - protected TestContext(Fixture fixture) { } -} + public abstract class TestContext { + protected TestContext(Fixture fixture) { } + } -[Collection(""test"")] -public class TestClass : TestContext { - public TestClass(Fixture fixture) : base(fixture) { } + [Collection("test")] + public class TestClass : TestContext { + public TestClass(Fixture fixture) : base(fixture) { } - [Fact] - public void TestMethod() { } -}"; + [Fact] + public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -205,27 +207,23 @@ public void TestMethod() { } [Fact] public async Task WithGenericFixture_TriggersWithV2_DoesNotTriggerWithV3() { - var source = @" -using Xunit; - -public class Fixture { } + var source = /* lang=c#-test */ """ + using Xunit; -[CollectionDefinition(""test"")] -public class TestCollection : ICollectionFixture> { } + public class Fixture { } -[Collection(""test"")] -public class TestClass { - public TestClass(Fixture fixture) { } + [CollectionDefinition("test")] + public class TestCollection : ICollectionFixture> { } - [Fact] - public void TestMethod() { } -}"; + [Collection("test")] + public class TestClass { + public TestClass(Fixture {|#0:fixture|}) { } - var expectedV2 = - Verify - .Diagnostic() - .WithSpan(11, 35, 11, 42) - .WithArguments("fixture"); + [Fact] + public void TestMethod() { } + } + """; + var expectedV2 = Verify.Diagnostic().WithLocation(0).WithArguments("fixture"); await Verify.VerifyAnalyzerV2(source, expectedV2); await Verify.VerifyAnalyzerV3(source); @@ -234,31 +232,27 @@ public void TestMethod() { } [Fact] public async Task WithInheritedGenericFixture_TriggersWithV2_DoesNotTriggerWithV3() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class Fixture { } + public class Fixture { } -[CollectionDefinition(""test"")] -public class TestCollection : ICollectionFixture> { } + [CollectionDefinition("test")] + public class TestCollection : ICollectionFixture> { } -[Collection(""test"")] -public abstract class TestContext { - protected TestContext(Fixture fixture) { } -} - -public class TestClass : TestContext { - public TestClass(Fixture fixture) : base(fixture) { } + [Collection("test")] + public abstract class TestContext { + protected TestContext(Fixture fixture) { } + } - [Fact] - public void TestMethod() { } -}"; + public class TestClass : TestContext { + public TestClass(Fixture {|#0:fixture|}) : base(fixture) { } - var expectedV2 = - Verify - .Diagnostic() - .WithSpan(15, 35, 15, 42) - .WithArguments("fixture"); + [Fact] + public void TestMethod() { } + } + """; + var expectedV2 = Verify.Diagnostic().WithLocation(0).WithArguments("fixture"); await Verify.VerifyAnalyzerV2(source, expectedV2); await Verify.VerifyAnalyzerV3(source); @@ -271,20 +265,20 @@ public async Task WithFixture_SupportsDerivation( string baseAttribute, string derivedAttribute) { - var source = @$" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -[CollectionDefinition(nameof(TestCollection))] -public class TestCollection : ICollectionFixture {{ }} + [CollectionDefinition(nameof(TestCollection))] + public class TestCollection : ICollectionFixture {{ }} -{baseAttribute} -public abstract class BaseClass {{ -}} + {0} + public abstract class BaseClass {{ }} -{derivedAttribute} -public class TestClass : BaseClass {{ - public TestClass(object _) {{ }} -}}"; + {1} + public class TestClass : BaseClass {{ + public TestClass(object _) {{ }} + }} + """, baseAttribute, derivedAttribute); await Verify.VerifyAnalyzer(source); } @@ -292,18 +286,19 @@ public TestClass(object _) {{ }} [Fact] public async Task WithFixture_WithDefinition_DoesNotTrigger() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -[CollectionDefinition(nameof(TestCollection))] -public class TestCollection : ICollectionFixture { } + [CollectionDefinition(nameof(TestCollection))] + public class TestCollection : ICollectionFixture { } -[Collection(nameof(TestCollection))] -public class TestClass { - public TestClass(object _) { } + [Collection(nameof(TestCollection))] + public class TestClass { + public TestClass(object _) { } - [Fact] public void TestMethod() { } -}"; + [Fact] public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -313,25 +308,21 @@ [Fact] public void TestMethod() { } [InlineData("[CollectionDefinition(nameof(TestCollection))]")] public async Task WithFixture_WithoutCollectionFixtureInterface_Triggers(string definitionAttribute) { - var source = @$" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -{definitionAttribute} -public class TestCollection {{ }} + {0} + public class TestCollection {{ }} -[Collection(nameof(TestCollection))] -public class TestClass {{ - public TestClass(object _) {{ }} + [Collection(nameof(TestCollection))] + public class TestClass {{ + public TestClass(object [|_|]) {{ }} - [Fact] public void TestMethod() {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(9, 29, 9, 30) - .WithArguments("_"); + [Fact] public void TestMethod() {{ }} + }} + """, definitionAttribute); - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } @@ -340,16 +331,17 @@ public class AssemblyFixtures [Fact] public async Task WithAssemblyFixture_DoesNotTrigger() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -[assembly: AssemblyFixture(typeof(object))] + [assembly: AssemblyFixture(typeof(object))] -public class TestClass { - public TestClass(object _) { } + public class TestClass { + public TestClass(object _) { } - [Fact] public void TestMethod() { } -}"; + [Fact] public void TestMethod() { } + } + """; await Verify.VerifyAnalyzerV3(source); } @@ -362,18 +354,19 @@ public class MixedFixtures [InlineData("[CollectionDefinition(nameof(TestCollection))]")] public async Task WithClassFixture_WithCollection_DoesNotTrigger(string definitionAttribute) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -{definitionAttribute} -public class TestCollection {{ }} + {0} + public class TestCollection {{ }} -[Collection(nameof(TestCollection))] -public class TestClass : IClassFixture {{ - public TestClass(object _) {{ }} + [Collection(nameof(TestCollection))] + public class TestClass : IClassFixture {{ + public TestClass(object _) {{ }} - [Fact] public void TestMethod() {{ }} -}}"; + [Fact] public void TestMethod() {{ }} + }} + """, definitionAttribute); await Verify.VerifyAnalyzer(source); } @@ -381,78 +374,71 @@ [Fact] public void TestMethod() {{ }} [Fact] public async Task WithMixedClassAndCollectionFixture_AndSupportedNonFixture_DoesNotTrigger() { - var source = @" -using Xunit; + var sourceTemplate = /* lang=c#-test */ """ + using Xunit; -public class ClassFixture {{ }} -public class CollectionFixture {{ }} + public class ClassFixture {{ }} + public class CollectionFixture {{ }} -[CollectionDefinition(nameof(TestCollection))] -public class TestCollection : ICollectionFixture {{ }} + [CollectionDefinition(nameof(TestCollection))] + public class TestCollection : ICollectionFixture {{ }} -[Collection(nameof(TestCollection))] -public class TestClass : IClassFixture {{ - public TestClass(ClassFixture _1, CollectionFixture _2, {0} _3) {{ }} + [Collection(nameof(TestCollection))] + public class TestClass : IClassFixture {{ + public TestClass(ClassFixture _1, CollectionFixture _2, {0} _3) {{ }} - [Fact] public void TestMethod() {{ }} -}}"; + [Fact] public void TestMethod() {{ }} + }} + """; - await Verify.VerifyAnalyzerV2(string.Format(source, "Xunit.Abstractions.ITestOutputHelper")); - await Verify.VerifyAnalyzerV3(string.Format(source, "Xunit.ITestContextAccessor")); + await Verify.VerifyAnalyzerV2(string.Format(sourceTemplate, "Xunit.Abstractions.ITestOutputHelper")); + await Verify.VerifyAnalyzerV3(string.Format(sourceTemplate, "Xunit.ITestContextAccessor")); } [Fact] public async Task MissingClassFixture_Triggers() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class ClassFixture { } -public class CollectionFixture { } + public class ClassFixture { } + public class CollectionFixture { } -[CollectionDefinition(nameof(TestCollection))] -public class TestCollection : ICollectionFixture { } + [CollectionDefinition(nameof(TestCollection))] + public class TestCollection : ICollectionFixture { } -[Collection(nameof(TestCollection))] -public class TestClass { - public TestClass(ClassFixture _1, CollectionFixture _2) { } + [Collection(nameof(TestCollection))] + public class TestClass { + public TestClass(ClassFixture [|_1|], CollectionFixture _2) { } - [Fact] public void TestMethod() { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(12, 35, 12, 37) - .WithArguments("_1"); + [Fact] public void TestMethod() { } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } [Fact] public async Task MissingCollectionFixture_Triggers() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class ClassFixture { } -public class CollectionFixture { } + public class ClassFixture { } + public class CollectionFixture { } -[CollectionDefinition(nameof(TestCollection))] -public class TestCollection { } + [CollectionDefinition(nameof(TestCollection))] + public class TestCollection { } -[Collection(nameof(TestCollection))] -public class TestClass : IClassFixture { - public TestClass(ClassFixture _1, CollectionFixture _2) { } + [Collection(nameof(TestCollection))] + public class TestClass : IClassFixture { + public TestClass(ClassFixture _1, CollectionFixture [|_2|]) { } - [Fact] public void TestMethod() { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(12, 57, 12, 59) - .WithArguments("_2"); + [Fact] public void TestMethod() { } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/FactMethodMustNotHaveParametersTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/FactMethodMustNotHaveParametersTests.cs index 15c5d65f..4e64e254 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/FactMethodMustNotHaveParametersTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/FactMethodMustNotHaveParametersTests.cs @@ -5,42 +5,41 @@ public class FactMethodMustNotHaveParametersTests { [Fact] - public async Task DoesNotFindErrorForFactWithNoParameters() + public async Task FactWithNoParameters_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Fact] - public void TestMethod() { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindErrorForTheoryWithParameters() + public async Task TheoryWithParameters_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Theory] - public void TestMethod(string p) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + public void TestMethod(string p) { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FindsErrorForFactWithParameter() + public async Task FactWithParameters_Triggers() { - var source = @" -public class TestClass { - [Xunit.Fact] - public void TestMethod(string p) { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 17, 4, 27); + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + public void [|TestMethod|](string p) { } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/FactMethodShouldNotHaveTestDataTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/FactMethodShouldNotHaveTestDataTests.cs index c87d3cb1..41f41d5a 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/FactMethodShouldNotHaveTestDataTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/FactMethodShouldNotHaveTestDataTests.cs @@ -5,13 +5,14 @@ public class FactMethodShouldNotHaveTestDataTests { [Fact] - public async Task DoesNotFindErrorForFactMethodWithNoDataAttributes() + public async Task FactWithNoDataAttributes_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Fact] - public void TestMethod() { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -20,14 +21,15 @@ public void TestMethod() { } [InlineData("InlineData")] [InlineData("MemberData(\"\")")] [InlineData("ClassData(typeof(string))")] - public async Task DoesNotFindErrorForTheoryMethodWithDataAttributes(string dataAttribute) + public async Task TheoryWithDataAttributes_DoesNotTrigger(string dataAttribute) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.{dataAttribute}] - public void TestMethod() {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.{0}] + public void TestMethod() {{ }} + }} + """, dataAttribute); await Verify.VerifyAnalyzer(source); } @@ -36,36 +38,34 @@ public void TestMethod() {{ }} [InlineData("InlineData")] [InlineData("MemberData(\"\")")] [InlineData("ClassData(typeof(string))")] - public async Task DoesNotFindErrorForDerivedFactMethodWithDataAttributes(string dataAttribute) + public async Task FactDerivedMethodWithDataAttributes_DoesNotTrigger(string dataAttribute) { - var source1 = "public class DerivedFactAttribute: Xunit.FactAttribute {}"; - var source2 = $@" -public class TestClass {{ - [DerivedFactAttribute] - [Xunit.{dataAttribute}] - public void TestMethod() {{ }} -}}"; + var source1 = /* lang=c#-test */ "public class DerivedFactAttribute: Xunit.FactAttribute {}"; + var source2 = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [DerivedFactAttribute] + [Xunit.{0}] + public void TestMethod() {{ }} + }} + """, dataAttribute); - await Verify.VerifyAnalyzer(new[] { source1, source2 }); + await Verify.VerifyAnalyzer([source1, source2]); } [Theory] [InlineData("InlineData")] [InlineData("MemberData(\"\")")] [InlineData("ClassData(typeof(string))")] - public async Task FindsErrorForFactMethodsWithDataAttributes(string dataAttribute) + public async Task FactWithDataAttributes_Triggers(string dataAttribute) { - var source = $@" -public class TestClass {{ - [Xunit.Fact] - [Xunit.{dataAttribute}] - public void TestMethod() {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 17, 5, 27); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Fact] + [Xunit.{0}] + public void [|TestMethod|]() {{ }} + }} + """, dataAttribute); - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/InlineDataMustMatchTheoryParametersTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/InlineDataMustMatchTheoryParametersTests.cs index ce73a8a5..bc3d0c86 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/InlineDataMustMatchTheoryParametersTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/InlineDataMustMatchTheoryParametersTests.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Testing; using Xunit; using Xunit.Analyzers; using Verify = CSharpVerifier; @@ -17,12 +16,13 @@ public class NonErrors [Fact] public async Task MethodUsingParamsArgument() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(""abc"", ""xyz"")] - public void TestMethod(params string[] args) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData("abc", "xyz")] + public void TestMethod(params string[] args) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -30,12 +30,13 @@ public void TestMethod(params string[] args) { } [Fact] public async Task MethodUsingNullParamsArgument_NonNullable() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(null)] - public void TestMethod(params string[] args) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(null)] + public void TestMethod(params string[] args) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -43,14 +44,15 @@ public void TestMethod(params string[] args) { } [Fact] public async Task MethodUsingNullParamsArgument_Nullable() { - var source = @" -#nullable enable + var source = /* lang=c#-test */ """ + #nullable enable -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(null)] - public void TestMethod(params string[]? args) { } -}"; + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(null)] + public void TestMethod(params string[]? args) { } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp9, source); } @@ -58,12 +60,13 @@ public void TestMethod(params string[]? args) { } [Fact] public async Task MethodUsingNormalAndParamsArgument() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(""abc"", ""xyz"")] - public void TestMethod(string first, params string[] args) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData("abc", "xyz")] + public void TestMethod(string first, params string[] args) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -71,12 +74,13 @@ public void TestMethod(string first, params string[] args) { } [Fact] public async Task MethodUsingNormalAndNullParamsArgument_NonNullable() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(""abc"", null)] - public void TestMethod(string first, params string[] args) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData("abc", null)] + public void TestMethod(string first, params string[] args) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -84,14 +88,15 @@ public void TestMethod(string first, params string[] args) { } [Fact] public async Task MethodUsingNormalAndNullParamsArgument_Nullable() { - var source = @" -#nullable enable + var source = /* lang=c#-test */ """ + #nullable enable -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(""abc"", null)] - public void TestMethod(string first, params string[]? args) { } -}"; + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData("abc", null)] + public void TestMethod(string first, params string[]? args) { } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp9, source); } @@ -99,12 +104,13 @@ public void TestMethod(string first, params string[]? args) { } [Fact] public async Task MethodUsingNormalAndUnusedParamsArgument() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(""abc"")] - public void TestMethod(string first, params string[] args) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData("abc")] + public void TestMethod(string first, params string[] args) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -112,12 +118,13 @@ public void TestMethod(string first, params string[] args) { } [Fact] public async Task MethodUsingEmptyArrayForParams() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(new int[] { })] - public void VariableArgumentsTest(params int[] sq) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(new int[] { })] + public void VariableArgumentsTest(params int[] sq) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -125,12 +132,13 @@ public void VariableArgumentsTest(params int[] sq) { } [Fact] public async Task MethodUsingMixedArgumentsAndEmptyArrayForParams() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(21.12, new int[] { })] - public void VariableArgumentsTest(double d, params int[] sq) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(21.12, new int[] { })] + public void VariableArgumentsTest(double d, params int[] sq) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -138,12 +146,13 @@ public void VariableArgumentsTest(double d, params int[] sq) { } [Fact] public async Task MethodUsingNonEmptyArrayForParams() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(new int[] { 1, 2, 3 })] - public void VariableArgumentsTest(params int[] sq) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(new int[] { 1, 2, 3 })] + public void VariableArgumentsTest(params int[] sq) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -151,25 +160,13 @@ public void VariableArgumentsTest(params int[] sq) { } [Fact] public async Task MethodUsingMixedArgumentsAndNonEmptyArrayForParams() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(21.12, new int[] { 1, 2, 3 })] - public void VariableArgumentsTest(double d, params int[] sq) { } -}"; - - await Verify.VerifyAnalyzer(source); - } - - [Fact] - public async Task MethodUsingIncompatibleExplicitArrayForParams() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(21.12, {|xUnit1010:new object[] { }|})] - public void VariableArgumentsTest(double d, params int[] sq) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(21.12, new int[] { 1, 2, 3 })] + public void VariableArgumentsTest(double d, params int[] sq) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -177,12 +174,13 @@ public void VariableArgumentsTest(double d, params int[] sq) { } [Fact] public async Task UsingParameters() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(""abc"", 1, null)] - public void TestMethod(string a, int b, object c) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData("abc", 1, null)] + public void TestMethod(string a, int b, object c) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -190,12 +188,13 @@ public void TestMethod(string a, int b, object c) { } [Fact] public async Task UsingParametersWithDefaultValues() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(""abc"")] - public void TestMethod(string a, string b = ""default"", string c = null) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData("abc")] + public void TestMethod(string a, string b = "default", string c = null) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -203,12 +202,13 @@ public void TestMethod(string a, string b = ""default"", string c = null) { } [Fact] public async Task UsingParametersWithDefaultValuesAndParamsArgument() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(""abc"")] - public void TestMethod(string a, string b = ""default"", string c = null, params string[] d) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData("abc")] + public void TestMethod(string a, string b = "default", string c = null, params string[] d) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -216,12 +216,13 @@ public void TestMethod(string a, string b = ""default"", string c = null, params [Fact] public async Task UsingParameterWithOptionalAttribute() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(""abc"")] - public void TestMethod(string a, [System.Runtime.InteropServices.Optional] string b) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData("abc")] + public void TestMethod(string a, [System.Runtime.InteropServices.Optional] string b) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -229,15 +230,16 @@ public void TestMethod(string a, [System.Runtime.InteropServices.Optional] strin [Fact] public async Task UsingMultipleParametersWithOptionalAttributes() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData] - [Xunit.InlineData(""abc"")] - [Xunit.InlineData(""abc"", ""def"")] - public void TestMethod([System.Runtime.InteropServices.Optional] string a, - [System.Runtime.InteropServices.Optional] string b) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData] + [Xunit.InlineData("abc")] + [Xunit.InlineData("abc", "def")] + public void TestMethod([System.Runtime.InteropServices.Optional] string a, + [System.Runtime.InteropServices.Optional] string b) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -245,12 +247,13 @@ public void TestMethod([System.Runtime.InteropServices.Optional] string a, [Fact] public async Task UsingExplicitArray() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(new object[] { ""abc"", 1, null })] - public void TestMethod(string a, int b, object c) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(new object[] { "abc", 1, null })] + public void TestMethod(string a, int b, object c) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -258,12 +261,13 @@ public void TestMethod(string a, int b, object c) { } [Fact] public async Task UsingExplicitNamedArray() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(data: new object[] { ""abc"", 1, null })] - public void TestMethod(string a, int b, object c) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(data: new object[] { "abc", 1, null })] + public void TestMethod(string a, int b, object c) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -271,12 +275,13 @@ public void TestMethod(string a, int b, object c) { } [Fact] public async Task UsingImplicitArray() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(new[] { (object)""abc"", 1, null })] - public void TestMethod(string a, int b, object c) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(new[] { (object)"abc", 1, null })] + public void TestMethod(string a, int b, object c) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -284,12 +289,13 @@ public void TestMethod(string a, int b, object c) { } [Fact] public async Task UsingImplicitNamedArray() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(data: new[] { (object)""abc"", 1, null })] - public void TestMethod(string a, int b, object c) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(data: new[] { (object)"abc", 1, null })] + public void TestMethod(string a, int b, object c) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -297,12 +303,13 @@ public void TestMethod(string a, int b, object c) { } [Fact] public async Task EmptyArray() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(new byte[0])] - public void TestMethod(byte[] input) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(new byte[0])] + public void TestMethod(byte[] input) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -313,12 +320,13 @@ public class X1009_TooFewValues [Fact] public async Task IgnoresFact() { - var source = @" -public class TestClass { - [Xunit.Fact] - [Xunit.InlineData] - public void TestMethod(string a) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + [Xunit.InlineData] + public void TestMethod(string a) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -328,64 +336,66 @@ public void TestMethod(string a) { } [InlineData("Xunit.InlineData")] public async Task NoArguments(string attribute) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [{attribute}] - public void TestMethod(int a) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1009") - .WithSpan(4, 6, 4, 6 + attribute.Length) - .WithSeverity(DiagnosticSeverity.Error); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [{{|xUnit1009:{0}|}}] + public void TestMethod(int a) {{ }} + }} + """, attribute); - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } [Fact] public async Task TooFewArguments() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(1)] - public void TestMethod(int a, int b, string c) { } -}"; - var expected = - Verify - .Diagnostic("xUnit1009") - .WithSpan(4, 6, 4, 25) - .WithSeverity(DiagnosticSeverity.Error); + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [{|xUnit1009:Xunit.InlineData(1)|}] + public void TestMethod(int a, int b, string c) { } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } [Fact] public async Task TooFewArguments_WithParams() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(1)] - public void TestMethod(int a, int b, params string[] value) { } -}"; - var expected = - Verify - .Diagnostic("xUnit1009") - .WithSpan(4, 6, 4, 25) - .WithSeverity(DiagnosticSeverity.Error); + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [{|xUnit1009:Xunit.InlineData(1)|}] + public void TestMethod(int a, int b, params string[] value) { } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } public class X1010_IncompatibleValueType { + [Fact] + public async Task MethodUsingIncompatibleExplicitArrayForParams() + { + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(21.12, {|xUnit1010:new object[] { }|})] + public void VariableArgumentsTest(double d, params int[] sq) { } + } + """; + + await Verify.VerifyAnalyzer(source); + } + public class NumericParameter : X1010_IncompatibleValueType { - public static readonly TheoryData NumericTypes = new() - { + public static readonly TheoryData NumericTypes = + [ "int", "uint", "long", @@ -397,17 +407,13 @@ public class NumericParameter : X1010_IncompatibleValueType "float", "double", "decimal", - }; + ]; - public static IEnumerable NumericValuesAndNumericTypes => - from value in NumericValues() - from type in NumericTypes - select new[] { value[0], type[0] }; + public static MatrixTheoryData NumericValuesAndNumericTypes = + new(NumericValues, NumericTypes); - public static IEnumerable BoolValuesAndNumericTypes => - from value in BoolValues - from type in NumericTypes - select new[] { value[0], type[0] }; + public static MatrixTheoryData BoolValuesAndNumericTypes = + new(BoolValues, NumericTypes); [Theory] [MemberData(nameof(NumericValuesAndNumericTypes))] @@ -415,12 +421,13 @@ public async Task CompatibleNumericValue_NonNullableType( string value, string type) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod({type} a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod({1} a) {{ }} + }} + """, value, type); await Verify.VerifyAnalyzer(source); } @@ -431,12 +438,13 @@ public async Task CompatibleNumericValue_NullableType( string value, string type) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod({type}? a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod({1}? a) {{ }} + }} + """, value, type); await Verify.VerifyAnalyzer(source); } @@ -447,17 +455,14 @@ public async Task BooleanValue_NumericType( string value, string type) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod({type} a) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(4, 23, 4, 23 + value.Length) - .WithArguments("a", type); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod({1} a) {{ }} + }} + """, value, type); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("a", type); await Verify.VerifyAnalyzer(source, expected); } @@ -466,12 +471,13 @@ public void TestMethod({type} a) {{ }} [MemberData(nameof(NumericTypes))] public async Task CharValue_NumericType(string type) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData('a')] - public void TestMethod({type} a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData('a')] + public void TestMethod({0} a) {{ }} + }} + """, type); await Verify.VerifyAnalyzer(source); } @@ -480,17 +486,14 @@ public void TestMethod({type} a) {{ }} [MemberData(nameof(NumericTypes))] public async Task EnumValue_NumericType(string type) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(System.StringComparison.InvariantCulture)] - public void TestMethod({type} a) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(4, 23, 4, 63) - .WithArguments("a", type); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:System.StringComparison.InvariantCulture|}})] + public void TestMethod({0} a) {{ }} + }} + """, type); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("a", type); await Verify.VerifyAnalyzer(source, expected); } @@ -502,12 +505,13 @@ public class BooleanParameter : X1010_IncompatibleValueType [MemberData(nameof(BoolValues))] public async Task FromBooleanValue_ToNonNullable(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(bool a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(bool a) {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -516,12 +520,13 @@ public void TestMethod(bool a) {{ }} [MemberData(nameof(BoolValues))] public async Task FromBooleanValue_ToNullable(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(bool? a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(bool? a) {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -534,16 +539,17 @@ public void TestMethod(bool? a) {{ }} [InlineData("typeof(string)")] public async Task FromIncompatibleValue(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(bool a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod(bool a) {{ }} + }} + """, value); var expected = Verify .Diagnostic("xUnit1010") - .WithSpan(4, 23, 4, 23 + value.Length) + .WithLocation(0) .WithArguments("a", "bool"); await Verify.VerifyAnalyzer(source, expected); @@ -557,12 +563,13 @@ public class CharParameter : X1010_IncompatibleValueType [MemberData(nameof(IntegerValues))] public async Task FromCharOrIntegerValue_ToNonNullable(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(char a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(char a) {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -572,12 +579,13 @@ public void TestMethod(char a) {{ }} [MemberData(nameof(IntegerValues))] public async Task FromCharOrIntegerValue_ToNullable(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(char? a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(char? a) {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -590,17 +598,14 @@ public void TestMethod(char? a) {{ }} [InlineData("typeof(string)")] public async Task FromIncompatibleValue(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(char a) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(4, 23, 4, 23 + value.Length) - .WithArguments("a", "char"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod(char a) {{ }} + }} + """, value); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("a", "char"); await Verify.VerifyAnalyzer(source, expected); } @@ -611,12 +616,13 @@ public class EnumParameter : X1010_IncompatibleValueType [Fact] public async Task FromEnumValue_ToNonNullable() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(System.StringComparison.Ordinal)] - public void TestMethod(System.StringComparison a) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(System.StringComparison.Ordinal)] + public void TestMethod(System.StringComparison a) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -624,12 +630,13 @@ public void TestMethod(System.StringComparison a) { } [Fact] public async Task FromEnumValue_ToNullable() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(System.StringComparison.Ordinal)] - public void TestMethod(System.StringComparison? a) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(System.StringComparison.Ordinal)] + public void TestMethod(System.StringComparison? a) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -642,17 +649,14 @@ public void TestMethod(System.StringComparison? a) { } [InlineData("typeof(string)")] public async Task FromIncompatibleValue(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(System.StringComparison a) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(4, 23, 4, 23 + value.Length) - .WithArguments("a", "System.StringComparison"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod(System.StringComparison a) {{ }} + }} + """, value); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("a", "System.StringComparison"); await Verify.VerifyAnalyzer(source, expected); } @@ -665,12 +669,13 @@ public class TypeParameter : X1010_IncompatibleValueType [InlineData("null")] public async Task FromTypeValue(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(System.Type a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(System.Type a) {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -680,12 +685,13 @@ public void TestMethod(System.Type a) {{ }} [InlineData("null")] public async Task FromTypeValue_ToParams(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(params System.Type[] a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(params System.Type[] a) {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -698,18 +704,14 @@ public void TestMethod(params System.Type[] a) {{ }} [InlineData("System.StringComparison.Ordinal")] public async Task FromIncompatibleValue(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(System.Type a) {{ }} -}}"; - - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(4, 23, 4, 23 + value.Length) - .WithArguments("a", "System.Type"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod(System.Type a) {{ }} + }} + """, value); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("a", "System.Type"); await Verify.VerifyAnalyzer(source, expected); } @@ -722,17 +724,14 @@ public void TestMethod(System.Type a) {{ }} [InlineData("System.StringComparison.Ordinal")] public async Task FromIncompatibleValue_ToParams(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(params System.Type[] a) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(4, 23, 4, 23 + value.Length) - .WithArguments("a", "System.Type"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod(params System.Type[] a) {{ }} + }} + """, value); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("a", "System.Type"); await Verify.VerifyAnalyzer(source, expected); } @@ -745,12 +744,13 @@ public class StringParameter : X1010_IncompatibleValueType [InlineData("null")] public async Task FromStringValue(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(string a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(string a) {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -763,17 +763,14 @@ public void TestMethod(string a) {{ }} [InlineData("typeof(string)")] public async Task FromIncompatibleValue(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(string a) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(4, 23, 4, 23 + value.Length) - .WithArguments("a", "string"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod(string a) {{ }} + }} + """, value); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("a", "string"); await Verify.VerifyAnalyzer(source, expected); } @@ -787,12 +784,13 @@ public class InterfaceParameter : X1010_IncompatibleValueType [InlineData("null")] public async Task FromTypeImplementingInterface(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(System.IFormattable a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(System.IFormattable a) {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -806,17 +804,14 @@ public void TestMethod(System.IFormattable a) {{ }} [MemberData(nameof(BoolValues))] public async Task FromIncompatibleValue(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(System.IFormattable a) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(4, 23, 4, 23 + value.Length) - .WithArguments("a", "System.IFormattable"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod(System.IFormattable a) {{ }} + }} + """, value); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("a", "System.IFormattable"); await Verify.VerifyAnalyzer(source, expected); } @@ -834,12 +829,13 @@ public class ObjectParameter : X1010_IncompatibleValueType [InlineData("typeof(string)")] public async Task FromAnyValue(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(object a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(object a) {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -854,12 +850,13 @@ public void TestMethod(object a) {{ }} [InlineData("typeof(string)")] public async Task FromAnyValue_ToParams(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(params object[] a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(params object[] a) {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -877,12 +874,13 @@ public class GenericParameter : X1010_IncompatibleValueType [InlineData("typeof(string)")] public async Task FromAnyValue_NoConstraint(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(T a) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(T a) {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -894,12 +892,13 @@ public void TestMethod(T a) {{ }} [InlineData("'a'")] public async Task FromValueTypeValue_WithStructConstraint(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(T a) where T: struct {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(T a) where T: struct {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -909,17 +908,14 @@ public void TestMethod(T a) where T: struct {{ }} [InlineData("typeof(string)")] public async Task FromReferenceTypeValue_WithStructConstraint(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(T a) where T: struct {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(4, 23, 4, 23 + value.Length) - .WithArguments("a", "T"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod(T a) where T: struct {{ }} + }} + """, value); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("a", "T"); await Verify.VerifyAnalyzer(source, expected); } @@ -930,12 +926,13 @@ public void TestMethod(T a) where T: struct {{ }} [InlineData("null")] public async Task FromReferenceTypeValue_WithClassConstraint(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(T a) where T: class {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(T a) where T: class {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -947,17 +944,14 @@ public void TestMethod(T a) where T: class {{ }} [InlineData("'a'")] public async Task FromValueTypeValue_WithClassConstraint(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(T a) where T: class {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(4, 23, 4, 23 + value.Length) - .WithArguments("a", "T"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod(T a) where T: class {{ }} + }} + """, value); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("a", "T"); await Verify.VerifyAnalyzer(source, expected); } @@ -968,12 +962,13 @@ public void TestMethod(T a) where T: class {{ }} [MemberData(nameof(NumericValues))] public async Task FromCompatibleValue_WithTypeConstraint(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(T a) where T: System.IConvertible, System.IFormattable {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(T a) where T: System.IConvertible, System.IFormattable {{ }} + }} + """, value); await Verify.VerifyAnalyzer(source); } @@ -987,17 +982,15 @@ public void TestMethod(T a) where T: System.IConvertible, System.IFormattable [MemberData(nameof(BoolValues))] public async Task FromIncompatibleValue_WithTypeConstraint(string value) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({value})] - public void TestMethod(T a) where T: System.IConvertible, System.IFormattable {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(4, 23, 4, 23 + value.Length) - .WithArguments("a", "T"); + var source = string.Format(/* lang=c#-test */ """ + + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod(T a) where T: System.IConvertible, System.IFormattable {{ }} + }} + """, value); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("a", "T"); await Verify.VerifyAnalyzer(source, expected); } @@ -1005,17 +998,14 @@ public void TestMethod(T a) where T: System.IConvertible, System.IFormattable [Fact] public async Task FromIncompatibleArray() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(new int[] { 1, 2, 3 })] - public void TestMethod(T a) where T: System.IConvertible, System.IFormattable { } -}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(4, 35, 4, 36) - .WithArguments("a", "T"); + var source =/* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(new int[] { {|#0:1|}, 2, 3 })] + public void TestMethod(T a) where T: System.IConvertible, System.IFormattable { } + } + """; + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("a", "T"); await Verify.VerifyAnalyzer(source, expected); } @@ -1023,12 +1013,13 @@ public void TestMethod(T a) where T: System.IConvertible, System.IFormattable [Fact] public async Task FromCompatibleArray() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(new int[] { 1, 2, 3 })] - public void TestMethod(T[] a) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(new int[] { 1, 2, 3 })] + public void TestMethod(T[] a) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -1036,20 +1027,17 @@ public void TestMethod(T[] a) { } public class DateTimeLikeParameter : X1010_IncompatibleValueType { - public static readonly TheoryData ValidDateTimeStrings = new() - { + public static readonly TheoryData ValidDateTimeStrings = + [ "\"\"", "\"2018-01-02\"", "\"2018-01-02 12:34\"", "\"obviously-rubbish-datetime-value\"", "MyConstString" - }; + ]; - public static IEnumerable ValueTypedArgumentsCombinedWithDateTimeLikeTypes => - ValueTypedValues().SelectMany(v => - new string[] { "System.DateTime", "System.DateTimeOffset" } - .Select(dateTimeLikeType => new[] { v[0], dateTimeLikeType }) - ); + public static MatrixTheoryData ValueTypedArgumentsCombinedWithDateTimeLikeTypes = + new(ValueTypedValues, ["System.DateTime", "System.DateTimeOffset"]); [Theory] [MemberData(nameof(ValueTypedArgumentsCombinedWithDateTimeLikeTypes))] @@ -1059,20 +1047,16 @@ public async Task NonStringValue( string data, string parameterType) { - var source = $@" -public class TestClass -{{ - const int MyConstInt = 1; - - [Xunit.Theory] - [Xunit.InlineData({data})] - public void TestMethod({parameterType} parameter) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(7, 23, 7, 23 + data.Length) - .WithArguments("parameter", parameterType); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + const int MyConstInt = 1; + + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod({1} parameter) {{ }} + }} + """, data, parameterType); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("parameter", parameterType); await Verify.VerifyAnalyzer(source, expected); } @@ -1099,59 +1083,51 @@ public async Task StringValue_ToDateTimeOffset(string data) [MemberData(nameof(ValidDateTimeStrings))] public async Task StringValue_ToDateTimeOffset_Pre240(string data) { - var source = CreateSourceWithStringConst(data, "System.DateTimeOffset"); - var expected = - Verify_v2_Pre240 - .Diagnostic("xUnit1010") - .WithSpan(7, 23, 7, 23 + data.Length) - .WithArguments("parameter", "System.DateTimeOffset"); + var source = CreateSourceWithStringConst("{|#0:" + data + "|}", "System.DateTimeOffset"); + var expected = Verify_v2_Pre240.Diagnostic("xUnit1010").WithLocation(0).WithArguments("parameter", "System.DateTimeOffset"); await Verify_v2_Pre240.VerifyAnalyzer(source, expected); } static string CreateSourceWithStringConst( string data, - string parameterType) => $@" -public class TestClass -{{ - const string MyConstString = ""some string""; - - [Xunit.Theory] - [Xunit.InlineData({data})] - public void TestMethod({parameterType} parameter) {{ }} -}}"; + string parameterType) => string.Format(/* lang=c#-test */ """ + public class TestClass {{ + const string MyConstString = "some string"; + + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod({1} parameter) {{ }} + }} + """, data, parameterType); } public class GuidParameter : X1010_IncompatibleValueType { - public static TheoryData ValidGuidStrings = new() - { + public static TheoryData ValidGuidStrings = + [ "\"\"", "\"{5B21E154-15EB-4B1E-BC30-127E8A41ECA1}\"", "\"4EBCD32C-A2B8-4600-9E72-3873347E285C\"", "\"39A3B4C85FEF43A988EB4BB4AC4D4103\"", "\"obviously-rubbish-guid-value\"" - }; + ]; [Theory] [MemberData(nameof(ValueTypedValues))] [InlineData("MyConstInt")] public async Task NonStringValue(string data) { - var source = $@" -public class TestClass -{{ - private const int MyConstInt = 1; - - [Xunit.Theory] - [Xunit.InlineData({data})] - public void TestMethod(System.Guid parameter) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1010") - .WithSpan(7, 23, 7, 23 + data.Length) - .WithArguments("parameter", "System.Guid"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + private const int MyConstInt = 1; + + [Xunit.Theory] + [Xunit.InlineData({{|#0:{0}|}})] + public void TestMethod(System.Guid parameter) {{ }} + }} + """, data); + var expected = Verify.Diagnostic("xUnit1010").WithLocation(0).WithArguments("parameter", "System.Guid"); await Verify.VerifyAnalyzer(source, expected); } @@ -1169,23 +1145,19 @@ public async Task StringValue(string inlineData) [MemberData(nameof(ValidGuidStrings))] public async Task StringValue_Pre240(string data) { - var source = CreateSource(data); - var expected = - Verify_v2_Pre240 - .Diagnostic("xUnit1010") - .WithSpan(5, 23, 5, 23 + data.Length) - .WithArguments("parameter", "System.Guid"); + var source = CreateSource("{|#0:" + data + "|}"); + var expected = Verify_v2_Pre240.Diagnostic("xUnit1010").WithLocation(0).WithArguments("parameter", "System.Guid"); await Verify_v2_Pre240.VerifyAnalyzer(source, expected); } - static string CreateSource(string data) => $@" -public class TestClass -{{ - [Xunit.Theory] - [Xunit.InlineData({data})] - public void TestMethod(System.Guid parameter) {{ }} -}}"; + static string CreateSource(string data) => string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + public void TestMethod(System.Guid parameter) {{ }} + }} + """, data); } public class UserDefinedConversionOperators : X1010_IncompatibleValueType @@ -1193,20 +1165,21 @@ public class UserDefinedConversionOperators : X1010_IncompatibleValueType [Fact] public async Task SupportsImplicitConversion() { - var source = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(""abc"")] - public void ParameterDeclaredImplicitConversion(Implicit i) => Assert.Equal(""abc"", i.Value); - - public class Implicit { - public string Value { get; set; } - public static implicit operator Implicit(string value) => new Implicit() { Value = value }; - public static implicit operator string(Implicit i) => i.Value; - } -}"; + var source = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + [InlineData("abc")] + public void ParameterDeclaredImplicitConversion(Implicit i) => Assert.Equal("abc", i.Value); + + public class Implicit { + public string Value { get; set; } + public static implicit operator Implicit(string value) => new Implicit() { Value = value }; + public static implicit operator string(Implicit i) => i.Value; + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -1214,20 +1187,21 @@ public class Implicit { [Fact] public async Task SupportsExplicitConversion() { - var source = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(""abc"")] - public void ParameterDeclaredExplicitConversion(Explicit i) => Assert.Equal(""abc"", i.Value); - - public class Explicit { - public string Value { get; set; } - public static explicit operator Explicit(string value) => new Explicit() { Value = value }; - public static explicit operator string(Explicit i) => i.Value; - } -}"; + var source = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + [InlineData("abc")] + public void ParameterDeclaredExplicitConversion(Explicit i) => Assert.Equal("abc", i.Value); + + public class Explicit { + public string Value { get; set; } + public static explicit operator Explicit(string value) => new Explicit() { Value = value }; + public static explicit operator string(Explicit i) => i.Value; + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -1235,20 +1209,20 @@ public class Explicit { // Note: decimal literal 42M is not valid as an attribute argument - public static TheoryData BoolValues = new() - { + public static TheoryData BoolValues = + [ "true", "false" - }; + ]; - public static TheoryData FloatingPointValues = new() - { + public static TheoryData FloatingPointValues = + [ "42f", "42d" - }; + ]; - public static TheoryData IntegerValues = new() - { + public static TheoryData IntegerValues = + [ "42", "42L", "42u", @@ -1257,25 +1231,13 @@ public class Explicit { "(byte)42", "(ushort)42", "(sbyte)42" - }; - - public static IEnumerable NumericValues() - { - foreach (var integerValue in IntegerValues) - yield return integerValue; - foreach (var floatingPointValue in FloatingPointValues) - yield return floatingPointValue; - } + ]; - public static IEnumerable ValueTypedValues() - { - foreach (var numericValue in NumericValues()) - yield return numericValue; - foreach (var boolValue in BoolValues) - yield return boolValue; + public static TheoryData NumericValues = + new(((IEnumerable)IntegerValues).Concat(FloatingPointValues)); - yield return new[] { "typeof(int)" }; - } + public static TheoryData ValueTypedValues = + new(((IEnumerable)IntegerValues).Concat(FloatingPointValues).Concat(BoolValues).Append("typeof(int)")); } public class X1011_ExtraValue @@ -1283,12 +1245,13 @@ public class X1011_ExtraValue [Fact] public async Task IgnoresFact() { - var source = @" -public class TestClass { - [Xunit.Fact] - [Xunit.InlineData(1, 2, ""abc"")] - public void TestMethod(int a) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + [Xunit.InlineData(1, 2, "abc")] + public void TestMethod(int a) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -1296,25 +1259,18 @@ public void TestMethod(int a) { } [Fact] public async Task ExtraArguments() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(1, 2, ""abc"")] - public void TestMethod(int a) { } -}"; - DiagnosticResult[] expected = + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(1, {|#0:2|}, {|#1:"abc"|})] + public void TestMethod(int a) { } + } + """; + var expected = new[] { - Verify - .Diagnostic("xUnit1011") - .WithSpan(4, 26, 4, 27) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("2"), - Verify - .Diagnostic("xUnit1011") - .WithSpan(4, 29, 4, 34) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("\"abc\""), - }; + Verify.Diagnostic("xUnit1011").WithLocation(0).WithArguments("2"), + Verify.Diagnostic("xUnit1011").WithLocation(1).WithArguments("\"abc\""), + }; await Verify.VerifyAnalyzer(source, expected); } @@ -1325,12 +1281,13 @@ public class X1012_NullShouldNotBeUsedForIncompatibleParameter [Fact] public async Task IgnoresFact() { - var source = @" -public class TestClass { - [Xunit.Fact] - [Xunit.InlineData(null)] - public void TestMethod(int a) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + [Xunit.InlineData(null)] + public void TestMethod(int a) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -1340,18 +1297,14 @@ public void TestMethod(int a) { } [InlineData("params int[]")] public async Task SingleNullValue(string type) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(null)] - public void TestMethod({type} a) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1012") - .WithSpan(4, 23, 4, 27) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("a", "int"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({{|#0:null|}})] + public void TestMethod({0} a) {{ }} + }} + """, type); + var expected = Verify.Diagnostic("xUnit1012").WithLocation(0).WithArguments("a", "int"); await Verify.VerifyAnalyzer(source, expected); } @@ -1360,25 +1313,18 @@ public void TestMethod({type} a) {{ }} [MemberData(nameof(ValueTypes))] public async Task NonNullableValueTypes(string type) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(1, null, null)] - public void TestMethod(int a, {type} b, params {type}[] c) {{ }} -}}"; - DiagnosticResult[] expected = + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData(1, {{|#0:null|}}, {{|#1:null|}})] + public void TestMethod(int a, {0} b, params {0}[] c) {{ }} + }} + """, type); + var expected = new[] { - Verify - .Diagnostic("xUnit1012") - .WithSpan(4, 26, 4, 30) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("b", type), - Verify - .Diagnostic("xUnit1012") - .WithSpan(4, 32, 4, 36) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("c", type), - }; + Verify.Diagnostic("xUnit1012").WithLocation(0).WithArguments("b", type), + Verify.Diagnostic("xUnit1012").WithLocation(1).WithArguments("c", type), + }; await Verify.VerifyAnalyzer(source, expected); } @@ -1387,12 +1333,13 @@ public void TestMethod(int a, {type} b, params {type}[] c) {{ }} [MemberData(nameof(ValueTypes))] public async Task NullableValueTypes(string type) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(1, null)] - public void TestMethod(int a, {type}? b) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData(1, null)] + public void TestMethod(int a, {0}? b) {{ }} + }} + """, type); await Verify.VerifyAnalyzer(source); } @@ -1403,12 +1350,13 @@ public void TestMethod(int a, {type}? b) {{ }} [InlineData("System.Exception")] public async Task ReferenceTypes(string type) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(1, null)] - public void TestMethod(int a, {type} b) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData(1, null)] + public void TestMethod(int a, {0} b) {{ }} + }} + """, type); await Verify.VerifyAnalyzer(source); } @@ -1419,23 +1367,16 @@ public void TestMethod(int a, {type} b) {{ }} [InlineData("System.Exception")] public async Task NonNullableReferenceTypes(string type) { - var source = $@" -#nullable enable -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(1, null)] - public void TestMethod(int a, {type} b) {{ }} -#nullable restore -}}"; - - DiagnosticResult[] expected = - { - Verify - .Diagnostic("xUnit1012") - .WithSpan(5, 26, 5, 30) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("b", type) - }; + var source = string.Format(/* lang=c#-test */ """ + #nullable enable + + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData(1, {{|#0:null|}})] + public void TestMethod(int a, {0} b) {{ }} + }} + """, type); + var expected = Verify.Diagnostic("xUnit1012").WithLocation(0).WithArguments("b", type); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source, expected); } @@ -1446,14 +1387,15 @@ public void TestMethod(int a, {type} b) {{ }} [InlineData("System.Exception")] public async Task NullableReferenceTypes(string type) { - var source = $@" -#nullable enable -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(1, null)] - public void TestMethod(int a, {type}? b) {{ }} -#nullable restore -}}"; + var source = string.Format(/* lang=c#-test */ """ + #nullable enable + + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData(1, null)] + public void TestMethod(int a, {0}? b) {{ }} + }} + """, type); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source); } @@ -1461,16 +1403,19 @@ public void TestMethod(int a, {type}? b) {{ }} [Theory] [InlineData("1", "object")] [InlineData("\"bob\"", "string")] - public async Task NullableParamsReferenceTypes(string param, string type) + public async Task NullableParamsReferenceTypes( + string param, + string type) { - var source = $@" -#nullable enable -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(1, {param}, null, null)] - public void TestMethod(int a, params {type}?[] b) {{ }} -#nullable restore -}}"; + var source = string.Format(/* lang=c#-test */ """ + #nullable enable + + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData(1, {0}, null, null)] + public void TestMethod(int a, params {1}?[] b) {{ }} + }} + """, param, type); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source); } @@ -1478,36 +1423,36 @@ public void TestMethod(int a, params {type}?[] b) {{ }} [Theory] [InlineData("1", "object")] [InlineData("\"bob\"", "string")] - public async Task NonNullableParamsReferenceTypes(string param, string type) + public async Task NonNullableParamsReferenceTypes( + string param, + string type) { - var source = $@" -#nullable enable -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(1, {param}, null, null)] - public void TestMethod(int a, params {type}[] b) {{ }} -#nullable restore -}}"; - - DiagnosticResult[] expected = + var source = string.Format(/* lang=c#-test */ """ + #nullable enable + + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData(1, {0}, {{|#0:null|}}, {{|#1:null|}})] + public void TestMethod(int a, params {1}[] b) {{ }} + }} + """, param, type); + var expected = new[] { Verify .Diagnostic("xUnit1012") - .WithSpan(5, 28 + param.Length, 5, 32 + param.Length) - .WithSeverity(DiagnosticSeverity.Warning) + .WithLocation(0) .WithArguments("b", type), Verify .Diagnostic("xUnit1012") - .WithSpan(5, 34 + param.Length, 5, 38 + param.Length) - .WithSeverity(DiagnosticSeverity.Warning) + .WithLocation(1) .WithArguments("b", type), }; await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source, expected); } - public static TheoryData ValueTypes = new() - { + public static TheoryData ValueTypes = + [ "bool", "int", "byte", @@ -1523,7 +1468,7 @@ public void TestMethod(int a, params {type}[] b) {{ }} "sbyte", "System.StringComparison", "System.Guid", - }; + ]; } internal class Analyzer_v2_Pre240 : InlineDataMustMatchTheoryParameters diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/InlineDataShouldBeUniqueWithinTheoryTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/InlineDataShouldBeUniqueWithinTheoryTests.cs index bc5e7f40..b826a78b 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/InlineDataShouldBeUniqueWithinTheoryTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/InlineDataShouldBeUniqueWithinTheoryTests.cs @@ -1,5 +1,5 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Xunit; using Verify = CSharpVerifier; @@ -8,13 +8,14 @@ public abstract class InlineDataShouldBeUniqueWithinTheoryTests public class ForNonRelatedToInlineDataMethod : InlineDataShouldBeUniqueWithinTheoryTests { [Fact] - public async Task DoesNotFindError_WhenNoDataAttributes() + public async Task WithNoDataAttributes_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Fact] - public void TestMethod() { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -22,15 +23,16 @@ public void TestMethod() { } [Theory] [InlineData("MemberData(\"\")")] [InlineData("ClassData(typeof(string))")] - public async Task DoesNotFindError_WhenDataAttributesOtherThanInline( + public async Task WithDataAttributesOtherThanInline_DoesNotTrigger( string dataAttribute) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.{dataAttribute}] - public void TestMethod() {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.{0}] + public void TestMethod() {{ }} + }} + """, dataAttribute); await Verify.VerifyAnalyzer(source); } @@ -39,147 +41,142 @@ public void TestMethod() {{ }} public class ForUniqueInlineDataMethod : InlineDataShouldBeUniqueWithinTheoryTests { [Fact] - public async Task DoesNotFindError_WhenNonTheorySingleInlineData() + public async Task NonTheory_SingleInlineData_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Fact] - [Xunit.InlineData] - public void TestMethod(int x) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + [Xunit.InlineData] + public void TestMethod(int x) { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindError_WhenNonTheoryDoubledInlineData() + public async Task NonTheory_DoubledInlineData_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Fact] - [Xunit.InlineData] - [Xunit.InlineData] - public void TestMethod(int x) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + [Xunit.InlineData] + [Xunit.InlineData] + public void TestMethod(int x) { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindError_WhenSingleInlineDataContainingValue() + public async Task SingleInlineData_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(10)] - public void TestMethod(int x) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(10)] + public void TestMethod(int x) { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindError_WhenInlineDataAttributesHaveDifferentParameterValues() + public async Task MultipleInlineData_DifferentValues_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(10)] - [Xunit.InlineData(20)] - public void TestMethod(int x) { } -}"; - - await Verify.VerifyAnalyzer(source); - } - - [Fact] - public async Task DoesNotFindError_WhenInlineDataAttributesDifferAtLastParameterValue() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(10, ""foo"")] - [Xunit.InlineData(10, ""bar"")] - public void TestMethod(int x, string y) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(10)] + [Xunit.InlineData(20)] + public void TestMethod(int x) { } + } + """; await Verify.VerifyAnalyzer(source); } [Theory] - [InlineData("new object[] { 1, 3 }")] - [InlineData("data: new object[] { 1, 3 }")] - [InlineData("new object[] { }")] - [InlineData("data: new object[] { 1 }")] - public async Task DoesNotFindError_WhenUniquenessProvidedWithParamsInitializerValues(string data) - { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(1, 2)] - [Xunit.InlineData({data})] - public void TestMethod(params int[] args) {{ }} -}}"; + [InlineData(/* lang=c#-test */ "new object[] { 1, 3 }")] + [InlineData(/* lang=c#-test */ "data: new object[] { 1, 3 }")] + [InlineData(/* lang=c#-test */ "new object[] { }")] + [InlineData(/* lang=c#-test */ "data: new object[] { 1 }")] + public async Task UniqueValues_WithParamsInitializerValues_DoesNotTrigger(string data) + { + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData(1, 2)] + [Xunit.InlineData({0})] + public void TestMethod(params int[] args) {{ }} + }} + """, data); await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindError_WhenUniquenessProvidedWithOverridingDefaultValues() + public async Task UniqueValues_WithOverridingDefaultValues_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(1)] - [Xunit.InlineData(1, ""non-default-val"")] - public void TestMethod(int x, string a = ""default-val"") { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(1)] + [Xunit.InlineData(1, "non-default-val")] + public void TestMethod(int x, string a = "default-val") { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindError_WhenNullAndEmptyInlineDataAttributes() + public async Task NullAndEmpty_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(null)] - [Xunit.InlineData] - public void TestMethod(string s) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(null)] + [Xunit.InlineData] + public void TestMethod(string s) { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindError_WhenNewArrayAndNullDataAttributes() + public async Task NullAndArray_DoesNotTrigger() { - var source = @" -public class TestClass{ - [Xunit.Theory] - [Xunit.InlineData(new[] { 0 })] - [Xunit.InlineData(null)] - public void TestMethod(int[] arr) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass{ + [Xunit.Theory] + [Xunit.InlineData(new[] { 0 })] + [Xunit.InlineData(null)] + public void TestMethod(int[] arr) { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindError_WhenFirstArrayIsEqualAndEmptyArraysAreUsed() + public async Task ArrayOrderVariance_DoesNotTrigger() { // Specially crafted InlineData values that will cause the InlineDataUniquenessComparer // to return same hashcodes, because GetFlattenedArgumentPrimitives ignores empty arrays. // This will trigger the actual bug, where the first parameter object array being equal // would cause the other parameters to not be evaluated for equality at all. - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(new int[] { 1 }, new int[0], new int[] { 1 })] - [Xunit.InlineData(new int[] { 1 }, new int[] { 1 }, new int[0])] - public static void Test(int[] x, int[] y, int[] z) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(new int[] { 1 }, new int[0], new int[] { 1 })] + [Xunit.InlineData(new int[] { 1 }, new int[] { 1 }, new int[0])] + public static void Test(int[] x, int[] y, int[] z) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -188,254 +185,205 @@ public static void Test(int[] x, int[] y, int[] z) { } public class ForDuplicatedInlineDataMethod : InlineDataShouldBeUniqueWithinTheoryTests { [Fact] - public async Task FindsError_WhenEmptyInlineDataRepeatedTwice() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData] - [Xunit.InlineData] - public void TestMethod(int x) { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 6, 5, 22) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + public async Task DoubleEmptyInlineData_Triggers() + { + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData] + [{|#0:Xunit.InlineData|}] + public void TestMethod(int x) { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsError_WhenNullInlineDataRepeatedTwice() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(null)] - [Xunit.InlineData(null)] - public void TestMethod(string x) { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 6, 5, 28) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + public async Task DoubleNullInlineData_Triggers() + { + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(null)] + [{|#0:Xunit.InlineData(null)|}] + public void TestMethod(string x) { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsError_WhenInlineDataAttributesHaveExactlySameDeclarations() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(10)] - [Xunit.InlineData(10)] - public void TestMethod(int x) { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 6, 5, 26) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + public async Task DoubleValues_Triggers() + { + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(10)] + [{|#0:Xunit.InlineData(10)|}] + public void TestMethod(int x) { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsError_WhenInlineDataAttributesHaveSameCompilationTimeEvaluation() + public async Task ValueFromConstant_Triggers() { - var source = @" -public class TestClass { - private const int X = 10; - [Xunit.Theory] - [Xunit.InlineData(10)] - [Xunit.InlineData(X)] - public void TestMethod(int x) { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(6, 6, 6, 25) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + var source = /* lang=c#-test */ """ + public class TestClass { + private const int X = 10; + + [Xunit.Theory] + [Xunit.InlineData(10)] + [{|#0:Xunit.InlineData(X)|}] + public void TestMethod(int x) { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Theory] - [InlineData("new object[] { 10, 20 }")] - [InlineData("data: new object[] { 10, 20 }")] - public async Task FindsError_WhenInlineDataHaveSameParameterValuesButDeclaredArrayCollectionOfArguments(string data) - { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(10, 20)] - [Xunit.InlineData({data})] - public void TestMethod(int x, int y) {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 6, 5, 24 + data.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + [InlineData(/* lang=c#-test */ "new object[] { 10, 20 }")] + [InlineData(/* lang=c#-test */ "data: new object[] { 10, 20 }")] + public async Task TwoParams_RawValuesVsArgumentArray_Triggers(string data) + { + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData(10, 20)] + [{{|#0:Xunit.InlineData({0})|}}] + public void TestMethod(int x, int y) {{ }} + }} + """, data); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Theory] - [InlineData("new object[] { 10, 20 }")] - [InlineData("data: new object[] { 10, 20 }")] - public async Task FindsError_WhenTestMethodIsDefinedWithParamsArrayOfArguments(string data) - { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(10, 20)] - [Xunit.InlineData({data})] - public void TestMethod(params int[] args) {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 6, 5, 24 + data.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + [InlineData(/* lang=c#-test */ "new object[] { 10, 20 }")] + [InlineData(/* lang=c#-test */ "data: new object[] { 10, 20 }")] + public async Task ParamsArray_RawValuesVsArgumentArray_Triggers(string data) + { + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData(10, 20)] + [{{|#0:Xunit.InlineData({0})|}}] + public void TestMethod(params int[] args) {{ }} + }} + """, data); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsError_WhenBothInlineDataHaveObjectArrayCollectionOfArguments() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(new object[] { 10, 20 })] - [Xunit.InlineData(new object[] { 10, 20 })] - public void TestMethod(int x, int y) { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 6, 5, 47) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + public async Task DoubledArgumentArrays_Triggers() + { + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(new object[] { 10, 20 })] + [{|#0:Xunit.InlineData(new object[] { 10, 20 })|}] + public void TestMethod(int x, int y) { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsError_WhenArgumentsAreArrayOfValues() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(new object[] {10, new object[] { new object[] {20}, 30}})] - [Xunit.InlineData(new object[] {10, new object[] { new object[] {20}, 30}})] - public void TestMethod(object x, object y) { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 6, 5, 80) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + public async Task DoubledComplexValuesForObject_Triggers() + { + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(new object[] {10, new object[] { new object[] {20}, 30}})] + [{|#0:Xunit.InlineData(new object[] {10, new object[] { new object[] {20}, 30}})|}] + public void TestMethod(object x, object y) { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsError_WhenArgumentsAreArrayOfValuesAndTestMethodOffersDefaultParameterValues() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(10, new object[] { new object[] {20}, 30}, 40)] - [Xunit.InlineData(new object[] {10, new object[] { new object[] {20}, 30}})] - [Xunit.InlineData(new object[] {10, new object[] { new object[] {20}, 30}, 50})] - [Xunit.InlineData(new object[] {10, new object[] { new object[] {90}, 30}, 40})] - public void TestMethod(object x, object y, int z = 40) { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 5, 5, 79) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + public async Task DoubledComplexValues_RawValuesVsArgumentArray_Triggers() + { + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(10, new object[] { new object[] {20}, 30}, 40)] + [{|#0:Xunit.InlineData(new object[] {10, new object[] { new object[] {20}, 30}})|}] + public void TestMethod(object x, object y, int z = 40) { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } // The value 1 doesn't seem to trigger bugs related to comparing boxed values, but 2 does - public static TheoryData DefaultValueData = new() { 1, 2 }; + public static TheoryData DefaultValueData = [1, 2]; [Theory] [MemberData(nameof(DefaultValueData))] - public async Task FindsError_WhenFirstDuplicatedByDefaultValueOfParameter_DefaultInlineDataFirst(int defaultValue) - { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData] - [Xunit.InlineData({defaultValue})] - public void TestMethod(int y = {defaultValue}) {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 6, 5, 25) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + public async Task DefaultValueVsExplicitValue_Triggers(int defaultValue) + { + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData] + [{{|#0:Xunit.InlineData({0})|}}] + public void TestMethod(int y = {0}) {{ }} + }} + """, defaultValue); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(DefaultValueData))] - public async Task FindsError_WhenSecondDuplicatedByDefaultValueOfParameter(int defaultValue) - { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({defaultValue})] - [Xunit.InlineData] - public void TestMethod(int y = {defaultValue}) {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 6, 5, 22) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + public async Task ExplicitValueVsDefaultValue_Triggers(int defaultValue) + { + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + [{{|#0:Xunit.InlineData|}}] + public void TestMethod(int y = {0}) {{ }} + }} + """, defaultValue); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(DefaultValueData))] - public async Task FindsError_WhenTwoDuplicatedByDefaultValueOfParameter(int defaultValue) - { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData] - [Xunit.InlineData] - public void TestMethod(int y = {defaultValue}) {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 6, 5, 22) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + public async Task DefaultValueVsDefaultValue_Triggers(int defaultValue) + { + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData] + [{{|#0:Xunit.InlineData|}}] + public void TestMethod(int y = {0}) {{ }} + }} + """, defaultValue); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } @@ -445,71 +393,59 @@ public void TestMethod(int y = {defaultValue}) {{ }} [InlineData("null", "")] [InlineData("", "null")] [InlineData("", "")] - public async Task FindsError_WhenBothNullEntirelyOrBySingleDefaultParameterNullValue( + public async Task DefaultValueVsNull_Triggers( string firstArg, string secondArg) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData({firstArg})] - [Xunit.InlineData({secondArg})] - public void TestMethod(string x = null) {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithLocation(5, 6) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData({0})] + [{{|#0:Xunit.InlineData({1})|}}] + public void TestMethod(string x = null) {{ }} + }} + """, firstArg, secondArg); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsError_WhenDuplicateContainsNulls() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(1, null)] - [Xunit.InlineData(new object[] {1, null})] - public void TestMethod(object x, object y) { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 6, 5, 46) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + public async Task Null_RawValuesVsExplicitArray_Triggers() + { + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(1, null)] + [{|#0:Xunit.InlineData(new object[] { 1, null })|}] + public void TestMethod(object x, object y) { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Theory] [InlineData("", "")] - [InlineData("", ", null")] - [InlineData(", null", "")] - [InlineData(", null", ", null")] - public async Task FindsError_WhenDuplicateContainsDefaultOfStruct( + [InlineData("", ", default")] + [InlineData(", default", "")] + [InlineData(", default", ", default")] + public async Task DefaultOfStruct_Triggers( string firstDefaultOverride, string secondDefaultOverride) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(1 {firstDefaultOverride})] - [Xunit.InlineData(1 {secondDefaultOverride})] - public void TestMethod(int x, System.DateTime date = default(System.DateTime)) {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 5, 5, 25 + secondDefaultOverride.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData(1{0})] + [{{|#0:Xunit.InlineData(1{1})|}}] + public void TestMethod(int x, System.DateTime date = default) {{ }} + }} + """, firstDefaultOverride, secondDefaultOverride); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(LanguageVersion.CSharp7_1, source, expected); } [Theory] @@ -517,122 +453,61 @@ public class TestClass {{ [InlineData("", ", null")] [InlineData(", null", "")] [InlineData(", null", ", null")] - public async Task FindsError_WhenDuplicateContainsDefaultOfString( + public async Task DefaultOfString_Triggers( string firstDefaultOverride, string secondDefaultOverride) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.InlineData(1 {firstDefaultOverride})] - [Xunit.InlineData(1 {secondDefaultOverride})] - public void TestMethod(int x, string y = null) {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 5, 5, 25 + secondDefaultOverride.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.InlineData(1{0})] + [{{|#0:Xunit.InlineData(1{1})|}}] + public void TestMethod(int x, string y = null) {{ }} + }} + """, firstDefaultOverride, secondDefaultOverride); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsError_WhenInlineDataDuplicateAndOriginalAreItemsOfDistinctAttributesLists() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(10, 20)] - [Xunit.InlineData(30, 40)] - [Xunit.InlineData(50, 60)] - [Xunit.InlineData(10, 20)] - public void TestMethod(int x, int y) { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(7, 6, 7, 30) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); - - await Verify.VerifyAnalyzer(source, expected); - } - - [Fact] - public async Task FindsErrorsTwiceOnCorrectLinesReferringToInitialOccurence_WhenThreeInlineDataAttributesConstituteDuplication() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(10)] - [Xunit.InlineData(10)] - [Xunit.InlineData(10)] - public void TestMethod(int x) { } -}"; + public async Task Tripled_TriggersTwice() + { + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(10)] + [{|#0:Xunit.InlineData(10)|}] + [{|#1:Xunit.InlineData(10)|}] + public void TestMethod(int x) { } + } + """; var expected = new[] { - Verify - .Diagnostic() - .WithSpan(5, 6, 5, 26) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"), - Verify - .Diagnostic() - .WithSpan(6, 6, 6, 26) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"), + Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"), + Verify.Diagnostic().WithLocation(1).WithArguments("TestMethod", "TestClass"), }; await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsErrorOnCorrectLineReferringToInitialOccurence_WhenDuplicateIsSeparatedByOtherNonDuplicateData() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(10)] - [Xunit.InlineData(50)] - [Xunit.InlineData(10)] - public void TestMethod(int x) { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(6, 6, 6, 26) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"); - - await Verify.VerifyAnalyzer(source, expected); - } - - [Fact] - public async Task FindsErrorOnCorrectLineReferringToInitialOccurence_WhenTwoDuplicationEquivalenceSetsExistWithinTheory() - { - var source = @" -public class TestClass { - [Xunit.Theory] - [Xunit.InlineData(10)] - [Xunit.InlineData(20)] - [Xunit.InlineData(10)] - [Xunit.InlineData(20)] - public void TestMethod(int x) { } -}"; + public async Task DoubledTwice_TriggersTwice() + { + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + [Xunit.InlineData(10)] + [Xunit.InlineData(20)] + [{|#0:Xunit.InlineData(10)|}] + [{|#1:Xunit.InlineData(20)|}] + public void TestMethod(int x) { } + } + """; var expected = new[] { - Verify - .Diagnostic() - .WithSpan(6, 6, 6, 26) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"), - Verify - .Diagnostic() - .WithSpan(7, 6, 7, 26) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass"), + Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass"), + Verify.Diagnostic().WithLocation(1).WithArguments("TestMethod", "TestClass"), }; await Verify.VerifyAnalyzer(source, expected); diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/LocalFunctionsCannotBeTestFunctionsTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/LocalFunctionsCannotBeTestFunctionsTests.cs index 5d72823e..10ef1fa2 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/LocalFunctionsCannotBeTestFunctionsTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/LocalFunctionsCannotBeTestFunctionsTests.cs @@ -6,17 +6,15 @@ public class LocalFunctionsCannotBeTestFunctionsTests { [Fact] - public async Task DoesNotTriggerOnLocalFunctionWithoutAttributes() + public async Task NoTestAttribute_DoesNotTrigger() { - var source = @" -using Xunit; - -public class TestClass { - public void Method() { - void LocalFunction() { - } - } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + public void Method() { + void LocalFunction() { } + } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp9, source); } @@ -27,27 +25,22 @@ void LocalFunction() { [InlineData("InlineData(42)")] [InlineData("MemberData(nameof(MyData))")] [InlineData("ClassData(typeof(TestClass))")] - public async Task LocalFunctionsCannotHaveTestAttributes(string attribute) + public async Task TestAttribute_Triggers(string attribute) { - var source = $@" -using System.Collections.Generic; -using Xunit; - -public class TestClass {{ - public void Method() {{ - [{attribute}] - void LocalFunction() {{ - }} - }} - - public static IEnumerable MyData; -}}"; - - var expected = - Verify - .Diagnostic() - .WithSpan(7, 10, 7, 10 + attribute.Length) - .WithArguments($"[{attribute}]"); + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; + + public class TestClass {{ + public void Method() {{ + [{{|#0:{0}|}}] + void LocalFunction() {{ }} + }} + + public static IEnumerable MyData; + }} + """, attribute); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"[{attribute}]"); await Verify.VerifyAnalyzer(LanguageVersion.CSharp9, source, expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/MemberDataShouldReferenceValidMemberTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/MemberDataShouldReferenceValidMemberTests.cs index d92defb5..c0f3a075 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/MemberDataShouldReferenceValidMemberTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/MemberDataShouldReferenceValidMemberTests.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Testing; using Xunit; @@ -9,95 +8,88 @@ public class MemberDataShouldReferenceValidMemberTests { public class X1014_MemberDataShouldUseNameOfOperator { - static readonly string sharedCode = @" -using System.Collections.Generic; -using Xunit; + static readonly string sharedCode = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public partial class TestClass { - public static TheoryData Data { get; set; } -} + public partial class TestClass { + public static TheoryData Data { get; set; } + } -public class OtherClass { - public static TheoryData OtherData { get; set; } -}"; + public class OtherClass { + public static TheoryData OtherData { get; set; } + } + """; [Fact] public async Task NameofOnSameClass_DoesNotTrigger() { - var source = @" -public partial class TestClass { - [Xunit.MemberData(nameof(Data))] - public void TestMethod(int _) { } -}"; + var source = /* lang=c#-test */ """ + public partial class TestClass { + [Xunit.MemberData(nameof(Data))] + public void TestMethod(int _) { } + } + """; - await Verify.VerifyAnalyzer(new[] { source, sharedCode }); + await Verify.VerifyAnalyzer([source, sharedCode]); } [Fact] public async Task NameofOnOtherClass_DoesNotTrigger() { - var source = @" -public partial class TestClass { - [Xunit.MemberData(nameof(OtherClass.OtherData), MemberType = typeof(OtherClass))] - public void TestMethod(int _) { } -}"; + var source = /* lang=c#-test */ """ + public partial class TestClass { + [Xunit.MemberData(nameof(OtherClass.OtherData), MemberType = typeof(OtherClass))] + public void TestMethod(int _) { } + } + """; - await Verify.VerifyAnalyzer(new[] { source, sharedCode }); + await Verify.VerifyAnalyzer([source, sharedCode]); } [Fact] public async Task StringNameOnSameClass_Triggers() { - var source = @" -public partial class TestClass { - [Xunit.MemberData(""Data"")] - public void TestMethod(int _) { } -}"; - var expected = - Verify - .Diagnostic("xUnit1014") - .WithSpan(3, 23, 3, 29) - .WithArguments("Data", "TestClass"); + var source = /* lang=c#-test */ """ + public partial class TestClass { + [Xunit.MemberData({|#0:"Data"|})] + public void TestMethod(int _) { } + } + """; + var expected = Verify.Diagnostic("xUnit1014").WithLocation(0).WithArguments("Data", "TestClass"); - await Verify.VerifyAnalyzer(new[] { source, sharedCode }, expected); + await Verify.VerifyAnalyzer([source, sharedCode], expected); } [Fact] public async Task StringNameOnOtherClass_Triggers() { - var source = @" -public partial class TestClass { - [Xunit.MemberData(""OtherData"", MemberType = typeof(OtherClass))] - public void TestMethod(int _) { } -}"; - var expected = - Verify - .Diagnostic("xUnit1014") - .WithSpan(3, 23, 3, 34) - .WithArguments("OtherData", "OtherClass"); + var source = /* lang=c#-test */ """ + public partial class TestClass { + [Xunit.MemberData({|#0:"OtherData"|}, MemberType = typeof(OtherClass))] + public void TestMethod(int _) { } + } + """; + var expected = Verify.Diagnostic("xUnit1014").WithLocation(0).WithArguments("OtherData", "OtherClass"); - await Verify.VerifyAnalyzer(new[] { source, sharedCode }, expected); + await Verify.VerifyAnalyzer([source, sharedCode], expected); } } public class X1015_MemberDataMustReferenceExistingMember { [Theory] - [InlineData("")] - [InlineData(", MemberType = typeof(TestClass)")] + [InlineData(/* lang=c#-test */ "")] + [InlineData(/* lang=c#-test */ ", MemberType = typeof(TestClass)")] public async Task InvalidStringNameOnSameClass_Triggers(string memberType) { - var source = @$" -public class TestClass {{ - [Xunit.MemberData(""BogusName""{memberType})] - public void TestMethod() {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1015") - .WithSpan(3, 6, 3, 35 + memberType.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("BogusName", "TestClass"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [{{|#0:Xunit.MemberData("BogusName"{0})|}}] + public void TestMethod() {{ }} + }} + """, memberType); + var expected = Verify.Diagnostic("xUnit1015").WithLocation(0).WithArguments("BogusName", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } @@ -105,39 +97,35 @@ public void TestMethod() {{ }} [Fact] public async Task InvalidStringNameOnOtherClass_Triggers() { - var source1 = @" -public class TestClass { - [Xunit.MemberData(""BogusName"", MemberType = typeof(OtherClass))] - public void TestMethod() { } -}"; - var source2 = "public class OtherClass { }"; - var expected = - Verify - .Diagnostic("xUnit1015") - .WithSpan(3, 6, 3, 68) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("BogusName", "OtherClass"); + var source1 = /* lang=c#-test */ """ + public class TestClass { + [{|#0:Xunit.MemberData("BogusName", MemberType = typeof(OtherClass))|}] + public void TestMethod() { } + } + """; + var source2 = /* lang=c#-test */ """ + public class OtherClass { } + """; + var expected = Verify.Diagnostic("xUnit1015").WithLocation(0).WithArguments("BogusName", "OtherClass"); - await Verify.VerifyAnalyzer(new[] { source1, source2 }, expected); + await Verify.VerifyAnalyzer([source1, source2], expected); } [Fact] public async Task InvalidNameofOnOtherClass_Triggers() { - var source1 = @" -public class TestClass { - [Xunit.MemberData(nameof(TestClass.TestMethod), MemberType = typeof(OtherClass))] - public void TestMethod() { } -}"; - var source2 = "public class OtherClass { }"; - var expected = - Verify - .Diagnostic("xUnit1015") - .WithSpan(3, 6, 3, 85) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("TestMethod", "OtherClass"); - - await Verify.VerifyAnalyzer(new[] { source1, source2 }, expected); + var source1 = /* lang=c#-test */ """ + public class TestClass { + [{|#0:Xunit.MemberData(nameof(TestClass.TestMethod), MemberType = typeof(OtherClass))|}] + public void TestMethod() { } + } + """; + var source2 = /* lang=c#-test */ """ + public class OtherClass { } + """; + var expected = Verify.Diagnostic("xUnit1015").WithLocation(0).WithArguments("TestMethod", "OtherClass"); + + await Verify.VerifyAnalyzer([source1, source2], expected); } } @@ -146,21 +134,22 @@ public class X1016_MemberDataMustReferencePublicMember [Fact] public async Task PublicMember_DoesNotTrigger() { - var source = @" -public class TestClass { - public static Xunit.TheoryData Data = null; + var source = /* lang=c#-test */ """ + public class TestClass { + public static Xunit.TheoryData Data = null; - [Xunit.MemberData(nameof(Data))] - public void TestMethod(int _) { } -}"; + [Xunit.MemberData(nameof(Data))] + public void TestMethod(int _) { } + } + """; await Verify.VerifyAnalyzer(source); } public static MatrixTheoryData NonPublicTestData => new( - new[] { "", "private", "protected", "internal", "protected internal" }, - new[] { "{|xUnit1014:\"Data\"|}", "DataNameConst", "DataNameofConst", "nameof(Data)", "nameof(TestClass.Data)", "OtherClass.Data", "nameof(OtherClass.Data)" } + /* lang=c#-test */ ["", "private", "protected", "internal", "protected internal"], + /* lang=c#-test */ ["{|xUnit1014:\"Data\"|}", "DataNameConst", "DataNameofConst", "nameof(Data)", "nameof(TestClass.Data)", "OtherClass.Data", "nameof(OtherClass.Data)"] ); [Theory] @@ -172,24 +161,22 @@ public async Task NonPublicNameExpression_Triggers( TestFileMarkupParser.GetPositionsAndSpans(dataNameExpression, out var parsedDataNameExpression, out _, out _); var dataNameExpressionLength = parsedDataNameExpression.Length; - var source1 = $@" -public class TestClass {{ - const string DataNameConst = ""Data""; - const string DataNameofConst = nameof(Data); + var source1 = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + const string DataNameConst = "Data"; + const string DataNameofConst = nameof(Data); - {accessModifier} static Xunit.TheoryData Data = null; + {0} static Xunit.TheoryData Data = null; - [Xunit.MemberData({dataNameExpression})] - public void TestMethod(int _) {{ }} -}}"; - var source2 = @"public static class OtherClass { public const string Data = ""Data""; }"; - var expected = - Verify - .Diagnostic("xUnit1016") - .WithSpan(8, 6, 8, 24 + dataNameExpressionLength) - .WithSeverity(DiagnosticSeverity.Error); + [{{|xUnit1016:Xunit.MemberData({1})|}}] + public void TestMethod(int _) {{ }} + }} + """, accessModifier, dataNameExpression); + var source2 = /* lang=c#-test */ """ + public static class OtherClass { public const string Data = "Data"; } + """; - await Verify.VerifyAnalyzer(new[] { source1, source2 }, expected); + await Verify.VerifyAnalyzer([source1, source2]); } } @@ -198,13 +185,14 @@ public class X1017_MemberDataMustReferenceStaticMember [Fact] public async Task StaticMember_DoesNotTrigger() { - var source = @" -public class TestClass { - public static Xunit.TheoryData Data = null; + var source = /* lang=c#-test */ """ + public class TestClass { + public static Xunit.TheoryData Data = null; - [Xunit.MemberData(nameof(Data))] - public void TestMethod(int _) { } -}"; + [Xunit.MemberData(nameof(Data))] + public void TestMethod(int _) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -212,62 +200,55 @@ public void TestMethod(int _) { } [Fact] public async Task InstanceMember_Triggers() { - var source = @" -public class TestClass { - public Xunit.TheoryData Data = null; + var source = /* lang=c#-test */ """ + public class TestClass { + public Xunit.TheoryData Data = null; - [Xunit.MemberData(nameof(Data))] - public void TestMethod(int _) { } -}"; - var expected = - Verify - .Diagnostic("xUnit1017") - .WithSpan(5, 6, 5, 36) - .WithSeverity(DiagnosticSeverity.Error); + [{|xUnit1017:Xunit.MemberData(nameof(Data))|}] + public void TestMethod(int _) { } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } public class X1018_MemberDataMustReferenceValidMemberKind { [Theory] - [InlineData("Data;")] - [InlineData("Data { get; set; }")] - [InlineData("Data() { return null; }")] + [InlineData(/* lang=c#-test */ "Data;")] + [InlineData(/* lang=c#-test */ "Data { get; set; }")] + [InlineData(/* lang=c#-test */ "Data() { return null; }")] public async Task ValidMemberKind_DoesNotTrigger(string member) { - var source = $@" -public class TestClass {{ - public static Xunit.TheoryData {member} + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + public static Xunit.TheoryData {0} - [Xunit.MemberData(nameof(Data))] - public void TestMethod(int _) {{ }} -}}"; + [Xunit.MemberData(nameof(Data))] + public void TestMethod(int _) {{ }} + }} + """, member); await Verify.VerifyAnalyzer(source); } [Theory] - [InlineData("public delegate System.Collections.Generic.IEnumerable Data();")] - [InlineData("public static class Data { }")] - [InlineData("public static event System.EventHandler Data;")] + [InlineData(/* lang=c#-test */ "public delegate System.Collections.Generic.IEnumerable Data();")] + [InlineData(/* lang=c#-test */ "public static class Data { }")] + [InlineData(/* lang=c#-test */ "public static event System.EventHandler Data;")] public async Task InvalidMemberKind_Triggers(string member) { - var source = $@" -public class TestClass {{ - {member} + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + {0} - [Xunit.MemberData(nameof(Data))] - public void TestMethod() {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1018") - .WithSpan(5, 6, 5, 36) - .WithSeverity(DiagnosticSeverity.Error); + [{{|xUnit1018:Xunit.MemberData(nameof(Data))|}}] + public void TestMethod() {{ }} + }} + """, member); - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } @@ -280,130 +261,115 @@ public class X1019_MemberDataMustReferenceMemberOfValidType [Fact] public async Task TheoryData_DoesNotTrigger() { - var source = @" -using System.Collections.Generic; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass { - public static TheoryData Data; + public class TestClass { + public static TheoryData Data; - [MemberData(nameof(Data))] - public void TestMethod(int _) { } -}"; + [MemberData(nameof(Data))] + public void TestMethod(int _) { } + } + """; await Verify.VerifyAnalyzer(source); } [Theory] - [InlineData("Task")] - [InlineData("ValueTask")] + [InlineData(/* lang=c#-test */ "Task")] + [InlineData(/* lang=c#-test */ "ValueTask")] public async Task Async_TheoryData_TriggersInV2_DoesNotTriggerInV3(string taskType) { - var source = @$" -using System.Collections.Generic; -using System.Threading.Tasks; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using System.Threading.Tasks; + using Xunit; -public class TestClass {{ - public static {taskType}> Data; + public class TestClass {{ + public static {0}> Data; - [MemberData(nameof(Data))] - public void TestMethod(int _) {{ }} -}}"; - var expectedV2 = - Verify - .Diagnostic("xUnit1019") - .WithSpan(9, 6, 9, 30) - .WithArguments("'System.Collections.Generic.IEnumerable'", $"System.Threading.Tasks.{taskType}>"); + [{{|#0:MemberData(nameof(Data))|}}] + public void TestMethod(int _) {{ }} + }} + """, taskType); + var expectedV2 = Verify.Diagnostic("xUnit1019").WithLocation(0).WithArguments("'System.Collections.Generic.IEnumerable'", $"System.Threading.Tasks.{taskType}>"); await Verify.VerifyAnalyzerV2(LanguageVersion.CSharp9, source, expectedV2); await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, source); } [Theory] - [InlineData("List>")] - [InlineData("IAsyncEnumerable>")] + [InlineData(/* lang=c#-test */ "List>")] + [InlineData(/* lang=c#-test */ "IAsyncEnumerable>")] public async Task GenericTheoryDataRow_DoesNotTrigger(string dataType) { - var source = @$" -using System; -using System.Collections.Generic; -using Xunit; -using Xunit.Sdk; + var source = string.Format(/* lang=c#-test */ """ + using System; + using System.Collections.Generic; + using Xunit; + using Xunit.Sdk; -public class TestClass -{{ - [Theory] - [MemberData(nameof(DataRowSource))] - public void SkippedDataRow(int x, string y) - {{ }} + public class TestClass {{ + [Theory] + [MemberData(nameof(DataRowSource))] + public void SkippedDataRow(int x, string y) {{ }} - public static {dataType} DataRowSource() {{ - throw new NotImplementedException(); - }} -}}"; + public static {0} DataRowSource() {{ + throw new NotImplementedException(); + }} + }} + """, dataType); await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, source); } [Theory] - [InlineData("Task>>")] - [InlineData("ValueTask>>")] + [InlineData(/* lang=c#-test */ "Task>>")] + [InlineData(/* lang=c#-test */ "ValueTask>>")] public async Task Async_GenericTheoryDataRow_DoesNotTrigger(string taskType) { - var source = @$" -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Xunit; -using Xunit.Sdk; + var source = string.Format(/* lang=c#-test */ """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + using Xunit; + using Xunit.Sdk; -public class TestClass -{{ - [Theory] - [MemberData(nameof(DataRowSource))] - public void SkippedDataRow(int x, string y) - {{ }} + public class TestClass {{ + [Theory] + [MemberData(nameof(DataRowSource))] + public void SkippedDataRow(int x, string y) {{ }} - public static async {taskType} DataRowSource() {{ - throw new NotImplementedException(); - }} -}}"; + public static async {0} DataRowSource() {{ + throw new NotImplementedException(); + }} + }} + """, taskType); await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, source); } [Theory] - [InlineData("System.Collections.Generic.IEnumerable")] - [InlineData("object[]")] - [InlineData("object")] - [InlineData("System.Tuple")] - [InlineData("System.Tuple[]")] + [InlineData(/* lang=c#-test */ "System.Collections.Generic.IEnumerable")] + [InlineData(/* lang=c#-test */ "object[]")] + [InlineData(/* lang=c#-test */ "object")] + [InlineData(/* lang=c#-test */ "System.Tuple")] + [InlineData(/* lang=c#-test */ "System.Tuple[]")] public async Task InvalidMemberType_Triggers(string memberType) { - var source = $@" -public class TestClass {{ - public static {memberType} Data; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + public static {0} Data; - [Xunit.MemberData(nameof(Data))] - public void TestMethod() {{ }} -}}"; - var expectedV2 = - Verify - .Diagnostic("xUnit1019") - .WithSpan(5, 6, 5, 36) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("'System.Collections.Generic.IEnumerable'", memberType); + [{{|#0:Xunit.MemberData(nameof(Data))|}}] + public void TestMethod() {{ }} + }} + """, memberType); + var expectedV2 = Verify.Diagnostic("xUnit1019").WithLocation(0).WithArguments("'System.Collections.Generic.IEnumerable'", memberType); + var expectedV3 = Verify.Diagnostic("xUnit1019").WithLocation(0).WithArguments("'System.Collections.Generic.IEnumerable', 'System.Collections.Generic.IAsyncEnumerable', 'System.Collections.Generic.IEnumerable', or 'System.Collections.Generic.IAsyncEnumerable'", memberType); await Verify.VerifyAnalyzerV2(source, expectedV2); - - var expectedV3 = - Verify - .Diagnostic("xUnit1019") - .WithSpan(5, 6, 5, 36) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("'System.Collections.Generic.IEnumerable', 'System.Collections.Generic.IAsyncEnumerable', 'System.Collections.Generic.IEnumerable', or 'System.Collections.Generic.IAsyncEnumerable'", memberType); - await Verify.VerifyAnalyzerV3(source, expectedV3); } } @@ -413,189 +379,153 @@ public class X1020_MemberDataPropertyMustHaveGetter [Fact] public async Task PropertyWithoutGetter_Triggers() { - var source = @" -public class TestClass { - public static Xunit.TheoryData Data { set { } } + var source = /* lang=c#-test */ """ + public class TestClass { + public static Xunit.TheoryData Data { set { } } - [Xunit.MemberData(nameof(Data))] - public void TestMethod(int _) { } -}"; - var expected = - Verify - .Diagnostic("xUnit1020") - .WithSpan(5, 6, 5, 36) - .WithSeverity(DiagnosticSeverity.Error); + [{|xUnit1020:Xunit.MemberData(nameof(Data))|}] + public void TestMethod(int _) { } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } [Theory] - [InlineData("internal")] - [InlineData("protected")] - [InlineData("private")] + [InlineData(/* lang=c#-test */ "internal")] + [InlineData(/* lang=c#-test */ "protected")] + [InlineData(/* lang=c#-test */ "private")] public async Task PropertyWithNonPublicGetter_Triggers(string visibility) { - var source = $@" -public class TestClass {{ - public static Xunit.TheoryData Data {{ {visibility} get {{ return null; }} set {{ }} }} + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + public static Xunit.TheoryData Data {{ {0} get {{ return null; }} set {{ }} }} - [Xunit.MemberData(nameof(Data))] - public void TestMethod(int _) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1020") - .WithSpan(5, 6, 5, 36) - .WithSeverity(DiagnosticSeverity.Error); + [{{|xUnit1020:Xunit.MemberData(nameof(Data))|}}] + public void TestMethod(int _) {{ }} + }} + """, visibility); - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } public class X1021_MemberDataNonMethodShouldNotHaveParameters { [Theory] - [InlineData("1")] // implicit params - [InlineData("new object[] { 1 }")] // explicit params + [InlineData(/* lang=c#-test */ "1")] // implicit params + [InlineData(/* lang=c#-test */ "new object[] { 1 }")] // explicit params public async Task MethodMemberWithParameters_DoesNotTrigger(string parameter) { - var source = @$" -public class TestClass {{ - private static void TestData() {{ }} + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + private static void TestData() {{ }} - public static Xunit.TheoryData TestData(int n) => new Xunit.TheoryData {{ n }}; - - [Xunit.MemberData(nameof(TestData), {parameter})] - public void TestMethod(int n) {{ }} -}}"; + public static Xunit.TheoryData TestData(int n) => new Xunit.TheoryData {{ n }}; + [Xunit.MemberData(nameof(TestData), {0})] + public void TestMethod(int n) {{ }} + }} + """, parameter); await Verify.VerifyAnalyzer(source); } [Theory] - [InlineData("1, 2")] // implicit params - [InlineData("new object[] { 1, 2 }")] // explicit params + [InlineData(/* lang=c#-test */ "1, 2")] // implicit params + [InlineData(/* lang=c#-test */ "new object[] { 1, 2 }")] // explicit params public async Task MethodMemberWithParamsArrayParameters_DoesNotTrigger(string parameters) { - var source = @$" -public class TestClass {{ - public static Xunit.TheoryData TestData(params int[] n) => new Xunit.TheoryData {{ n[0] }}; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + public static Xunit.TheoryData TestData(params int[] n) => new Xunit.TheoryData {{ n[0] }}; - [Xunit.MemberData(nameof(TestData), {parameters})] - public void TestMethod(int n) {{ }} -}}"; + [Xunit.MemberData(nameof(TestData), {0})] + public void TestMethod(int n) {{ }} + }} + """, parameters); await Verify.VerifyAnalyzer(source); } [Theory] - [InlineData("1")] // implicit params - [InlineData("new object[] { 1 }")] // explicit params + [InlineData(/* lang=c#-test */ "1")] // implicit params + [InlineData(/* lang=c#-test */ "new object[] { 1 }")] // explicit params public async Task MethodMemberOnBaseType_DoesNotTrigger(string parameter) { - var source = $@" -public class TestClassBase {{ - public static Xunit.TheoryData TestData(int n) => new Xunit.TheoryData {{ n }}; -}} + var source = string.Format(/* lang=c#-test */ """ + public class TestClassBase {{ + public static Xunit.TheoryData TestData(int n) => new Xunit.TheoryData {{ n }}; + }} -public class TestClass : TestClassBase {{ - private static void TestData() {{ }} + public class TestClass : TestClassBase {{ + private static void TestData() {{ }} - [Xunit.MemberData(nameof(TestData), {parameter})] - public void TestMethod(int n) {{ }} -}}"; + [Xunit.MemberData(nameof(TestData), {0})] + public void TestMethod(int n) {{ }} + }} + """, parameter); await Verify.VerifyAnalyzer(source); } [Theory] - [InlineData("'a', 123")] - [InlineData("new object[] {{ 'a', 123 }}")] - [InlineData("{0}: new object[] {{ 'a', 123 }}")] + [InlineData(/* lang=c#-test */ "'a', 123")] + [InlineData(/* lang=c#-test */ "new object[] {{ 'a', 123 }}")] + [InlineData(/* lang=c#-test */ "{0}: new object[] {{ 'a', 123 }}")] public async Task FieldMemberWithParameters_Triggers(string paramsArgument) { - var sourceTemplate = @" -public class TestClass {{ - public static Xunit.TheoryData Data; - - [Xunit.MemberData(nameof(Data), {0}, MemberType = typeof(TestClass))] - public void TestMethod(int _) {{ }} -}}"; + var sourceTemplate = /* lang=c#-test */ """ + public class TestClass {{ + public static Xunit.TheoryData Data; - var argV2 = string.Format(paramsArgument, "parameters"); - var sourceV2 = string.Format(sourceTemplate, argV2); - var expectedV2 = - Verify - .Diagnostic("xUnit1021") - .WithSpan(5, 37, 5, 37 + argV2.Length) - .WithSeverity(DiagnosticSeverity.Warning); + [Xunit.MemberData(nameof(Data), {{|xUnit1021:{0}|}}, MemberType = typeof(TestClass))] + public void TestMethod(int _) {{ }} + }} + """; - await Verify.VerifyAnalyzerV2(sourceV2, expectedV2); - - var argV3 = string.Format(paramsArgument, "arguments"); - var sourceV3 = string.Format(sourceTemplate, argV3); - var expectedV3 = - Verify - .Diagnostic("xUnit1021") - .WithSpan(5, 37, 5, 37 + argV3.Length) - .WithSeverity(DiagnosticSeverity.Warning); - - await Verify.VerifyAnalyzerV3(sourceV3, expectedV3); + await Verify.VerifyAnalyzerV2(string.Format(sourceTemplate, string.Format(paramsArgument, "parameters"))); + await Verify.VerifyAnalyzerV3(string.Format(sourceTemplate, string.Format(paramsArgument, "arguments"))); } [Theory] - [InlineData("'a', 123")] - [InlineData("new object[] {{ 'a', 123 }}")] - [InlineData("{0}: new object[] {{ 'a', 123 }}")] + [InlineData(/* lang=c#-test */ "'a', 123")] + [InlineData(/* lang=c#-test */ "new object[] {{ 'a', 123 }}")] + [InlineData(/* lang=c#-test */ "{0}: new object[] {{ 'a', 123 }}")] public async Task PropertyMemberWithParameters_Triggers(string paramsArgument) { - var sourceTemplate = @" -public class TestClass {{ - public static Xunit.TheoryData Data {{ get; set; }} - - [Xunit.MemberData(nameof(Data), {0}, MemberType = typeof(TestClass))] - public void TestMethod(int _) {{ }} -}}"; - - var argV2 = string.Format(paramsArgument, "parameters"); - var sourceV2 = string.Format(sourceTemplate, argV2); - var expectedV2 = - Verify - .Diagnostic("xUnit1021") - .WithSpan(5, 37, 5, 37 + argV2.Length) - .WithSeverity(DiagnosticSeverity.Warning); + var sourceTemplate = /* lang=c#-test */ """ + public class TestClass {{ + public static Xunit.TheoryData Data {{ get; set; }} - await Verify.VerifyAnalyzerV2(sourceV2, expectedV2); + [Xunit.MemberData(nameof(Data), {{|xUnit1021:{0}|}}, MemberType = typeof(TestClass))] + public void TestMethod(int _) {{ }} + }} + """; - var argV3 = string.Format(paramsArgument, "arguments"); - var sourceV3 = string.Format(sourceTemplate, argV3); - var expectedV3 = - Verify - .Diagnostic("xUnit1021") - .WithSpan(5, 37, 5, 37 + argV3.Length) - .WithSeverity(DiagnosticSeverity.Warning); - - await Verify.VerifyAnalyzerV3(sourceV3, expectedV3); + await Verify.VerifyAnalyzerV2(string.Format(sourceTemplate, string.Format(paramsArgument, "parameters"))); + await Verify.VerifyAnalyzerV3(string.Format(sourceTemplate, string.Format(paramsArgument, "arguments"))); } } public class X1034_MemberDataArgumentsMustMatchMethodParameters_NullShouldNotBeUsedForIncompatibleParameter { [Theory] - [InlineData("", "string")] - [InlineData("#nullable enable", "string?")] + [InlineData(/* lang=c#-test */ "", "string")] + [InlineData(/* lang=c#-test */ "#nullable enable", "string?")] public async Task PassingNullForNullableReferenceType_DoesNotTrigger( string header, string argumentType) { - var source = $@" -{header} -public class TestClass {{ - public static Xunit.TheoryData TestData({argumentType} f) => new Xunit.TheoryData {{ 42 }}; + var source = string.Format(/* lang=c#-test */ """ + {0} + + public class TestClass {{ + public static Xunit.TheoryData TestData({1} f) => new Xunit.TheoryData {{ 42 }}; - [Xunit.MemberData(nameof(TestData), new object[] {{ null }})] - public void TestMethod(int _) {{ }} -}}"; + [Xunit.MemberData(nameof(TestData), new object[] {{ null }})] + public void TestMethod(int _) {{ }} + }} + """, header, argumentType); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source); } @@ -603,20 +533,15 @@ public void TestMethod(int _) {{ }} [Fact] public async Task PassingNullForStructType_Triggers() { - var source = @" -public class TestClass { - public static Xunit.TheoryData TestData(int n) => new Xunit.TheoryData { n }; - - [Xunit.MemberData(nameof(TestData), new object[] { null })] - public void TestMethod(int _) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + public static Xunit.TheoryData TestData(int n) => new Xunit.TheoryData { n }; - var expected = - Verify - .Diagnostic("xUnit1034") - .WithSpan(5, 56, 5, 60) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("n", "int"); + [Xunit.MemberData(nameof(TestData), new object[] { {|#0:null|} })] + public void TestMethod(int _) { } + } + """; + var expected = Verify.Diagnostic("xUnit1034").WithLocation(0).WithArguments("n", "int"); await Verify.VerifyAnalyzer(source, expected); } @@ -624,22 +549,17 @@ public void TestMethod(int _) { } [Fact] public async Task PassingNullForNonNullableReferenceType_Triggers() { - var source = @" -#nullable enable -public class TestClass { - public static Xunit.TheoryData TestData(string f) => new Xunit.TheoryData { f }; + var source = /* lang=c#-test */ """ + #nullable enable - [Xunit.MemberData(nameof(TestData), new object[] { null })] - public void TestMethod(string _) { } -} -#nullable restore"; + public class TestClass { + public static Xunit.TheoryData TestData(string f) => new Xunit.TheoryData { f }; - var expected = - Verify - .Diagnostic("xUnit1034") - .WithSpan(6, 56, 6, 60) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("f", "string"); + [Xunit.MemberData(nameof(TestData), new object[] { {|#0:null|} })] + public void TestMethod(string _) { } + } + """; + var expected = Verify.Diagnostic("xUnit1034").WithLocation(0).WithArguments("f", "string"); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source, expected); } @@ -649,74 +569,73 @@ public class X1035_MemberDataArgumentsMustMatchMethodParameters_IncompatibleValu { // https://github.com/xunit/xunit/issues/2817 [Theory] - [InlineData("Foo.Bar")] - [InlineData("(Foo)42")] + [InlineData(/* lang=c#-test */ "Foo.Bar")] + [InlineData(/* lang=c#-test */ "(Foo)42")] public async Task ValidEnumValue_DoesNotTrigger(string enumValue) { - var source = $@" -using System; -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System; + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - [Theory] - [MemberData(nameof(SomeData), {enumValue})] - public void TestMethod(int _) {{ }} + public class TestClass {{ + [Theory] + [MemberData(nameof(SomeData), {0})] + public void TestMethod(int _) {{ }} - public enum Foo {{ Bar }} + public enum Foo {{ Bar }} - public static Xunit.TheoryData SomeData(Foo foo) => new Xunit.TheoryData(); -}}"; + public static Xunit.TheoryData SomeData(Foo foo) => new Xunit.TheoryData(); + }} + """, enumValue); await Verify.VerifyAnalyzer(source); } // https://github.com/xunit/xunit/issues/2852 [Theory] - [InlineData("")] - [InlineData("#nullable enable")] + [InlineData(/* lang=c#-test */ "")] + [InlineData(/* lang=c#-test */ "#nullable enable")] public async Task ArrayInitializerWithCorrectType_DoesNotTrigger(string header) { - var source = $@" -{header} + var source = string.Format(/* lang=c#-test */ """ + {0} -using System.Collections.Generic; -using Xunit; + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - public static TheoryData GetSequences(IEnumerable seq) => new TheoryData {{ 42, 2112 }}; + public class TestClass {{ + public static TheoryData GetSequences(IEnumerable seq) => new TheoryData {{ 42, 2112 }}; - [Theory] - [MemberData(nameof(GetSequences), new int[] {{ 1, 2 }})] - public void Test(int value) {{ }} -}}"; + [Theory] + [MemberData(nameof(GetSequences), new int[] {{ 1, 2 }})] + public void Test(int value) {{ }} + }} + """, header); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source); } [Theory] - [InlineData("")] - [InlineData("#nullable enable")] + [InlineData(/* lang=c#-test */ "")] + [InlineData(/* lang=c#-test */ "#nullable enable")] public async Task ArrayInitializerWithIncorrectType_Triggers(string header) { - var source = $@" -{header} + var source = string.Format(/* lang=c#-test */ """ + {0} -using System.Collections.Generic; -using Xunit; + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - public static TheoryData GetSequences(IEnumerable seq) => new TheoryData {{ 42, 2112 }}; + public class TestClass {{ + public static TheoryData GetSequences(IEnumerable seq) => new TheoryData {{ 42, 2112 }}; - [Theory] - [MemberData(nameof(GetSequences), new char[] {{ 'a', 'b' }})] - public void Test(int value) {{ }} -}}"; - var expected = - Verify - .Diagnostic("xUnit1035") - .WithSpan(11, 39, 11, 62) - .WithArguments("seq", "System.Collections.Generic.IEnumerable"); + [Theory] + [MemberData(nameof(GetSequences), {{|#0:new char[] {{ 'a', 'b' }}|}})] + public void Test(int value) {{ }} + }} + """, header); + var expected = Verify.Diagnostic("xUnit1035").WithLocation(0).WithArguments("seq", "System.Collections.Generic.IEnumerable"); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source, expected); } @@ -724,19 +643,15 @@ public void Test(int value) {{ }} [Fact] public async Task ValidMemberWithIncorrectArgumentTypes_Triggers() { - var source = @" -public class TestClass { - public static Xunit.TheoryData TestData(string n) => new Xunit.TheoryData { n.Length }; + var source = /* lang=c#-test */ """ + public class TestClass { + public static Xunit.TheoryData TestData(string n) => new Xunit.TheoryData { n.Length }; - [Xunit.MemberData(nameof(TestData), new object[] { 1 })] - public void TestMethod(int n) { } -}"; - - var expected = - Verify - .Diagnostic("xUnit1035") - .WithSpan(5, 56, 5, 57) - .WithArguments("n", "string"); + [Xunit.MemberData(nameof(TestData), new object[] { {|#0:1|} })] + public void TestMethod(int n) { } + } + """; + var expected = Verify.Diagnostic("xUnit1035").WithLocation(0).WithArguments("n", "string"); await Verify.VerifyAnalyzer(source, expected); } @@ -744,19 +659,15 @@ public void TestMethod(int n) { } [Fact] public async Task ValidMemberWithIncorrectArgumentTypesParams_Triggers() { - var source = @" -public class TestClass { - public static Xunit.TheoryData TestData(params int[] n) => new Xunit.TheoryData { n[0] }; - - [Xunit.MemberData(nameof(TestData), new object[] { 1, ""bob"" })] - public void TestMethod(int n) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + public static Xunit.TheoryData TestData(params int[] n) => new Xunit.TheoryData { n[0] }; - var expected = - Verify - .Diagnostic("xUnit1035") - .WithSpan(5, 59, 5, 64) - .WithArguments("n", "int"); + [Xunit.MemberData(nameof(TestData), new object[] { 1, {|#0:"bob"|} })] + public void TestMethod(int n) { } + } + """; + var expected = Verify.Diagnostic("xUnit1035").WithLocation(0).WithArguments("n", "int"); await Verify.VerifyAnalyzer(source, expected); } @@ -765,61 +676,57 @@ public void TestMethod(int n) { } public class X1036_MemberDataArgumentsMustMatchMethodParameters_ExtraValue { [Theory] - [InlineData("1")] - [InlineData("new object[] { 1 }")] + [InlineData(/* lang=c#-test */ "1")] + [InlineData(/* lang=c#-test */ "new object[] { 1 }")] public async Task ValidArgumentCount_DoesNotTrigger(string parameter) { - var source = $@" -public class TestClass {{ - private static void TestData() {{ }} + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + private static void TestData() {{ }} - public static Xunit.TheoryData TestData(int n) => new Xunit.TheoryData {{ n }}; + public static Xunit.TheoryData TestData(int n) => new Xunit.TheoryData {{ n }}; - [Xunit.MemberData(nameof(TestData), {parameter})] - public void TestMethod(int n) {{ }} -}}"; + [Xunit.MemberData(nameof(TestData), {0})] + public void TestMethod(int n) {{ }} + }} + """, parameter); await Verify.VerifyAnalyzer(source); } [Theory] - [InlineData("1")] - [InlineData("new object[] { 1 }")] + [InlineData(/* lang=c#-test */ "1")] + [InlineData(/* lang=c#-test */ "new object[] { 1 }")] public async Task ValidArgumentCount_InNullableContext_DoesNotTrigger(string parameter) { - var source = $@" -#nullable enable -public class TestClass {{ - public static Xunit.TheoryData TestData(int n) => new Xunit.TheoryData {{ n }}; + var source = string.Format(/* lang=c#-test */ """ + #nullable enable + + public class TestClass {{ + public static Xunit.TheoryData TestData(int n) => new Xunit.TheoryData {{ n }}; - [Xunit.MemberData(nameof(TestData), {parameter})] - public void TestMethod(int n) {{ }} -}} -#nullable restore"; + [Xunit.MemberData(nameof(TestData), {0})] + public void TestMethod(int n) {{ }} + }} + """, parameter); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source); } [Theory] - [InlineData("1, 2", 44)] - [InlineData("new object[] { 1, 2 }", 59)] - public async Task TooManyArguments_Triggers( - string parameters, - int startColumn) - { - var source = $@" -public class TestClass {{ - public static Xunit.TheoryData TestData(int n) => new Xunit.TheoryData {{ n }}; - - [Xunit.MemberData(nameof(TestData), {parameters})] - public void TestMethod(int n) {{ }} -}}"; - - var expected = - Verify - .Diagnostic("xUnit1036") - .WithSpan(5, startColumn, 5, startColumn + 1) - .WithArguments("2"); + [InlineData(/* lang=c#-test */ "1, {|#0:2|}")] + [InlineData(/* lang=c#-test */ "new object[] { 1, {|#0:2|} }")] + public async Task TooManyArguments_Triggers(string parameters) + { + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + public static Xunit.TheoryData TestData(int n) => new Xunit.TheoryData {{ n }}; + + [Xunit.MemberData(nameof(TestData), {0})] + public void TestMethod(int n) {{ }} + }} + """, parameters); + var expected = Verify.Diagnostic("xUnit1036").WithLocation(0).WithArguments("2"); await Verify.VerifyAnalyzer(source, expected); } @@ -829,10 +736,10 @@ public class X1037_TheoryDataTypeArgumentsMustMatchTestMethodParameters_TooFewTy { public static TheoryData MemberSyntaxAndArgs = new() { - { " = ", "" }, // Field - { " => ", "" }, // Property - { "() => ", "" }, // Method w/o args - { "(int n) => ", ", 42" }, // Method w/ args + /* lang=c#-test */ { " = ", "" }, // Field + /* lang=c#-test */ { " => ", "" }, // Property + /* lang=c#-test */ { "() => ", "" }, // Method w/o args + /* lang=c#-test */ { "(int n) => ", ", 42" }, // Method w/ args }; [Theory] @@ -841,22 +748,17 @@ public async Task ValidTheoryDataMemberWithNotEnoughTypeParameters_Triggers( string memberSyntax, string memberArgs) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - public static TheoryData TestData{memberSyntax}new TheoryData(); + public class TestClass {{ + public static TheoryData TestData{0}new TheoryData(); - [MemberData(nameof(TestData){memberArgs})] - public void TestMethod(int n, string f) {{ }} -}}"; - - var expected = - Verify - .Diagnostic("xUnit1037") - .WithSpan(7, 6, 7, 34 + memberArgs.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Xunit.TheoryData"); + [{{|#0:MemberData(nameof(TestData){1})|}}] + public void TestMethod(int n, string f) {{ }} + }} + """, memberSyntax, memberArgs); + var expected = Verify.Diagnostic("xUnit1037").WithLocation(0).WithArguments("Xunit.TheoryData"); await Verify.VerifyAnalyzer(source, expected); } @@ -867,23 +769,18 @@ public async Task ValidTheoryDataRowMemberWithNotEnoughTypeParameters_Triggers( string memberSyntax, string memberArgs) { - var source = $@" -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - public static IEnumerable> TestData{memberSyntax}null; + public class TestClass {{ + public static IEnumerable> TestData{0}null; - [MemberData(nameof(TestData){memberArgs})] - public void TestMethod(int n, string f) {{ }} -}}"; - - var expected = - Verify - .Diagnostic("xUnit1037") - .WithSpan(8, 6, 8, 34 + memberArgs.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Xunit.TheoryDataRow"); + [{{|#0:MemberData(nameof(TestData){1})|}}] + public void TestMethod(int n, string f) {{ }} + }} + """, memberSyntax, memberArgs); + var expected = Verify.Diagnostic("xUnit1037").WithLocation(0).WithArguments("Xunit.TheoryDataRow"); await Verify.VerifyAnalyzerV3(source, expected); } @@ -894,24 +791,19 @@ public async Task ValidSubclassedTheoryDataMemberWithNotEnoughTypeParameters_Tri string memberSyntax, string memberArgs) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} -public class TestClass {{ - public static DerivedTheoryData TestData{memberSyntax}new DerivedTheoryData(); + public class TestClass {{ + public static DerivedTheoryData TestData{0}new DerivedTheoryData(); - [MemberData(nameof(TestData){memberArgs})] - public void TestMethod(int n, string f) {{ }} -}}"; - - var expected = - Verify - .Diagnostic("xUnit1037") - .WithSpan(9, 6, 9, 34 + memberArgs.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Xunit.TheoryData"); + [{{|#0:MemberData(nameof(TestData){1})|}}] + public void TestMethod(int n, string f) {{ }} + }} + """, memberSyntax, memberArgs); + var expected = Verify.Diagnostic("xUnit1037").WithLocation(0).WithArguments("Xunit.TheoryData"); await Verify.VerifyAnalyzer(source, expected); } @@ -919,30 +811,27 @@ public void TestMethod(int n, string f) {{ }} public class X1038_TheoryDataTypeArgumentsMustMatchTestMethodParameters_ExtraTypeParameters { - public static TheoryData MemberSyntaxAndArgs() => - new() { - { " = ", "" }, // Field - { " => ", "" }, // Property - { "() => ", "" }, // Method w/o args - { "(int n) => ", ", 42" }, // Method w/ args - }; - - public static MatrixTheoryData<(string syntax, string args), string> MemberSyntaxAndArgs_WithTheoryDataType(string theoryDataTypes) => - new( - new[] - { - ( " = ", "" ), // Field - ( " => ", "" ), // Property - ( "() => ", "" ), // Method w/o args - ( "(int n) => ", ", 42" ), // Method w/ args - }, - new[] - { - $"TheoryData<{theoryDataTypes}>", - "DerivedTheoryData", - $"DerivedTheoryData<{theoryDataTypes}>" - } - ); + public static TheoryData MemberSyntaxAndArgs() => new() + { + { " = ", "" }, // Field + { " => ", "" }, // Property + { "() => ", "" }, // Method w/o args + { "(int n) => ", ", 42" }, // Method w/ args + }; + + public static MatrixTheoryData<(string syntax, string args), string> MemberSyntaxAndArgs_WithTheoryDataType(string theoryDataTypes) => new( + [ + (" = ", ""), // Field + (" => ", ""), // Property + ("() => ", ""), // Method w/o args + ("(int n) => ", ", 42"), // Method w/ args + ], + [ + $"TheoryData<{theoryDataTypes}>", + "DerivedTheoryData", + $"DerivedTheoryData<{theoryDataTypes}>" + ] + ); [Theory] [MemberData(nameof(MemberSyntaxAndArgs_WithTheoryDataType), "int", DisableDiscoveryEnumeration = true)] @@ -950,18 +839,19 @@ public async Task ValidTheoryData_DoesNotTrigger( (string syntax, string args) member, string theoryDataType) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public class DerivedTheoryData : TheoryData {{ }} -public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} -public class TestClass {{ - public static {theoryDataType} TestData{member.syntax}new {theoryDataType}(); + public class TestClass {{ + public static {2} TestData{0}new {2}(); - [MemberData(nameof(TestData){member.args})] - public void TestMethod(int n) {{ }} -}}"; + [MemberData(nameof(TestData){1})] + public void TestMethod(int n) {{ }} + }} + """, member.syntax, member.args, theoryDataType); await Verify.VerifyAnalyzer(source); } @@ -972,16 +862,17 @@ public async Task ValidTheoryDataRow_DoesNotTrigger( string memberSyntax, string memberArgs) { - var source = $@" -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - public static IEnumerable> TestData{memberSyntax}new List>(); + public class TestClass {{ + public static IEnumerable> TestData{0}new List>(); - [MemberData(nameof(TestData){memberArgs})] - public void TestMethod(int n) {{ }} -}}"; + [MemberData(nameof(TestData){1})] + public void TestMethod(int n) {{ }} + }} + """, memberSyntax, memberArgs); await Verify.VerifyAnalyzerV3(source); } @@ -992,18 +883,19 @@ public async Task ValidTheoryDataWithOptionalParameters_DoesNotTrigger( (string syntax, string args) member, string theoryDataType) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public class DerivedTheoryData : TheoryData {{ }} -public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} -public class TestClass {{ - public static {theoryDataType} TestData{member.syntax}new {theoryDataType}(); + public class TestClass {{ + public static {2} TestData{0}new {2}(); - [MemberData(nameof(TestData){member.args})] - public void TestMethod(int n, int a = 0) {{ }} -}}"; + [MemberData(nameof(TestData){1})] + public void TestMethod(int n, int a = 0) {{ }} + }} + """, member.syntax, member.args, theoryDataType); await Verify.VerifyAnalyzer(source); } @@ -1014,16 +906,17 @@ public async Task ValidTheoryDataRowWithOptionalParameters_DoesNotTrigger( string memberSyntax, string memberArgs) { - var source = $@" -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - public static TheoryDataRow[] TestData{memberSyntax}new TheoryDataRow[0]; + public class TestClass {{ + public static TheoryDataRow[] TestData{0}new TheoryDataRow[0]; - [MemberData(nameof(TestData){memberArgs})] - public void TestMethod(int n, int a = 0) {{ }} -}}"; + [MemberData(nameof(TestData){1})] + public void TestMethod(int n, int a = 0) {{ }} + }} + """, memberSyntax, memberArgs); await Verify.VerifyAnalyzerV3(source); } @@ -1034,18 +927,19 @@ public async Task ValidTheoryDataWithNoValuesForParamsArray_DoesNotTrigger( (string syntax, string args) member, string theoryDataType) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public class DerivedTheoryData : TheoryData {{ }} -public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} -public class TestClass {{ - public static {theoryDataType} TestData{member.syntax}new {theoryDataType}(); + public class TestClass {{ + public static {2} TestData{0}new {2}(); - [MemberData(nameof(TestData){member.args})] - public void TestMethod(int n, params int[] a) {{ }} -}}"; + [MemberData(nameof(TestData){1})] + public void TestMethod(int n, params int[] a) {{ }} + }} + """, member.syntax, member.args, theoryDataType); await Verify.VerifyAnalyzer(source); } @@ -1056,16 +950,17 @@ public async Task ValidTheoryDataRowWithNoValuesForParamsArray_DoesNotTrigger( string memberSyntax, string memberArgs) { - var source = $@" -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - public static ICollection> TestData{memberSyntax}new List>(); + public class TestClass {{ + public static ICollection> TestData{0}new List>(); - [MemberData(nameof(TestData){memberArgs})] - public void TestMethod(int n, params int[] a) {{ }} -}}"; + [MemberData(nameof(TestData){1})] + public void TestMethod(int n, params int[] a) {{ }} + }} + """, memberSyntax, memberArgs); await Verify.VerifyAnalyzerV3(source); } @@ -1076,18 +971,19 @@ public async Task ValidTheoryDataWithSingleValueForParamsArray_DoesNotTrigger( (string syntax, string args) member, string theoryDataType) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public class DerivedTheoryData : TheoryData {{ }} -public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} -public class TestClass {{ - public static {theoryDataType} TestData{member.syntax}new {theoryDataType}(); + public class TestClass {{ + public static {2} TestData{0}new {2}(); - [MemberData(nameof(TestData){member.args})] - public void TestMethod(int n, params int[] a) {{ }} -}}"; + [MemberData(nameof(TestData){1})] + public void TestMethod(int n, params int[] a) {{ }} + }} + """, member.syntax, member.args, theoryDataType); await Verify.VerifyAnalyzer(source); } @@ -1098,16 +994,17 @@ public async Task ValidTheoryDataRowWithSingleValueForParamsArray_DoesNotTrigger string memberSyntax, string memberArgs) { - var source = $@" -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - public static IEnumerable> TestData{memberSyntax}new List>(); + public class TestClass {{ + public static IEnumerable> TestData{0}new List>(); - [MemberData(nameof(TestData){memberArgs})] - public void TestMethod(int n, params int[] a) {{ }} -}}"; + [MemberData(nameof(TestData){1})] + public void TestMethod(int n, params int[] a) {{ }} + }} + """, memberSyntax, memberArgs); await Verify.VerifyAnalyzerV3(source); } @@ -1118,18 +1015,19 @@ public async Task ValidTheoryDataWithGenericTestParameter_DoesNotTrigger( (string syntax, string args) member, string theoryDataType) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public class DerivedTheoryData : TheoryData {{ }} -public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} -public class TestClass {{ - public static {theoryDataType} TestData{member.syntax}new {theoryDataType}(); + public class TestClass {{ + public static {2} TestData{0}new {2}(); - [MemberData(nameof(TestData){member.args})] - public void TestMethod(T n) {{ }} -}}"; + [MemberData(nameof(TestData){1})] + public void TestMethod(T n) {{ }} + }} + """, member.syntax, member.args, theoryDataType); await Verify.VerifyAnalyzer(source); } @@ -1140,16 +1038,17 @@ public async Task ValidTheoryDataRowWithGenericTestParameter_DoesNotTrigger( string memberSyntax, string memberArgs) { - var source = $@" -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - public static ISet> TestData{memberSyntax}new HashSet>(); + public class TestClass {{ + public static ISet> TestData{0}new HashSet>(); - [MemberData(nameof(TestData){memberArgs})] - public void TestMethod(T n) {{ }} -}}"; + [MemberData(nameof(TestData){1})] + public void TestMethod(T n) {{ }} + }} + """, memberSyntax, memberArgs); await Verify.VerifyAnalyzerV3(source); } @@ -1160,20 +1059,21 @@ public async Task ValidTheoryDataWithNullableGenericTestParameter_DoesNotTrigger (string syntax, string args) member, string theoryDataType) { - var source = $@" -#nullable enable + var source = string.Format(/* lang=c#-test */ """ + #nullable enable -using Xunit; + using Xunit; -public class DerivedTheoryData : TheoryData {{ }} -public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} -public class TestClass {{ - public static {theoryDataType} TestData{member.syntax}new {theoryDataType}(); + public class TestClass {{ + public static {2} TestData{0}new {2}(); - [Xunit.MemberData(nameof(TestData){member.args})] - public void TestMethod(T? n) {{ }} -}}"; + [Xunit.MemberData(nameof(TestData){1})] + public void TestMethod(T? n) {{ }} + }} + """, member.syntax, member.args, theoryDataType); await Verify.VerifyAnalyzer(LanguageVersion.CSharp9, source); } @@ -1184,18 +1084,19 @@ public async Task ValidTheoryDataRowWithNullableGenericTestParameter_DoesNotTrig string memberSyntax, string memberArgs) { - var source = $@" -#nullable enable + var source = string.Format(/* lang=c#-test */ """ + #nullable enable -using System.Collections.Generic; -using Xunit; + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - public static IEnumerable> TestData{memberSyntax}new List>(); + public class TestClass {{ + public static IEnumerable> TestData{0}new List>(); - [Xunit.MemberData(nameof(TestData){memberArgs})] - public void TestMethod(T? n) {{ }} -}}"; + [Xunit.MemberData(nameof(TestData){1})] + public void TestMethod(T? n) {{ }} + }} + """, memberSyntax, memberArgs); await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp9, source); } @@ -1206,17 +1107,18 @@ public async Task ValidTheoryDataDoubleGenericSubclassMember_DoesNotTrigger( string memberSyntax, string memberArgs) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} -public class TestClass {{ - public static DerivedTheoryData TestData{memberSyntax}new DerivedTheoryData(); + public class TestClass {{ + public static DerivedTheoryData TestData{0}new DerivedTheoryData(); - [MemberData(nameof(TestData){memberArgs})] - public void TestMethod(int n) {{ }} -}}"; + [MemberData(nameof(TestData){1})] + public void TestMethod(int n) {{ }} + }} + """, memberSyntax, memberArgs); await Verify.VerifyAnalyzer(source); } @@ -1224,20 +1126,21 @@ public void TestMethod(int n) {{ }} [Fact] public async Task WithIntArrayArguments_DoesNotTrigger() { - var source = @" -using System.Collections.Generic; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass { - public static TheoryData> GetSequences(IEnumerable seq) => new TheoryData> { seq }; + public class TestClass { + public static TheoryData> GetSequences(IEnumerable seq) => new TheoryData> { seq }; - [Theory] - [MemberData(nameof(GetSequences), new[] { 1, 2 })] - [MemberData(nameof(GetSequences), new[] { 3, 4, 5 })] - public void Test(IEnumerable seq) { - Assert.NotEmpty(seq); - } -}"; + [Theory] + [MemberData(nameof(GetSequences), new[] { 1, 2 })] + [MemberData(nameof(GetSequences), new[] { 3, 4, 5 })] + public void Test(IEnumerable seq) { + Assert.NotEmpty(seq); + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -1248,25 +1151,20 @@ public async Task ValidSubclassTheoryDataMemberWithTooManyTypeParameters_Trigger (string syntax, string args) member, string theoryDataType) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public class DerivedTheoryData : TheoryData {{ }} -public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} -public class TestClass {{ - public static {theoryDataType} TestData{member.syntax}new {theoryDataType}(); + public class TestClass {{ + public static {2} TestData{0}new {2}(); - [MemberData(nameof(TestData){member.args})] - public void TestMethod(int n) {{ }} -}}"; - - var expected = - Verify - .Diagnostic("xUnit1038") - .WithSpan(10, 6, 10, 34 + member.args.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Xunit.TheoryData"); + [{{|#0:MemberData(nameof(TestData){1})|}}] + public void TestMethod(int n) {{ }} + }} + """, member.syntax, member.args, theoryDataType); + var expected = Verify.Diagnostic("xUnit1038").WithLocation(0).WithArguments("Xunit.TheoryData"); await Verify.VerifyAnalyzer(source, expected); } @@ -1277,23 +1175,18 @@ public async Task ValidSubclassTheoryDataRowMemberWithTooManyTypeParameters_Trig string memberSyntax, string memberArgs) { - var source = $@" -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - public static IEnumerable> TestData{memberSyntax}new List>(); + public class TestClass {{ + public static IEnumerable> TestData{0}new List>(); - [MemberData(nameof(TestData){memberArgs})] - public void TestMethod(int n) {{ }} -}}"; - - var expected = - Verify - .Diagnostic("xUnit1038") - .WithSpan(8, 6, 8, 34 + memberArgs.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Xunit.TheoryDataRow"); + [{{|#0:MemberData(nameof(TestData){1})|}}] + public void TestMethod(int n) {{ }} + }} + """, memberSyntax, memberArgs); + var expected = Verify.Diagnostic("xUnit1038").WithLocation(0).WithArguments("Xunit.TheoryDataRow"); await Verify.VerifyAnalyzerV3(source, expected); } @@ -1304,25 +1197,20 @@ public async Task ExtraTheoryDataTypeExistsPastArrayForParamsArray_Triggers( (string syntax, string args) member, string theoryDataType) { - var source = $@" -using Xunit; - -public class DerivedTheoryData : TheoryData {{ }} -public class DerivedTheoryData : TheoryData {{ }} + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - public static {theoryDataType} TestData{member.syntax}new {theoryDataType}(); + public class DerivedTheoryData : TheoryData {{ }} + public class DerivedTheoryData : TheoryData {{ }} - [MemberData(nameof(TestData){member.args})] - public void PuzzleOne(int _1, params string[] _2) {{ }} -}}"; + public class TestClass {{ + public static {2} TestData{0}new {2}(); - var expected = - Verify - .Diagnostic("xUnit1038") - .WithSpan(10, 6, 10, 34 + member.args.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Xunit.TheoryData"); + [{{|#0:MemberData(nameof(TestData){1})|}}] + public void PuzzleOne(int _1, params string[] _2) {{ }} + }} + """, member.syntax, member.args, theoryDataType); + var expected = Verify.Diagnostic("xUnit1038").WithLocation(0).WithArguments("Xunit.TheoryData"); await Verify.VerifyAnalyzer(source, expected); } @@ -1333,23 +1221,18 @@ public async Task ExtraTheoryDataRowTypeExistsPastArrayForParamsArray_Triggers( string memberSyntax, string memberArgs) { - var source = $@" -using System.Collections.Generic; -using Xunit; - -public class TestClass {{ - public static ICollection> TestData{memberSyntax}new TheoryDataRow[0]; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; - [MemberData(nameof(TestData){memberArgs})] - public void PuzzleOne(int _1, params string[] _2) {{ }} -}}"; + public class TestClass {{ + public static ICollection> TestData{0}new TheoryDataRow[0]; - var expected = - Verify - .Diagnostic("xUnit1038") - .WithSpan(8, 6, 8, 34 + memberArgs.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Xunit.TheoryDataRow"); + [{{|#0:MemberData(nameof(TestData){1})|}}] + public void PuzzleOne(int _1, params string[] _2) {{ }} + }} + """, memberSyntax, memberArgs); + var expected = Verify.Diagnostic("xUnit1038").WithLocation(0).WithArguments("Xunit.TheoryDataRow"); await Verify.VerifyAnalyzerV3(source, expected); } @@ -1357,34 +1240,32 @@ public void PuzzleOne(int _1, params string[] _2) {{ }} public class X1039_TheoryDataTypeArgumentsMustMatchTestMethodParameters_IncompatibleTypes { - public static MatrixTheoryData<(string syntax, string args), string> TypeWithMemberSyntaxAndArgs = - new( - new[] - { - ( " = ", "" ), // Field - ( " => ", "" ), // Property - ( "() => ", "" ), // Method w/o args - ( "(int n) => ", ", 42" ), // Method w/ args - }, - new[] - { - "int", - "System.Exception", - } - ); + public static MatrixTheoryData<(string syntax, string args), string> TypeWithMemberSyntaxAndArgs = new( + [ + (" = ", ""), // Field + (" => ", ""), // Property + ("() => ", ""), // Method w/o args + ("(int n) => ", ", 42"), // Method w/ args + ], + [ + "int", + "System.Exception", + ] + ); [Fact] public async Task WhenPassingMultipleValuesForParamsArray_TheoryData_DoesNotTrigger() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - public static TheoryData TestData = new TheoryData(); + public class TestClass { + public static TheoryData TestData = new TheoryData(); - [MemberData(nameof(TestData))] - public void PuzzleOne(int _1, params string[] _2) { } -}"; + [MemberData(nameof(TestData))] + public void PuzzleOne(int _1, params string[] _2) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -1392,16 +1273,17 @@ public void PuzzleOne(int _1, params string[] _2) { } [Fact] public async Task WhenPassingMultipleValuesForParamsArray_TheoryDataRow_DoesNotTrigger() { - var source = @" -using System.Collections.Generic; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass { - public static IEnumerable> TestData = new List>(); + public class TestClass { + public static IEnumerable> TestData = new List>(); - [MemberData(nameof(TestData))] - public void PuzzleOne(int _1, params string[] _2) { } -}"; + [MemberData(nameof(TestData))] + public void PuzzleOne(int _1, params string[] _2) { } + } + """; await Verify.VerifyAnalyzerV3(source); } @@ -1409,15 +1291,16 @@ public void PuzzleOne(int _1, params string[] _2) { } [Fact] public async Task WhenPassingArrayForParamsArray_TheoryData_DoesNotTrigger() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - public static TheoryData TestData = new TheoryData(); + public class TestClass { + public static TheoryData TestData = new TheoryData(); - [MemberData(nameof(TestData))] - public void PuzzleOne(int _1, params string[] _2) { } -}"; + [MemberData(nameof(TestData))] + public void PuzzleOne(int _1, params string[] _2) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -1425,15 +1308,16 @@ public void PuzzleOne(int _1, params string[] _2) { } [Fact] public async Task WhenPassingArrayForParamsArray_TheoryDataRow_DoesNotTrigger() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - public static TheoryDataRow[] TestData = new TheoryDataRow[0]; + public class TestClass { + public static TheoryDataRow[] TestData = new TheoryDataRow[0]; - [MemberData(nameof(TestData))] - public void PuzzleOne(int _1, params string[] _2) { } -}"; + [MemberData(nameof(TestData))] + public void PuzzleOne(int _1, params string[] _2) { } + } + """; await Verify.VerifyAnalyzerV3(source); } @@ -1441,15 +1325,16 @@ public void PuzzleOne(int _1, params string[] _2) { } [Fact] public async Task WhenPassingTupleWithoutFieldNames_TheoryData_DoesNotTrigger() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - public static TheoryData<(int, int)> TestData = new TheoryData<(int, int)>(); + public class TestClass { + public static TheoryData<(int, int)> TestData = new TheoryData<(int, int)>(); - [MemberData(nameof(TestData))] - public void TestMethod((int a, int b) x) { } -}"; + [MemberData(nameof(TestData))] + public void TestMethod((int a, int b) x) { } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source); } @@ -1457,16 +1342,17 @@ public void TestMethod((int a, int b) x) { } [Fact] public async Task WhenPassingTupleWithoutFieldNames_TheoryDataRow_DoesNotTrigger() { - var source = @" -using System.Collections.Generic; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass { - public static IList> TestData = new List>(); + public class TestClass { + public static IList> TestData = new List>(); - [MemberData(nameof(TestData))] - public void TestMethod((int a, int b) x) { } -}"; + [MemberData(nameof(TestData))] + public void TestMethod((int a, int b) x) { } + } + """; await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp8, source); } @@ -1474,15 +1360,16 @@ public void TestMethod((int a, int b) x) { } [Fact] public async Task WhenPassingTupleWithDifferentFieldNames_TheoryData_DoesNotTrigger() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - public static TheoryData<(int c, int d)> TestData = new TheoryData<(int, int)>(); + public class TestClass { + public static TheoryData<(int c, int d)> TestData = new TheoryData<(int, int)>(); - [MemberData(nameof(TestData))] - public void TestMethod((int a, int b) x) { } -}"; + [MemberData(nameof(TestData))] + public void TestMethod((int a, int b) x) { } + } + """; await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source); } @@ -1490,16 +1377,17 @@ public void TestMethod((int a, int b) x) { } [Fact] public async Task WhenPassingTupleWithDifferentFieldNames_TheoryDataRow_DoesNotTrigger() { - var source = @" -using System.Collections.Generic; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass { - public static IEnumerable> TestData = new List>(); + public class TestClass { + public static IEnumerable> TestData = new List>(); - [MemberData(nameof(TestData))] - public void TestMethod((int a, int b) x) { } -}"; + [MemberData(nameof(TestData))] + public void TestMethod((int a, int b) x) { } + } + """; await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp8, source); } @@ -1507,22 +1395,17 @@ public void TestMethod((int a, int b) x) { } [Fact] public async Task WithExtraValueNotCompatibleWithParamsArray_TheoryData_Triggers() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - public static TheoryData TestData = new TheoryData(); + public class TestClass { + public static TheoryData TestData = new TheoryData(); - [MemberData(nameof(TestData))] - public void PuzzleOne(int _1, params string[] _2) { } -}"; - - var expected = - Verify - .Diagnostic("xUnit1039") - .WithSpan(8, 42, 8, 50) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("int", "TestClass.TestData", "_2"); + [MemberData(nameof(TestData))] + public void PuzzleOne(int _1, params {|#0:string[]|} _2) { } + } + """; + var expected = Verify.Diagnostic("xUnit1039").WithLocation(0).WithArguments("int", "TestClass.TestData", "_2"); await Verify.VerifyAnalyzer(source, expected); } @@ -1530,23 +1413,18 @@ public void PuzzleOne(int _1, params string[] _2) { } [Fact] public async Task WithExtraValueNotCompatibleWithParamsArray_TheoryDataRow_Triggers() { - var source = @" -using System.Collections.Generic; -using Xunit; - -public class TestClass { - public static IEnumerable> TestData = new List>(); + var source = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; - [MemberData(nameof(TestData))] - public void PuzzleOne(int _1, params string[] _2) { } -}"; + public class TestClass { + public static IEnumerable> TestData = new List>(); - var expected = - Verify - .Diagnostic("xUnit1039") - .WithSpan(9, 42, 9, 50) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("int", "TestClass.TestData", "_2"); + [MemberData(nameof(TestData))] + public void PuzzleOne(int _1, params {|#0:string[]|} _2) { } + } + """; + var expected = Verify.Diagnostic("xUnit1039").WithLocation(0).WithArguments("int", "TestClass.TestData", "_2"); await Verify.VerifyAnalyzerV3(source, expected); } @@ -1557,22 +1435,17 @@ public async Task ValidTheoryDataMemberWithIncompatibleTypeParameters_Triggers( (string syntax, string args) member, string type) { - var source = $@" -using Xunit; - -public class TestClass {{ - public static TheoryData<{type}> TestData{member.syntax}new TheoryData<{type}>(); + var source = string.Format(/* lang=c#-test */ """ + using Xunit; - [MemberData(nameof(TestData){member.args})] - public void TestMethod(string f) {{ }} -}}"; + public class TestClass {{ + public static TheoryData<{2}> TestData{0}new TheoryData<{2}>(); - var expected = - Verify - .Diagnostic("xUnit1039") - .WithSpan(8, 28, 8, 34) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments(type, "TestClass.TestData", "f"); + [MemberData(nameof(TestData){1})] + public void TestMethod({{|#0:string|}} f) {{ }} + }} + """, member.syntax, member.args, type); + var expected = Verify.Diagnostic("xUnit1039").WithLocation(0).WithArguments(type, "TestClass.TestData", "f"); await Verify.VerifyAnalyzer(source, expected); } @@ -1583,23 +1456,18 @@ public async Task ValidTheoryDataRowMemberWithIncompatibleTypeParameters_Trigger (string syntax, string args) member, string type) { - var source = $@" -using System.Collections.Generic; -using Xunit; - -public class TestClass {{ - public static IList> TestData{member.syntax}new List>(); + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; - [MemberData(nameof(TestData){member.args})] - public void TestMethod(string f) {{ }} -}}"; + public class TestClass {{ + public static IList> TestData{0}new List>(); - var expected = - Verify - .Diagnostic("xUnit1039") - .WithSpan(9, 28, 9, 34) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments(type, "TestClass.TestData", "f"); + [MemberData(nameof(TestData){1})] + public void TestMethod({{|#0:string|}} f) {{ }} + }} + """, member.syntax, member.args, type); + var expected = Verify.Diagnostic("xUnit1039").WithLocation(0).WithArguments(type, "TestClass.TestData", "f"); await Verify.VerifyAnalyzerV3(source, expected); } @@ -1609,10 +1477,10 @@ public class X1040_TheoryDataTypeArgumentsMustMatchTestMethodParameters_Incompat { public static TheoryData MemberSyntaxAndArgs = new() { - { " = ", "" }, // Field - { " => ", "" }, // Property - { "() => ", "" }, // Method w/o args - { "(int n) => ", ", 42" }, // Method w/ args + /* lang=c#-test */ { " = ", "" }, // Field + /* lang=c#-test */ { " => ", "" }, // Property + /* lang=c#-test */ { "() => ", "" }, // Method w/o args + /* lang=c#-test */ { "(int n) => ", ", 42" }, // Method w/ args }; [Theory] @@ -1621,24 +1489,19 @@ public async Task ValidTheoryDataMemberWithMismatchedNullability_Triggers( string memberSyntax, string memberArgs) { - var source = $@" -#nullable enable + var source = string.Format(/* lang=c#-test */ """ + #nullable enable -using Xunit; + using Xunit; -public class TestClass {{ - public static TheoryData TestData{memberSyntax}new TheoryData(); + public class TestClass {{ + public static TheoryData TestData{0}new TheoryData(); - [MemberData(nameof(TestData){memberArgs})] - public void TestMethod(string f) {{ }} -}}"; - - var expected = - Verify - .Diagnostic("xUnit1040") - .WithSpan(10, 28, 10, 34) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("string?", "TestClass.TestData", "f"); + [MemberData(nameof(TestData){1})] + public void TestMethod({{|#0:string|}} f) {{ }} + }} + """, memberSyntax, memberArgs); + var expected = Verify.Diagnostic("xUnit1040").WithLocation(0).WithArguments("string?", "TestClass.TestData", "f"); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source, expected); } @@ -1649,25 +1512,20 @@ public async Task ValidTheoryDataRowMemberWithMismatchedNullability_Triggers( string memberSyntax, string memberArgs) { - var source = $@" -#nullable enable + var source = string.Format(/* lang=c#-test */ """ + #nullable enable -using System.Collections.Generic; -using Xunit; + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - public static IEnumerable> TestData{memberSyntax}new List>(); + public class TestClass {{ + public static IEnumerable> TestData{0}new List>(); - [MemberData(nameof(TestData){memberArgs})] - public void TestMethod(string f) {{ }} -}}"; - - var expected = - Verify - .Diagnostic("xUnit1040") - .WithSpan(11, 28, 11, 34) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("string?", "TestClass.TestData", "f"); + [MemberData(nameof(TestData){1})] + public void TestMethod({{|#0:string|}} f) {{ }} + }} + """, memberSyntax, memberArgs); + var expected = Verify.Diagnostic("xUnit1040").WithLocation(0).WithArguments("string?", "TestClass.TestData", "f"); await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp8, source, expected); } @@ -1678,16 +1536,17 @@ public class X1042_MemberDataTheoryDataIsRecommendedForStronglyTypedAnalysis [Fact] public async Task TheoryData_DoesNotTrigger() { - var source = @" -using System.Collections.Generic; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass { - public static TheoryData Data; + public class TestClass { + public static TheoryData Data; - [MemberData(nameof(Data))] - public void TestMethod(int _) { } -}"; + [MemberData(nameof(Data))] + public void TestMethod(int _) { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -1695,38 +1554,40 @@ public void TestMethod(int _) { } [Fact] public async Task MatrixTheoryData_DoesNotTrigger() { - var source = @" -using System.Collections.Generic; -using Xunit; + var source = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass { - public static MatrixTheoryData Data; + public class TestClass { + public static MatrixTheoryData Data; - [MemberData(nameof(Data))] - public void TestMethod(int _1, string _2) { } -}"; + [MemberData(nameof(Data))] + public void TestMethod(int _1, string _2) { } + } + """; await Verify.VerifyAnalyzerV3(source); } [Theory] - [InlineData("IEnumerable>")] - [InlineData("IAsyncEnumerable>")] - [InlineData("List>")] - [InlineData("TheoryDataRow[]")] + [InlineData(/* lang=c#-test */ "IEnumerable>")] + [InlineData(/* lang=c#-test */ "IAsyncEnumerable>")] + [InlineData(/* lang=c#-test */ "List>")] + [InlineData(/* lang=c#-test */ "TheoryDataRow[]")] public async Task GenericTheoryDataRow_DoesNotTrigger(string memberType) { - var source = $@" -using System.Collections.Generic; -using Xunit; -using Xunit.v3; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; + using Xunit.v3; -public class TestClass {{ - public static {memberType} Data; + public class TestClass {{ + public static {0} Data; - [MemberData(nameof(Data))] - public void TestMethod(int _) {{ }} -}}"; + [MemberData(nameof(Data))] + public void TestMethod(int _) {{ }} + }} + """, memberType); await Verify.VerifyAnalyzerV3(source); } @@ -1736,29 +1597,19 @@ public void TestMethod(int _) {{ }} [InlineData("List")] public async Task ValidTypesWhichAreNotTheoryData_Trigger(string memberType) { - var source = $@" -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; + + public class TestClass {{ + public static {0} Data; -public class TestClass {{ - public static {memberType} Data; - - [MemberData(nameof(Data))] - public void TestMethod(int _) {{ }} -}}"; - - var expectedV2 = - Verify - .Diagnostic("xUnit1042") - .WithSpan(8, 6, 8, 30) - .WithSeverity(DiagnosticSeverity.Info) - .WithArguments("TheoryData<>"); - var expectedV3 = - Verify - .Diagnostic("xUnit1042") - .WithSpan(8, 6, 8, 30) - .WithSeverity(DiagnosticSeverity.Info) - .WithArguments("TheoryData<> or IEnumerable>"); + [{{|#0:MemberData(nameof(Data))|}}] + public void TestMethod(int _) {{ }} + }} + """, memberType); + var expectedV2 = Verify.Diagnostic("xUnit1042").WithLocation(0).WithArguments("TheoryData<>"); + var expectedV3 = Verify.Diagnostic("xUnit1042").WithLocation(0).WithArguments("TheoryData<> or IEnumerable>"); await Verify.VerifyAnalyzerV2(source, expectedV2); await Verify.VerifyAnalyzerV3(source, expectedV3); @@ -1767,47 +1618,41 @@ public void TestMethod(int _) {{ }} // For v2, we test for xUnit1019 above, since it's incompatible rather than "compatible, // but you could do better". [Theory] - [InlineData("IAsyncEnumerable")] - [InlineData("Task>")] - [InlineData("ValueTask>")] - [InlineData("IEnumerable")] - [InlineData("IAsyncEnumerable")] - [InlineData("Task>")] - [InlineData("Task>")] - [InlineData("ValueTask>")] - [InlineData("IEnumerable")] - [InlineData("Task>")] - [InlineData("Task>")] - [InlineData("ValueTask")] + [InlineData(/* lang=c#-test */ "IAsyncEnumerable")] + [InlineData(/* lang=c#-test */ "Task>")] + [InlineData(/* lang=c#-test */ "ValueTask>")] + [InlineData(/* lang=c#-test */ "IEnumerable")] + [InlineData(/* lang=c#-test */ "IAsyncEnumerable")] + [InlineData(/* lang=c#-test */ "Task>")] + [InlineData(/* lang=c#-test */ "Task>")] + [InlineData(/* lang=c#-test */ "ValueTask>")] + [InlineData(/* lang=c#-test */ "IEnumerable")] + [InlineData(/* lang=c#-test */ "Task>")] + [InlineData(/* lang=c#-test */ "Task>")] + [InlineData(/* lang=c#-test */ "ValueTask")] public async Task ValidTypesWhichAreNotTheoryDataOrGenericTheoryDataRow_TriggersInV3(string memberType) { - var source = $@" -using System.Collections; -using System.Collections.Generic; -using System.Threading.Tasks; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections; + using System.Collections.Generic; + using System.Threading.Tasks; + using Xunit; -public class TestClass {{ - public static {memberType} Data; + public class TestClass {{ + public static {0} Data; - [MemberData(nameof(Data))] - public void TestMethod(int _) {{ }} -}} + [{{|#0:MemberData(nameof(Data))|}}] + public void TestMethod(int _) {{ }} + }} -public class EnumerableOfITheoryDataRow : IEnumerable -{{ - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -}}"; + public class EnumerableOfITheoryDataRow : IEnumerable {{ + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + }} + """, memberType); + var expected = Verify.Diagnostic("xUnit1042").WithLocation(0).WithArguments("TheoryData<> or IEnumerable>"); - var expectedV2 = - Verify - .Diagnostic("xUnit1042") - .WithSpan(10, 6, 10, 30) - .WithSeverity(DiagnosticSeverity.Info) - .WithArguments("TheoryData<> or IEnumerable>"); - - await Verify.VerifyAnalyzerV3(source, expectedV2); + await Verify.VerifyAnalyzerV3(source, expected); } } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/PublicMethodShouldBeMarkedAsTestTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/PublicMethodShouldBeMarkedAsTestTests.cs index bdd29f64..3fbfa4d1 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/PublicMethodShouldBeMarkedAsTestTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/PublicMethodShouldBeMarkedAsTestTests.cs @@ -1,307 +1,310 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Verify = CSharpVerifier; public class PublicMethodShouldBeMarkedAsTestTests { [Fact] - public async Task DoesNotFindErrorForPublicMethodInNonTestClass() + public async Task PublicMethodInNonTestClass_DoesNotTrigger() { - var source = @" -public class TestClass { - public void TestMethod() { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } [Theory] - [InlineData("Xunit.Fact")] - [InlineData("Xunit.Theory")] - public async Task DoesNotFindErrorForTestMethods(string attribute) + [InlineData(/* lang=c#-test */ "Xunit.Fact")] + [InlineData(/* lang=c#-test */ "Xunit.Theory")] + public async Task TestMethods_DoesNotTrigger(string attribute) { - var source = $@" -public class TestClass {{ - [{attribute}] - public void TestMethod() {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [{0}] + public void TestMethod() {{ }} + }} + """, attribute); await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindErrorForIDisposableDisposeMethod() + public async Task IDisposableDisposeMethod_DoesNotTrigger() { - var source = @" -public class TestClass: System.IDisposable { - [Xunit.Fact] - public void TestMethod() { } + var source = /* lang=c#-test */ """ + public class TestClass: System.IDisposable { + [Xunit.Fact] + public void TestMethod() { } - public void Dispose() { } -}"; + public void Dispose() { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindErrorForPublicAbstractMethod() + public async Task PublicAbstractMethod_DoesNotTrigger() { - var source = @" -public abstract class TestClass { - [Xunit.Fact] - public void TestMethod() { } + var source = /* lang=c#-test */ """ + public abstract class TestClass { + [Xunit.Fact] + public void TestMethod() { } - public abstract void AbstractMethod(); -}"; + public abstract void AbstractMethod(); + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindErrorForDerivedMethodWithFactOnBaseAbstractMethod() + public async Task DerivedMethodWithFactOnBaseAbstractMethod_DoesNotTrigger() { - var source = @" -public abstract class BaseClass { - [Xunit.Fact] - public abstract void TestMethod(); -} + var source = /* lang=c#-test */ """ + public abstract class BaseClass { + [Xunit.Fact] + public abstract void TestMethod(); + } -public class TestClass : BaseClass { - public override void TestMethod() { } + public class TestClass : BaseClass { + public override void TestMethod() { } - [Xunit.Fact] - public void TestMethod2() { } -}"; + [Xunit.Fact] + public void TestMethod2() { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindErrorForPublicAbstractMethodMarkedWithFact() + public async Task PublicAbstractMethodMarkedWithFact_DoesNotTrigger() { - var source = @" -public abstract class TestClass { - [Xunit.Fact] - public void TestMethod() { } + var source = /* lang=c#-test */ """ + public abstract class TestClass { + [Xunit.Fact] + public void TestMethod() { } - [Xunit.Fact] - public abstract void AbstractMethod(); -}"; + [Xunit.Fact] + public abstract void AbstractMethod(); + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindErrorForIDisposableDisposeMethodOverrideFromParentClass() + public async Task IDisposableDisposeMethodOverrideFromParentClass_DoesNotTrigger() { - var source = @" -public class BaseClass: System.IDisposable { - public virtual void Dispose() { } -} + var source = /* lang=c#-test */ """ + public class BaseClass: System.IDisposable { + public virtual void Dispose() { } + } -public class TestClass: BaseClass { - [Xunit.Fact] - public void TestMethod() { } + public class TestClass: BaseClass { + [Xunit.Fact] + public void TestMethod() { } - public override void Dispose() { } -}"; + public override void Dispose() { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindErrorForIDisposableDisposeMethodOverrideFromParentClassWithRepeatedInterfaceDeclaration() + public async Task IDisposableDisposeMethodOverrideFromParentClassWithRepeatedInterfaceDeclaration_DoesNotTrigger() { - var source = @" -public class BaseClass: System.IDisposable { - public virtual void Dispose() { } -} + var source = /* lang=c#-test */ """ + public class BaseClass: System.IDisposable { + public virtual void Dispose() { } + } -public class TestClass: BaseClass, System.IDisposable { - [Xunit.Fact] - public void TestMethod() { } + public class TestClass: BaseClass, System.IDisposable { + [Xunit.Fact] + public void TestMethod() { } - public override void Dispose() { } -}"; + public override void Dispose() { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindErrorForIDisposableDisposeMethodOverrideFromGrandParentClass() + public async Task IDisposableDisposeMethodOverrideFromGrandParentClass_DoesNotTrigger() { - var source = @" -public abstract class BaseClass: System.IDisposable { - public abstract void Dispose(); -} + var source = /* lang=c#-test */ """ + public abstract class BaseClass: System.IDisposable { + public abstract void Dispose(); + } -public abstract class IntermediateClass: BaseClass { } + public abstract class IntermediateClass: BaseClass { } -public class TestClass: IntermediateClass { - [Xunit.Fact] - public void TestMethod() { } + public class TestClass: IntermediateClass { + [Xunit.Fact] + public void TestMethod() { } - public override void Dispose() { } -}"; + public override void Dispose() { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindErrorForIAsyncLifetimeMethods_V2() + public async Task IAsyncLifetimeMethods_V2_DoesNotTrigger() { - var source = @" -public class TestClass: Xunit.IAsyncLifetime { - [Xunit.Fact] - public void TestMethod() { } - - public System.Threading.Tasks.Task DisposeAsync() - { - throw new System.NotImplementedException(); - } - - public System.Threading.Tasks.Task InitializeAsync() - { - throw new System.NotImplementedException(); - } -}"; + var source = /* lang=c#-test */ """ + public class TestClass: Xunit.IAsyncLifetime { + [Xunit.Fact] + public void TestMethod() { } + + public System.Threading.Tasks.Task DisposeAsync() + { + throw new System.NotImplementedException(); + } + + public System.Threading.Tasks.Task InitializeAsync() + { + throw new System.NotImplementedException(); + } + } + """; await Verify.VerifyAnalyzerV2(source); } [Fact] - public async Task DoesNotFindErrorForIAsyncLifetimeMethods_V3() + public async Task IAsyncLifetimeMethods_V3_DoesNotTrigger() { - var source = @" -public class TestClass: Xunit.IAsyncLifetime { - [Xunit.Fact] - public void TestMethod() { } - - public System.Threading.Tasks.ValueTask DisposeAsync() - { - throw new System.NotImplementedException(); - } - - public System.Threading.Tasks.ValueTask InitializeAsync() - { - throw new System.NotImplementedException(); - } -}"; + var source = /* lang=c#-test */ """ + public class TestClass: Xunit.IAsyncLifetime { + [Xunit.Fact] + public void TestMethod() { } + + public System.Threading.Tasks.ValueTask DisposeAsync() + { + throw new System.NotImplementedException(); + } + + public System.Threading.Tasks.ValueTask InitializeAsync() + { + throw new System.NotImplementedException(); + } + } + """; await Verify.VerifyAnalyzerV3(source); } [Fact] - public async Task DoesNotFindErrorForPublicMethodMarkedWithAttributeWhichIsMarkedWithIgnoreXunitAnalyzersRule1013() + public async Task PublicMethodMarkedWithAttributeWhichIsMarkedWithIgnoreXunitAnalyzersRule1013_DoesNotTrigger() { - var source = @" -public class IgnoreXunitAnalyzersRule1013Attribute: System.Attribute { } + var source = /* lang=c#-test */ """ + public class IgnoreXunitAnalyzersRule1013Attribute: System.Attribute { } -[IgnoreXunitAnalyzersRule1013] -public class CustomTestTypeAttribute: System.Attribute { } + [IgnoreXunitAnalyzersRule1013] + public class CustomTestTypeAttribute: System.Attribute { } -public class TestClass { - [Xunit.Fact] - public void TestMethod() { } + public class TestClass { + [Xunit.Fact] + public void TestMethod() { } - [CustomTestType] - public void CustomTestMethod() { } -}"; + [CustomTestType] + public void CustomTestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FindsWarningForPublicMethodMarkedWithAttributeWhichInheritsFromAttributeMarkedWithIgnoreXunitAnalyzersRule1013() + public async Task PublicMethodMarkedWithAttributeWhichInheritsFromAttributeMarkedWithIgnoreXunitAnalyzersRule1013_Triggers() { - var source = @" -public class IgnoreXunitAnalyzersRule1013Attribute: System.Attribute { } + var source = /* lang=c#-test */ """ + public class IgnoreXunitAnalyzersRule1013Attribute: System.Attribute { } -[IgnoreXunitAnalyzersRule1013] -public class BaseCustomTestTypeAttribute: System.Attribute { } + [IgnoreXunitAnalyzersRule1013] + public class BaseCustomTestTypeAttribute: System.Attribute { } -public class DerivedCustomTestTypeAttribute: BaseCustomTestTypeAttribute { } + public class DerivedCustomTestTypeAttribute: BaseCustomTestTypeAttribute { } -public class TestClass { - [Xunit.Fact] - public void TestMethod() { } + public class TestClass { + [Xunit.Fact] + public void TestMethod() { } - [DerivedCustomTestType] - public void CustomTestMethod() { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(14, 17, 14, 33) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("CustomTestMethod", "TestClass", "Fact"); + [DerivedCustomTestType] + public void {|#0:CustomTestMethod|}() { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("CustomTestMethod", "TestClass", "Fact"); await Verify.VerifyAnalyzer(source, expected); } [Theory] - [InlineData("Xunit.Fact")] - [InlineData("Xunit.Theory")] - public async Task FindsWarningForPublicMethodWithoutParametersInTestClass(string attribute) + [InlineData(/* lang=c#-test */ "Xunit.Fact")] + [InlineData(/* lang=c#-test */ "Xunit.Theory")] + public async Task PublicMethodWithoutParametersInTestClass_Triggers(string attribute) { - var source = $@" -public class TestClass {{ - [{attribute}] - public void TestMethod() {{ }} - - public void Method() {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(6, 17, 6, 23) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Method", "TestClass", "Fact"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [{0}] + public void TestMethod() {{ }} + + public void {{|#0:Method|}}() {{ }} + }} + """, attribute); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Method", "TestClass", "Fact"); await Verify.VerifyAnalyzer(source, expected); } [Theory] - [InlineData("Xunit.Fact")] - [InlineData("Xunit.Theory")] - public async Task FindsWarningForPublicMethodWithParametersInTestClass(string attribute) + [InlineData(/* lang=c#-test */ "Xunit.Fact")] + [InlineData(/* lang=c#-test */ "Xunit.Theory")] + public async Task PublicMethodWithParametersInTestClass_Triggers(string attribute) { - var source = $@" -public class TestClass {{ - [{attribute}] - public void TestMethod() {{ }} - - public void Method(int a) {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(6, 17, 6, 23) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Method", "TestClass", "Theory"); + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [{0}] + public void TestMethod() {{ }} + + public void {{|#0:Method|}}(int a) {{ }} + }} + """, attribute); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Method", "TestClass", "Theory"); await Verify.VerifyAnalyzer(source, expected); } [Theory] - [InlineData("Xunit.Fact")] - [InlineData("Xunit.Theory")] - public async Task DoesNotFindErrorForOverridenMethod(string attribute) + [InlineData(/* lang=c#-test */ "Fact")] + [InlineData(/* lang=c#-test */ "Theory")] + public async Task OverridenMethod_FromParentNonTestClass_DoesNotTrigger(string attribute) { - var source = $@" -public class TestClass {{ - [{attribute}] - public void TestMethod() {{ }} - - public override void Method() {{ }} -}}"; - var expected = - Verify - .CompilerError("CS0115") - .WithSpan(6, 26, 6, 32) - .WithMessage("'TestClass.Method()': no suitable method found to override"); + var source = string.Format(/* lang=c#-test */ """ + using Xunit; - await Verify.VerifyAnalyzer(source, expected); + public abstract class ParentClass {{ + public abstract void ParentMethod(); + }} + + public class TestClass : ParentClass {{ + [{0}] + public void TestMethod() {{ }} + + public override void ParentMethod() {{ }} + + public override void {{|CS0115:MissingMethod|}}() {{ }} + }} + """, attribute); + + await Verify.VerifyAnalyzer(source); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TestClassCannotBeNestedInGenericClassTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TestClassCannotBeNestedInGenericClassTests.cs index cdc811a2..00be7a9e 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TestClassCannotBeNestedInGenericClassTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TestClassCannotBeNestedInGenericClassTests.cs @@ -5,97 +5,77 @@ public class TestClassCannotBeNestedInGenericClassTests { [Fact] - public async Task ReportsDiagnostic_WhenTestClassIsNestedInOpenGenericType() + public async Task WhenTestClassIsNestedInOpenGenericType_Triggers() { - var source = @" -public abstract class OpenGenericType -{ - public class NestedTestClass - { - [Xunit.Fact] - public void TestMethod() { } - } -}"; - - var expected = - Verify - .Diagnostic() - .WithLocation(4, 18); + var source = /* lang=c#-test */ """ + public abstract class OpenGenericType { + public class [|NestedTestClass|] { + [Xunit.Fact] + public void TestMethod() { } + } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } [Fact] - public async Task ReportsDiagnostic_WhenDerivedTestClassIsNestedInOpenGenericType() + public async Task WhenDerivedTestClassIsNestedInOpenGenericType_Triggers() { - var source = @" -public abstract class BaseTestClass -{ - [Xunit.Fact] - public void TestMethod() { } -} - -public abstract class OpenGenericType -{ - public class NestedTestClass : BaseTestClass - { - } -}"; + var source = /* lang=c#-test */ """ + public abstract class BaseTestClass { + [Xunit.Fact] + public void TestMethod() { } + } - var expected = - Verify - .Diagnostic() - .WithLocation(10, 18); + public abstract class OpenGenericType { + public class [|NestedTestClass|] : BaseTestClass { } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotReportDiagnostic_WhenTestClassIsNestedInClosedGenericType() + public async Task WhenTestClassIsNestedInClosedGenericType_DoesNotTrigger() { - var source = @" -public abstract class OpenGenericType -{ -} + var source = /* lang=c#-test */ """ + public abstract class OpenGenericType { } -public abstract class ClosedGenericType : OpenGenericType -{ - public class NestedTestClass - { - [Xunit.Fact] - public void TestMethod() { } - } -}"; + public abstract class ClosedGenericType : OpenGenericType { + public class NestedTestClass { + [Xunit.Fact] + public void TestMethod() { } + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotReportDiagnostic_WhenNestedClassIsNotTestClass() + public async Task WhenNestedClassIsNotTestClass_DoesNotTrigger() { - var source = @" -public abstract class OpenGenericType -{ - public class NestedClass - { - } -}"; + var source = /* lang=c#-test */ """ + public abstract class OpenGenericType { + public class NestedClass { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotReportDiagnostic_WhenTestClassIsNotNestedInOpenGenericType() + public async Task WhenTestClassIsNotNestedInOpenGenericType_DoesNotTrigger() { - var source = @" -public abstract class NonGenericType -{ - public class NestedTestClass - { - [Xunit.Fact] - public void TestMethod() { } - } -}"; + var source = /* lang=c#-test */ """ + public abstract class NonGenericType { + public class NestedTestClass { + [Xunit.Fact] + public void TestMethod() { } + } + } + """; await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TestClassMustBePublicTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TestClassMustBePublicTests.cs index c7ab515c..8f67c1a6 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TestClassMustBePublicTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TestClassMustBePublicTests.cs @@ -1,108 +1,105 @@ -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using Xunit; using Verify = CSharpVerifier; public class TestClassMustBePublicTests { - public static IEnumerable CreateFactsInNonPublicClassCases = - from attribute in new[] { "Xunit.Fact", "Xunit.Theory" } - from modifier in new[] { "", "internal" } - select new[] { attribute, modifier }; + public static MatrixTheoryData CreateFactsInNonPublicClassCases = + new( + /* lang=c#-test */ ["Xunit.Fact", "Xunit.Theory"], + /* lang=c#-test */ ["", "internal"] + ); [Fact] - public async Task ForPublicClass_DoesNotFindError() + public async Task ForPublicClass_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Fact] - public void TestMethod() { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(CreateFactsInNonPublicClassCases))] - public async Task ForFriendOrInternalClass_FindsError( + public async Task ForFriendOrInternalClass_Triggers( string attribute, string modifier) { - var source = $@" -{modifier} class TestClass {{ - [{attribute}] - public void TestMethod() {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(2, 8 + modifier.Length, 2, 17 + modifier.Length); + var source = string.Format(/* lang=c#-test */ """ + {1} class [|TestClass|] {{ + [{0}] + public void TestMethod() {{ }} + }} + """, attribute, modifier); - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } [Theory] - [InlineData("")] - [InlineData("public")] - public async Task ForPartialClassInSameFile_WhenClassIsPublic_DoesNotFindError(string modifier) + [InlineData(/* lang=c#-test */ "")] + [InlineData(/* lang=c#-test */ "public")] + public async Task ForPartialClassInSameFile_WhenClassIsPublic_DoesNotTrigger(string modifier) { - var source = $@" -public partial class TestClass {{ - [Xunit.Fact] - public void Test1() {{ }} -}} + var source = string.Format(/* lang=c#-test */ """ + public partial class TestClass {{ + [Xunit.Fact] + public void Test1() {{ }} + }} -{modifier} partial class TestClass {{ - [Xunit.Fact] - public void Test2() {{ }} -}}"; + {0} partial class TestClass {{ + [Xunit.Fact] + public void Test2() {{ }} + }} + """, modifier); await Verify.VerifyAnalyzer(source); } [Theory] - [InlineData("")] - [InlineData("public")] - public async Task ForPartialClassInOtherFiles_WhenClassIsPublic_DoesNotFindError(string modifier) + [InlineData(/* lang=c#-test */ "")] + [InlineData(/* lang=c#-test */ "public")] + public async Task ForPartialClassInOtherFiles_WhenClassIsPublic_DoesNotTrigger(string modifier) { - var source1 = @" -public partial class TestClass { - [Xunit.Fact] - public void Test1() { } -}"; - var source2 = $@" -{modifier} partial class TestClass {{ - [Xunit.Fact] - public void Test2() {{ }} -}}"; + var source1 = /* lang=c#-test */ """ + public partial class TestClass { + [Xunit.Fact] + public void Test1() { } + } + """; + var source2 = string.Format(/* lang=c#-test */ """ + {0} partial class TestClass {{ + [Xunit.Fact] + public void Test2() {{ }} + }} + """, modifier); - await Verify.VerifyAnalyzer(new[] { source1, source2 }); + await Verify.VerifyAnalyzer([source1, source2]); } [Theory] [InlineData("", "")] [InlineData("", "internal")] [InlineData("internal", "internal")] - public async Task ForPartialClassInSameFile_WhenClassIsNonPublic_FindsError( + public async Task ForPartialClassInSameFile_WhenClassIsNonPublic_Triggers( string modifier1, string modifier2) { - var source = $@" -{modifier1} partial class TestClass {{ - [Xunit.Fact] - public void Test1() {{ }} -}} + var source = string.Format(/* lang=c#-test */ """ + {0} partial class {{|#0:TestClass|}} {{ + [Xunit.Fact] + public void Test1() {{ }} + }} -{modifier2} partial class TestClass {{ - [Xunit.Fact] - public void Test2() {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(2, 16 + modifier1.Length, 2, 25 + modifier1.Length) - .WithSpan(7, 16 + modifier2.Length, 7, 25 + modifier2.Length); + {1} partial class {{|#1:TestClass|}} {{ + [Xunit.Fact] + public void Test2() {{ }} + }} + """, modifier1, modifier2); + var expected = Verify.Diagnostic().WithLocation(0).WithLocation(1); await Verify.VerifyAnalyzer(source, expected); } @@ -111,26 +108,24 @@ public void Test2() {{ }} [InlineData("", "")] [InlineData("", "internal")] [InlineData("internal", "internal")] - public async Task ForPartialClassInOtherFiles_WhenClassIsNonPublic_FindsError( + public async Task ForPartialClassInOtherFiles_WhenClassIsNonPublic_Triggers( string modifier1, string modifier2) { - var source1 = $@" -{modifier1} partial class TestClass {{ - [Xunit.Fact] - public void Test1() {{ }} -}}"; - var source2 = $@" -{modifier2} partial class TestClass {{ - [Xunit.Fact] - public void Test2() {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(2, 16 + modifier1.Length, 2, 25 + modifier1.Length) - .WithSpan("/0/Test1.cs", 2, 16 + modifier2.Length, 2, 25 + modifier2.Length); + var source1 = string.Format(/* lang=c#-test */ """ + {0} partial class {{|#0:TestClass|}} {{ + [Xunit.Fact] + public void Test1() {{ }} + }} + """, modifier1); + var source2 = string.Format(/* lang=c#-test */ """ + {0} partial class {{|#1:TestClass|}} {{ + [Xunit.Fact] + public void Test2() {{ }} + }} + """, modifier2); + var expected = Verify.Diagnostic().WithLocation(0).WithLocation(1); - await Verify.VerifyAnalyzer(new[] { source1, source2 }, expected); + await Verify.VerifyAnalyzer([source1, source2], expected); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TestClassShouldHaveTFixtureArgumentTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TestClassShouldHaveTFixtureArgumentTests.cs index ad33f9ac..02e3534b 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TestClassShouldHaveTFixtureArgumentTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TestClassShouldHaveTFixtureArgumentTests.cs @@ -1,74 +1,72 @@ -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using Xunit; using Verify = CSharpVerifier; public class TestClassShouldHaveTFixtureArgumentTests { - public static IEnumerable CreateFactsInNonPublicClassCases = - from attribute in new[] { "Xunit.Fact", "Xunit.Theory" } - from @interface in new[] { "Xunit.IClassFixture", "Xunit.ICollectionFixture" } - select new[] { attribute, @interface }; + public static MatrixTheoryData CreateFactsInNonPublicClassCases = + new( + /* lang=c#-test */ ["Xunit.Fact", "Xunit.Theory"], + /* lang=c#-test */ ["Xunit.IClassFixture", "Xunit.ICollectionFixture"] + ); [Theory] [MemberData(nameof(CreateFactsInNonPublicClassCases))] - public async Task ForClassWithIClassFixtureWithoutConstructorArg_FindsInfo( + public async Task ForClassWithIClassFixtureWithoutConstructorArg_Triggers( string attribute, string @interface) { - var source = $@" -public class FixtureData {{ }} + var source = string.Format(/* lang=c#-test */ """ + public class FixtureData {{ }} -public class TestClass: {@interface} {{ - [{attribute}] - public void TestMethod() {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 14, 4, 23) - .WithArguments("TestClass", "FixtureData"); + public class {{|#0:TestClass|}}: {1} {{ + [{0}] + public void TestMethod() {{ }} + }} + """, attribute, @interface); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestClass", "FixtureData"); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(CreateFactsInNonPublicClassCases))] - public async Task ForClassWithIClassFixtureWithConstructorArg_DonnotFindInfo( + public async Task ForClassWithIClassFixtureWithConstructorArg_DoesNotTrigger( string attribute, string @interface) { - var source = $@" -public class FixtureData {{ }} + var source = string.Format(/* lang=c#-test */ """ + public class FixtureData {{ }} -public class TestClass: {@interface} {{ - public TestClass(FixtureData fixtureData) {{ }} + public class TestClass: {1} {{ + public TestClass(FixtureData fixtureData) {{ }} - [{attribute}] - public void TestMethod() {{ }} -}}"; + [{0}] + public void TestMethod() {{ }} + }} + """, attribute, @interface); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(CreateFactsInNonPublicClassCases))] - public async Task ForClassWithIClassFixtureWithConstructorMultipleArg_DonnotFindInfo( + public async Task ForClassWithIClassFixtureWithConstructorMultipleArg_DoesNotTrigger( string attribute, string @interface) { - var source = $@" -public class FixtureData {{ }} + var source = /* lang=c#-test */ """ + public class FixtureData {{ }} -public class TestClass: {@interface} {{ - public TestClass(FixtureData fixtureData, Xunit.Abstractions.ITestOutputHelper output) {{ }} + public class TestClass: {1} {{ + public TestClass(FixtureData fixtureData, {2}.ITestOutputHelper output) {{ }} - [{attribute}] - public void TestMethod() {{ }} -}}"; + [{0}] + public void TestMethod() {{ }} + }} + """; - // This is a v2-only test because of the use of Xunit.Abstractions.ITestOutputHelper - await Verify.VerifyAnalyzerV2(source); + await Verify.VerifyAnalyzerV2(string.Format(source, attribute, @interface, "Xunit.Abstractions")); + await Verify.VerifyAnalyzerV3(string.Format(source, attribute, @interface, "Xunit")); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodCannotHaveOverloadsTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodCannotHaveOverloadsTests.cs index 3697d02b..88776872 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodCannotHaveOverloadsTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodCannotHaveOverloadsTests.cs @@ -1,135 +1,113 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Verify = CSharpVerifier; public class TestMethodCannotHaveOverloadsTests { [Fact] - public async Task FindsErrors_ForInstanceMethodOverloads_InSameInstanceClass() + public async Task ForInstanceMethodOverloads_InSameInstanceClass_Triggers() { - var source = @" -public class TestClass { - [Xunit.Fact] - public void TestMethod() { } + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + public void {|#0:TestMethod|}() { } - [Xunit.Theory] - public void TestMethod(int a) { } -}"; + [Xunit.Theory] + public void {|#1:TestMethod|}(int a) { } + } + """; var expected = new[] { - Verify - .Diagnostic() - .WithSpan(4, 17, 4, 27) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("TestMethod", "TestClass", "TestClass"), - Verify - .Diagnostic() - .WithSpan(7, 17, 7, 27) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("TestMethod", "TestClass", "TestClass"), + Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass", "TestClass"), + Verify.Diagnostic().WithLocation(1).WithArguments("TestMethod", "TestClass", "TestClass"), }; await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsErrors_ForStaticMethodOverloads_InSameStaticClass() + public async Task ForStaticMethodOverloads_InSameStaticClass_Triggers() { - var source = @" -public static class TestClass { - [Xunit.Fact] - public static void TestMethod() { } + var source = /* lang=c#-test */ """ + public static class TestClass { + [Xunit.Fact] + public static void {|#0:TestMethod|}() { } - [Xunit.Theory] - public static void TestMethod(int a) { } -}"; + [Xunit.Theory] + public static void {|#1:TestMethod|}(int a) { } + } + """; var expected = new[] { - Verify - .Diagnostic() - .WithSpan(4, 24, 4, 34) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("TestMethod", "TestClass", "TestClass"), - Verify - .Diagnostic() - .WithSpan(7, 24, 7, 34) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("TestMethod", "TestClass", "TestClass"), + Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass", "TestClass"), + Verify.Diagnostic().WithLocation(1).WithArguments("TestMethod", "TestClass", "TestClass"), }; await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsErrors_ForInstanceMethodOverload_InDerivedClass() + public async Task ForInstanceMethodOverload_InDerivedClass_Triggers() { - var source1 = @" -public class TestClass : BaseClass { - [Xunit.Theory] - public void TestMethod(int a) { } + var source1 = /* lang=c#-test */ """ + public class TestClass : BaseClass { + [Xunit.Theory] + public void {|#0:TestMethod|}(int a) { } - private void TestMethod(int a, byte c) { } -}"; - var source2 = @" -public class BaseClass { - [Xunit.Fact] - public void TestMethod() { } -}"; + private void {|#1:TestMethod|}(int a, byte c) { } + } + """; + var source2 = /* lang=c#-test */ """ + public class BaseClass { + [Xunit.Fact] + public void TestMethod() { } + } + """; var expected = new[] { - Verify - .Diagnostic() - .WithSpan(4, 17, 4, 27) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("TestMethod", "TestClass", "BaseClass"), - Verify - .Diagnostic() - .WithSpan(6, 18, 6, 28) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("TestMethod", "TestClass", "BaseClass"), + Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass", "BaseClass"), + Verify.Diagnostic().WithLocation(1).WithArguments("TestMethod", "TestClass", "BaseClass"), }; - await Verify.VerifyAnalyzer(new[] { source1, source2 }, expected); + await Verify.VerifyAnalyzer([source1, source2], expected); } [Fact] - public async Task FindsError_ForStaticAndInstanceMethodOverload() + public async Task ForStaticAndInstanceMethodOverload_Triggers() { - var source1 = @" -public class TestClass : BaseClass { - [Xunit.Theory] - public void TestMethod(int a) { } -}"; - var source2 = @" -public class BaseClass { - [Xunit.Fact] - public static void TestMethod() { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 17, 4, 27) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("TestMethod", "TestClass", "BaseClass"); + var source1 = /* lang=c#-test */ """ + public class TestClass : BaseClass { + [Xunit.Theory] + public void {|#0:TestMethod|}(int a) { } + } + """; + var source2 = /* lang=c#-test */ """ + public class BaseClass { + [Xunit.Fact] + public static void TestMethod() { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass", "BaseClass"); - await Verify.VerifyAnalyzer(new[] { source1, source2 }, expected); + await Verify.VerifyAnalyzer([source1, source2], expected); } [Fact] - public async Task DoesNotFindError_ForMethodOverrides() + public async Task ForMethodOverrides_DoesNotTrigger() { - var source1 = @" -public class BaseClass { - [Xunit.Fact] - public virtual void TestMethod() { } -}"; - var source2 = @" -public class TestClass : BaseClass { - [Xunit.Fact] - public override void TestMethod() { } -}"; + var source1 = /* lang=c#-test */ """ + public class BaseClass { + [Xunit.Fact] + public virtual void TestMethod() { } + } + """; + var source2 = /* lang=c#-test */ """ + public class TestClass : BaseClass { + [Xunit.Fact] + public override void TestMethod() { } + } + """; - await Verify.VerifyAnalyzer(new[] { source1, source2 }); + await Verify.VerifyAnalyzer([source1, source2]); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodMustNotHaveMultipleFactAttributesTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodMustNotHaveMultipleFactAttributesTests.cs index 2a9259fe..03dac6e0 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodMustNotHaveMultipleFactAttributesTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodMustNotHaveMultipleFactAttributesTests.cs @@ -7,49 +7,46 @@ public class TestMethodMustNotHaveMultipleFactAttributesTests [Theory] [InlineData("Fact")] [InlineData("Theory")] - public async Task DoesNotFindErrorForMethodWithSingleAttribute(string attribute) + public async Task MethodWithSingleAttribute_DoesNotTrigger(string attribute) { - var source = $@" -public class TestClass {{ - [Xunit.{attribute}] - public void TestMethod() {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.{0}] + public void TestMethod() {{ }} + }} + """, attribute); await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FindsErrorForMethodWithTheoryAndFact() + public async Task MethodWithFactAndTheory_Triggers() { - var source = @" -public class TestClass { - [Xunit.Fact] - [Xunit.Theory] - public void TestMethod() { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 17, 5, 27); + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + [Xunit.Theory] + public void [|TestMethod|]() { } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FindsErrorForMethodWithCustomFactAttribute() + public async Task MethodWithFactAndCustomFactAttribute_Triggers() { - var source1 = @" -public class TestClass { - [Xunit.Fact] - [CustomFact] - public void TestMethod() { } -}"; - var source2 = "public class CustomFactAttribute : Xunit.FactAttribute { }"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 17, 5, 27); + var source1 = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + [CustomFact] + public void [|TestMethod|]() { } + } + """; + var source2 = /* lang=c#-test */ """ + public class CustomFactAttribute : Xunit.FactAttribute { } + """; - await Verify.VerifyAnalyzer(new[] { source1, source2 }, expected); + await Verify.VerifyAnalyzer([source1, source2]); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodShouldNotBeSkippedTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodShouldNotBeSkippedTests.cs index 4143b9ef..f2387d6c 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodShouldNotBeSkippedTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodShouldNotBeSkippedTests.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Verify = CSharpVerifier; @@ -8,13 +7,14 @@ public class TestMethodShouldNotBeSkippedTests [Theory] [InlineData("Fact")] [InlineData("Theory")] - public async Task DoesNotFindErrorForNotSkippedTest(string attribute) + public async Task NotSkippedTest_DoesNotTrigger(string attribute) { - var source = $@" -public class TestClass {{ - [Xunit.{attribute}] - public void TestMethod() {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.{0}] + public void TestMethod() {{ }} + }} + """, attribute); await Verify.VerifyAnalyzer(source); } @@ -22,19 +22,15 @@ public void TestMethod() {{ }} [Theory] [InlineData("Fact")] [InlineData("Theory")] - public async Task FindsErrorForSkippedTests(string attribute) + public async Task SkippedTest_Triggers(string attribute) { - var source = $@" -class TestClass {{ - [Xunit.{attribute}(Skip=""Lazy"")] - public void TestMethod() {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(3, 13 + attribute.Length, 3, 24 + attribute.Length) - .WithSeverity(DiagnosticSeverity.Info); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + [Xunit.{0}([|Skip="Lazy"|])] + public void TestMethod() {{ }} + }} + """, attribute); - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodSupportedReturnTypeTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodSupportedReturnTypeTests.cs index b5a81528..aab31bce 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodSupportedReturnTypeTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TestMethodSupportedReturnTypeTests.cs @@ -6,96 +6,80 @@ public class TestMethodSupportedReturnTypeTests { [Fact] - public async Task NonTestMethod() + public async Task NonTestMethod_DoesNotTrigger() { - var source = @" -public class NonTestClass { - public int Add(int x, int y) { - return x + y; - } -}"; + var source = /* lang=c#-test */ """ + public class NonTestClass { + public int Add(int x, int y) { + return x + y; + } + } + """; await Verify.VerifyAnalyzer(source); } [Theory] - [InlineData("int")] [InlineData("object")] - public async Task InvalidReturnType(string returnType) + [InlineData("Task")] + [InlineData("ValueTask")] + public async Task InvalidReturnType_Triggers(string returnType) { - var sourceTemplate = @" -using Xunit; - -public class TestClass {{ - [Fact] - public {0} TestMethod() {{ - return default({0}); - }} -}}"; - - var source = string.Format(sourceTemplate, returnType); - - // v2 - var expectedV2 = - Verify - .Diagnostic() - .WithSpan(6, 13 + returnType.Length, 6, 23 + returnType.Length) - .WithArguments("void, Task"); + var source = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public {0} {{|#0:TestMethod|}}() {{ + return default({0}); + }} + }} + """, returnType); + var expectedV2 = Verify.Diagnostic().WithLocation(0).WithArguments("void, Task"); + var expectedV3 = Verify.Diagnostic().WithLocation(0).WithArguments("void, Task, ValueTask"); await Verify.VerifyAnalyzerV2(source, expectedV2); - - // v3 - var expectedV3 = - Verify - .Diagnostic() - .WithSpan(6, 13 + returnType.Length, 6, 23 + returnType.Length) - .WithArguments("void, Task, ValueTask"); - await Verify.VerifyAnalyzerV3(source, expectedV3); } [Fact] - public async Task V2DoesNotSupportValueTask() + public async Task ValueTask_TriggersInV2_DoesNotTriggerInV3() { - var source = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public ValueTask TestMethod() { - return default(ValueTask); - } -}"; + var source = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public ValueTask {|#0:TestMethod|}() { + return default(ValueTask); + } + } + """; + var expectedV2 = Verify.Diagnostic().WithLocation(0).WithArguments("void, Task"); - var expectedV2 = - Verify - .Diagnostic() - .WithSpan(7, 22, 7, 32) - .WithArguments("void, Task"); await Verify.VerifyAnalyzerV2(LanguageVersion.CSharp7, source, expectedV2); - await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp7, source); } [Theory] [InlineData("MyTest")] [InlineData("MyTestAttribute")] - public async Task CustomTestAttribute(string attribute) + public async Task CustomTestAttribute_DoesNotTrigger(string attribute) { - var sourceTemplate = @" -using Xunit; - -class MyTestAttribute : FactAttribute {{ }} - -public class TestClass {{ - [{0}] - public int TestMethod() {{ - return 0; - }} -}}"; - - var source = string.Format(sourceTemplate, attribute); + var source = string.Format(/* lang=c#-test */ """ + using Xunit; + + class MyTestAttribute : FactAttribute {{ }} + + public class TestClass {{ + [{0}] + public int TestMethod() {{ + return 0; + }} + }} + """, attribute); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryDataRowArgumentsShouldBeSerializableTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryDataRowArgumentsShouldBeSerializableTests.cs index f2a45714..fba27736 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryDataRowArgumentsShouldBeSerializableTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryDataRowArgumentsShouldBeSerializableTests.cs @@ -8,18 +8,19 @@ public sealed class TheoryDataRowArgumentsShouldBeSerializableTests [Fact] public async Task ParamArrayArguments_NotUsingTheoryDataRow_DoesNotTrigger() { - var source = @" -#nullable enable + var source = /* lang=c#-test */ """ + #nullable enable -public class Foo { - public Foo(params object[] args) { } -} + public class Foo { + public Foo(params object[] args) { } + } -public class TestClass { - public void TestMethod() { - var foo = new Foo(new object()); - } -}"; + public class TestClass { + public void TestMethod() { + var foo = new Foo(new object()); + } + } + """; await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp8, source); } @@ -54,25 +55,26 @@ public async Task IntrinsicallySerializableValue_DoesNotTrigger( string value, string type) { - var source = $@" -#nullable enable - -using System; -using System.Collections.Generic; -using System.Numerics; -using Xunit; - -public class MyClass {{ - public IEnumerable MyMethod() {{ - var value = {value}; - var defaultValue = default({type}); - var nullValue = default({type}?); - var arrayValue = new {type}[0]; - - yield return new TheoryDataRow(value, defaultValue, nullValue, arrayValue); - yield return new TheoryDataRow<{type}, {type}?, {type}?, {type}[]>({value}, default({type}), default({type}?), new {type}[0]); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + #nullable enable + + using System; + using System.Collections.Generic; + using System.Numerics; + using Xunit; + + public class MyClass {{ + public IEnumerable MyMethod() {{ + var value = {0}; + var defaultValue = default({1}); + var nullValue = default({1}?); + var arrayValue = new {1}[0]; + + yield return new TheoryDataRow(value, defaultValue, nullValue, arrayValue); + yield return new TheoryDataRow<{1}, {1}?, {1}?, {1}[]>({0}, default({1}), default({1}?), new {1}[0]); + }} + }} + """, value, type); await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp8, source); } @@ -82,36 +84,37 @@ public IEnumerable MyMethod() {{ [InlineData("SerializableStruct")] public async Task IXunitSerializableValue_DoesNotTrigger(string type) { - var source = $@" -#nullable enable - -using System.Collections.Generic; -using Xunit; -using Xunit.Sdk; - -public class MyClass {{ - public IEnumerable MyMethod() {{ - var value = new {type}(); - var defaultValue = default({type}); - var nullValue = default({type}?); - var arrayValue = new {type}[0]; - - yield return new TheoryDataRow(value, defaultValue, nullValue, arrayValue); - yield return new TheoryDataRow<{type}, {type}?, {type}?, {type}[]>(new {type}(), default({type}), default({type}?), new {type}[0]); - }} -}} - -public interface ISerializableInterface : IXunitSerializable {{ }} - -public class SerializableClass : ISerializableInterface {{ - public void Deserialize(IXunitSerializationInfo info) {{ }} - public void Serialize(IXunitSerializationInfo info) {{ }} -}} - -public struct SerializableStruct : ISerializableInterface {{ - public void Deserialize(IXunitSerializationInfo info) {{ }} - public void Serialize(IXunitSerializationInfo info) {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + #nullable enable + + using System.Collections.Generic; + using Xunit; + using Xunit.Sdk; + + public class MyClass {{ + public IEnumerable MyMethod() {{ + var value = new {0}(); + var defaultValue = default({0}); + var nullValue = default({0}?); + var arrayValue = new {0}[0]; + + yield return new TheoryDataRow(value, defaultValue, nullValue, arrayValue); + yield return new TheoryDataRow<{0}, {0}?, {0}?, {0}[]>(new {0}(), default({0}), default({0}?), new {0}[0]); + }} + }} + + public interface ISerializableInterface : IXunitSerializable {{ }} + + public class SerializableClass : ISerializableInterface {{ + public void Deserialize(IXunitSerializationInfo info) {{ }} + public void Serialize(IXunitSerializationInfo info) {{ }} + }} + + public struct SerializableStruct : ISerializableInterface {{ + public void Deserialize(IXunitSerializationInfo info) {{ }} + public void Serialize(IXunitSerializationInfo info) {{ }} + }} + """, type); await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp8, source); } @@ -126,55 +129,36 @@ public async Task KnownNonSerializableValue_Triggers1046( string defaultValueType, string nullValueType) { - var source = $@" -#nullable enable - -using System; -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + #nullable enable -public class MyClass {{ - public IEnumerable MyMethod() {{ - var defaultValue = default({type}); - var nullValue = default({type}?); - var arrayValue = new {type}[0]; + using System; + using System.Collections.Generic; + using Xunit; - yield return new TheoryDataRow(defaultValue, nullValue, arrayValue); - yield return new TheoryDataRow<{defaultValueType}, {nullValueType}, {type}[]>(default({type}), default({type}?), new {type}[0]); - }} -}} + public class MyClass {{ + public IEnumerable MyMethod() {{ + var defaultValue = default({0}); + var nullValue = default({0}?); + var arrayValue = new {0}[0]; -public sealed class NonSerializableSealedClass {{ }} + yield return new TheoryDataRow({{|#0:defaultValue|}}, {{|#1:nullValue|}}, {{|#2:arrayValue|}}); + yield return new TheoryDataRow<{1}, {2}, {0}[]>({{|#3:default({0})|}}, {{|#4:default({0}?)|}}, {{|#5:new {0}[0]|}}); + }} + }} -public struct NonSerializableStruct {{ }}"; + public sealed class NonSerializableSealedClass {{ }} - var leftGeneric = 48 + defaultValueType.Length + nullValueType.Length + type.Length; + public struct NonSerializableStruct {{ }} + """, type, defaultValueType, nullValueType); var expected = new[] { - Verify - .Diagnostic("xUnit1046") - .WithSpan(14, 40, 14, 52) - .WithArguments("defaultValue", defaultValueType), - Verify - .Diagnostic("xUnit1046") - .WithSpan(14, 54, 14, 63) - .WithArguments("nullValue", nullValueType), - Verify - .Diagnostic("xUnit1046") - .WithSpan(14, 65, 14, 75) - .WithArguments("arrayValue", $"{type}[]"), - Verify - .Diagnostic("xUnit1046") - .WithSpan(15, leftGeneric, 15, leftGeneric + 9 + type.Length) // +9 for "default()" - .WithArguments($"default({type})", defaultValueType), - Verify - .Diagnostic("xUnit1046") - .WithSpan(15, leftGeneric + 11 + type.Length, 15, leftGeneric + 21 + type.Length * 2) // +10 for "default(?)" - .WithArguments($"default({type}?)", nullValueType), - Verify - .Diagnostic("xUnit1046") - .WithSpan(15, leftGeneric + 23 + type.Length * 2, 15, leftGeneric + 30 + type.Length * 3) // +7 for "new [0]" - .WithArguments($"new {type}[0]", $"{type}[]"), - }; + Verify.Diagnostic("xUnit1046").WithLocation(0).WithArguments("defaultValue", defaultValueType), + Verify.Diagnostic("xUnit1046").WithLocation(1).WithArguments("nullValue", nullValueType), + Verify.Diagnostic("xUnit1046").WithLocation(2).WithArguments("arrayValue", $"{type}[]"), + Verify.Diagnostic("xUnit1046").WithLocation(3).WithArguments($"default({type})", defaultValueType), + Verify.Diagnostic("xUnit1046").WithLocation(4).WithArguments($"default({type}?)", nullValueType), + Verify.Diagnostic("xUnit1046").WithLocation(5).WithArguments($"new {type}[0]", $"{type}[]"), + }; await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp8, source, expected); } @@ -184,45 +168,33 @@ public struct NonSerializableStruct {{ }}"; [InlineData("NonSerializableStruct")] public async Task KnownNonSerializableValue_Constructable_Triggers1046(string type) { - var source = $@" -#nullable enable - -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + #nullable enable -public class MyClass {{ - public IEnumerable MyMethod() {{ - var value = new {type}(); + using System.Collections.Generic; + using Xunit; - yield return new TheoryDataRow(value); - yield return new TheoryDataRow(new {type}()); - yield return new TheoryDataRow<{type}>(value); - yield return new TheoryDataRow<{type}>(new {type}()); - }} -}} + public class MyClass {{ + public IEnumerable MyMethod() {{ + var value = new {0}(); -public sealed class NonSerializableSealedClass {{ }} + yield return new TheoryDataRow({{|#0:value|}}); + yield return new TheoryDataRow({{|#1:new {0}()|}}); + yield return new TheoryDataRow<{0}>({{|#2:value|}}); + yield return new TheoryDataRow<{0}>({{|#3:new {0}()|}}); + }} + }} -public struct NonSerializableStruct {{ }}"; + public sealed class NonSerializableSealedClass {{ }} + public struct NonSerializableStruct {{ }} + """, type); var expected = new[] { - Verify - .Diagnostic("xUnit1046") - .WithSpan(11, 40, 11, 45) - .WithArguments("value", type), - Verify - .Diagnostic("xUnit1046") - .WithSpan(12, 40, 12, 46 + type.Length) - .WithArguments($"new {type}()", type), - Verify - .Diagnostic("xUnit1046") - .WithSpan(13, 42 + type.Length, 13, 47 + type.Length) - .WithArguments("value", type), - Verify - .Diagnostic("xUnit1046") - .WithSpan(14, 42 + type.Length, 14, 48 + type.Length * 2) - .WithArguments($"new {type}()", type), - }; + Verify.Diagnostic("xUnit1046").WithLocation(0).WithArguments("value", type), + Verify.Diagnostic("xUnit1046").WithLocation(1).WithArguments($"new {type}()", type), + Verify.Diagnostic("xUnit1046").WithLocation(2).WithArguments("value", type), + Verify.Diagnostic("xUnit1046").WithLocation(3).WithArguments($"new {type}()", type), + }; await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp8, source, expected); } @@ -238,55 +210,36 @@ public struct NonSerializableStruct {{ }}"; [InlineData("PossiblySerializableUnsealedClass")] public async Task MaybeNonSerializableValue_Triggers1047(string type) { - var source = $@" -#nullable enable - -using System; -using System.Collections; -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + #nullable enable -public class MyClass {{ - public IEnumerable MyMethod() {{ - var defaultValue = default({type}); - var nullValue = default({type}?); - var arrayValue = new {type}[0]; + using System; + using System.Collections; + using System.Collections.Generic; + using Xunit; - yield return new TheoryDataRow(defaultValue, nullValue, arrayValue); - yield return new TheoryDataRow<{type}, {type}, {type}[]>(default({type}), default({type}?), new {type}[0]); - }} -}} + public class MyClass {{ + public IEnumerable MyMethod() {{ + var defaultValue = default({0}); + var nullValue = default({0}?); + var arrayValue = new {0}[0]; -public interface IPossiblySerializableInterface {{ }} + yield return new TheoryDataRow({{|#0:defaultValue|}}, {{|#1:nullValue|}}, {{|#2:arrayValue|}}); + yield return new TheoryDataRow<{0}, {0}, {0}[]>({{|#3:default({0})|}}, {{|#4:default({0}?)|}}, {{|#5:new {0}[0]|}}); + }} + }} -public class PossiblySerializableUnsealedClass {{ }}"; + public interface IPossiblySerializableInterface {{ }} - var leftGeneric = 48 + type.Length * 3; + public class PossiblySerializableUnsealedClass {{ }} + """, type); var expected = new[] { - Verify - .Diagnostic("xUnit1047") - .WithSpan(15, 40, 15, 52) - .WithArguments("defaultValue", $"{type}?"), - Verify - .Diagnostic("xUnit1047") - .WithSpan(15, 54, 15, 63) - .WithArguments("nullValue", $"{type}?"), - Verify - .Diagnostic("xUnit1047") - .WithSpan(15, 65, 15, 75) - .WithArguments("arrayValue", $"{type}[]"), - Verify - .Diagnostic("xUnit1047") - .WithSpan(16, leftGeneric, 16, leftGeneric + 9 + type.Length) // +9 for "default()" - .WithArguments($"default({type})", $"{type}?"), - Verify - .Diagnostic("xUnit1047") - .WithSpan(16, leftGeneric + 11 + type.Length, 16, leftGeneric + 21 + type.Length * 2) // +10 for "default(?)" - .WithArguments($"default({type}?)", $"{type}?"), - Verify - .Diagnostic("xUnit1047") - .WithSpan(16, leftGeneric + 23 + type.Length * 2, 16, leftGeneric + 30 + type.Length * 3) // +7 for "new [0]" - .WithArguments($"new {type}[0]", $"{type}[]"), + Verify.Diagnostic("xUnit1047").WithLocation(0).WithArguments("defaultValue", $"{type}?"), + Verify.Diagnostic("xUnit1047").WithLocation(1).WithArguments("nullValue", $"{type}?"), + Verify.Diagnostic("xUnit1047").WithLocation(2).WithArguments("arrayValue", $"{type}[]"), + Verify.Diagnostic("xUnit1047").WithLocation(3).WithArguments($"default({type})", $"{type}?"), + Verify.Diagnostic("xUnit1047").WithLocation(4).WithArguments($"default({type}?)", $"{type}?"), + Verify.Diagnostic("xUnit1047").WithLocation(5).WithArguments($"new {type}[0]", $"{type}[]"), }; await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp8, source, expected); @@ -298,42 +251,30 @@ public class PossiblySerializableUnsealedClass {{ }}"; [InlineData("PossiblySerializableUnsealedClass")] public async Task MaybeNonSerializableValue_Constructable_Triggers1047(string type) { - var source = $@" -#nullable enable - -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + #nullable enable -public class MyClass {{ - public IEnumerable MyMethod() {{ - var value = new {type}(); + using System.Collections.Generic; + using Xunit; - yield return new TheoryDataRow(value); - yield return new TheoryDataRow(new {type}()); - yield return new TheoryDataRow<{type}>(value); - yield return new TheoryDataRow<{type}>(new {type}()); - }} -}} + public class MyClass {{ + public IEnumerable MyMethod() {{ + var value = new {0}(); -public class PossiblySerializableUnsealedClass {{ }}"; + yield return new TheoryDataRow({{|#0:value|}}); + yield return new TheoryDataRow({{|#1:new {0}()|}}); + yield return new TheoryDataRow<{0}>({{|#2:value|}}); + yield return new TheoryDataRow<{0}>({{|#3:new {0}()|}}); + }} + }} + public class PossiblySerializableUnsealedClass {{ }} + """, type); var expected = new[] { - Verify - .Diagnostic("xUnit1047") - .WithSpan(11, 40, 11, 45) - .WithArguments("value", type), - Verify - .Diagnostic("xUnit1047") - .WithSpan(12, 40, 12, 46 + type.Length) - .WithArguments($"new {type}()", type), - Verify - .Diagnostic("xUnit1047") - .WithSpan(13, 42 + type.Length, 13, 47 + type.Length) - .WithArguments("value", type), - Verify - .Diagnostic("xUnit1047") - .WithSpan(14, 42 + type.Length, 14, 48 + type.Length * 2) - .WithArguments($"new {type}()", type), + Verify.Diagnostic("xUnit1047").WithLocation(0).WithArguments("value", type), + Verify.Diagnostic("xUnit1047").WithLocation(1).WithArguments($"new {type}()", type), + Verify.Diagnostic("xUnit1047").WithLocation(2).WithArguments("value", type), + Verify.Diagnostic("xUnit1047").WithLocation(3).WithArguments($"new {type}()", type), }; await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp8, source, expected); diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryDataTypeArgumentsShouldBeSerializableTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryDataTypeArgumentsShouldBeSerializableTests.cs index b74b418f..61f164d7 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryDataTypeArgumentsShouldBeSerializableTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryDataTypeArgumentsShouldBeSerializableTests.cs @@ -16,19 +16,20 @@ public static TheoryData TheoryDataClass( string type2, string type3) { - var source = $@" -using System; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System; + using Xunit; -public class TestClass {{ - [{theoryAttribute}] - [ClassData(typeof(DerivedClass))] - public void TestMethod({type1} a, {type2} b, {type3} c) {{ }} -}} + public class TestClass {{ + [{0}] + [ClassData(typeof(DerivedClass))] + public void TestMethod({1} a, {2} b, {3} c) {{ }} + }} -public class BaseClass : TheoryData {{ }} + public class BaseClass : TheoryData {{ }} -public class DerivedClass : BaseClass<{type1}, {type2}, object, Delegate> {{ }}"; + public class DerivedClass : BaseClass<{1}, {2}, object, Delegate> {{ }} + """, theoryAttribute, type1, type2, type3); return new TheoryData { @@ -38,82 +39,85 @@ public class DerivedClass : BaseClass<{type1}, {type2}, object, Delegate> {{ }}" public static TheoryData TheoryDataMembers(string type) { - var @class = $@"public sealed class Class : TheoryData<{type}> {{ }}"; - var field = $@"public static readonly TheoryData<{type}> Field = new TheoryData<{type}>() {{ }};"; - var method = $@"public static TheoryData<{type}> Method(int a, string b) => new TheoryData<{type}>() {{ }};"; - var property = $@"public static TheoryData<{type}> Property => new TheoryData<{type}>() {{ }};"; + var c = string.Format(/* lang=c#-test */ "public sealed class Class : TheoryData<{0}> {{ }}", type); + var f = string.Format(/* lang=c#-test */ "public static readonly TheoryData<{0}> Field = new TheoryData<{0}>() {{ }};", type); + var m = string.Format(/* lang=c#-test */ "public static TheoryData<{0}> Method(int a, string b) => new TheoryData<{0}>() {{ }};", type); + var p = string.Format(/* lang=c#-test */ "public static TheoryData<{0}> Property => new TheoryData<{0}>() {{ }};", type); return new TheoryData { - { @class, "ClassData(typeof(Class))", type }, - { field, "MemberData(nameof(Field))", type }, - { method, @"MemberData(nameof(Method), 1, ""2"")", type }, - { property, "MemberData(nameof(Property))", type } + { c, "ClassData(typeof(Class))", type }, + { f, "MemberData(nameof(Field))", type }, + { m, @"MemberData(nameof(Method), 1, ""2"")", type }, + { p, "MemberData(nameof(Property))", type } }; } public static TheoryData TheoryDataMembersWithDiscoveryEnumerationDisabled(string type) { - var field = $@"public static readonly TheoryData<{type}> Field = new TheoryData<{type}>() {{ }};"; - var method = $@"public static TheoryData<{type}> Method(int a, string b) => new TheoryData<{type}>() {{ }};"; - var property = $@"public static TheoryData<{type}> Property => new TheoryData<{type}>() {{ }};"; + var f = string.Format(/* lang=c#-test */ "public static readonly TheoryData<{0}> Field = new TheoryData<{0}>() {{ }};", type); + var m = string.Format(/* lang=c#-test */ "public static TheoryData<{0}> Method(int a, string b) => new TheoryData<{0}>() {{ }};", type); + var p = string.Format(/* lang=c#-test */ "public static TheoryData<{0}> Property => new TheoryData<{0}>() {{ }};", type); return new TheoryData { - { field, "MemberData(nameof(Field), DisableDiscoveryEnumeration = true)", type }, - { method, @"MemberData(nameof(Method), 1, ""2"", DisableDiscoveryEnumeration = true)", type }, - { property, "MemberData(nameof(Property), DisableDiscoveryEnumeration = true)", type } + { f, "MemberData(nameof(Field), DisableDiscoveryEnumeration = true)", type }, + { m, @"MemberData(nameof(Method), 1, ""2"", DisableDiscoveryEnumeration = true)", type }, + { p, "MemberData(nameof(Property), DisableDiscoveryEnumeration = true)", type } }; } public sealed class NoDiagnostic : TheoryDataTypeArgumentsShouldBeSerializableTests { [Fact] - public async Task GivenMethodWithoutAttributes_FindsNoDiagnostic() + public async Task GivenMethodWithoutAttributes_DoesNotTrigger() { - var source = @" -public class TestClass { - public void TestMethod() { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task GivenFact_FindsNoDiagnostic() + public async Task GivenFact_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Fact] - public void TestMethod() { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task GivenTheory_WithoutTheoryDataAsDataSource_FindsNoDiagnostic() + public async Task GivenTheory_WithoutTheoryDataAsDataSource_DoesNotTrigger() { - var source = @" -using System; -using System.Collections; -using System.Collections.Generic; -using Xunit; - -public class TestClass { - public static IEnumerable Property1 => Array.Empty(); - public static DataSource Property2 => new DataSource(); - - [Theory] - [MemberData(nameof(Property1))] - [MemberData(nameof(Property2))] - public void TestMethod(object a, object b) { } -} - -public class DataSource : IEnumerable { - public IEnumerator GetEnumerator() { yield break; } - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); -}"; + var source = /* lang=c#-test */ """ + using System; + using System.Collections; + using System.Collections.Generic; + using Xunit; + + public class TestClass { + public static IEnumerable Property1 => Array.Empty(); + public static DataSource Property2 => new DataSource(); + + [Theory] + [MemberData(nameof(Property1))] + [MemberData(nameof(Property2))] + public void TestMethod(object a, object b) { } + } + + public class DataSource : IEnumerable { + public IEnumerator GetEnumerator() { yield break; } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } + """; await Verify.VerifyAnalyzer(source); } @@ -165,9 +169,7 @@ public class DataSource : IEnumerable { [MemberData(nameof(TheoryDataMembers), "SerializableEnumeration")] [MemberData(nameof(TheoryDataMembers), "SerializableEnumeration?")] [MemberData(nameof(TheoryDataMembers), "Dictionary>")] - #if NET6_0_OR_GREATER && ROSLYN_4_4_OR_GREATER - [MemberData(nameof(TheoryDataMembers), "DateOnly")] [MemberData(nameof(TheoryDataMembers), "DateOnly[]")] [MemberData(nameof(TheoryDataMembers), "DateOnly?")] @@ -176,29 +178,28 @@ public class DataSource : IEnumerable { [MemberData(nameof(TheoryDataMembers), "TimeOnly[]")] [MemberData(nameof(TheoryDataMembers), "TimeOnly?")] [MemberData(nameof(TheoryDataMembers), "TimeOnly?[]")] - #endif - - public async Task GivenTheory_WithSerializableTheoryDataMember_FindsNoDiagnostic( + public async Task GivenTheory_WithSerializableTheoryDataMember_DoesNotTrigger( string member, string attribute, string type) { - var source = $@" -using System; -using System.Collections.Generic; -using System.Numerics; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System; + using System.Collections.Generic; + using System.Numerics; + using Xunit; -public class TestClass {{ - {member} + public class TestClass {{ + {0} - [Theory] - [{attribute}] - public void TestMethod({type} parameter) {{ }} -}} + [Theory] + [{1}] + public void TestMethod({2} parameter) {{ }} + }} -public enum SerializableEnumeration {{ Zero }}"; + public enum SerializableEnumeration {{ Zero }} + """, member, attribute, type); await Verify.VerifyAnalyzer(source); } @@ -214,43 +215,42 @@ public enum SerializableEnumeration {{ Zero }}"; [MemberData(nameof(TheoryDataMembers), "SerializableStruct[]")] [MemberData(nameof(TheoryDataMembers), "SerializableStruct?")] [MemberData(nameof(TheoryDataMembers), "SerializableStruct?[]")] - public async Task GivenTheory_WithIXunitSerializableTheoryDataMember_FindsNoDiagnostic( + public async Task GivenTheory_WithIXunitSerializableTheoryDataMember_DoesNotTrigger( string member, string attribute, string type) { - var sourceV2 = GetSource(iXunitSerializableNamespace: "Xunit.Abstractions"); - var sourceV3 = GetSource(iXunitSerializableNamespace: "Xunit.Sdk"); + var sourceV2 = GetSource("Xunit.Abstractions"); + var sourceV3 = GetSource("Xunit.Sdk"); await Verify.VerifyAnalyzerV2(sourceV2); await Verify.VerifyAnalyzerV3(sourceV3); - string GetSource(string iXunitSerializableNamespace) - { - return $@" -using Xunit; -using {iXunitSerializableNamespace}; + string GetSource(string ns) => + string.Format(/* lang=c#-test */ """ + using Xunit; + using {3}; -public class TestClass {{ - {member} + public class TestClass {{ + {0} - [Theory] - [{attribute}] - public void TestMethod({type} parameter) {{ }} -}} + [Theory] + [{1}] + public void TestMethod({2} parameter) {{ }} + }} -public interface ISerializableInterface : IXunitSerializable {{ }} + public interface ISerializableInterface : IXunitSerializable {{ }} -public class SerializableClass : ISerializableInterface {{ - public void Deserialize(IXunitSerializationInfo info) {{ }} - public void Serialize(IXunitSerializationInfo info) {{ }} -}} + public class SerializableClass : ISerializableInterface {{ + public void Deserialize(IXunitSerializationInfo info) {{ }} + public void Serialize(IXunitSerializationInfo info) {{ }} + }} -public struct SerializableStruct : ISerializableInterface {{ - public void Deserialize(IXunitSerializationInfo info) {{ }} - public void Serialize(IXunitSerializationInfo info) {{ }} -}}"; - } + public struct SerializableStruct : ISerializableInterface {{ + public void Deserialize(IXunitSerializationInfo info) {{ }} + public void Serialize(IXunitSerializationInfo info) {{ }} + }} + """, member, attribute, type, ns); } [Theory] @@ -262,30 +262,31 @@ public void Serialize(IXunitSerializationInfo info) {{ }} [MemberData(nameof(TheoryDataMembers), "object[]")] [MemberData(nameof(TheoryDataMembers), "IPossiblySerializableInterface")] [MemberData(nameof(TheoryDataMembers), "PossiblySerializableUnsealedClass")] - public async Task GivenTheory_WithNonSerializableTheoryDataMember_WithDiscoveryEnumerationDisabledForTheory_FindsNoDiagnostic( + public async Task GivenTheory_WithNonSerializableTheoryDataMember_WithDiscoveryEnumerationDisabledForTheory_DoesNotTrigger( string member, string attribute, string type) { - var source = $@" -using System; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System; + using Xunit; -public class TestClass {{ - {member} + public class TestClass {{ + {0} - [Theory(DisableDiscoveryEnumeration = true)] - [{attribute}] - public void TestMethod({type} parameter) {{ }} -}} + [Theory(DisableDiscoveryEnumeration = true)] + [{1}] + public void TestMethod({2} parameter) {{ }} + }} -public sealed class NonSerializableSealedClass {{ }} + public sealed class NonSerializableSealedClass {{ }} -public struct NonSerializableStruct {{ }} + public struct NonSerializableStruct {{ }} -public interface IPossiblySerializableInterface {{ }} + public interface IPossiblySerializableInterface {{ }} -public class PossiblySerializableUnsealedClass {{ }}"; + public class PossiblySerializableUnsealedClass {{ }} + """, member, attribute, type); await Verify.VerifyAnalyzerV3(source); } @@ -299,37 +300,38 @@ public class PossiblySerializableUnsealedClass {{ }}"; [MemberData(nameof(TheoryDataMembersWithDiscoveryEnumerationDisabled), "object[]")] [MemberData(nameof(TheoryDataMembersWithDiscoveryEnumerationDisabled), "IPossiblySerializableInterface")] [MemberData(nameof(TheoryDataMembersWithDiscoveryEnumerationDisabled), "PossiblySerializableUnsealedClass")] - public async Task GivenTheory_WithNonSerializableTheoryDataMember_WithDiscoveryEnumerationDisabledForMemberData_FindsNoDiagnostic( + public async Task GivenTheory_WithNonSerializableTheoryDataMember_WithDiscoveryEnumerationDisabledForMemberData_DoesNotTrigger( string member, string attribute, string type) { - var source = $@" -using System; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System; + using Xunit; -public class TestClass {{ - {member} + public class TestClass {{ + {0} - [Theory] - [{attribute}] - public void TestMethod({type} parameter) {{ }} -}} + [Theory] + [{1}] + public void TestMethod({2} parameter) {{ }} + }} -public sealed class NonSerializableSealedClass {{ }} + public sealed class NonSerializableSealedClass {{ }} -public struct NonSerializableStruct {{ }} + public struct NonSerializableStruct {{ }} -public interface IPossiblySerializableInterface {{ }} + public interface IPossiblySerializableInterface {{ }} -public class PossiblySerializableUnsealedClass {{ }}"; + public class PossiblySerializableUnsealedClass {{ }} + """, member, attribute, type); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(TheoryDataClass), "int", "double", "string")] - public async Task GivenTheory_WithSerializableTheoryDataClass_FindsNoDiagnostic( + public async Task GivenTheory_WithSerializableTheoryDataClass_DoesNotTrigger( string source, string _1, string _2, @@ -341,7 +343,7 @@ public async Task GivenTheory_WithSerializableTheoryDataClass_FindsNoDiagnostic( [Theory] [MemberData(nameof(TheoryDataClass), "Theory(DisableDiscoveryEnumeration = true)", "Action", "TimeZoneInfo", "TimeZoneInfo.TransitionTime")] [MemberData(nameof(TheoryDataClass), "Theory(DisableDiscoveryEnumeration = true)", "object[]", "Array", "IDisposable")] - public async Task GivenTheory_WithNonSerializableTheoryDataClass_WithDiscoveryEnumerationDisabled_FindsNoDiagnostic( + public async Task GivenTheory_WithNonSerializableTheoryDataClass_WithDiscoveryEnumerationDisabled_DoesNotTrigger( string source, string _1, string _2, @@ -353,8 +355,6 @@ public async Task GivenTheory_WithNonSerializableTheoryDataClass_WithDiscoveryEn public sealed class X1044_AvoidUsingTheoryDataTypeArgumentsThatAreNotSerializable : TheoryDataTypeArgumentsShouldBeSerializableTests { - const string Id = "xUnit1044"; - [Theory] [MemberData(nameof(TheoryDataMembers), "Delegate")] [MemberData(nameof(TheoryDataMembers), "Delegate[]")] @@ -366,76 +366,53 @@ public sealed class X1044_AvoidUsingTheoryDataTypeArgumentsThatAreNotSerializabl [MemberData(nameof(TheoryDataMembers), "NonSerializableStruct[]")] [MemberData(nameof(TheoryDataMembers), "NonSerializableStruct?")] [MemberData(nameof(TheoryDataMembers), "NonSerializableStruct?[]")] - public async Task GivenTheory_WithNonSerializableTheoryDataMember_FindsDiagnostic( + public async Task GivenTheory_WithNonSerializableTheoryDataMember_Triggers( string member, string attribute, string type) { - var source = $@" -using System; -using System.Text; -using Xunit; - -public class TestClass {{ - {member} + var source = string.Format(/* lang=c#-test */ """ + using System; + using System.Text; + using Xunit; - [Theory] - [{attribute}] - public void TestMethod({type} parameter) {{ }} -}} + public class TestClass {{ + {0} -public sealed class NonSerializableSealedClass {{ }} + [Theory] + [{{|#0:{1}|}}] + public void TestMethod({2} parameter) {{ }} + }} -public struct NonSerializableStruct {{ }}"; + public sealed class NonSerializableSealedClass {{ }} - var expected = - Verify - .Diagnostic(Id) - .WithSpan(10, 6, 10, 6 + attribute.Length) - .WithArguments(type); + public struct NonSerializableStruct {{ }} + """, member, attribute, type); + var expected = Verify.Diagnostic("xUnit1044").WithLocation(0).WithArguments(type); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(TheoryDataClass), "Action", "TimeZoneInfo", "TimeZoneInfo.TransitionTime")] - public async Task GivenTheory_WithNonSerializableTheoryDataClass_FindsDiagnostic( + public async Task GivenTheory_WithNonSerializableTheoryDataClass_Triggers( string source, string type1, string type2, string type3) { - var expectedForType1 = - Verify - .Diagnostic(Id) - .WithSpan(7, 6, 7, 37) - .WithArguments(type1); - - var expectedForType2 = - Verify - .Diagnostic(Id) - .WithSpan(7, 6, 7, 37) - .WithArguments(type2); - - var expectedForType3 = - Verify - .Diagnostic(Id) - .WithSpan(7, 6, 7, 37) - .WithArguments(type3); - - await Verify.VerifyAnalyzer( - source, - expectedForType1, - expectedForType2, - expectedForType3 - ); + var expected = new[] { + Verify.Diagnostic("xUnit1044").WithSpan(6, 6, 6, 37).WithArguments(type1), + Verify.Diagnostic("xUnit1044").WithSpan(6, 6, 6, 37).WithArguments(type2), + Verify.Diagnostic("xUnit1044").WithSpan(6, 6, 6, 37).WithArguments(type3), + }; + + await Verify.VerifyAnalyzer(source, expected); } } public sealed class X1045_AvoidUsingTheoryDataTypeArgumentsThatMightNotBeSerializable : TheoryDataTypeArgumentsShouldBeSerializableTests { - const string Id = "xUnit1045"; - [Theory] [MemberData(nameof(TheoryDataMembers), "object")] [MemberData(nameof(TheoryDataMembers), "object[]")] @@ -453,70 +430,49 @@ public sealed class X1045_AvoidUsingTheoryDataTypeArgumentsThatMightNotBeSeriali [MemberData(nameof(TheoryDataMembers), "IPossiblySerializableInterface[]")] [MemberData(nameof(TheoryDataMembers), "PossiblySerializableUnsealedClass")] [MemberData(nameof(TheoryDataMembers), "PossiblySerializableUnsealedClass[]")] - public async Task GivenTheory_WithPossiblySerializableTheoryDataMember_FindsDiagnostic( + public async Task GivenTheory_WithPossiblySerializableTheoryDataMember_Triggers( string member, string attribute, string type) { - var source = $@" -using System; -using System.Collections; -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System; + using System.Collections; + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - {member} + public class TestClass {{ + {0} - [Theory] - [{attribute}] - public void TestMethod({type} parameter) {{ }} -}} + [Theory] + [{{|#0:{1}|}}] + public void TestMethod({2} parameter) {{ }} + }} -public interface IPossiblySerializableInterface {{ }} + public interface IPossiblySerializableInterface {{ }} -public class PossiblySerializableUnsealedClass {{ }}"; - - var expected = - Verify - .Diagnostic(Id) - .WithSpan(11, 6, 11, 6 + attribute.Length) - .WithArguments(type); + public class PossiblySerializableUnsealedClass {{ }} + """, member, attribute, type); + var expected = Verify.Diagnostic("xUnit1045").WithLocation(0).WithArguments(type); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(TheoryDataClass), "object[]", "Array", "IDisposable")] - public async Task GivenTheory_WithPossiblySerializableTheoryDataClass_FindsDiagnostic( + public async Task GivenTheory_WithPossiblySerializableTheoryDataClass_Triggers( string source, string type1, string type2, string type3) { - var expectedForType1 = - Verify - .Diagnostic(Id) - .WithSpan(7, 6, 7, 37) - .WithArguments(type1); - - var expectedForType2 = - Verify - .Diagnostic(Id) - .WithSpan(7, 6, 7, 37) - .WithArguments(type2); - - var expectedForType3 = - Verify - .Diagnostic(Id) - .WithSpan(7, 6, 7, 37) - .WithArguments(type3); - - await Verify.VerifyAnalyzer( - source, - expectedForType1, - expectedForType2, - expectedForType3 - ); + var expected = new[] { + Verify.Diagnostic("xUnit1045").WithSpan(6, 6, 6, 37).WithArguments(type1), + Verify.Diagnostic("xUnit1045").WithSpan(6, 6, 6, 37).WithArguments(type2), + Verify.Diagnostic("xUnit1045").WithSpan(6, 6, 6, 37).WithArguments(type3), + }; + + await Verify.VerifyAnalyzer(source, expected); } } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodCannotHaveDefaultParameterTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodCannotHaveDefaultParameterTests.cs index 428d9d08..4302ba4e 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodCannotHaveDefaultParameterTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodCannotHaveDefaultParameterTests.cs @@ -9,31 +9,28 @@ public class TheoryMethodCannotHaveDefaultParameterTests { [Fact] - public async Task FindsErrorForTheoryWithDefaultParameter_WhenDefaultValueNotSupported() + public async Task TheoryWithDefaultParameter_WhenDefaultValueNotSupported_Triggers() { - var source = @" -class TestClass { - [Xunit.Theory] - public void TestMethod(int a, string b, string c = """") { } -}"; - var expected = - Verify_v2_Pre220 - .Diagnostic() - .WithSpan(4, 54, 4, 58) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("TestMethod", "TestClass", "c"); + var source = /* lang=c#-test */ """ + class TestClass { + [Xunit.Theory] + public void TestMethod(int a, string b, string c {|#0:= ""|}) { } + } + """; + var expected = Verify_v2_Pre220.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass", "c"); await Verify_v2_Pre220.VerifyAnalyzer(source, expected); } [Fact] - public async Task DoesNotFindErrorForTheoryWithDefaultParameter_WhenDefaultValueSupported() + public async Task TheoryWithDefaultParameter_WhenDefaultValueSupported_DoesNotTrigger() { - var source = @" -class TestClass { - [Xunit.Theory] - public void TestMethod(int a, string b, string c = """") { } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + [Xunit.Theory] + public void TestMethod(int a, string b, string c = "") { } + } + """; await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodCannotHaveParamsArrayTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodCannotHaveParamsArrayTests.cs index ac6ce7db..f810a328 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodCannotHaveParamsArrayTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodCannotHaveParamsArrayTests.cs @@ -9,55 +9,54 @@ public class TheoryMethodCannotHaveParamsArrayTests { [Fact] - public async Task FindsErrorForTheoryWithParamsArrayAsync_WhenParamsArrayNotSupported() + public async Task TheoryWithParamsArrayAsync_WhenParamsArrayNotSupported_DoesNotTrigger() { - var source = @" -class TestClass { - [Xunit.Theory] - public void TestMethod(int a, string b, params string[] c) { } -}"; - var expected = - Verify_v2_Pre220 - .Diagnostic() - .WithSpan(4, 45, 4, 62) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("TestMethod", "TestClass", "c"); + var source = /* lang=c#-test */ """ + class TestClass { + [Xunit.Theory] + public void TestMethod(int a, string b, {|#0:params string[] c|}) { } + } + """; + var expected = Verify_v2_Pre220.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass", "c"); await Verify_v2_Pre220.VerifyAnalyzer(source, expected); } [Fact] - public async Task DoesNotFindErrorForTheoryWithParamsArrayAsync_WhenParamsArraySupported() + public async Task TheoryWithParamsArrayAsync_WhenParamsArraySupported_DoesNotTrigger() { - var source = @" -class TestClass { - [Xunit.Theory] - public void TestMethod(int a, string b, params string[] c) { } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + [Xunit.Theory] + public void TestMethod(int a, string b, params string[] c) { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindErrorForTheoryWithNonParamsArrayAsync_WhenParamsArrayNotSupported() + public async Task TheoryWithNonParamsArrayAsync_WhenParamsArrayNotSupported_DoesNotTrigger() { - var source = @" -class TestClass { - [Xunit.Theory] - public void TestMethod(int a, string b, string[] c) { } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + [Xunit.Theory] + public void TestMethod(int a, string b, string[] c) { } + } + """; await Verify_v2_Pre220.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindErrorForTheoryWithNonParamsArrayAsync_WhenParamsArraySupported() + public async Task TheoryWithNonParamsArrayAsync_WhenParamsArraySupported_DoesNotTrigger() { - var source = @" -class TestClass { - [Xunit.Theory] - public void TestMethod(int a, string b, string[] c) { } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + [Xunit.Theory] + public void TestMethod(int a, string b, string[] c) { } + } + """; await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodMustHaveTestDataTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodMustHaveTestDataTests.cs index 5a09b952..3e895a48 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodMustHaveTestDataTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodMustHaveTestDataTests.cs @@ -5,13 +5,14 @@ public class TheoryMethodMustHaveTestDataTests { [Fact] - public async Task DoesNotFindErrorForFactMethod() + public async Task FactMethod_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Fact] - public void TestMethod() { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } @@ -20,31 +21,29 @@ public void TestMethod() { } [InlineData("InlineData")] [InlineData("MemberData(\"\")")] [InlineData("ClassData(typeof(string))")] - public async Task DoesNotFindErrorForTheoryMethodWithDataAttributes(string dataAttribute) + public async Task TheoryMethodWithDataAttributes_DoesNotTrigger(string dataAttribute) { - var source = $@" -public class TestClass {{ - [Xunit.Theory] - [Xunit.{dataAttribute}] - public void TestMethod() {{ }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Theory] + [Xunit.{0}] + public void TestMethod() {{ }} + }} + """, dataAttribute); await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FindsErrorForTheoryMethodMissingData() + public async Task TheoryMethodMissingData_Triggers() { - var source = @" -class TestClass { - [Xunit.Theory] - public void TestMethod() { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 17, 4, 27); + var source = /* lang=c#-test */ """ + class TestClass { + [Xunit.Theory] + public void [|TestMethod|]() { } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodShouldHaveParametersTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodShouldHaveParametersTests.cs index 3c0a246a..4e3777a2 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodShouldHaveParametersTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodShouldHaveParametersTests.cs @@ -5,42 +5,41 @@ public class TheoryMethodShouldHaveParametersTests { [Fact] - public async Task DoesNotFindErrorForFactMethod() + public async Task FactMethod_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Fact] - public void TestMethod() { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + public void TestMethod() { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindErrorForTheoryMethodWithParameters() + public async Task TheoryMethodWithParameters_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Theory] - public void TestMethod(string s) { } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Theory] + public void TestMethod(string s) { } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FindsErrorForTheoryMethodWithoutParameters() + public async Task TheoryMethodWithoutParameters_Triggers() { - var source = @" -class TestClass { - [Xunit.Theory] - public void TestMethod() { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 17, 4, 27); + var source = /* lang=c#-test */ """ + class TestClass { + [Xunit.Theory] + public void [|TestMethod|]() { } + } + """; - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodShouldUseAllParametersTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodShouldUseAllParametersTests.cs index 9b5df85e..8b6fbaa3 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodShouldUseAllParametersTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/TheoryMethodShouldUseAllParametersTests.cs @@ -1,210 +1,177 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Verify = CSharpVerifier; public class TheoryMethodShouldUseAllParametersTests { [Fact] - public async Task FindsWarning_ParameterNotReferenced() + public async Task ParameterNotReferenced_Triggers() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -class TestClass { - [Theory] - void TestMethod(int unused) { } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(6, 25, 6, 31) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass", "unused"); + class TestClass { + [Theory] + void TestMethod(int {|#0:unused|}) { } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass", "unused"); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsWarning_ParameterUnread() + public async Task ParameterUnread_Triggers() { - var source = @" -using System; -using Xunit; - -class TestClass { - [Theory] - void TestMethod(int unused) { - unused = 3; - int.TryParse(""123"", out unused); - } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(7, 25, 7, 31) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass", "unused"); + var source = /* lang=c#-test */ """ + using System; + using Xunit; + + class TestClass { + [Theory] + void TestMethod(int {|#0:unused|}) { + unused = 3; + int.TryParse("123", out unused); + } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass", "unused"); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsWarning_MultipleUnreadParameters() + public async Task MultipleUnreadParameters_Triggers() { - var source = @" -using Xunit; - -class TestClass { - [Theory] - void TestMethod(int foo, int bar, int baz) { } -}"; + var source = /* lang=c#-test */ """ + using Xunit; + + class TestClass { + [Theory] + void TestMethod(int {|#0:foo|}, int {|#1:bar|}, int {|#2:baz|}) { } + } + """; var expected = new[] { - Verify - .Diagnostic() - .WithSpan(6, 25, 6, 28) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass", "foo"), - Verify - .Diagnostic() - .WithSpan(6, 34, 6, 37) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass", "bar"), - Verify - .Diagnostic() - .WithSpan(6, 43, 6, 46) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass", "baz"), + Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass", "foo"), + Verify.Diagnostic().WithLocation(1).WithArguments("TestMethod", "TestClass", "bar"), + Verify.Diagnostic().WithLocation(2).WithArguments("TestMethod", "TestClass", "baz"), }; await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsWarning_SomeUnreadParameters() + public async Task SomeUnreadParameters_Triggers() { - var source = @" -using System; -using Xunit; - -class TestClass { - [Theory] - void TestMethod(int foo, int bar, int baz) { - Console.WriteLine(bar); - baz = 3; - } -}"; + var source = /* lang=c#-test */ """ + using System; + using Xunit; + + class TestClass { + [Theory] + void TestMethod(int {|#0:foo|}, int bar, int {|#1:baz|}) { + Console.WriteLine(bar); + baz = 3; + } + } + """; var expected = new[] { - Verify - .Diagnostic() - .WithSpan(7, 25, 7, 28) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass", "foo"), - Verify - .Diagnostic() - .WithSpan(7, 43, 7, 46) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass", "baz"), + Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass", "foo"), + Verify.Diagnostic().WithLocation(1).WithArguments("TestMethod", "TestClass", "baz"), }; await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsWarning_ExpressionBodiedMethod() + public async Task ExpressionBodiedMethod_Triggers() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -class TestClass { - [Theory] - void TestMethod(int unused) => Assert.Equal(5, 2 + 2); -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(6, 25, 6, 31) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass", "unused"); + class TestClass { + [Theory] + void TestMethod(int {|#0:unused|}) => Assert.Equal(5, 2 + 2); + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass", "unused"); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task DoesNotFindWarning_ParameterRead() + public async Task ParameterRead_DoesNotTrigger() { - var source = @" -using System; -using Xunit; - -class TestClass { - [Theory] - void TestMethod(int used) { - Console.WriteLine(used); - } -}"; + var source = /* lang=c#-test */ """ + using System; + using Xunit; + + class TestClass { + [Theory] + void TestMethod(int used) { + Console.WriteLine(used); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindWarning_ParameterCapturedAsOutParameterInMockSetup() + public async Task ParameterCapturedAsOutParameterInMockSetup_DoesNotTrigger() { - var source = @" -using System; -using Xunit; - -class TestClass { - [Theory] - void TestMethod(string used, int usedOut) { - // mimicking mock setup use case - // var mock = new Mock(); - // mock.Setup(m => m.SomeMethod(out used)); - Action setup = () => int.TryParse(used, out usedOut); - } -}"; + var source = /* lang=c#-test */ """ + using System; + using Xunit; + + class TestClass { + [Theory] + void TestMethod(string used, int usedOut) { + // mimicking mock setup use case + // var mock = new Mock(); + // mock.Setup(m => m.SomeMethod(out used)); + Action setup = () => int.TryParse(used, out usedOut); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindWarning_ExpressionBodiedMethod() + public async Task ExpressionBodiedMethod_DoesNotTrigger() { - var source = @" -using Xunit; + var source = /* lang=c#-test */ """ + using Xunit; -class TestClass { - [Theory] - void TestMethod(int used) => Assert.Equal(used, 2 + 2); -}"; + class TestClass { + [Theory] + void TestMethod(int used) => Assert.Equal(used, 2 + 2); + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindWarning_WhenParameterIsDiscardNamed() + public async Task WhenParameterIsDiscardNamed_DoesNotTrigger() { - var source = @" -using System; -using Xunit; - -class TestClass { - [Theory] - void TestMethod(int used, string _, object _1, DateTime _42, double _a) - { - Assert.Equal(42, used); - } -}"; - + var source = /* lang=c#-test */ """ + using System; + using Xunit; + + class TestClass { + [Theory] + void TestMethod(int used, string _, object _1, DateTime _42, double {|#0:_a|}) + { + Assert.Equal(42, used); + } + } + """; // Only a single warning, for _a; everything else is either used or matches the discard pattern - var expected = - Verify - .Diagnostic() - .WithSpan(7, 73, 7, 75) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("TestMethod", "TestClass", "_a"); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("TestMethod", "TestClass", "_a"); await Verify.VerifyAnalyzer(source, expected); } @@ -212,13 +179,14 @@ void TestMethod(int used, string _, object _1, DateTime _42, double _a) [Fact] public async Task DoesNotCrash_MethodWithoutBody() { - var source = @" -using Xunit; - -class TestClass { - [Theory] - extern void TestMethod(int foo); -}"; + var source = /* lang=c#-test */ """ + using Xunit; + + class TestClass { + [Theory] + extern void TestMethod(int foo); + } + """; await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X1000/UseCancellationTokenTests.cs b/src/xunit.analyzers.tests/Analyzers/X1000/UseCancellationTokenTests.cs index 7ee3f6a5..160e3cce 100644 --- a/src/xunit.analyzers.tests/Analyzers/X1000/UseCancellationTokenTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X1000/UseCancellationTokenTests.cs @@ -8,16 +8,17 @@ public class UseCancellationTokenTests [Fact] public async Task NoCancellationToken_DoesNotTrigger() { - var source = @" -using System.Threading; -using Xunit; - -class TestClass { - [Fact] - public void TestMethod() { - Thread.Sleep(1); - } -}"; + var source = /* lang=c#-test */ """ + using System.Threading; + using Xunit; + + class TestClass { + [Fact] + public void TestMethod() { + Thread.Sleep(1); + } + } + """; await Verify.VerifyAnalyzerV3(source); } @@ -27,17 +28,18 @@ public void TestMethod() { [InlineData("new CancellationTokenSource().Token")] public async Task WithAnyCancellationToken_DoesNotTrigger(string token) { - var source = @$" -using System.Threading; -using System.Threading.Tasks; -using Xunit; - -class TestClass {{ - [Fact] - public async Task TestMethod() {{ - await Task.Delay(1, {token}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Threading; + using System.Threading.Tasks; + using Xunit; + + class TestClass {{ + [Fact] + public async Task TestMethod() {{ + await Task.Delay(1, {0}); + }} + }} + """, token); await Verify.VerifyAnalyzerV3(source); } @@ -45,17 +47,18 @@ public async Task TestMethod() {{ [Fact] public async Task WithoutCancellationToken_V2_DoesNotTrigger() { - var source = @$" -using System.Threading; -using System.Threading.Tasks; -using Xunit; - -class TestClass {{ - [Fact] - public async Task TestMethod() {{ - await Task.Delay(1); - }} -}}"; + var source = /* lang=c#-test */ """ + using System.Threading; + using System.Threading.Tasks; + using Xunit; + + class TestClass { + [Fact] + public async Task TestMethod() { + await Task.Delay(1); + } + } + """; await Verify.VerifyAnalyzerV2(source); } @@ -63,20 +66,21 @@ public async Task TestMethod() {{ [Fact] public async Task WithoutCancellationToken_WithoutDirectUpgrade_DoesNotTrigger() { - var source = @" -using System.Threading; -using System.Threading.Tasks; -using Xunit; - -class TestClass { - [Fact] - public void TestMethod() { - FunctionWithOverload(42); - } - - void FunctionWithOverload(int _) { } - void FunctionWithOverload(CancellationToken _) { } -}"; + var source = /* lang=c#-test */ """ + using System.Threading; + using System.Threading.Tasks; + using Xunit; + + class TestClass { + [Fact] + public void TestMethod() { + FunctionWithOverload(42); + } + + void FunctionWithOverload(int _) { } + void FunctionWithOverload(CancellationToken _) { } + } + """; await Verify.VerifyAnalyzerV3(source); } @@ -93,27 +97,24 @@ void FunctionWithOverload(CancellationToken _) { } [InlineData("FunctionWithOverload(42, default(CancellationToken))")] public async Task WithoutCancellationToken_V3_Triggers(string invocation) { - var source = @$" -using System.Threading; -using System.Threading.Tasks; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.Threading; + using System.Threading.Tasks; + using Xunit; -class TestClass {{ - [Fact] - public void TestMethod() {{ - {invocation}; - }} + class TestClass {{ + [Fact] + public void TestMethod() {{ + [|{0}|]; + }} - void FunctionWithDefaults(int _1 = 2112, CancellationToken cancellationToken = default) {{ }} + void FunctionWithDefaults(int _1 = 2112, CancellationToken cancellationToken = default) {{ }} - void FunctionWithOverload(int _) {{ }} - void FunctionWithOverload(int _1, CancellationToken _2) {{ }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(9, 9, 9, 9 + invocation.Length); + void FunctionWithOverload(int _) {{ }} + void FunctionWithOverload(int _1, CancellationToken _2) {{ }} + }} + """, invocation); - await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp7_1, source, expected); + await Verify.VerifyAnalyzerV3(LanguageVersion.CSharp7_1, source); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertCollectionContainsShouldNotUseBoolCheckTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertCollectionContainsShouldNotUseBoolCheckTests.cs index 1b8900e2..b450dff6 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertCollectionContainsShouldNotUseBoolCheckTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertCollectionContainsShouldNotUseBoolCheckTests.cs @@ -5,228 +5,216 @@ public class AssertCollectionContainsShouldNotUseBoolCheckTests { - public static TheoryData Collections = new() - { + public static TheoryData Collections = + [ "new System.Collections.Generic.List()", "new System.Collections.Generic.HashSet()", "new System.Collections.ObjectModel.Collection()", - }; - public static TheoryData Enumerables = new() - { + ]; + public static TheoryData Enumerables = + [ "new int[0]", "System.Linq.Enumerable.Empty()", - }; + ]; [Theory] [MemberData(nameof(Collections))] - public async Task FindsWarningForTrueCollectionContainsCheck(string collection) + public async Task TrueCollectionContainsCheck_Triggers(string collection) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.True({collection}.Contains(1)); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 40 + collection.Length) - .WithArguments("Assert.True()", Constants.Asserts.Contains); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.True({0}.Contains(1))|}}; + }} + }} + """, collection); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.True()", Constants.Asserts.Contains); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Collections))] - public async Task FindsWarningForFalseCollectionContainsCheck(string collection) + public async Task FalseCollectionContainsCheck_Triggers(string collection) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.False({collection}.Contains(1)); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 41 + collection.Length) - .WithArguments("Assert.False()", Constants.Asserts.DoesNotContain); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.False({0}.Contains(1))|}}; + }} + }} + """, collection); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.False()", Constants.Asserts.DoesNotContain); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Enumerables))] - public async Task FindsWarningForTrueLinqContainsCheck(string enumerable) + public async Task TrueLinqContainsCheck_Triggers(string enumerable) { - var source = $@" -using System.Linq; - -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.True({enumerable}.Contains(1)); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(6, 9, 6, 40 + enumerable.Length) - .WithArguments("Assert.True()", Constants.Asserts.Contains); + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; + + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.True({0}.Contains(1))|}}; + }} + }} + """, enumerable); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.True()", Constants.Asserts.Contains); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Enumerables))] - public async Task FindsWarningForTrueLinqContainsCheckWithEqualityComparer(string enumerable) + public async Task TrueLinqContainsCheckWithEqualityComparer_Triggers(string enumerable) { - var source = $@" -using System.Linq; - -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.True({enumerable}.Contains(1, System.Collections.Generic.EqualityComparer.Default)); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(6, 9, 6, 98 + enumerable.Length) - .WithArguments("Assert.True()", Constants.Asserts.Contains); + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; + + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.True({0}.Contains(1, System.Collections.Generic.EqualityComparer.Default))|}}; + }} + }} + """, enumerable); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.True()", Constants.Asserts.Contains); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Enumerables))] - public async Task FindsWarningForFalseLinqContainsCheck(string enumerable) + public async Task FalseLinqContainsCheck_Triggers(string enumerable) { - var source = $@" -using System.Linq; - -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.False({enumerable}.Contains(1)); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(6, 9, 6, 41 + enumerable.Length) - .WithArguments("Assert.False()", Constants.Asserts.DoesNotContain); + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; + + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.False({0}.Contains(1))|}}; + }} + }} + """, enumerable); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.False()", Constants.Asserts.DoesNotContain); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Enumerables))] - public async Task FindsWarningForFalseLinqContainsCheckWithEqualityComparer(string enumerable) + public async Task FalseLinqContainsCheckWithEqualityComparer_Triggers(string enumerable) { - var source = $@" -using System.Linq; - -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.False({enumerable}.Contains(1, System.Collections.Generic.EqualityComparer.Default)); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(6, 9, 6, 99 + enumerable.Length) - .WithArguments("Assert.False()", Constants.Asserts.DoesNotContain); + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; + + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.False({0}.Contains(1, System.Collections.Generic.EqualityComparer.Default))|}}; + }} + }} + """, enumerable); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.False()", Constants.Asserts.DoesNotContain); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Collections))] - public async Task DoesNotFindWarningForTrueCollectionContainsCheckWithAssertionMessage(string collection) + public async Task TrueCollectionContainsCheckWithAssertionMessage_DoesNotTrigger(string collection) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.True({collection}.Contains(1), ""Custom message""); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.True({0}.Contains(1), "Custom message"); + }} + }} + """, collection); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Collections))] - public async Task DoesNotFindWarningForFalseCollectionContainsCheckWithAssertionMessage(string collection) + public async Task FalseCollectionContainsCheckWithAssertionMessage_DoesNotTrigger(string collection) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.False({collection}.Contains(1), ""Custom message""); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.False({0}.Contains(1), "Custom message"); + }} + }} + """, collection); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Enumerables))] - public async Task DoesNotFindWarningForTrueLinqContainsCheckWithAssertionMessage(string enumerable) + public async Task TrueLinqContainsCheckWithAssertionMessage_DoesNotTrigger(string enumerable) { - var source = $@" -using System.Linq; + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.True({enumerable}.Contains(1), ""Custom message""); - }} -}}"; + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.True({0}.Contains(1), "Custom message"); + }} + }} + """, enumerable); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Enumerables))] - public async Task DoesNotFindWarningForFalseLinqContainsCheckWithAssertionMessage(string enumerable) + public async Task FalseLinqContainsCheckWithAssertionMessage_DoesNotTrigger(string enumerable) { - var source = $@" -using System.Linq; + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.False({enumerable}.Contains(1), ""Custom message""); - }} -}}"; + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.False({0}.Contains(1), "Custom message"); + }} + }} + """, enumerable); await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotCrashForCollectionWithDifferentTypeParametersThanICollectionImplementation_ZeroParameters() + public async Task CollectionWithDifferentTypeParametersThanICollectionImplementation_ZeroParameters_Triggers() { - var source = @" -using System.Collections.Generic; + var source = /* lang=c#-test */ """ + using System.Collections.Generic; -class IntList : List { } + class IntList : List { } -class TestClass { - void TestMethod() { - [|Xunit.Assert.False(new IntList().Contains(1))|]; - } -}"; + class TestClass { + void TestMethod() { + [|Xunit.Assert.False(new IntList().Contains(1))|]; + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotCrashForCollectionWithDifferentTypeParametersThanICollectionImplementation_TwoParameters() + public async Task CollectionWithDifferentTypeParametersThanICollectionImplementation_TwoParameters_DoesNotTrigger() { - var source = @" -using System.Collections.Generic; - -class TestClass { - void TestMethod() { - Xunit.Assert.False(new Dictionary().ContainsKey(1)); - } -}"; + var source = /* lang=c#-test */ """ + using System.Collections.Generic; + + class TestClass { + void TestMethod() { + Xunit.Assert.False(new Dictionary().ContainsKey(1)); + } + } + """; await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEmptyCollectionCheckShouldNotBeUsedTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEmptyCollectionCheckShouldNotBeUsedTests.cs index b53014b4..7e45adec 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEmptyCollectionCheckShouldNotBeUsedTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEmptyCollectionCheckShouldNotBeUsedTests.cs @@ -4,8 +4,8 @@ public class AssertEmptyCollectionCheckShouldNotBeUsedTests { - public static TheoryData Collections = new() - { + public static TheoryData Collections = + [ "new int[0]", "new System.Collections.Generic.List()", "new System.Collections.Generic.HashSet()", @@ -14,34 +14,36 @@ public class AssertEmptyCollectionCheckShouldNotBeUsedTests #if NETCOREAPP3_0_OR_GREATER "default(System.Collections.Generic.IAsyncEnumerable)", #endif - }; + ]; [Theory] [MemberData(nameof(Collections))] - public async Task FindsWarningForCollectionCheckWithoutAction(string collection) + public async Task CollectionCheckWithoutAction_Triggers(string collection) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - [|Xunit.Assert.Collection({collection})|]; - [|Xunit.Assert.CollectionAsync({collection})|]; - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + [|Xunit.Assert.Collection({0})|]; + [|Xunit.Assert.CollectionAsync({0})|]; + }} + }} + """, collection); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Collections))] - public async Task DoesNotFindWarningForCollectionCheckWithAction(string collection) + public async Task CollectionCheckWithAction_DoesNotTrigger(string collection) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.Collection({collection}, i => Xunit.Assert.True(true)); - Xunit.Assert.CollectionAsync({collection}, async i => {{ await System.Threading.Tasks.Task.Yield(); Xunit.Assert.True(true); }}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.Collection({0}, i => Xunit.Assert.True(true)); + Xunit.Assert.CollectionAsync({0}, async i => {{ await System.Threading.Tasks.Task.Yield(); Xunit.Assert.True(true); }}); + }} + }} + """, collection); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheckTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheckTests.cs index d806fc0f..b1375e1e 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheckTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheckTests.cs @@ -23,14 +23,14 @@ public async Task Containers_WithoutWhereClause_DoesNotTrigger( string collection, string _) { - var source = $@" -class TestClass -{{ - void TestMethod() - {{ - Xunit.Assert.Empty({collection}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.Empty({0}); + }} + }} + """, collection); + await Verify.VerifyAnalyzer(source); } @@ -41,15 +41,15 @@ public async Task Containers_WithWhereClause_Triggers( string collection, string comparison) { - var source = $@" -using System.Linq; -class TestClass -{{ - void TestMethod() - {{ - [|Xunit.Assert.Empty({collection}.Where(f => {comparison}))|]; - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; + + class TestClass {{ + void TestMethod() {{ + [|Xunit.Assert.Empty({0}.Where(f => {1}))|]; + }} + }} + """, collection, comparison); await Verify.VerifyAnalyzer(source); } @@ -61,15 +61,16 @@ public async Task Containers_WithWhereClauseWithIndex_DoesNotTrigger( string collection, string comparison) { - var source = $@" -using System.Linq; -class TestClass -{{ - void TestMethod() - {{ - Xunit.Assert.Empty({collection}.Where((f, i) => {comparison} && i > 0)); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; + + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.Empty({0}.Where((f, i) => {1} && i > 0)); + }} + }} + """, collection, comparison); + await Verify.VerifyAnalyzer(source); } @@ -80,34 +81,34 @@ public async Task DoesNotFindWarningForEnumurableEmptyCheckWithChainedLinq( string collection, string comparison) { - var source = $@" -using System.Linq; -class TestClass -{{ - void TestMethod() - {{ - Xunit.Assert.Empty({collection}.Where(f => {comparison}).Select(f => f)); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; + + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.Empty({0}.Where(f => {1}).Select(f => f)); + }} + }} + """, collection, comparison); await Verify.VerifyAnalyzer(source); } - public static TheoryData GetSampleStrings() => - new(string.Empty, "123", @"abc\n\t\\\"""); - [Theory] - [MemberData(nameof(GetSampleStrings))] + [InlineData("")] + [InlineData("123")] + [InlineData(@"abc\n\t\\\""")] public async Task Strings_WithWhereClause_DoesNotTrigger(string sampleString) { - var source = $@" -using System.Linq; -class TestClass -{{ - void TestMethod() - {{ - [|Xunit.Assert.Empty(""{sampleString}"".Where(f => f > 0))|]; - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; + + class TestClass {{ + void TestMethod() {{ + [|Xunit.Assert.Empty("{0}".Where(f => f > 0))|]; + }} + }} + """, sampleString); + await Verify.VerifyAnalyzer(source); } } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheckTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheckTests.cs index 7e01323b..c500071c 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheckTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheckTests.cs @@ -5,24 +5,25 @@ public class AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheckTests { - public static TheoryData Methods = new() - { + public static TheoryData Methods = + [ Constants.Asserts.True, Constants.Asserts.False, - }; + ]; [Theory] [MemberData(nameof(Methods))] - public async Task FindsWarning_ForLinqAnyCheck(string method) + public async Task ForLinqAnyCheck_Triggers(string method) { - var source = $@" -using System.Linq; + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; -class TestClass {{ - void TestMethod() {{ - [|Xunit.Assert.{method}(new [] {{ 1 }}.Any(i => true))|]; - }} -}}"; + class TestClass {{ + void TestMethod() {{ + [|Xunit.Assert.{0}(new [] {{ 1 }}.Any(i => true))|]; + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualGenericShouldNotBeUsedForStringValueTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualGenericShouldNotBeUsedForStringValueTests.cs index c0274113..86ea238b 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualGenericShouldNotBeUsedForStringValueTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualGenericShouldNotBeUsedForStringValueTests.cs @@ -17,64 +17,68 @@ public class AssertEqualGenericShouldNotBeUsedForStringValueTests [Theory] [MemberData(nameof(Data))] - public async Task DoesNotFindWarningForStringEqualityCheckWithoutGenericType( + public async Task StringEqualityCheckWithoutGenericType_DoesNotTrigger( string expected, string value) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.Equal({expected}, {value}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.Equal({0}, {1}); + }} + }} + """, expected, value); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Data))] - public async Task FindsWarningForStringEqualityCheckWithGenericType( + public async Task StringEqualityCheckWithGenericType_Triggers( string expected, string value) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - [|Xunit.Assert.Equal({expected}, {value})|]; - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + [|Xunit.Assert.Equal({0}, {1})|]; + }} + }} + """, expected, value); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Data))] - public async Task FindsWarningForStrictStringEqualityCheck( + public async Task StrictStringEqualityCheck_Triggers( string expected, string value) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - [|Xunit.Assert.StrictEqual({expected}, {value})|]; - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + [|Xunit.Assert.StrictEqual({0}, {1})|]; + }} + }} + """, expected, value); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Data))] - public async Task FindsWarningForStrictStringEqualityCheckWithGenericType( + public async Task StrictStringEqualityCheckWithGenericType_Triggers( string expected, string value) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - [|Xunit.Assert.StrictEqual({expected}, {value})|]; - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + [|Xunit.Assert.StrictEqual({0}, {1})|]; + }} + }} + """, expected, value); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualLiteralValueShouldBeFirstTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualLiteralValueShouldBeFirstTests.cs index 273101a3..af01461a 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualLiteralValueShouldBeFirstTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualLiteralValueShouldBeFirstTests.cs @@ -5,14 +5,15 @@ public class AssertEqualLiteralValueShouldBeFirstTests { [Fact] - public async Task DoesNotFindWarningWhenConstantOrLiteralUsedForBothArguments() + public async Task WhenConstantOrLiteralUsedForBothArguments_DoesNotTrigger() { - var source = @" -class TestClass { - void TestMethod() { - Xunit.Assert.Equal(""TestMethod"", nameof(TestMethod)); - } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + void TestMethod() { + Xunit.Assert.Equal("TestMethod", nameof(TestMethod)); + } + } + """; await Verify.VerifyAnalyzer(source); } @@ -32,52 +33,51 @@ void TestMethod() { [Theory] [MemberData(nameof(TypesAndValues))] - public async Task DoesNotFindWarningForExpectedConstantOrLiteralValueAsFirstArgument( + public async Task ExpectedConstantOrLiteralValueAsFirstArgument_DoesNotTrigger( string type, string value) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - var v = default({type}); - Xunit.Assert.Equal({value}, v); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + var v = default({0}); + Xunit.Assert.Equal({1}, v); + }} + }} + """, type, value); await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindWarningForConstantsUsedInStringConstructorAsFirstArgument() + public async Task ConstantsUsedInStringConstructorAsFirstArgument_DoesNotTrigger() { - var source = @" -class TestClass { - void TestMethod() { - Xunit.Assert.Equal(new string(' ', 4), "" ""); - } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + void TestMethod() { + Xunit.Assert.Equal(new string(' ', 4), " "); + } + } + """; await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(TypesAndValues))] - public async Task FindsWarningForExpectedConstantOrLiteralValueAsSecondArgument( + public async Task ExpectedConstantOrLiteralValueAsSecondArgument_Triggers( string type, string value) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - var v = default({type}); - Xunit.Assert.Equal(v, {value}); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithLocation(5, 9) - .WithArguments(value, "Assert.Equal(expected, actual)", "TestMethod", "TestClass"); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + var v = default({0}); + {{|#0:Xunit.Assert.Equal(v, {1})|}}; + }} + }} + """, type, value); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(value, "Assert.Equal(expected, actual)", "TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } @@ -85,38 +85,35 @@ void TestMethod() {{ [Theory] [InlineData(true)] [InlineData(false)] - public async Task DoesNotFindWarningForExpectedConstantOrLiteralValueAsNamedExpectedArgument(bool useAlternateForm) + public async Task ExpectedConstantOrLiteralValueAsNamedExpectedArgument_DoesNotTrigger(bool useAlternateForm) { - var prefix = useAlternateForm ? "@" : ""; - var source = $@" -class TestClass {{ - void TestMethod() {{ - var v = default(int); - Xunit.Assert.Equal({prefix}actual: v, {prefix}expected: 0); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + var v = default(int); + Xunit.Assert.Equal({0}actual: v, {0}expected: 0); + }} + }} + """, useAlternateForm ? "@" : ""); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(TypesAndValues))] - public async Task FindsWarningForExpectedConstantOrLiteralValueAsNamedExpectedArgument( + public async Task ExpectedConstantOrLiteralValueAsNamedExpectedArgument_Triggers( string type, string value) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - var v = default({type}); - Xunit.Assert.Equal(actual: {value}, expected: v); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithLocation(5, 9) - .WithArguments(value, "Assert.Equal(expected, actual)", "TestMethod", "TestClass"); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + var v = default({0}); + {{|#0:Xunit.Assert.Equal(actual: {1}, expected: v)|}}; + }} + }} + """, type, value); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(value, "Assert.Equal(expected, actual)", "TestMethod", "TestClass"); await Verify.VerifyAnalyzer(source, expected); } @@ -131,13 +128,14 @@ public async Task DoesNotFindWarningWhenArgumentsAreNotNamedCorrectly( string firstArgumentName, string secondArgumentName) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - var v = default(int); - Xunit.Assert.{methodName}({firstArgumentName}: 1, {secondArgumentName}: v); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + var v = default(int); + Xunit.Assert.{0}({1}: 1, {2}: v); + }} + }} + """, methodName, firstArgumentName, secondArgumentName); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualPrecisionShouldBeInRangeTest.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualPrecisionShouldBeInRangeTest.cs index 254c9d9d..4dee1b9e 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualPrecisionShouldBeInRangeTest.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualPrecisionShouldBeInRangeTest.cs @@ -1,16 +1,16 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Verify = CSharpVerifier; public class AssertEqualPrecisionShouldBeInRangeTest { - static readonly string Template = @" -class TestClass {{ - void TestMethod() {{ - {0} - }} -}}"; + static readonly string Template = /* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {0} + }} + }} + """; [Theory] [InlineData(0)] @@ -39,14 +39,9 @@ public async Task FindsError_ForDoubleArgumentWithPrecisionProvidedOutOfRange(in { var source = string.Format( Template, - $"double num = 0.133d; Xunit.Assert.Equal(0.13d, num, {precision});" + $"double num = 0.133d; Xunit.Assert.Equal(0.13d, num, {{|#0:{precision}|}});" ); - var expected = - Verify - .Diagnostic() - .WithLocation(4, 61) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("[0..15]", "double"); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("[0..15]", "double"); await Verify.VerifyAnalyzer(source, expected); } @@ -78,14 +73,9 @@ public async Task FindsError_ForDecimalArgumentWithPrecisionProvidedOutOfRange(i { var source = string.Format( Template, - $"decimal num = 0.133m; Xunit.Assert.Equal(0.13m, num, {precision});" + $"decimal num = 0.133m; Xunit.Assert.Equal(0.13m, num, {{|#0:{precision}|}});" ); - var expected = - Verify - .Diagnostic() - .WithLocation(4, 62) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("[0..28]", "decimal"); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("[0..28]", "decimal"); await Verify.VerifyAnalyzer(source, expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForBoolLiteralCheckTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForBoolLiteralCheckTests.cs index 23012129..73070478 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForBoolLiteralCheckTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForBoolLiteralCheckTests.cs @@ -1,41 +1,36 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Xunit.Analyzers; using Verify = CSharpVerifier; public class AssertEqualShouldNotBeUsedForBoolLiteralCheckTests { - public static TheoryData Methods = new() - { + public static TheoryData Methods = + [ Constants.Asserts.Equal, Constants.Asserts.NotEqual, Constants.Asserts.StrictEqual, Constants.Asserts.NotStrictEqual, - }; + ]; [Theory] [InlineData(Constants.Asserts.Equal, Constants.Asserts.True)] [InlineData(Constants.Asserts.StrictEqual, Constants.Asserts.True)] [InlineData(Constants.Asserts.NotEqual, Constants.Asserts.False)] [InlineData(Constants.Asserts.NotStrictEqual, Constants.Asserts.False)] - public async Task FindsWarning_ForFirstBoolLiteral( + public async Task ForFirstBoolLiteral_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - bool val = true; - Xunit.Assert.{method}(true, val); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 33 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + bool val = true; + {{|#0:Xunit.Assert.{0}(true, val)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } @@ -43,68 +38,67 @@ void TestMethod() {{ [Theory] [InlineData(Constants.Asserts.Equal, Constants.Asserts.False)] [InlineData(Constants.Asserts.NotEqual, Constants.Asserts.True)] - public async Task FindsWarning_ForFirstBoolLiteral_WithCustomComparer( + public async Task ForFirstBoolLiteral_WithCustomComparer_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - bool val = false; - Xunit.Assert.{method}(false, val, System.Collections.Generic.EqualityComparer.Default); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 93 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + bool val = false; + {{|#0:Xunit.Assert.{0}(false, val, System.Collections.Generic.EqualityComparer.Default)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForFirstBoolLiteral_ObjectOverload(string method) + public async Task ForFirstBoolLiteral_ObjectOverload_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - object val = false; - Xunit.Assert.{method}(true, val); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + object val = false; + Xunit.Assert.{0}(true, val); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForOtherLiteral(string method) + public async Task ForOtherLiteral_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - int val = 1; - Xunit.Assert.{method}(1, val); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + int val = 1; + Xunit.Assert.{0}(1, val); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForSecondBoolLiteral(string method) + public async Task ForSecondBoolLiteral_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - bool val = false; - Xunit.Assert.{method}(val, true); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + bool val = false; + Xunit.Assert.{0}(val, true); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForCollectionSizeCheckTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForCollectionSizeCheckTests.cs index 2d8035ee..cae84524 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForCollectionSizeCheckTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForCollectionSizeCheckTests.cs @@ -1,19 +1,17 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Xunit.Analyzers; using Verify = CSharpVerifier; public class AssertEqualShouldNotBeUsedForCollectionSizeCheckTests { - public static TheoryData AllowedCollections = new() - { + public static TheoryData AllowedCollections = + [ "new System.ArraySegment().Count", "Microsoft.Extensions.Primitives.StringValues.Empty.Count", - }; - - public static TheoryData DisallowedCollections = new() - { + ]; + public static TheoryData DisallowedCollections = + [ "new int[0].Length", "new System.Collections.ArrayList().Count", "new System.Collections.Generic.List().Count", @@ -22,29 +20,29 @@ public class AssertEqualShouldNotBeUsedForCollectionSizeCheckTests "new System.Collections.ObjectModel.Collection().Count", "new System.Collections.Generic.List().AsReadOnly().Count", "System.Linq.Enumerable.Empty().Count()", - }; - - public static TheoryData DisallowedCollectionInterfaces = new() - { + ]; + public static TheoryData DisallowedCollectionInterfaces = + [ "ICollection", "ICollection", "IReadOnlyCollection", - }; + ]; [Theory] [MemberData(nameof(AllowedCollections))] public async Task AllowedCollection_DoesNotTrigger(string collection) { - var source = $@" -using System.Linq; - -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.Equal(0, {collection}); - Xunit.Assert.Equal(1, {collection}); - Xunit.Assert.NotEqual(0, {collection}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; + + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.Equal(0, {0}); + Xunit.Assert.Equal(1, {0}); + Xunit.Assert.NotEqual(0, {0}); + }} + }} + """, collection); await Verify.VerifyAnalyzer(source); } @@ -55,16 +53,17 @@ void TestMethod() {{ public async Task AllowedCheck_DoesNotTrigger(string collection) { // Anything that's non-zero for Equal/NotEqual and non-one for Equal is allowed - var source = $@" -using System.Linq; - -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.Equal(2, {collection}); - Xunit.Assert.NotEqual(1, {collection}); - Xunit.Assert.NotEqual(2, {collection}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; + + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.Equal(2, {0}); + Xunit.Assert.NotEqual(1, {0}); + Xunit.Assert.NotEqual(2, {0}); + }} + }} + """, collection); await Verify.VerifyAnalyzer(source); } @@ -74,33 +73,22 @@ void TestMethod() {{ [MemberData(nameof(DisallowedCollections))] public async Task InvalidCheckWithConcreteType_Triggers(string collection) { - var source = $@" -using System.Linq; - -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.Equal(0, {collection}); - Xunit.Assert.Equal(1, {collection}); - Xunit.Assert.NotEqual(0, {collection}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Linq; + + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.Equal(0, {0})|}}; + {{|#1:Xunit.Assert.Equal(1, {0})|}}; + {{|#2:Xunit.Assert.NotEqual(0, {0})|}}; + }} + }} + """, collection); var expected = new[] { - Verify - .Diagnostic() - .WithSpan(6, 9, 6, 32 + collection.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.Equal()", Constants.Asserts.Empty), - Verify - .Diagnostic() - .WithSpan(7, 9, 7, 32 + collection.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.Equal()", Constants.Asserts.Single), - Verify - .Diagnostic() - .WithSpan(8, 9, 8, 35 + collection.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.NotEqual()", Constants.Asserts.NotEmpty), + Verify.Diagnostic().WithLocation(0).WithArguments("Assert.Equal()", Constants.Asserts.Empty), + Verify.Diagnostic().WithLocation(1).WithArguments("Assert.Equal()", Constants.Asserts.Single), + Verify.Diagnostic().WithLocation(2).WithArguments("Assert.NotEqual()", Constants.Asserts.NotEmpty), }; await Verify.VerifyAnalyzer(source, expected); @@ -110,35 +98,24 @@ void TestMethod() {{ [MemberData(nameof(DisallowedCollectionInterfaces))] public async Task InvalidCheckWithInterfaceType_Triggers(string @interface) { - var source = $@" -using System.Collections; -using System.Collections.Generic; - -class TestClass {{ - void TestMethod() {{ - {@interface} collection = null; - Xunit.Assert.Equal(0, collection.Count); - Xunit.Assert.Equal(1, collection.Count); - Xunit.Assert.NotEqual(0, collection.Count); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System.Collections; + using System.Collections.Generic; + + class TestClass {{ + void TestMethod() {{ + {0} collection = null; + {{|#0:Xunit.Assert.Equal(0, collection.Count)|}}; + {{|#1:Xunit.Assert.Equal(1, collection.Count)|}}; + {{|#2:Xunit.Assert.NotEqual(0, collection.Count)|}}; + }} + }} + """, @interface); var expected = new[] { - Verify - .Diagnostic() - .WithSpan(8, 9, 8, 48) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.Equal()", Constants.Asserts.Empty), - Verify - .Diagnostic() - .WithSpan(9, 9, 9, 48) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.Equal()", Constants.Asserts.Single), - Verify - .Diagnostic() - .WithSpan(10, 9, 10, 51) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.NotEqual()", Constants.Asserts.NotEmpty), + Verify.Diagnostic().WithLocation(0).WithArguments("Assert.Equal()", Constants.Asserts.Empty), + Verify.Diagnostic().WithLocation(1).WithArguments("Assert.Equal()", Constants.Asserts.Single), + Verify.Diagnostic().WithLocation(2).WithArguments("Assert.NotEqual()", Constants.Asserts.NotEmpty), }; await Verify.VerifyAnalyzer(source, expected); @@ -147,47 +124,36 @@ void TestMethod() {{ [Fact] public async Task InvalidCheckWithCustomNonGenericCollection_Triggers() { - var source = @" -using System.Collections; -using System.Collections.Generic; -using Xunit; - -class IntCollection : ICollection { - public int Count { get { throw null; } } - public bool IsReadOnly { get { throw null; } } - public void Add(int item) { throw null; } - public void Clear() { throw null; } - public bool Contains(int item) { throw null; } - public void CopyTo(int[] array, int arrayIndex) { throw null; } - public IEnumerator GetEnumerator() { throw null; } - public bool Remove(int item) { throw null; } - IEnumerator IEnumerable.GetEnumerator() { throw null; } -} - -class TestClass { - void TestMethod() { - Assert.Equal(0, new IntCollection().Count); - Assert.Equal(1, new IntCollection().Count); - Assert.NotEqual(0, new IntCollection().Count); - } -}"; + var source = /* lang=c#-test */ """ + using System.Collections; + using System.Collections.Generic; + using Xunit; + + class IntCollection : ICollection { + public int Count { get { throw null; } } + public bool IsReadOnly { get { throw null; } } + public void Add(int item) { throw null; } + public void Clear() { throw null; } + public bool Contains(int item) { throw null; } + public void CopyTo(int[] array, int arrayIndex) { throw null; } + public IEnumerator GetEnumerator() { throw null; } + public bool Remove(int item) { throw null; } + IEnumerator IEnumerable.GetEnumerator() { throw null; } + } + + class TestClass { + void TestMethod() { + {|#0:Assert.Equal(0, new IntCollection().Count)|}; + {|#1:Assert.Equal(1, new IntCollection().Count)|}; + {|#2:Assert.NotEqual(0, new IntCollection().Count)|}; + } + } + """; var expected = new[] { - Verify - .Diagnostic() - .WithSpan(20, 9, 20, 51) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.Equal()", Constants.Asserts.Empty), - Verify - .Diagnostic() - .WithSpan(21, 9, 21, 51) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.Equal()", Constants.Asserts.Single), - Verify - .Diagnostic() - .WithSpan(22, 9, 22, 54) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.NotEqual()", Constants.Asserts.NotEmpty), + Verify.Diagnostic().WithLocation(0).WithArguments("Assert.Equal()", Constants.Asserts.Empty), + Verify.Diagnostic().WithLocation(1).WithArguments("Assert.Equal()", Constants.Asserts.Single), + Verify.Diagnostic().WithLocation(2).WithArguments("Assert.NotEqual()", Constants.Asserts.NotEmpty), }; await Verify.VerifyAnalyzer(source, expected); @@ -196,41 +162,43 @@ void TestMethod() { [Fact] public async Task OverridingCountMethod_DoesNotTrigger() { - var source = @" -using System.Collections.Generic; - -interface IIntCollection : ICollection { - new int Count { get; } -} - -interface ICustomCollection : ICollection { - new int Count { get; } -} - -interface ICustomDictionary : ICollection> { - new int Count { get; } -} - -class TestClass { - void TestMethod() { - Xunit.Assert.Equal(1, ((IIntCollection)null).Count); - Xunit.Assert.Equal(1, ((ICustomCollection)null).Count); - Xunit.Assert.Equal(1, ((ICustomDictionary)null).Count); - } -}"; + var source = /* lang=c#-test */ """ + using System.Collections.Generic; + + interface IIntCollection : ICollection { + new int Count { get; } + } + + interface ICustomCollection : ICollection { + new int Count { get; } + } + + interface ICustomDictionary : ICollection> { + new int Count { get; } + } + + class TestClass { + void TestMethod() { + Xunit.Assert.Equal(1, ((IIntCollection)null).Count); + Xunit.Assert.Equal(1, ((ICustomCollection)null).Count); + Xunit.Assert.Equal(1, ((ICustomDictionary)null).Count); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotCrash_ForNonIntArguments() + public async Task ForNonIntArguments_DoesNotCrash() { - var source = @" -class TestClass { - void TestMethod() { - Xunit.Assert.Equal('b', new int[0].Length); - } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + void TestMethod() { + Xunit.Assert.Equal('b', new int[0].Length); + } + } + """; await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForNullCheckTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForNullCheckTests.cs index ddc4abf4..3d57fbfd 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForNullCheckTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForNullCheckTests.cs @@ -1,20 +1,19 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Xunit.Analyzers; using Verify = CSharpVerifier; public class AssertEqualShouldNotBeUsedForNullCheckTests { - public static TheoryData Methods_All = new() - { + public static TheoryData Methods_All = + [ Constants.Asserts.Equal, Constants.Asserts.NotEqual, Constants.Asserts.StrictEqual, Constants.Asserts.NotStrictEqual, Constants.Asserts.Same, Constants.Asserts.NotSame, - }; + ]; public static TheoryData Methods_Equal_WithReplacement = new() { { Constants.Asserts.Equal, Constants.Asserts.Null }, @@ -23,46 +22,38 @@ public class AssertEqualShouldNotBeUsedForNullCheckTests [Theory] [MemberData(nameof(Methods_Equal_WithReplacement))] - public async Task FindsWarning_ForFirstNullLiteral_StringOverload( + public async Task ForFirstNullLiteral_StringOverload_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - string val = null; - Xunit.Assert.{method}(null, val); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 33 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + string val = null; + {{|#0:Xunit.Assert.{0}(null, val)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods_Equal_WithReplacement))] - public async Task FindsWarning_ForFirstNullLiteral_StringOverload_WithCustomComparer( + public async Task ForFirstNullLiteral_StringOverload_WithCustomComparer_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - string val = null; - Xunit.Assert.{method}(null, val, System.StringComparer.Ordinal); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 64 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + string val = null; + {{|#0:Xunit.Assert.{0}(null, val, System.StringComparer.Ordinal)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } @@ -74,46 +65,38 @@ void TestMethod() {{ [InlineData(Constants.Asserts.NotEqual, Constants.Asserts.NotNull)] [InlineData(Constants.Asserts.NotStrictEqual, Constants.Asserts.NotNull)] [InlineData(Constants.Asserts.NotSame, Constants.Asserts.NotNull)] - public async Task FindsWarning_ForFirstNullLiteral_ObjectOverload( + public async Task ForFirstNullLiteral_ObjectOverload_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - object val = null; - Xunit.Assert.{method}(null, val); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 33 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + object val = null; + {{|#0:Xunit.Assert.{0}(null, val)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods_Equal_WithReplacement))] - public async Task FindsWarning_ForFirstNullLiteral_ObjectOverload_WithCustomComparer( + public async Task ForFirstNullLiteral_ObjectOverload_WithCustomComparer_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - object val = null; - Xunit.Assert.{method}(null, val, System.Collections.Generic.EqualityComparer.Default); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 94 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + object val = null; + {{|#0:Xunit.Assert.{0}(null, val, System.Collections.Generic.EqualityComparer.Default)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } @@ -123,76 +106,70 @@ void TestMethod() {{ [InlineData(Constants.Asserts.NotEqual, Constants.Asserts.NotNull)] [InlineData(Constants.Asserts.StrictEqual, Constants.Asserts.Null)] [InlineData(Constants.Asserts.NotStrictEqual, Constants.Asserts.NotNull)] - public async Task FindsWarning_ForFirstNullLiteral_GenericOverload( + public async Task ForFirstNullLiteral_GenericOverload_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - TestClass val = null; - Xunit.Assert.{method}(null, val); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 44 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + TestClass val = null; + {{|#0:Xunit.Assert.{0}(null, val)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods_Equal_WithReplacement))] - public async Task FindsWarning_ForFirstNullLiteral_GenericOverload_WithCustomComparer( + public async Task ForFirstNullLiteral_GenericOverload_WithCustomComparer_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - TestClass val = null; - Xunit.Assert.{method}(null, val, System.Collections.Generic.EqualityComparer.Default); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 108 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + TestClass val = null; + {{|#0:Xunit.Assert.{0}(null, val, System.Collections.Generic.EqualityComparer.Default)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods_All))] - public async Task DoesNotFindWarning_ForOtherLiteral(string method) + public async Task ForOtherLiteral_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - int val = 1; - Xunit.Assert.{method}(1, val); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + int val = 1; + Xunit.Assert.{0}(1, val); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods_All))] - public async Task DoesNotFindWarning_ForSecondNullLiteral(string method) + public async Task ForSecondNullLiteral_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - string val = null; - Xunit.Assert.{method}(val, null); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + string val = null; + Xunit.Assert.{0}(val, null); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualsShouldNotBeUsedTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualsShouldNotBeUsedTests.cs index 57221740..63af1b09 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualsShouldNotBeUsedTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualsShouldNotBeUsedTests.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Xunit.Analyzers; using Verify = CSharpVerifier; @@ -9,28 +8,17 @@ public class AssertEqualsShouldNotBeUsedTests [Theory] [InlineData(nameof(object.Equals), Constants.Asserts.Equal)] [InlineData(nameof(object.ReferenceEquals), Constants.Asserts.Same)] - public async Task FindsHiddenDiagnosticWhenProhibitedMethodIsUsed( + public async Task WhenProhibitedMethodIsUsed_Triggers( string method, string replacement) { var source = $@" class TestClass {{ void TestMethod() {{ - Xunit.Assert.{method}(null, null); + {{|#0:{{|CS0619:Xunit.Assert.{method}(null, null)|}}|}}; }} }}"; - var expected = new[] - { - Verify - .CompilerError("CS0619") - .WithSpan(4, 9, 4, 34 + method.Length) - .WithMessage($"'Assert.{method}(object, object)' is obsolete: 'This is an override of Object.{method}(). Call Assert.{replacement}() instead.'"), - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 34 + method.Length) - .WithSeverity(DiagnosticSeverity.Hidden) - .WithArguments($"Assert.{method}()", replacement), - }; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertIsTypeShouldNotBeUsedForAbstractTypeTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertIsTypeShouldNotBeUsedForAbstractTypeTests.cs index 00b37865..c900f1ac 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertIsTypeShouldNotBeUsedForAbstractTypeTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertIsTypeShouldNotBeUsedForAbstractTypeTests.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Verify = CSharpVerifier; @@ -13,93 +12,82 @@ public class AssertIsTypeShouldNotBeUsedForAbstractTypeTests [Theory] [MemberData(nameof(Methods))] - public async Task FindsError_Interface( + public async Task Interface_Triggers( string method, string replacement) { - var source = $@" -using System; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System; + using Xunit; -class TestClass {{ - void TestMethod() {{ - Assert.{method}(new object()); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(7, 9, 7, 43 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("interface", "System.IDisposable", replacement); + class TestClass {{ + void TestMethod() {{ + {{|#0:Assert.{0}(new object())|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("interface", "System.IDisposable", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods))] - public async Task FindsError_AbstractClass( + public async Task AbstractClass_Triggers( string method, string replacement) { - var source = $@" -using System.IO; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System.IO; + using Xunit; -class TestClass {{ - void TestMethod() {{ - Assert.{method}(new object()); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(7, 9, 7, 38 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("abstract class", "System.IO.Stream", replacement); + class TestClass {{ + void TestMethod() {{ + {{|#0:Assert.{0}(new object())|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("abstract class", "System.IO.Stream", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods))] - public async Task FindsError_UsingStatic( + public async Task UsingStatic_Triggers( string method, string replacement) { - var source = $@" -using System; -using static Xunit.Assert; + var source = string.Format(/* lang=c#-test */ """ + using System; + using static Xunit.Assert; -class TestClass {{ - void TestMethod() {{ - {method}(new object()); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(7, 9, 7, 36 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("interface", "System.IDisposable", replacement); + class TestClass {{ + void TestMethod() {{ + {{|#0:{0}(new object())|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("interface", "System.IDisposable", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindError_NonAbstractClass( + public async Task NonAbstractClass_DoesNotTrigger( string method, string _) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -class TestClass {{ - void TestMethod() {{ - Assert.{method}(new object()); - }} -}}"; + class TestClass {{ + void TestMethod() {{ + Assert.{0}(new object()); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertIsTypeShouldUseGenericOverloadTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertIsTypeShouldUseGenericOverloadTests.cs index 2e9bd5a5..4cb58fae 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertIsTypeShouldUseGenericOverloadTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertIsTypeShouldUseGenericOverloadTests.cs @@ -1,47 +1,43 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Verify = CSharpVerifier; public class AssertIsTypeShouldUseGenericOverloadTests { - public static TheoryData Methods = new() - { + public static TheoryData Methods = + [ "IsType", "IsNotType", "IsAssignableFrom", - }; + ]; [Theory] [MemberData(nameof(Methods))] - public async Task FindsWarning_ForNonGenericCall(string method) + public async Task ForNonGenericCall_Triggers(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(typeof(int), 1); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 38 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("int"); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.{0}(typeof(int), 1)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("int"); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForGenericCall(string method) + public async Task ForGenericCall_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(1); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.{0}(1); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertIsTypeShouldUseGenericOverloadTypeTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertIsTypeShouldUseGenericOverloadTypeTests.cs index d1789150..fcd81f40 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertIsTypeShouldUseGenericOverloadTypeTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertIsTypeShouldUseGenericOverloadTypeTests.cs @@ -1,4 +1,4 @@ -#if NETCOREAPP && ROSLYN_4_4_OR_GREATER // Static abstract methods are only supported on .NET with C# 11 +#if NETCOREAPP using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp; @@ -9,33 +9,36 @@ public class AssertIsTypeShouldUseGenericOverloadTypeTests { public class StaticAbstractInterfaceMethods { - const string methodCode = "static abstract void Method();"; - const string codeTemplate = @" -using Xunit; +#if ROSLYN_4_4_OR_GREATER // Static abstract methods are only supported on .NET with C# 11 + + const string methodCode = /* lang=c#-test */ "static abstract void Method();"; + const string codeTemplate = /* lang=c#-test */ """ + using Xunit; -public interface IParentClass {{ - {0} -}} + public interface IParentClass {{ + {0} + }} -public interface IClass : IParentClass {{ - {1} -}} + public interface IClass : IParentClass {{ + {1} + }} -public class Class : IClass {{ - public static void Method() {{ }} -}} + public class Class : IClass {{ + public static void Method() {{ }} + }} -public abstract class TestClass {{ - [Fact] - public void TestMethod() {{ - var data = new Class(); + public abstract class TestClass {{ + [Fact] + public void TestMethod() {{ + var data = new Class(); - Assert.IsAssignableFrom(typeof(IClass), data); - }} -}}"; + Assert.IsAssignableFrom(typeof(IClass), data); + }} + }} + """; [Fact] - public async Task DoesNotFindWarning_ForStaticAbstractInterfaceMembers() + public async Task ForStaticAbstractInterfaceMembers_DoesNotTrigger() { string source = string.Format(codeTemplate, string.Empty, methodCode); @@ -43,43 +46,44 @@ public async Task DoesNotFindWarning_ForStaticAbstractInterfaceMembers() } [Fact] - public async Task DoesNotFindWarning_ForNestedStaticAbstractInterfaceMembers() + public async Task ForNestedStaticAbstractInterfaceMembers_DoesNotTrigger() { string source = string.Format(codeTemplate, methodCode, string.Empty); await Verify.VerifyAnalyzer(LanguageVersion.CSharp11, source); } +#endif + [Theory] [InlineData("static", "", "{ }")] [InlineData("", "abstract", ";")] - public async Task FindsWarning_ForNotStaticAbstractInterfaceMembers(string staticModifier, string abstractModifier, string methodBody) + public async Task ForNotStaticAbstractInterfaceMembers_Triggers( + string staticModifier, + string abstractModifier, + string methodBody) { - string source = $@" -using Xunit; - -public interface IClass {{ - {staticModifier} {abstractModifier} void Method() {methodBody} -}} - -public class Class : IClass {{ - public {staticModifier} void Method() {{ }} -}} - -public abstract class TestClass {{ - [Fact] - public void TestMethod() {{ - var data = new Class(); - - Assert.IsAssignableFrom(typeof(IClass), data); - }} -}}"; - - var expected = - Verify - .Diagnostic() - .WithSpan(17, 9, 17, 54) - .WithArguments("IClass"); + string source = string.Format(/* lang=c#-test */ """ + using Xunit; + + public interface IClass {{ + {0} {1} void Method() {2} + }} + + public class Class : IClass {{ + public {0} void Method() {{ }} + }} + + public abstract class TestClass {{ + [Fact] + public void TestMethod() {{ + var data = new Class(); + + {{|#0:Assert.IsAssignableFrom(typeof(IClass), data)|}}; + }} + }} + """, staticModifier, abstractModifier, methodBody); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("IClass"); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source, expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertNullShouldNotBeCalledOnValueTypesTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertNullShouldNotBeCalledOnValueTypesTests.cs index 39bc9914..859cd2e9 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertNullShouldNotBeCalledOnValueTypesTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertNullShouldNotBeCalledOnValueTypesTests.cs @@ -1,111 +1,111 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Verify = CSharpVerifier; public class AssertNullShouldNotBeCalledOnValueTypesTests { - public static TheoryData Methods = new() - { + public static TheoryData Methods = + [ "Null", "NotNull", - }; + ]; [Theory] [MemberData(nameof(Methods))] - public async Task FindsWarning_ForValueType(string method) + public async Task ForValueType_Triggers(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - int val = 1; - Xunit.Assert.{method}(val); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 27 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", "int"); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + int val = 1; + {{|#0:Xunit.Assert.{0}(val)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", "int"); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForNullableValueType(string method) + public async Task ForNullableValueType_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - int? val = 1; - Xunit.Assert.{method}(val); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + int? val = 1; + Xunit.Assert.{0}(val); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForNullableReferenceType(string method) + public async Task ForNullableReferenceType_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - string val = null; - Xunit.Assert.{method}(val); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + string val = null; + Xunit.Assert.{0}(val); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForClassConstrainedGenericTypes(string method) + public async Task ForClassConstrainedGenericTypes_DoesNotTrigger(string method) { - var source = $@" -class Class where T : class {{ - public void Method(T arg) {{ - Xunit.Assert.{method}(arg); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class Class where T : class {{ + public void Method(T arg) {{ + Xunit.Assert.{0}(arg); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForInterfaceConstrainedGenericTypes(string method) + public async Task ForInterfaceConstrainedGenericTypes_DoesNotTrigger(string method) { - var source = $@" -interface IDo {{ }} - -class Class where T : IDo {{ - public void Method(System.Collections.Generic.IEnumerable collection) {{ - foreach (T item in collection) {{ - Xunit.Assert.{method}(item); - }} - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + interface IDo {{ }} + + class Class where T : IDo {{ + public void Method(System.Collections.Generic.IEnumerable collection) {{ + foreach (T item in collection) {{ + Xunit.Assert.{0}(item); + }} + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForUnconstrainedGenericTypes(string method) + public async Task ForUnconstrainedGenericTypes_DoesNotTrigger(string method) { - var source = $@" -class Class {{ - public void Method(System.Collections.Generic.IEnumerable collection) {{ - foreach (T item in collection) {{ - Xunit.Assert.{method}(item); - }} - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class Class {{ + public void Method(System.Collections.Generic.IEnumerable collection) {{ + foreach (T item in collection) {{ + Xunit.Assert.{0}(item); + }} + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } @@ -113,31 +113,26 @@ public void Method(System.Collections.Generic.IEnumerable collection) {{ [Theory] [MemberData(nameof(Methods))] // https://github.com/xunit/xunit/issues/2395 - public async Task DoesNotFindWarning_ForUserDefinedImplicitConversion(string method) + public async Task ForUserDefinedImplicitConversion_DoesNotTrigger(string method) { - var source = $@" -public class TestClass -{{ - public void TestMethod() - {{ - Xunit.Assert.{method}((MyBuggyInt)42); - Xunit.Assert.{method}((MyBuggyInt)(int?)42); - Xunit.Assert.{method}((MyBuggyIntBase)42); - Xunit.Assert.{method}((MyBuggyIntBase)(int?)42); - }} -}} - -public abstract class MyBuggyIntBase -{{ - public static implicit operator MyBuggyIntBase(int i) => new MyBuggyInt(); -}} - -public class MyBuggyInt : MyBuggyIntBase -{{ - public MyBuggyInt() - {{ - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + public void TestMethod() {{ + Xunit.Assert.{0}((MyBuggyInt)42); + Xunit.Assert.{0}((MyBuggyInt)(int?)42); + Xunit.Assert.{0}((MyBuggyIntBase)42); + Xunit.Assert.{0}((MyBuggyIntBase)(int?)42); + }} + }} + + public abstract class MyBuggyIntBase {{ + public static implicit operator MyBuggyIntBase(int i) => new MyBuggyInt(); + }} + + public class MyBuggyInt : MyBuggyIntBase {{ + public MyBuggyInt() {{ }} + }} + """, method); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertRegexMatchShouldNotUseBoolLiteralCheckTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertRegexMatchShouldNotUseBoolLiteralCheckTests.cs index 9e9ea69a..3f5982b4 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertRegexMatchShouldNotUseBoolLiteralCheckTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertRegexMatchShouldNotUseBoolLiteralCheckTests.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Xunit.Analyzers; using Verify = CSharpVerifier; @@ -14,67 +13,55 @@ public class AssertRegexMatchShouldNotUseBoolLiteralCheckTests [Theory] [MemberData(nameof(Methods_WithReplacement))] - public async Task FindsWarning_ForStaticRegexIsMatch( + public async Task ForStaticRegexIsMatch_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(System.Text.RegularExpressions.Regex.IsMatch(""abc"", ""\\w*"")); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 83 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.{0}(System.Text.RegularExpressions.Regex.IsMatch("abc", "\\w*"))|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods_WithReplacement))] - public async Task FindsWarning_ForInstanceRegexIsMatchWithInlineConstructedRegex( + public async Task ForInstanceRegexIsMatchWithInlineConstructedRegex_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(new System.Text.RegularExpressions.Regex(""abc"").IsMatch(""\\w*"")); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 87 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.{0}(new System.Text.RegularExpressions.Regex("abc").IsMatch("\\w*"))|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods_WithReplacement))] - public async Task FindsWarning_ForInstanceRegexIsMatchWithConstructedRegexVariable( + public async Task ForInstanceRegexIsMatchWithConstructedRegexVariable_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - var regex = new System.Text.RegularExpressions.Regex(""abc""); - Xunit.Assert.{method}(regex.IsMatch(""\\w*"")); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 45 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + var regex = new System.Text.RegularExpressions.Regex("abc"); + {{|#0:Xunit.Assert.{0}(regex.IsMatch("\\w*"))|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertSameShouldNotBeCalledOnValueTypesTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertSameShouldNotBeCalledOnValueTypesTests.cs index 7c3af4d0..9ecf363d 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertSameShouldNotBeCalledOnValueTypesTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertSameShouldNotBeCalledOnValueTypesTests.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Xunit.Analyzers; using Verify = CSharpVerifier; @@ -14,69 +13,57 @@ public class AssertSameShouldNotBeCalledOnValueTypesTests [Theory] [MemberData(nameof(Methods_WithReplacement))] - public async Task FindsWarningForTwoValueParameters( + public async Task TwoValueParameters_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - int a = 0; - Xunit.Assert.{method}(0, a); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 28 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", "int", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + int a = 0; + {{|#0:Xunit.Assert.{0}(0, a)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", "int", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods_WithReplacement))] - public async Task FindsWarningForFirstValueParameters( + public async Task FirstValueParameters_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - object a = 0; - Xunit.Assert.{method}(0, a); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 28 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", "int", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + object a = 0; + {{|#0:Xunit.Assert.{0}(0, a)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", "int", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods_WithReplacement))] - public async Task FindsWarningForSecondValueParameters( + public async Task SecondValueParameters_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - object a = 0; - Xunit.Assert.{method}(a, 0); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 28 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", "int", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + object a = 0; + {{|#0:Xunit.Assert.{0}(a, 0)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", "int", replacement); await Verify.VerifyAnalyzer(source, expected); } @@ -84,86 +71,71 @@ void TestMethod() {{ [Theory] [MemberData(nameof(Methods_WithReplacement))] // https://github.com/xunit/xunit/issues/2395 - public async Task DoesNotFindWarningForUserDefinedImplicitConversion( + public async Task UserDefinedImplicitConversion_DoesNotTrigger( string method, - string replacement) + string _) { - _ = replacement; // Verifies that diagnostic is not issued, so the replacement method is not needed - - var source = $@" -public class TestClass -{{ - public void TestMethod() - {{ - var o = new object(); - - Xunit.Assert.{method}((MyBuggyInt)42, o); - Xunit.Assert.{method}((MyBuggyInt)(int?)42, o); - Xunit.Assert.{method}((MyBuggyIntBase)42, o); - Xunit.Assert.{method}((MyBuggyIntBase)(int?)42, o); - - Xunit.Assert.{method}(o, (MyBuggyInt)42); - Xunit.Assert.{method}(o, (MyBuggyInt)(int?)42); - Xunit.Assert.{method}(o, (MyBuggyIntBase)42); - Xunit.Assert.{method}(o, (MyBuggyIntBase)(int?)42); - }} -}} - -public abstract class MyBuggyIntBase -{{ - public static implicit operator MyBuggyIntBase(int i) => new MyBuggyInt(); -}} - -public class MyBuggyInt : MyBuggyIntBase -{{ - public MyBuggyInt() - {{ - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + public class TestClass {{ + public void TestMethod() {{ + var o = new object(); + + Xunit.Assert.{0}((MyBuggyInt)42, o); + Xunit.Assert.{0}((MyBuggyInt)(int?)42, o); + Xunit.Assert.{0}((MyBuggyIntBase)42, o); + Xunit.Assert.{0}((MyBuggyIntBase)(int?)42, o); + + Xunit.Assert.{0}(o, (MyBuggyInt)42); + Xunit.Assert.{0}(o, (MyBuggyInt)(int?)42); + Xunit.Assert.{0}(o, (MyBuggyIntBase)42); + Xunit.Assert.{0}(o, (MyBuggyIntBase)(int?)42); + }} + }} + + public abstract class MyBuggyIntBase {{ + public static implicit operator MyBuggyIntBase(int i) => new MyBuggyInt(); + }} + + public class MyBuggyInt : MyBuggyIntBase {{ + public MyBuggyInt() {{ }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods_WithReplacement))] - public async Task FindsWarningForFirstValueParametersIfSecondIsNull( + public async Task FirstValueParametersIfSecondIsNull_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(0, null); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 31 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", "int", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.{0}(0, null)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", "int", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods_WithReplacement))] - public async Task FindsWarningForSecondValueParametersIfFirstIsNull( + public async Task SecondValueParametersIfFirstIsNull_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(null, 0); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 31 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", "int", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.{0}(null, 0)|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", "int", replacement); await Verify.VerifyAnalyzer(source, expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertSingleShouldBeUsedForSingleParameterTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertSingleShouldBeUsedForSingleParameterTests.cs index 56f18384..cdba147f 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertSingleShouldBeUsedForSingleParameterTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertSingleShouldBeUsedForSingleParameterTests.cs @@ -9,24 +9,20 @@ public class AssertSingleShouldBeUsedForSingleParameterTests #if NETCOREAPP3_0_OR_GREATER [InlineData("default(IAsyncEnumerable)")] #endif - public async Task FindsInfo_ForSingleItemCollectionCheck(string collection) + public async Task ForSingleItemCollectionCheck_Triggers(string collection) { - var code = @$" -using Xunit; -using System.Collections.Generic; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - Assert.Collection({collection}, item => Assert.NotNull(item)); - }} -}}"; + var code = string.Format(/* lang=c#-test */ """ + using Xunit; + using System.Collections.Generic; - var expected = - Verify - .Diagnostic() - .WithSpan(8, 9, 8, 58 + collection.Length) - .WithArguments("Collection"); + public class TestClass {{ + [Fact] + public void TestMethod() {{ + {{|#0:Assert.Collection({0}, item => Assert.NotNull(item))|}}; + }} + }} + """, collection); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Collection"); await Verify.VerifyAnalyzer(code, expected); } @@ -36,18 +32,19 @@ public void TestMethod() {{ #if NETCOREAPP3_0_OR_GREATER [InlineData("default(IAsyncEnumerable)")] #endif - public async Task DoesNotFindInfo_ForMultipleItemCollectionCheck(string collection) + public async Task ForMultipleItemCollectionCheck_DoesNotTrigger(string collection) { - var code = @$" -using Xunit; -using System.Collections.Generic; + var code = string.Format(/* lang=c#-test */ """ + using Xunit; + using System.Collections.Generic; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - Assert.Collection({collection}, item1 => Assert.NotNull(item1), item2 => Assert.NotNull(item2)); - }} -}}"; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + Assert.Collection({0}, item1 => Assert.NotNull(item1), item2 => Assert.NotNull(item2)); + }} + }} + """, collection); await Verify.VerifyAnalyzer(code); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertStringEqualityCheckShouldNotUseBoolCheckTest.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertStringEqualityCheckShouldNotUseBoolCheckTest.cs index 59b0631c..5e4967a7 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertStringEqualityCheckShouldNotUseBoolCheckTest.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertStringEqualityCheckShouldNotUseBoolCheckTest.cs @@ -1,6 +1,5 @@ using System; using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Xunit.Analyzers; using Verify = CSharpVerifier; @@ -12,164 +11,152 @@ public class AssertStringEqualityCheckShouldNotUseBoolCheckTest { Constants.Asserts.True, Constants.Asserts.Equal }, { Constants.Asserts.False, Constants.Asserts.NotEqual }, }; - public static TheoryData SupportedStringComparisons = new() - { + public static TheoryData SupportedStringComparisons = + [ StringComparison.Ordinal, StringComparison.OrdinalIgnoreCase, - }; - public static TheoryData UnsupportedStringComparisons = new() - { + ]; + public static TheoryData UnsupportedStringComparisons = + [ StringComparison.CurrentCulture, StringComparison.CurrentCultureIgnoreCase, StringComparison.InvariantCulture, StringComparison.InvariantCultureIgnoreCase, - }; - public static TheoryData AllStringComparisons = new() - { + ]; + public static TheoryData AllStringComparisons = + [ StringComparison.Ordinal, StringComparison.OrdinalIgnoreCase, StringComparison.CurrentCulture, StringComparison.CurrentCultureIgnoreCase, StringComparison.InvariantCulture, StringComparison.InvariantCultureIgnoreCase, - }; + ]; [Theory] [MemberData(nameof(Methods_WithReplacement))] - public async Task FindsWarning_ForInstanceEqualsCheck( + public async Task ForInstanceEqualsCheck_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(""abc"".Equals(""a"")); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 41 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.{0}("abc".Equals("a"))|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(SupportedStringComparisons))] - public async Task FindsWarning_ForTrueInstanceEqualsCheck_WithSupportedStringComparison(StringComparison comparison) + public async Task ForTrueInstanceEqualsCheck_WithSupportedStringComparison_Triggers(StringComparison comparison) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.True(""abc"".Equals(""a"", System.StringComparison.{comparison})); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 71 + comparison.ToString().Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.True()", Constants.Asserts.Equal); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.True("abc".Equals("a", System.StringComparison.{0}))|}}; + }} + }} + """, comparison); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.True()", Constants.Asserts.Equal); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(UnsupportedStringComparisons))] - public async Task DoesNotFindWarning_ForTrueInstanceEqualsCheck_WithUnsupportedStringComparison(StringComparison comparison) + public async Task ForTrueInstanceEqualsCheck_WithUnsupportedStringComparison_DoesNotTrigger(StringComparison comparison) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.True(""abc"".Equals(""a"", System.StringComparison.{comparison})); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.True("abc".Equals("a", System.StringComparison.{0})); + }} + }} + """, comparison); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(AllStringComparisons))] - public async Task DoesNotFindWarning_ForFalseInstanceEqualsCheck_WithStringComparison(StringComparison comparison) + public async Task ForFalseInstanceEqualsCheck_WithStringComparison_DoesNotTrigger(StringComparison comparison) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.False(""abc"".Equals(""a"", System.StringComparison.{comparison})); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.False("abc".Equals("a", System.StringComparison.{0})); + }} + }} + """, comparison); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods_WithReplacement))] - public async Task FindsWarning_ForStaticEqualsCheck( + public async Task ForStaticEqualsCheck_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(System.String.Equals(""abc"", ""a"")); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 56 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.{0}(System.String.Equals("abc", "a"))|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(SupportedStringComparisons))] - public async Task FindsWarning_ForTrueStaticEqualsCheck_WithSupportedStringComparison(StringComparison comparison) + public async Task ForTrueStaticEqualsCheck_WithSupportedStringComparison_Triggers(StringComparison comparison) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.True(System.String.Equals(""abc"", ""a"", System.StringComparison.{comparison})); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 86 + comparison.ToString().Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.True()", Constants.Asserts.Equal); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.True(System.String.Equals("abc", "a", System.StringComparison.{0}))|}}; + }} + }} + """, comparison); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.True()", Constants.Asserts.Equal); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(UnsupportedStringComparisons))] - public async Task DoesNotFindWarning_ForTrueStaticEqualsCheck_WithUnsupportedStringComparison(StringComparison comparison) + public async Task ForTrueStaticEqualsCheck_WithUnsupportedStringComparison_DoesNotTrigger(StringComparison comparison) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.True(System.String.Equals(""abc"", ""a"", System.StringComparison.{comparison})); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.True(System.String.Equals("abc", "a", System.StringComparison.{0})); + }} + }} + """, comparison); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(AllStringComparisons))] - public async Task DoesNotFindWarning_ForFalseStaticEqualsCheck_WithStringComparison(StringComparison comparison) + public async Task ForFalseStaticEqualsCheck_WithStringComparison_DoesNotTrigger(StringComparison comparison) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.False(System.String.Equals(""abc"", ""a"", System.StringComparison.{comparison})); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.False(System.String.Equals("abc", "a", System.StringComparison.{0})); + }} + }} + """, comparison); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertSubstringCheckShouldNotUseBoolCheckTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertSubstringCheckShouldNotUseBoolCheckTests.cs index a95cd007..b452cbe9 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertSubstringCheckShouldNotUseBoolCheckTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertSubstringCheckShouldNotUseBoolCheckTests.cs @@ -1,290 +1,282 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Xunit.Analyzers; using Verify = CSharpVerifier; public class AssertSubstringCheckShouldNotUseBoolCheckTests { - public static TheoryData Methods = new() - { + public static TheoryData Methods = + [ Constants.Asserts.True, Constants.Asserts.False, - }; + ]; [Theory] [InlineData(Constants.Asserts.True, Constants.Asserts.Contains)] [InlineData(Constants.Asserts.False, Constants.Asserts.DoesNotContain)] - public async Task FindsWarning_ForBooleanContainsCheck( + public async Task ForBooleanContainsCheck_Triggers( string method, string replacement) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(""abc"".Contains(""a"")); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 43 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments($"Assert.{method}()", replacement); + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.{0}("abc".Contains("a"))|}}; + }} + }} + """, method); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments($"Assert.{method}()", replacement); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForBooleanContainsCheck_WithUserMessage(string method) + public async Task ForBooleanContainsCheck_WithUserMessage_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(""abc"".Contains(""a""), ""message""); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.{0}("abc".Contains("a"), "message"); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FindsWarning_ForBooleanTrueStartsWithCheck() + public async Task ForBooleanTrueStartsWithCheck_Triggers() { - var source = @" -class TestClass { - void TestMethod() { - Xunit.Assert.True(""abc"".StartsWith(""a"")); - } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 49) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.True()", Constants.Asserts.StartsWith); + var source = /* lang=c#-test */ """ + class TestClass { + void TestMethod() { + {|#0:Xunit.Assert.True("abc".StartsWith("a"))|}; + } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.True()", Constants.Asserts.StartsWith); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsWarning_ForBooleanTrueStartsWithCheck_WithStringComparison() + public async Task ForBooleanTrueStartsWithCheck_WithStringComparison_Triggers() { - var source = @" -class TestClass { - void TestMethod() { - Xunit.Assert.True(""abc"".StartsWith(""a"", System.StringComparison.CurrentCulture)); - } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 89) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.True()", Constants.Asserts.StartsWith); + var source = /* lang=c#-test */ """ + class TestClass { + void TestMethod() { + {|#0:Xunit.Assert.True("abc".StartsWith("a", System.StringComparison.CurrentCulture))|}; + } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.True()", Constants.Asserts.StartsWith); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task DoesNotFindWarning_ForBooleanFalseStartsWithCheck() + public async Task ForBooleanFalseStartsWithCheck_DoesNotTrigger() { - var source = @" -class TestClass { - void TestMethod() { - Xunit.Assert.False(""abc"".StartsWith(""a"")); - } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + void TestMethod() { + Xunit.Assert.False("abc".StartsWith("a")); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindWarning_ForBooleanFalseStartsWithCheck_WithStringComparison() + public async Task ForBooleanFalseStartsWithCheck_WithStringComparison_DoesNotTrigger() { - var source = @" -class TestClass { - void TestMethod() { - Xunit.Assert.False(""abc"".StartsWith(""a"", System.StringComparison.CurrentCulture)); - } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + void TestMethod() { + Xunit.Assert.False("abc".StartsWith("a", System.StringComparison.CurrentCulture)); + } + } + """; await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForBooleanStartsWithCheck_WithUserMessage(string method) + public async Task ForBooleanStartsWithCheck_WithUserMessage_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(""abc"".StartsWith(""a""), ""message""); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.{0}("abc".StartsWith("a"), "message"); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForBooleanStartsWithCheck_WithStringComparison_AndUserMessage(string method) + public async Task ForBooleanStartsWithCheck_WithStringComparison_AndUserMessage_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(""abc"".StartsWith(""a"", System.StringComparison.CurrentCulture), ""message""); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.{0}("abc".StartsWith("a", System.StringComparison.CurrentCulture), "message"); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForBooleanStartsWithCheck_WithBoolAndCulture(string method) + public async Task ForBooleanStartsWithCheck_WithBoolAndCulture_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(""abc"".StartsWith(""a"", true, System.Globalization.CultureInfo.CurrentCulture)); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.{0}("abc".StartsWith("a", true, System.Globalization.CultureInfo.CurrentCulture)); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForBooleanStartsWithCheck_WithBoolAndCulture_AndUserMessage(string method) + public async Task ForBooleanStartsWithCheck_WithBoolAndCulture_AndUserMessage_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(""abc"".StartsWith(""a"", true, System.Globalization.CultureInfo.CurrentCulture), ""message""); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.{0}("abc".StartsWith("a", true, System.Globalization.CultureInfo.CurrentCulture), "message"); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FindsWarning_ForBooleanTrueEndsWithCheck() + public async Task ForBooleanTrueEndsWithCheck_Triggers() { - var source = @" -class TestClass { - void TestMethod() { - Xunit.Assert.True(""abc"".EndsWith(""a"")); - } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 47) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.True()", Constants.Asserts.EndsWith); + var source = /* lang=c#-test */ """ + class TestClass { + void TestMethod() { + {|#0:Xunit.Assert.True("abc".EndsWith("a"))|}; + } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.True()", Constants.Asserts.EndsWith); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task FindsWarning_ForBooleanTrueEndsWithCheck_WithStringComparison() + public async Task ForBooleanTrueEndsWithCheck_WithStringComparison_Triggers() { - var source = @" -class TestClass { - void TestMethod() { - Xunit.Assert.True(""abc"".EndsWith(""a"", System.StringComparison.CurrentCulture)); - } -}"; - var expected = - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 87) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.True()", Constants.Asserts.EndsWith); + var source = /* lang=c#-test */ """ + class TestClass { + void TestMethod() { + {|#0:Xunit.Assert.True("abc".EndsWith("a", System.StringComparison.CurrentCulture))|}; + } + } + """; + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.True()", Constants.Asserts.EndsWith); await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async Task DoesNotFindWarning_ForBooleanFalseEndsWithCheck() + public async Task ForBooleanFalseEndsWithCheck_DoesNotTrigger() { - var source = @" -class TestClass { - void TestMethod() { - Xunit.Assert.False(""abc"".EndsWith(""a"")); - } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + void TestMethod() { + Xunit.Assert.False("abc".EndsWith("a")); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindWarning_ForBooleanFalseEndsWithCheck_WithStringComparison() + public async Task ForBooleanFalseEndsWithCheck_WithStringComparison_DoesNotTrigger() { - var source = @" -class TestClass { - void TestMethod() { - Xunit.Assert.False(""abc"".EndsWith(""a"", System.StringComparison.CurrentCulture)); - } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + void TestMethod() { + Xunit.Assert.False("abc".EndsWith("a", System.StringComparison.CurrentCulture)); + } + } + """; await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForBooleanEndsWithCheck_WithUserMessage(string method) + public async Task ForBooleanEndsWithCheck_WithUserMessage_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(""abc"".EndsWith(""a""), ""message""); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.{0}("abc".EndsWith("a"), "message"); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForBooleanEndsWithCheck_WithStringComparison_AndUserMessage(string method) + public async Task ForBooleanEndsWithCheck_WithStringComparison_AndUserMessage_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(""abc"".EndsWith(""a"", System.StringComparison.CurrentCulture), ""message""); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.{0}("abc".EndsWith("a", System.StringComparison.CurrentCulture), "message"); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForBooleanEndsWithCheck_WithBoolAndCulture(string method) + public async Task ForBooleanEndsWithCheck_WithBoolAndCulture_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(""abc"".EndsWith(""a"", true, System.Globalization.CultureInfo.CurrentCulture)); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.{0}("abc".EndsWith("a", true, System.Globalization.CultureInfo.CurrentCulture)); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(Methods))] - public async Task DoesNotFindWarning_ForBooleanEndsWithCheck_WithBoolAndCulture_AndUserMessage(string method) + public async Task ForBooleanEndsWithCheck_WithBoolAndCulture_AndUserMessage_DoesNotTrigger(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(""abc"".EndsWith(""a"", true, System.Globalization.CultureInfo.CurrentCulture), ""message""); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + Xunit.Assert.{0}("abc".EndsWith("a", true, System.Globalization.CultureInfo.CurrentCulture), "message"); + }} + }} + """, method); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertThrowsShouldNotBeUsedForAsyncThrowsCheckTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertThrowsShouldNotBeUsedForAsyncThrowsCheckTests.cs index b9f7113a..ddbf2b5d 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertThrowsShouldNotBeUsedForAsyncThrowsCheckTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertThrowsShouldNotBeUsedForAsyncThrowsCheckTests.cs @@ -1,268 +1,233 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Testing; using Xunit; using Xunit.Analyzers; using Verify = CSharpVerifier; public class AssertThrowsShouldNotBeUsedForAsyncThrowsCheckTests { - public static TheoryData NonAsyncLambdas = new() - { + public static TheoryData NonAsyncLambdas = + [ "ThrowingMethod", "() => 1", - }; + ]; - public static TheoryData AsyncLambdas = new() - { + public static TheoryData AsyncLambdas = + [ "(System.Func)ThrowingMethod", "() => System.Threading.Tasks.Task.Delay(0)", "(System.Func)(async () => await System.Threading.Tasks.Task.Delay(0))", "(System.Func)(async () => await System.Threading.Tasks.Task.Delay(0).ConfigureAwait(false))", - }; + ]; [Theory] [MemberData(nameof(NonAsyncLambdas))] - public async Task Throws_NonGeneric_WithNonAsyncLambda_FindsNoDiagnostics(string lambda) + public async Task Throws_NonGeneric_WithNonAsyncLambda_DoesNotTrigger(string lambda) { - var source = $@" -class TestClass {{ - System.Action ThrowingMethod = () => {{ - throw new System.NotImplementedException(); - }}; - - void TestMethod() {{ - Xunit.Assert.Throws(typeof(System.NotImplementedException), {lambda}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + System.Action ThrowingMethod = () => {{ + throw new System.NotImplementedException(); + }}; + + void TestMethod() {{ + Xunit.Assert.Throws(typeof(System.NotImplementedException), {0}); + }} + }} + """, lambda); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(NonAsyncLambdas))] - public async Task Throws_Generic_WithNonAsyncLambda_FindsNoDiagnostics(string lambda) + public async Task Throws_Generic_WithNonAsyncLambda_DoesNotTrigger(string lambda) { - var source = $@" -class TestClass {{ - System.Action ThrowingMethod = () => {{ - throw new System.NotImplementedException(); - }}; - - void TestMethod() {{ - Xunit.Assert.Throws({lambda}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + System.Action ThrowingMethod = () => {{ + throw new System.NotImplementedException(); + }}; + + void TestMethod() {{ + Xunit.Assert.Throws({0}); + }} + }} + """, lambda); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(NonAsyncLambdas))] - public async Task Throws_Generic_WithNamedArgumentException_WithNonAsyncLambda_FindsNoDiagnostics(string lambda) + public async Task Throws_Generic_WithNamedArgumentException_WithNonAsyncLambda_DoesNotTrigger(string lambda) { - var source = $@" -class TestClass {{ - System.Action ThrowingMethod = () => {{ - throw new System.NotImplementedException(); - }}; - - void TestMethod() {{ - Xunit.Assert.Throws(""param1"", {lambda}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + System.Action ThrowingMethod = () => {{ + throw new System.NotImplementedException(); + }}; + + void TestMethod() {{ + Xunit.Assert.Throws("param1", {0}); + }} + }} + """, lambda); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(AsyncLambdas))] - public async Task Throws_NonGeneric_WithAsyncLambda_FindsDiagnostic(string lambda) + public async Task Throws_NonGeneric_WithAsyncLambda_Triggers(string lambda) { - var source = $@" -class TestClass {{ - System.Threading.Tasks.Task ThrowingMethod() {{ - throw new System.NotImplementedException(); - }} - - void TestMethod() {{ - Xunit.Assert.Throws(typeof(System.NotImplementedException), {lambda}); - }} -}}"; - var expected = new[] - { - DiagnosticResult - .CompilerError("CS0619") - .WithSpan(8, 9, 8, 70 + lambda.Length) - .WithArguments("Xunit.Assert.Throws(System.Type, System.Func)", "You must call Assert.ThrowsAsync (and await the result) when testing async code."), - Verify - .Diagnostic() - .WithSpan(8, 9, 8, 70 + lambda.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Assert.Throws()", Constants.Asserts.ThrowsAsync), - }; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + System.Threading.Tasks.Task ThrowingMethod() {{ + throw new System.NotImplementedException(); + }} + + void TestMethod() {{ + {{|#0:{{|CS0619:Xunit.Assert.Throws(typeof(System.NotImplementedException), {0})|}}|}}; + }} + }} + """, lambda); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.Throws()", Constants.Asserts.ThrowsAsync); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(AsyncLambdas))] - public async Task Throws_Generic_WithAsyncLambda_FindsDiagnostic(string lambda) + public async Task Throws_Generic_WithAsyncLambda_Triggers(string lambda) { - var source = $@" -class TestClass {{ - System.Threading.Tasks.Task ThrowingMethod() {{ - throw new System.NotImplementedException(); - }} - - void TestMethod() {{ - Xunit.Assert.Throws({lambda}); - }} -}}"; - var expected = new[] - { - Verify - .CompilerError("CS0619") - .WithSpan(8, 9, 8, 62 + lambda.Length) - .WithMessage("'Assert.Throws(Func)' is obsolete: 'You must call Assert.ThrowsAsync (and await the result) when testing async code.'"), - Verify - .Diagnostic() - .WithSpan(8, 9, 8, 62 + lambda.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Assert.Throws()", Constants.Asserts.ThrowsAsync), - }; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + System.Threading.Tasks.Task ThrowingMethod() {{ + throw new System.NotImplementedException(); + }} + + void TestMethod() {{ + {{|#0:{{|CS0619:Xunit.Assert.Throws({0})|}}|}}; + }} + }} + """, lambda); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.Throws()", Constants.Asserts.ThrowsAsync); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(AsyncLambdas))] - public async Task Throws_Generic_WithNamedArgumentException_WithAsyncLambda_FindsDiagnostic(string lambda) + public async Task Throws_Generic_WithNamedArgumentException_WithAsyncLambda_Triggers(string lambda) { - var source = $@" -class TestClass {{ - System.Threading.Tasks.Task ThrowingMethod() {{ - throw new System.NotImplementedException(); - }} - - void TestMethod() {{ - Xunit.Assert.Throws(""param1"", {lambda}); - }} -}}"; - var expected = new[] - { - Verify - .CompilerError("CS0619") - .WithSpan(8, 9, 8, 66 + lambda.Length) - .WithArguments("Xunit.Assert.Throws(string?, System.Func)", "You must call Assert.ThrowsAsync (and await the result) when testing async code."), - Verify - .Diagnostic() - .WithSpan(8, 9, 8, 66 + lambda.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Assert.Throws()", Constants.Asserts.ThrowsAsync), - }; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + System.Threading.Tasks.Task ThrowingMethod() {{ + throw new System.NotImplementedException(); + }} + + void TestMethod() {{ + {{|#0:{{|CS0619:Xunit.Assert.Throws("param1", {0})|}}|}}; + }} + }} + """, lambda); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.Throws()", Constants.Asserts.ThrowsAsync); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(AsyncLambdas))] - public async Task ThrowsAsync_NonGeneric_WithAsyncLambda_FindsNoDiagnostics(string lambda) + public async Task ThrowsAsync_NonGeneric_WithAsyncLambda_DoesNotTrigger(string lambda) { - var source = $@" -class TestClass {{ - System.Threading.Tasks.Task ThrowingMethod() {{ - throw new System.NotImplementedException(); - }} - - async System.Threading.Tasks.Task TestMethod() {{ - await Xunit.Assert.ThrowsAsync(typeof(System.NotImplementedException), {lambda}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + System.Threading.Tasks.Task ThrowingMethod() {{ + throw new System.NotImplementedException(); + }} + + async System.Threading.Tasks.Task TestMethod() {{ + await Xunit.Assert.ThrowsAsync(typeof(System.NotImplementedException), {0}); + }} + }} + """, lambda); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(AsyncLambdas))] - public async Task ThrowsAsync_Generic_WithAsyncLambda_FindsNoDiagnostics(string lambda) + public async Task ThrowsAsync_Generic_WithAsyncLambda_DoesNotTrigger(string lambda) { - var source = $@" -class TestClass {{ - System.Threading.Tasks.Task ThrowingMethod() {{ - throw new System.NotImplementedException(); - }} - - async void TestMethod() {{ - await Xunit.Assert.ThrowsAsync({lambda}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + System.Threading.Tasks.Task ThrowingMethod() {{ + throw new System.NotImplementedException(); + }} + + async void TestMethod() {{ + await Xunit.Assert.ThrowsAsync({0}); + }} + }} + """, lambda); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(NonAsyncLambdas))] - public async Task ThrowsAny_WithNonAsyncLambda_FindsNoDiagnostics(string lambda) + public async Task ThrowsAny_WithNonAsyncLambda_DoesNotTrigger(string lambda) { - var source = $@" -class TestClass {{ - System.Action ThrowingMethod = () => {{ - throw new System.NotImplementedException(); - }}; - - void TestMethod() {{ - Xunit.Assert.ThrowsAny({lambda}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + System.Action ThrowingMethod = () => {{ + throw new System.NotImplementedException(); + }}; + + void TestMethod() {{ + Xunit.Assert.ThrowsAny({0}); + }} + }} + """, lambda); await Verify.VerifyAnalyzer(source); } [Theory] [MemberData(nameof(AsyncLambdas))] - public async Task ThrowsAny_WithAsyncLambda_FindsDiagnostic(string lambda) + public async Task ThrowsAny_WithAsyncLambda_Triggers(string lambda) { - var source = $@" -class TestClass {{ - System.Threading.Tasks.Task ThrowingMethod() {{ - throw new System.NotImplementedException(); - }} - - void TestMethod() {{ - Xunit.Assert.ThrowsAny({lambda}); - }} -}}"; - var expected = new[] - { - DiagnosticResult - .CompilerError("CS0619") - .WithSpan(8, 9, 8, 65 + lambda.Length) - .WithArguments("Xunit.Assert.ThrowsAny(System.Func)", "You must call Assert.ThrowsAnyAsync (and await the result) when testing async code."), - Verify - .Diagnostic() - .WithSpan(8, 9, 8, 65 + lambda.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments("Assert.ThrowsAny()", Constants.Asserts.ThrowsAnyAsync), - }; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + System.Threading.Tasks.Task ThrowingMethod() {{ + throw new System.NotImplementedException(); + }} + + void TestMethod() {{ + {{|#0:{{|CS0619:Xunit.Assert.ThrowsAny({0})|}}|}}; + }} + }} + """, lambda); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments("Assert.ThrowsAny()", Constants.Asserts.ThrowsAnyAsync); await Verify.VerifyAnalyzer(source, expected); } [Theory] [MemberData(nameof(AsyncLambdas))] - public async Task ThrowsAnyAsync_WithAsyncLambda_FindsNoDiagnostics(string lambda) + public async Task ThrowsAnyAsync_WithAsyncLambda_DoesNotTrigger(string lambda) { - var source = $@" -class TestClass {{ - System.Threading.Tasks.Task ThrowingMethod() {{ - throw new System.NotImplementedException(); - }} - - async void TestMethod() {{ - await Xunit.Assert.ThrowsAnyAsync({lambda}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + System.Threading.Tasks.Task ThrowingMethod() {{ + throw new System.NotImplementedException(); + }} + + async void TestMethod() {{ + await Xunit.Assert.ThrowsAnyAsync({0}); + }} + }} + """, lambda); await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertThrowsShouldUseGenericOverloadCheckTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertThrowsShouldUseGenericOverloadCheckTests.cs index e9e090c3..0872e42c 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertThrowsShouldUseGenericOverloadCheckTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertThrowsShouldUseGenericOverloadCheckTests.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Testing; using Xunit; using Xunit.Analyzers; @@ -8,142 +7,116 @@ public class AssertThrowsShouldUseGenericOverloadCheckTests { - public static TheoryData Methods = new() - { + public static TheoryData Methods = + [ Constants.Asserts.Throws, Constants.Asserts.ThrowsAsync, - }; + ]; [Theory] [MemberData(nameof(Methods))] - public async Task FindsWarning_ForThrowsCheck_WithExceptionParameter_OnThrowingMethod(string method) + public async Task ForThrowsCheck_WithExceptionParameter_OnThrowingMethod_Triggers(string method) { - var source = $@" -class TestClass {{ - System.Threading.Tasks.Task ThrowingMethod() {{ - throw new System.NotImplementedException(); - }} - - void TestMethod() {{ - Xunit.Assert.{method}(typeof(System.NotImplementedException), (System.Func)ThrowingMethod); - }} -}}"; - var expected = new List - { - Verify - .Diagnostic() - .WithSpan(8, 9, 8, 120 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments(method, "System.NotImplementedException"), + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + System.Threading.Tasks.Task ThrowingMethod() {{ + throw new System.NotImplementedException(); + }} + + void TestMethod() {{ + {{|#0:Xunit.Assert.{0}(typeof(System.NotImplementedException), (System.Func)ThrowingMethod)|}}; + }} + }} + """, method); + var expected = new List { + Verify.Diagnostic().WithLocation(0).WithArguments(method, "System.NotImplementedException"), }; - if (method == Constants.Asserts.Throws) - expected.Add( - DiagnosticResult - .CompilerError("CS0619") - .WithSpan(8, 9, 8, 120 + method.Length) - .WithArguments("Xunit.Assert.Throws(System.Type, System.Func)", "You must call Assert.ThrowsAsync (and await the result) when testing async code.") - ); + expected.Add(DiagnosticResult.CompilerError("CS0619").WithLocation(0).WithArguments("Xunit.Assert.Throws(System.Type, System.Func)", "You must call Assert.ThrowsAsync (and await the result) when testing async code.")); - await Verify.VerifyAnalyzer(source, expected.ToArray()); + await Verify.VerifyAnalyzer(source, [.. expected]); } [Theory] [MemberData(nameof(Methods))] - public async Task FindsWarning_ForThrowsCheck_WithExceptionParameter_OnThrowingLambda(string method) + public async Task ForThrowsCheck_WithExceptionParameter_OnThrowingLambda_Triggers(string method) { - var source = $@" -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.{method}(typeof(System.NotImplementedException), () => System.Threading.Tasks.Task.Delay(0)); - }} -}}"; - var expected = new List - { - Verify - .Diagnostic() - .WithSpan(4, 9, 4, 106 + method.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments(method, "System.NotImplementedException") + var source = string.Format(/* lang=c#-test */ """ + class TestClass {{ + void TestMethod() {{ + {{|#0:Xunit.Assert.{0}(typeof(System.NotImplementedException), () => System.Threading.Tasks.Task.Delay(0))|}}; + }} + }} + """, method); + var expected = new List { + Verify.Diagnostic().WithLocation(0).WithArguments(method, "System.NotImplementedException"), }; - if (method == Constants.Asserts.Throws) - expected.Add( - DiagnosticResult - .CompilerError("CS0619") - .WithSpan(4, 9, 4, 106 + method.Length) - .WithArguments("Xunit.Assert.Throws(System.Type, System.Func)", "You must call Assert.ThrowsAsync (and await the result) when testing async code.") - ); + expected.Add(DiagnosticResult.CompilerError("CS0619").WithLocation(0).WithArguments("Xunit.Assert.Throws(System.Type, System.Func)", "You must call Assert.ThrowsAsync (and await the result) when testing async code.")); await Verify.VerifyAnalyzer(source, expected.ToArray()); } [Fact] - public async Task FindsCompilerError_ForThrowsCheck_WithExceptionTypeArgument_OnThrowingMethod() + public async Task ForThrowsCheck_WithExceptionTypeArgument_OnThrowingMethod_TriggersCompilerError() { - var source = @" -class TestClass { - System.Threading.Tasks.Task ThrowingMethod() { - throw new System.NotImplementedException(); - } - - void TestMethod() { - Xunit.Assert.Throws((System.Func)ThrowingMethod); - } -}"; - var expected = - Verify - .CompilerError("CS0619") - .WithSpan(8, 9, 8, 118) - .WithMessage($"'Assert.Throws(Func)' is obsolete: 'You must call Assert.ThrowsAsync (and await the result) when testing async code.'"); - - await Verify.VerifyAnalyzer(source, expected); + var source = /* lang=c#-test */ """ + class TestClass { + System.Threading.Tasks.Task ThrowingMethod() { + throw new System.NotImplementedException(); + } + + void TestMethod() { + {|CS0619:Xunit.Assert.Throws((System.Func)ThrowingMethod)|}; + } + } + """; + + await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindWarning_ForThrowsAsyncCheck_WithExceptionTypeArgument_OnThrowingMethod() + public async Task ForThrowsAsyncCheck_WithExceptionTypeArgument_OnThrowingMethod_DoesNotTrigger() { - var source = @" -class TestClass { - System.Threading.Tasks.Task ThrowingMethod() { - throw new System.NotImplementedException(); - } - - async System.Threading.Tasks.Task TestMethod() { - await Xunit.Assert.ThrowsAsync((System.Func)ThrowingMethod); - } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + System.Threading.Tasks.Task ThrowingMethod() { + throw new System.NotImplementedException(); + } + + async System.Threading.Tasks.Task TestMethod() { + await Xunit.Assert.ThrowsAsync((System.Func)ThrowingMethod); + } + } + """; await Verify.VerifyAnalyzer(source); } [Fact] - public async Task FindsCompilerError_ForThrowsCheck_WithExceptionTypeArgument_OnThrowingLambda() + public async Task ForThrowsCheck_WithExceptionTypeArgument_OnThrowingLambda_TriggersCompilerError() { - var source = @" -class TestClass { - void TestMethod() { - Xunit.Assert.Throws(() => System.Threading.Tasks.Task.Delay(0)); - } -}"; - var expected = - Verify - .CompilerError("CS0619") - .WithSpan(4, 9, 4, 104) - .WithMessage("'Assert.Throws(Func)' is obsolete: 'You must call Assert.ThrowsAsync (and await the result) when testing async code.'"); - - await Verify.VerifyAnalyzer(source, expected); + var source = /* lang=c#-test */ """ + class TestClass { + void TestMethod() { + {|CS0619:Xunit.Assert.Throws(() => System.Threading.Tasks.Task.Delay(0))|}; + } + } + """; + + await Verify.VerifyAnalyzer(source); } [Fact] - public async Task DoesNotFindWarning_ForThrowsAsyncCheck_WithExceptionTypeArgument_OnThrowingLambda() + public async Task ForThrowsAsyncCheck_WithExceptionTypeArgument_OnThrowingLambda_DoesNotTrigger() { - var source = @" -class TestClass { - async System.Threading.Tasks.Task TestMethod() { - await Xunit.Assert.ThrowsAsync(() => System.Threading.Tasks.Task.Delay(0)); - } -}"; + var source = /* lang=c#-test */ """ + class TestClass { + async System.Threading.Tasks.Task TestMethod() { + await Xunit.Assert.ThrowsAsync(() => System.Threading.Tasks.Task.Delay(0)); + } + } + """; await Verify.VerifyAnalyzer(source); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AsyncAssertsShouldBeAwaitedTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AsyncAssertsShouldBeAwaitedTests.cs index 5d56e55f..45caaff0 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AsyncAssertsShouldBeAwaitedTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AsyncAssertsShouldBeAwaitedTests.cs @@ -1,6 +1,5 @@ using System.Globalization; using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Xunit; using Verify = CSharpVerifier; @@ -8,69 +7,71 @@ public class AsyncAssertsShouldBeAwaitedTests { [Fact] - public async Task UnawaitedNonAssertionDoesNotTrigger() + public async Task UnawaitedNonAssertion_DoesNotTrigger() { - var code = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - Task.Delay(1); - } -}"; + var code = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + Task.Delay(1); + } + } + """; await Verify.VerifyAnalyzer(code); } - string codeTemplate = @" -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Threading.Tasks; -using Xunit; + readonly string codeTemplate = /* lang=c#-test */ """ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Threading.Tasks; + using Xunit; -public class TestClass : INotifyPropertyChanged {{ - public int Property {{ get; set; }} + public class TestClass : INotifyPropertyChanged {{ + public int Property {{ get; set; }} - public event PropertyChangedEventHandler? PropertyChanged; - public event EventHandler? SimpleEvent; - public event EventHandler? SimpleIntEvent; + public event PropertyChangedEventHandler? PropertyChanged; + public event EventHandler? SimpleEvent; + public event EventHandler? SimpleIntEvent; - [Fact] - public async Task TestMethod() {{ - {0} - }} -}} + [Fact] + public async Task TestMethod() {{ + {0} + }} + }} -public static class MyTaskExtensions {{ - public static void ConsumeTask(this Task t) {{ }} -}}"; + public static class MyTaskExtensions {{ + public static void ConsumeTask(this Task t) {{ }} + }} + """; public static TheoryData AsyncAssertions = new() { - { "AllAsync", "Assert.AllAsync(default(IEnumerable), i => Task.FromResult(true))" }, + /* lang=c#-test */ { "AllAsync", "Assert.AllAsync(default(IEnumerable), i => Task.FromResult(true))" }, #if NETCOREAPP3_0_OR_GREATER - { "AllAsync", "Assert.AllAsync(default(IAsyncEnumerable), i => Task.FromResult(true))" }, + /* lang=c#-test */ { "AllAsync", "Assert.AllAsync(default(IAsyncEnumerable), i => Task.FromResult(true))" }, #endif - { "CollectionAsync", "Assert.CollectionAsync(default(IEnumerable))" }, + /* lang=c#-test */ { "CollectionAsync", "Assert.CollectionAsync(default(IEnumerable))" }, #if NETCOREAPP3_0_OR_GREATER - { "CollectionAsync", "Assert.CollectionAsync(default(IAsyncEnumerable))" }, + /* lang=c#-test */ { "CollectionAsync", "Assert.CollectionAsync(default(IAsyncEnumerable))" }, #endif - { "PropertyChangedAsync", "Assert.PropertyChangedAsync(this, nameof(Property), async () => throw new DivideByZeroException())" }, - { "RaisesAnyAsync", "Assert.RaisesAnyAsync(eh => SimpleEvent += eh, eh => SimpleEvent -= eh, async () => throw new DivideByZeroException())" }, - { "RaisesAnyAsync", "Assert.RaisesAnyAsync(eh => SimpleIntEvent += eh, eh => SimpleIntEvent -= eh, async () => throw new DivideByZeroException())" }, - { "RaisesAsync", "Assert.RaisesAsync(eh => SimpleIntEvent += eh, eh => SimpleIntEvent -= eh, async () => throw new DivideByZeroException())" }, - { "ThrowsAnyAsync", "Assert.ThrowsAnyAsync(async () => throw new DivideByZeroException())" }, - { "ThrowsAsync", "Assert.ThrowsAsync(typeof(DivideByZeroException), async () => throw new DivideByZeroException())" }, - { "ThrowsAsync", "Assert.ThrowsAsync(async () => throw new DivideByZeroException())" }, - { "ThrowsAsync", "Assert.ThrowsAsync(\"argName\", async () => throw new DivideByZeroException())" }, + /* lang=c#-test */ { "PropertyChangedAsync", "Assert.PropertyChangedAsync(this, nameof(Property), async () => throw new DivideByZeroException())" }, + /* lang=c#-test */ { "RaisesAnyAsync", "Assert.RaisesAnyAsync(eh => SimpleEvent += eh, eh => SimpleEvent -= eh, async () => throw new DivideByZeroException())" }, + /* lang=c#-test */ { "RaisesAnyAsync", "Assert.RaisesAnyAsync(eh => SimpleIntEvent += eh, eh => SimpleIntEvent -= eh, async () => throw new DivideByZeroException())" }, + /* lang=c#-test */ { "RaisesAsync", "Assert.RaisesAsync(eh => SimpleIntEvent += eh, eh => SimpleIntEvent -= eh, async () => throw new DivideByZeroException())" }, + /* lang=c#-test */ { "ThrowsAnyAsync", "Assert.ThrowsAnyAsync(async () => throw new DivideByZeroException())" }, + /* lang=c#-test */ { "ThrowsAsync", "Assert.ThrowsAsync(typeof(DivideByZeroException), async () => throw new DivideByZeroException())" }, + /* lang=c#-test */ { "ThrowsAsync", "Assert.ThrowsAsync(async () => throw new DivideByZeroException())" }, + /* lang=c#-test */ { "ThrowsAsync", "Assert.ThrowsAsync(\"argName\", async () => throw new DivideByZeroException())" }, }; [Theory] [MemberData(nameof(AsyncAssertions))] - public async Task AwaitedAssertDoesNotTrigger( + public async Task AwaitedAssert_DoesNotTrigger( string _, string assertion) { @@ -81,7 +82,7 @@ public async Task AwaitedAssertDoesNotTrigger( [Theory] [MemberData(nameof(AsyncAssertions))] - public async Task AssertionWithConsumptionNotTrigger( + public async Task AssertionWithConsumption_DoesNotTrigger( string _, string assertion) { @@ -92,7 +93,7 @@ public async Task AssertionWithConsumptionNotTrigger( [Theory] [MemberData(nameof(AsyncAssertions))] - public async Task AssertionWithConsumptionViaExtensionNotTrigger( + public async Task AssertionWithConsumptionViaExtension_DoesNotTrigger( string _, string assertion) { @@ -103,7 +104,7 @@ public async Task AssertionWithConsumptionViaExtensionNotTrigger( [Theory] [MemberData(nameof(AsyncAssertions))] - public async Task AssertionWithStoredTaskDoesNotTrigger( + public async Task AssertionWithStoredTask_DoesNotTrigger( string _, string assertion) { @@ -114,34 +115,24 @@ public async Task AssertionWithStoredTaskDoesNotTrigger( [Theory] [MemberData(nameof(AsyncAssertions))] - public async Task AssertionWithoutAwaitTriggers( + public async Task AssertionWithoutAwait_Triggers( string assertionName, string assertion) { - var code = string.Format(CultureInfo.InvariantCulture, codeTemplate, $"{assertion};"); - var expected = - Verify - .Diagnostic() - .WithSpan(17, 9, 17, 9 + assertion.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments(assertionName); + var code = string.Format(CultureInfo.InvariantCulture, codeTemplate, $"{{|#0:{assertion}|}};"); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(assertionName); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, code, expected); } [Theory] [MemberData(nameof(AsyncAssertions))] - public async Task AssertionWithUnawaitedContinuationTriggers( + public async Task AssertionWithUnawaitedContinuation_Triggers( string assertionName, string assertion) { - var code = string.Format(CultureInfo.InvariantCulture, codeTemplate, $"{assertion}.ContinueWith(t => {{ }});"); - var expected = - Verify - .Diagnostic() - .WithSpan(17, 9, 17, 9 + assertion.Length) - .WithSeverity(DiagnosticSeverity.Error) - .WithArguments(assertionName); + var code = string.Format(CultureInfo.InvariantCulture, codeTemplate, $"{{|#0:{assertion}|}}.ContinueWith(t => {{ }});"); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(assertionName); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, code, expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/BooleanAssertsShouldNotBeNegatedTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/BooleanAssertsShouldNotBeNegatedTests.cs index 6fcddd53..7406b581 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/BooleanAssertsShouldNotBeNegatedTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/BooleanAssertsShouldNotBeNegatedTests.cs @@ -7,26 +7,23 @@ public class BooleanAssertsShouldNotBeNegatedTests [Theory] [InlineData("False", "True")] [InlineData("True", "False")] - public async Task NegatedBooleanAssertionTriggers( + public async Task NegatedBooleanAssertion_Triggers( string assertion, string replacement) { - var code = $@" -using Xunit; + var code = string.Format(/* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - bool condition = true; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + bool condition = true; - Assert.{assertion}(!condition); - }} -}}"; - var expected = - Verify - .Diagnostic() - .WithSpan(9, 9, 9, 28 + assertion.Length) - .WithArguments(assertion, replacement); + {{|#0:Assert.{0}(!condition)|}}; + }} + }} + """, assertion); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(assertion, replacement); await Verify.VerifyAnalyzer(code, expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckTests.cs index d296b20c..2c498358 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckTests.cs @@ -1,7 +1,5 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Testing; using Xunit; using Xunit.Analyzers; using Verify = CSharpVerifier; @@ -12,8 +10,8 @@ public class X2024_BooleanAssertionsShouldNotBeUsedForSimpleEqualityCheck { public static MatrixTheoryData MethodOperator = new( - new[] { Constants.Asserts.True, Constants.Asserts.False }, - new[] { "==", "!=" } + [Constants.Asserts.True, Constants.Asserts.False], + ["==", "!="] ); [Theory] @@ -22,28 +20,29 @@ public async Task ComparingAgainstNonLiteral_DoesNotTrigger( string method, string @operator) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - public void TestMethod() {{ - var value1 = 42; - var value2 = 2112; - var value3 = new {{ innerValue = 2600 }}; + public class TestClass {{ + public void TestMethod() {{ + var value1 = 42; + var value2 = 2112; + var value3 = new {{ innerValue = 2600 }}; - Assert.{method}(value1 {@operator} value2); - Assert.{method}(value1 {@operator} value3.innerValue); - }} -}}"; + Assert.{0}(value1 {1} value2); + Assert.{0}(value1 {1} value3.innerValue); + }} + }} + """, method, @operator); await Verify.VerifyAnalyzer(source); } public static MatrixTheoryData MethodOperatorValue = new( - new[] { Constants.Asserts.True, Constants.Asserts.False }, - new[] { "==", "!=" }, - new[] { "\"bacon\"", "'5'", "5", "5l", "5.0d", "5.0f", "5.0m", "MyEnum.Bacon" } + [Constants.Asserts.True, Constants.Asserts.False], + ["==", "!="], + ["\"bacon\"", "'5'", "5", "5l", "5.0d", "5.0f", "5.0m", "MyEnum.Bacon"] ); [Theory] @@ -53,19 +52,20 @@ public async Task ComparingAgainstLiteral_WithMessage_DoesNotTrigger( string @operator, string value) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public enum MyEnum {{ None, Bacon, Veggie }} + public enum MyEnum {{ None, Bacon, Veggie }} -public class TestClass {{ - public void TestMethod() {{ - var value = {value}; + public class TestClass {{ + public void TestMethod() {{ + var value = {2}; - Assert.{method}(value {@operator} {value}, ""message""); - Assert.{method}({value} {@operator} value, ""message""); - }} -}}"; + Assert.{0}(value {1} {2}, "message"); + Assert.{0}({2} {1} value, "message"); + }} + }} + """, method, @operator, value); await Verify.VerifyAnalyzer(source); } @@ -77,37 +77,30 @@ public async Task ComparingAgainstLiteral_WithoutMessage_Triggers( string @operator, string value) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public enum MyEnum {{ None, Bacon, Veggie }} + public enum MyEnum {{ None, Bacon, Veggie }} -public class TestClass {{ - public void TestMethod() {{ - var value = {value}; + public class TestClass {{ + public void TestMethod() {{ + var value = {2}; - Assert.{method}(value {@operator} {value}); - Assert.{method}({value} {@operator} value); - }} -}}"; + {{|#0:Assert.{0}(value {1} {2})|}}; + {{|#1:Assert.{0}({2} {1} value)|}}; + }} + }} + """, method, @operator, value); var suggestedAssert = (method, @operator) switch { (Constants.Asserts.True, "==") or (Constants.Asserts.False, "!=") => Constants.Asserts.Equal, (_, _) => Constants.Asserts.NotEqual, }; - DiagnosticResult[] expected = + var expected = new[] { - Verify - .Diagnostic("xUnit2024") - .WithSpan(10, 9, 10, 27 + method.Length + value.Length) - .WithSeverity(DiagnosticSeverity.Info) - .WithArguments(method, suggestedAssert), - Verify - .Diagnostic("xUnit2024") - .WithSpan(11, 9, 11, 27 + method.Length + value.Length) - .WithSeverity(DiagnosticSeverity.Info) - .WithArguments(method, suggestedAssert), + Verify.Diagnostic("xUnit2024").WithLocation(0).WithArguments(method, suggestedAssert), + Verify.Diagnostic("xUnit2024").WithLocation(1).WithArguments(method, suggestedAssert), }; await Verify.VerifyAnalyzer(source, expected); @@ -115,9 +108,9 @@ public void TestMethod() {{ public static MatrixTheoryData MethodOperatorType = new( - new[] { Constants.Asserts.True, Constants.Asserts.False }, - new[] { "==", "!=" }, - new[] { "string", "int", "object", "MyEnum" } + [Constants.Asserts.True, Constants.Asserts.False], + ["==", "!="], + ["string", "int", "object", "MyEnum"] ); [Theory] @@ -127,19 +120,20 @@ public async Task ComparingAgainstNull_WithMessage_DoesNotTrigger( string @operator, string type) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public enum MyEnum {{ None, Bacon, Veggie }} + public enum MyEnum {{ None, Bacon, Veggie }} -public class TestClass {{ - {type}? field = default; + public class TestClass {{ + {2}? field = default; - public void TestMethod() {{ - Assert.{method}(field {@operator} null, ""Message""); - Assert.{method}(null {@operator} field, ""Message""); - }} -}}"; + public void TestMethod() {{ + Assert.{0}(field {1} null, "Message"); + Assert.{0}(null {1} field, "Message"); + }} + }} + """, method, @operator, type); await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source); } @@ -151,37 +145,30 @@ public async Task ComparingAgainstNull_WithoutMessage_Triggers( string @operator, string type) { - var source = $@" -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using Xunit; -public enum MyEnum {{ None, Bacon, Veggie }} + public enum MyEnum {{ None, Bacon, Veggie }} -public class TestClass {{ - {type}? field = default; + public class TestClass {{ + {2}? field = default; - public void TestMethod() {{ - Assert.{method}(field {@operator} null); - Assert.{method}(null {@operator} field); - }} -}}"; + public void TestMethod() {{ + {{|#0:Assert.{0}(field {1} null)|}}; + {{|#1:Assert.{0}(null {1} field)|}}; + }} + }} + """, method, @operator, type); var suggestedAssert = (method, @operator) switch { (Constants.Asserts.True, "==") or (Constants.Asserts.False, "!=") => Constants.Asserts.Null, (_, _) => Constants.Asserts.NotNull, }; - DiagnosticResult[] expected = new[] + var expected = new[] { - Verify - .Diagnostic("xUnit2024") - .WithSpan(10, 9, 10, 31 + method.Length) - .WithSeverity(DiagnosticSeverity.Info) - .WithArguments(method, suggestedAssert), - Verify - .Diagnostic("xUnit2024") - .WithSpan(11, 9, 11, 31 + method.Length) - .WithSeverity(DiagnosticSeverity.Info) - .WithArguments(method, suggestedAssert), + Verify.Diagnostic("xUnit2024").WithLocation(0).WithArguments(method, suggestedAssert), + Verify.Diagnostic("xUnit2024").WithLocation(1).WithArguments(method, suggestedAssert), }; await Verify.VerifyAnalyzer(LanguageVersion.CSharp8, source, expected); @@ -192,9 +179,9 @@ public class X2025_BooleanAssertionCanBeSimplified { public static MatrixTheoryData MethodOperatorValue = new( - new[] { Constants.Asserts.True, Constants.Asserts.False }, - new[] { "==", "!=" }, - new[] { "true", "false" } + [Constants.Asserts.True, Constants.Asserts.False], + ["==", "!="], + ["true", "false"] ); [Theory] @@ -204,41 +191,26 @@ public async Task ComparingAgainstBooleanLiteral_Triggers( string @operator, string value) { - var source = $@" -using Xunit; - -public class TestClass {{ - bool field = {value}; - - void TestMethod() {{ - Assert.{method}(field {@operator} {value}); - Assert.{method}(field {@operator} {value}, ""Message""); - Assert.{method}({value} {@operator} field); - Assert.{method}({value} {@operator} field, ""Message""); - }} -}}"; - DiagnosticResult[] expected = new[] + var source = string.Format(/* lang=c#-test */ """ + using Xunit; + + public class TestClass {{ + bool field = {2}; + + void TestMethod() {{ + {{|#0:Assert.{0}(field {1} {2})|}}; + {{|#1:Assert.{0}(field {1} {2}, "Message")|}}; + {{|#2:Assert.{0}({2} {1} field)|}}; + {{|#3:Assert.{0}({2} {1} field, "Message")|}}; + }} + }} + """, method, @operator, value); + var expected = new[] { - Verify - .Diagnostic("xUnit2025") - .WithSpan(8, 9, 8, 27 + method.Length + value.Length) - .WithSeverity(DiagnosticSeverity.Info) - .WithArguments(method), - Verify - .Diagnostic("xUnit2025") - .WithSpan(9, 9, 9, 38 + method.Length + value.Length) - .WithSeverity(DiagnosticSeverity.Info) - .WithArguments(method), - Verify - .Diagnostic("xUnit2025") - .WithSpan(10, 9, 10, 27 + method.Length + value.Length) - .WithSeverity(DiagnosticSeverity.Info) - .WithArguments(method), - Verify - .Diagnostic("xUnit2025") - .WithSpan(11, 9, 11, 38 + method.Length + value.Length) - .WithSeverity(DiagnosticSeverity.Info) - .WithArguments(method), + Verify.Diagnostic("xUnit2025").WithLocation(0).WithArguments(method), + Verify.Diagnostic("xUnit2025").WithLocation(1).WithArguments(method), + Verify.Diagnostic("xUnit2025").WithLocation(2).WithArguments(method), + Verify.Diagnostic("xUnit2025").WithLocation(3).WithArguments(method), }; await Verify.VerifyAnalyzer(source, expected); diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/DoNotUseAssertEmptyWithProblematicTypesTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/DoNotUseAssertEmptyWithProblematicTypesTests.cs index 43a66ecd..c11fb2ce 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/DoNotUseAssertEmptyWithProblematicTypesTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/DoNotUseAssertEmptyWithProblematicTypesTests.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Xunit; using Verify = CSharpVerifier; @@ -7,27 +6,28 @@ public class DoNotUseAssertEmptyWithProblematicTypesTests { public static TheoryData ProblematicTypes = new() { - { "StringValues.Empty", "StringValues", "it is implicitly cast to a string, not a collection" }, - { "new ArraySegment()", "ArraySegment", "its implementation of GetEnumerator() can throw" }, + /* lang=c#-test */ { "StringValues.Empty", "Microsoft.Extensions.Primitives.StringValues", "it is implicitly cast to a string, not a collection" }, + /* lang=c#-test */ { "new ArraySegment()", "System.ArraySegment", "its implementation of GetEnumerator() can throw" }, }; [Theory] - [InlineData("new int[0]")] - [InlineData("new List()")] - [InlineData("new Dictionary()")] + [InlineData(/* lang=c#-test */ "new int[0]")] + [InlineData(/* lang=c#-test */ "new List()")] + [InlineData(/* lang=c#-test */ "new Dictionary()")] public async Task NonProblematicCollection_DoesNotTrigger(string invocation) { - var source = @$" -using System; -using System.Collections.Generic; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System; + using System.Collections.Generic; + using Xunit; -public class TestClass {{ - public void TestMethod() {{ - Assert.Empty({invocation}); - Assert.NotEmpty({invocation}); - }} -}}"; + public class TestClass {{ + public void TestMethod() {{ + Assert.Empty({0}); + Assert.NotEmpty({0}); + }} + }} + """, invocation); await Verify.VerifyAnalyzer(source); } @@ -39,18 +39,19 @@ public async Task ConvertingToCollection_DoesNotTrigger( string _1, string _2) { - var source = @$" -using System; -using System.Linq; -using Microsoft.Extensions.Primitives; -using Xunit; + var source = string.Format(/* lang=c#-test */ """ + using System; + using System.Linq; + using Microsoft.Extensions.Primitives; + using Xunit; -public class TestClass {{ - public void TestMethod() {{ - Assert.Empty({invocation}.ToArray()); - Assert.NotEmpty({invocation}.ToArray()); - }} -}}"; + public class TestClass {{ + public void TestMethod() {{ + Assert.Empty({0}.ToArray()); + Assert.NotEmpty({0}.ToArray()); + }} + }} + """, invocation); await Verify.VerifyAnalyzer(source); } @@ -62,30 +63,22 @@ public async Task UsingProblematicType_Triggers( string typeName, string problem) { - var source = @$" -using System; -using Microsoft.Extensions.Primitives; -using Xunit; - -public class TestClass {{ - public void TestMethod() {{ - Assert.Empty({invocation}); - Assert.NotEmpty({invocation}); - }} -}}"; + var source = string.Format(/* lang=c#-test */ """ + using System; + using Microsoft.Extensions.Primitives; + using Xunit; + public class TestClass {{ + public void TestMethod() {{ + {{|#0:Assert.Empty({0})|}}; + {{|#1:Assert.NotEmpty({0})|}}; + }} + }} + """, invocation); var expected = new[] { - Verify - .Diagnostic() - .WithSpan(8, 9, 8, 23 + invocation.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Empty", typeName, problem), - Verify - .Diagnostic() - .WithSpan(9, 9, 9, 26 + invocation.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("NotEmpty", typeName, problem), + Verify.Diagnostic().WithLocation(0).WithArguments("Empty", typeName, problem), + Verify.Diagnostic().WithLocation(1).WithArguments("NotEmpty", typeName, problem), }; await Verify.VerifyAnalyzer(source, expected); diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/SetEqualityAnalyzerTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/SetEqualityAnalyzerTests.cs index 23789535..4fc85f85 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/SetEqualityAnalyzerTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/SetEqualityAnalyzerTests.cs @@ -5,46 +5,47 @@ public class SetEqualityAnalyzerTests { - const string customSetAndComparer = @" -using System.Collections; -using System.Collections.Generic; - -public class MySet : ISet { - public int Count => throw new System.NotImplementedException(); - public bool IsReadOnly => throw new System.NotImplementedException(); - - public bool Add(int item) => throw new System.NotImplementedException(); - public void Clear() => throw new System.NotImplementedException(); - public bool Contains(int item) => throw new System.NotImplementedException(); - public void CopyTo(int[] array, int arrayIndex) => throw new System.NotImplementedException(); - public void ExceptWith(IEnumerable other) => throw new System.NotImplementedException(); - public IEnumerator GetEnumerator() => throw new System.NotImplementedException(); - public void IntersectWith(IEnumerable other) => throw new System.NotImplementedException(); - public bool IsProperSubsetOf(IEnumerable other) => throw new System.NotImplementedException(); - public bool IsProperSupersetOf(IEnumerable other) => throw new System.NotImplementedException(); - public bool IsSubsetOf(IEnumerable other) => throw new System.NotImplementedException(); - public bool IsSupersetOf(IEnumerable other) => throw new System.NotImplementedException(); - public bool Overlaps(IEnumerable other) => throw new System.NotImplementedException(); - public bool Remove(int item) => throw new System.NotImplementedException(); - public bool SetEquals(IEnumerable other) => throw new System.NotImplementedException(); - public void SymmetricExceptWith(IEnumerable other) => throw new System.NotImplementedException(); - public void UnionWith(IEnumerable other) => throw new System.NotImplementedException(); - void ICollection.Add(int item) => throw new System.NotImplementedException(); - IEnumerator IEnumerable.GetEnumerator() => throw new System.NotImplementedException(); -} + const string customSetAndComparer = /* lang=c#-test */ """ + using System.Collections; + using System.Collections.Generic; + + public class MySet : ISet { + public int Count => throw new System.NotImplementedException(); + public bool IsReadOnly => throw new System.NotImplementedException(); + + public bool Add(int item) => throw new System.NotImplementedException(); + public void Clear() => throw new System.NotImplementedException(); + public bool Contains(int item) => throw new System.NotImplementedException(); + public void CopyTo(int[] array, int arrayIndex) => throw new System.NotImplementedException(); + public void ExceptWith(IEnumerable other) => throw new System.NotImplementedException(); + public IEnumerator GetEnumerator() => throw new System.NotImplementedException(); + public void IntersectWith(IEnumerable other) => throw new System.NotImplementedException(); + public bool IsProperSubsetOf(IEnumerable other) => throw new System.NotImplementedException(); + public bool IsProperSupersetOf(IEnumerable other) => throw new System.NotImplementedException(); + public bool IsSubsetOf(IEnumerable other) => throw new System.NotImplementedException(); + public bool IsSupersetOf(IEnumerable other) => throw new System.NotImplementedException(); + public bool Overlaps(IEnumerable other) => throw new System.NotImplementedException(); + public bool Remove(int item) => throw new System.NotImplementedException(); + public bool SetEquals(IEnumerable other) => throw new System.NotImplementedException(); + public void SymmetricExceptWith(IEnumerable other) => throw new System.NotImplementedException(); + public void UnionWith(IEnumerable other) => throw new System.NotImplementedException(); + void ICollection.Add(int item) => throw new System.NotImplementedException(); + IEnumerator IEnumerable.GetEnumerator() => throw new System.NotImplementedException(); + } -public class MyComparer : IEqualityComparer { - public bool Equals(int x, int y) => throw new System.NotImplementedException(); - public int GetHashCode(int obj) => throw new System.NotImplementedException(); -}"; + public class MyComparer : IEqualityComparer { + public bool Equals(int x, int y) => throw new System.NotImplementedException(); + public int GetHashCode(int obj) => throw new System.NotImplementedException(); + } + """; public class X2026_SetsMustBeComparedWithEqualityComparer { public static MatrixTheoryData MethodWithCollectionCreationData => new( - new[] { "Equal", "NotEqual" }, - new[] { "new HashSet()", "new HashSet().ToImmutableHashSet()", "new MySet()" }, - new[] { "new HashSet()", "new HashSet().ToImmutableHashSet()", "new MySet()" } + /* lang=c#-test */ ["Equal", "NotEqual"], + /* lang=c#-test */ ["new HashSet()", "new HashSet().ToImmutableHashSet()", "new MySet()"], + /* lang=c#-test */ ["new HashSet()", "new HashSet().ToImmutableHashSet()", "new MySet()"] ); [Theory] @@ -54,22 +55,23 @@ public async Task WithCollectionComparer_DoesNotTrigger( string collection1, string collection2) { - var code = @$" -using Xunit; -using System.Collections.Generic; -using System.Collections.Immutable; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var collection1 = {collection1}; - var collection2 = {collection2}; - - Assert.{method}(collection1, collection2, (IEnumerable e1, IEnumerable e2) => true); - }} -}}"; - - await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, new[] { code, customSetAndComparer }); + var code = string.Format(/* lang=c#-test */ """ + using Xunit; + using System.Collections.Generic; + using System.Collections.Immutable; + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var collection1 = {1}; + var collection2 = {2}; + + Assert.{0}(collection1, collection2, (IEnumerable e1, IEnumerable e2) => true); + }} + }} + """, method, collection1, collection2); + + await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, [code, customSetAndComparer]); } [Theory] @@ -79,35 +81,33 @@ public async Task WithEqualityComparer_DoesNotTrigger( string collection1, string collection2) { - var code = @$" -using Xunit; -using System.Collections.Generic; -using System.Collections.Immutable; - -public class TestEqualityComparer : IEqualityComparer -{{ - public bool Equals(int x, int y) - {{ - return true; - }} - - public int GetHashCode(int obj) - {{ - return 0; - }} -}} - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var collection1 = {collection1}; - var collection2 = {collection2}; - - Assert.{method}(collection1, collection2, new TestEqualityComparer()); - }} -}}"; - - await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, new[] { code, customSetAndComparer }); + var code = string.Format(/* lang=c#-test */ """ + using Xunit; + using System.Collections.Generic; + using System.Collections.Immutable; + + public class TestEqualityComparer : IEqualityComparer {{ + public bool Equals(int x, int y) {{ + return true; + }} + + public int GetHashCode(int obj) {{ + return 0; + }} + }} + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var collection1 = {1}; + var collection2 = {2}; + + Assert.{0}(collection1, collection2, new TestEqualityComparer()); + }} + }} + """, method, collection1, collection2); + + await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, [code, customSetAndComparer]); } [Theory] @@ -117,38 +117,34 @@ public async Task WithComparerLambda_Triggers( string collection1, string collection2) { - var code = @$" -using Xunit; -using System.Collections.Generic; -using System.Collections.Immutable; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var collection1 = {collection1}; - var collection2 = {collection2}; - - Assert.{method}(collection1, collection2, (int e1, int e2) => true); - }} -}}"; - - var expected = - Verify - .Diagnostic("xUnit2026") - .WithSpan(12, 9, 12, 68 + method.Length) - .WithArguments(method); - - await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, new[] { code, customSetAndComparer }, expected); + var code = string.Format(/* lang=c#-test */ """ + using Xunit; + using System.Collections.Generic; + using System.Collections.Immutable; + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var collection1 = {1}; + var collection2 = {2}; + + {{|#0:Assert.{0}(collection1, collection2, (int e1, int e2) => true)|}}; + }} + }} + """, method, collection1, collection2); + var expected = Verify.Diagnostic("xUnit2026").WithLocation(0).WithArguments(method); + + await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, [code, customSetAndComparer], expected); } #if ROSLYN_4_4_OR_GREATER // No C# 10 in Roslyn 3.11, so no local functions public static MatrixTheoryData ComparerFunctionData() => new( - new[] { "Equal", "NotEqual" }, - new[] { "(int e1, int e2) => true", "FuncComparer", "LocalFunc", "funcDelegate" }, - new[] { "new HashSet()", "new HashSet().ToImmutableHashSet()", "new MySet()" }, - new[] { "new HashSet()", "new HashSet().ToImmutableHashSet()", "new MySet()" } + /* lang=c#-test */ ["Equal", "NotEqual"], + /* lang=c#-test */ ["(int e1, int e2) => true", "FuncComparer", "LocalFunc", "funcDelegate"], + /* lang=c#-test */ ["new HashSet()", "new HashSet().ToImmutableHashSet()", "new MySet()"], + /* lang=c#-test */ ["new HashSet()", "new HashSet().ToImmutableHashSet()", "new MySet()"] ); [Theory] @@ -159,54 +155,47 @@ public async Task WithComparerFunction_Triggers( string collection1, string collection2) { - var code = @$" -using Xunit; -using System.Collections.Generic; -using System.Collections.Immutable; + var code = string.Format(/* lang=c#-test */ """ + using Xunit; + using System.Collections.Generic; + using System.Collections.Immutable; -public class TestClass {{ - private bool FuncComparer(int obj1, int obj2) - {{ - return true; - }} + public class TestClass {{ + private bool FuncComparer(int obj1, int obj2) {{ + return true; + }} - private delegate bool FuncDelegate(int obj1, int obj2); + private delegate bool FuncDelegate(int obj1, int obj2); - [Fact] - public void TestMethod() {{ - var collection1 = {collection1}; - var collection2 = {collection2}; + [Fact] + public void TestMethod() {{ + var collection1 = {2}; + var collection2 = {3}; - bool LocalFunc(int obj1, int obj2) - {{ - return true; - }} + bool LocalFunc(int obj1, int obj2) {{ + return true; + }} - var funcDelegate = FuncComparer; + var funcDelegate = FuncComparer; - Assert.{method}(collection1, collection2, {comparerFuncSyntax}); - }} -}}"; - - var expected = - Verify - .Diagnostic("xUnit2026") - .WithSpan(26, 9, 26, 44 + method.Length + comparerFuncSyntax.Length) - .WithArguments(method); + {{|#0:Assert.{0}(collection1, collection2, {1})|}}; + }} + }} + """, method, comparerFuncSyntax, collection1, collection2); + var expected = Verify.Diagnostic("xUnit2026").WithLocation(0).WithArguments(method); await Verify.VerifyAnalyzer(LanguageVersion.CSharp10, new[] { code, customSetAndComparer }, expected); } #endif - } public class X2027_SetsShouldNotBeComparedToLinearContainers { public static MatrixTheoryData MethodAndLinearContainers => new( - new[] { "Equal", "NotEqual" }, - new[] { "new List()", "new SortedSet()", "new HashSet().OrderBy(x => x)", "new MySet().OrderBy(x => x)" } + /* lang=c#-test */ ["Equal", "NotEqual"], + /* lang=c#-test */ ["new List()", "new SortedSet()", "new HashSet().OrderBy(x => x)", "new MySet().OrderBy(x => x)"] ); [Theory] @@ -215,57 +204,59 @@ public async Task LinearContainers_DoesNotTrigger( string method, string collection) { - var code = @$" -using Xunit; -using System.Collections.Generic; -using System.Linq; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var collection1 = new List(); - var collection2 = {collection}; - - Assert.{method}(collection1, collection2); - Assert.{method}(collection1, collection2, (int e1, int e2) => true); - Assert.{method}(collection1, collection2, new MyComparer()); - }} -}}"; - - await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, new[] { code, customSetAndComparer }); + var code = string.Format(/* lang=c#-test */ """ + using Xunit; + using System.Collections.Generic; + using System.Linq; + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var collection1 = new List(); + var collection2 = {1}; + + Assert.{0}(collection1, collection2); + Assert.{0}(collection1, collection2, (int e1, int e2) => true); + Assert.{0}(collection1, collection2, new MyComparer()); + }} + }} + """, method, collection); + + await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, [code, customSetAndComparer]); } [Fact] public async Task CastedSet_DoesNotTrigger() { - var code = @" -using Xunit; -using System.Collections.Generic; - -public class TestClass { - [Fact] - public void TestMethod() { - var expected = new HashSet { ""bar"", ""foo"" }; - var actual = new HashSet { ""foo"", ""bar"" }; - - Assert.Equal(expected, actual); - Assert.Equal(expected, (ISet)actual); - Assert.Equal((ISet)expected, actual); - Assert.Equal((ISet)expected, (ISet)actual); - } -}"; + var code = /* lang=c#-test */ """ + using Xunit; + using System.Collections.Generic; + + public class TestClass { + [Fact] + public void TestMethod() { + var expected = new HashSet { "bar", "foo" }; + var actual = new HashSet { "foo", "bar" }; + + Assert.Equal(expected, actual); + Assert.Equal(expected, (ISet)actual); + Assert.Equal((ISet)expected, actual); + Assert.Equal((ISet)expected, (ISet)actual); + } + } + """; await Verify.VerifyAnalyzer(code); } public static MatrixTheoryData MethodAndTypeAndInitializer => new( - new[] { "Equal", "NotEqual" }, - new[] { - ("HashSet", "new HashSet()"), - ("ImmutableHashSet", "new HashSet().ToImmutableHashSet()"), - ("MySet", "new MySet()") - } + /* lang=c#-test */ ["Equal", "NotEqual"], + /* lang=c#-test */ [ + ("System.Collections.Generic.HashSet", "new HashSet()"), + ("System.Collections.Immutable.ImmutableHashSet", "new HashSet().ToImmutableHashSet()"), + ("MySet", "new MySet()") + ] ); [Theory] @@ -274,57 +265,39 @@ public async Task SetWithLinearContainer_Triggers( string method, (string type, string initializer) collection) { - var code = @$" -using Xunit; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var collection1 = new List(); - var collection2 = {collection.initializer}; - - Assert.{method}(collection1, collection2); - Assert.{method}(collection1, collection2, (int e1, int e2) => true); - Assert.{method}(collection1, collection2, new MyComparer()); - - Assert.{method}(collection2, collection1); - Assert.{method}(collection2, collection1, (int e1, int e2) => true); - Assert.{method}(collection2, collection1, new MyComparer()); - }} -}}"; + var code = string.Format(/* lang=c#-test */ """ + using Xunit; + using System.Collections.Generic; + using System.Collections.Immutable; + using System.Linq; + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var collection1 = new List(); + var collection2 = {1}; + + {{|#0:Assert.{0}(collection1, collection2)|}}; + {{|#1:Assert.{0}(collection1, collection2, (int e1, int e2) => true)|}}; + {{|#2:Assert.{0}(collection1, collection2, new MyComparer())|}}; + + {{|#3:Assert.{0}(collection2, collection1)|}}; + {{|#4:Assert.{0}(collection2, collection1, (int e1, int e2) => true)|}}; + {{|#5:Assert.{0}(collection2, collection1, new MyComparer())|}}; + }} + }} + """, method, collection.initializer); var expected = new[] { - Verify - .Diagnostic("xUnit2027") - .WithSpan(13, 9, 13, 42 + method.Length) - .WithArguments("List", collection.type), - Verify - .Diagnostic("xUnit2027") - .WithSpan(14, 9, 14, 68 + method.Length) - .WithArguments("List", collection.type), - Verify - .Diagnostic("xUnit2027") - .WithSpan(15, 9, 15, 60 + method.Length) - .WithArguments("List", collection.type), - - Verify - .Diagnostic("xUnit2027") - .WithSpan(17, 9, 17, 42 + method.Length) - .WithArguments(collection.type, "List"), - Verify - .Diagnostic("xUnit2027") - .WithSpan(18, 9, 18, 68 + method.Length) - .WithArguments(collection.type, "List"), - Verify - .Diagnostic("xUnit2027") - .WithSpan(19, 9, 19, 60 + method.Length) - .WithArguments(collection.type, "List"), + Verify.Diagnostic("xUnit2027").WithLocation(0).WithArguments("System.Collections.Generic.List", collection.type), + Verify.Diagnostic("xUnit2027").WithLocation(1).WithArguments("System.Collections.Generic.List", collection.type), + Verify.Diagnostic("xUnit2027").WithLocation(2).WithArguments("System.Collections.Generic.List", collection.type), + Verify.Diagnostic("xUnit2027").WithLocation(3).WithArguments(collection.type, "System.Collections.Generic.List"), + Verify.Diagnostic("xUnit2027").WithLocation(4).WithArguments(collection.type, "System.Collections.Generic.List"), + Verify.Diagnostic("xUnit2027").WithLocation(5).WithArguments(collection.type, "System.Collections.Generic.List"), }; - await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, new[] { code, customSetAndComparer }, expected); + await Verify.VerifyAnalyzer(LanguageVersion.CSharp7, [code, customSetAndComparer], expected); } } } diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/UseAssertFailInsteadOfBooleanAssertTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/UseAssertFailInsteadOfBooleanAssertTests.cs index ff180ab3..94d4f313 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/UseAssertFailInsteadOfBooleanAssertTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/UseAssertFailInsteadOfBooleanAssertTests.cs @@ -8,27 +8,36 @@ public class UseAssertFailInsteadOfBooleanAssertTests { - const string codeTemplate = @" -public class TestClass {{ - [Xunit.Fact] - public void TestMethod() {{ - Xunit.Assert.{0}({1}, ""failure message""); - }} -}}"; + const string codeTemplate = /* lang=c#-test */ """ + public class TestClass {{ + [Xunit.Fact] + public void TestMethod() {{ + {{|#0:Xunit.Assert.{0}({1}, "failure message")|}}; + }} + }} + """; [Theory] [InlineData(Constants.Asserts.True, "false")] [InlineData(Constants.Asserts.False, "true")] - public async Task SignalsFor25( + public async Task OppositeTestWithMessage_Prev25_DoesNotTrigger( string assertion, string targetValue) { var source = string.Format(codeTemplate, assertion, targetValue); - var expected = - Verify - .Diagnostic() - .WithSpan(5, 9, 5, 52) - .WithArguments(assertion, targetValue); + + await Verify_Unsupported.VerifyAnalyzer(source); + } + + [Theory] + [InlineData(Constants.Asserts.True, "false")] + [InlineData(Constants.Asserts.False, "true")] + public async Task OppositeTestWithMessage_v25_Triggers( + string assertion, + string targetValue) + { + var source = string.Format(codeTemplate, assertion, targetValue); + var expected = Verify.Diagnostic().WithLocation(0).WithArguments(assertion, targetValue); await Verify.VerifyAnalyzer(source, expected); } @@ -36,7 +45,7 @@ public async Task SignalsFor25( [Theory] [InlineData(Constants.Asserts.True, "true")] [InlineData(Constants.Asserts.False, "false")] - public async Task DoesNotSignalForNonFailure( + public async Task SameTestWithMessage_DoesNotTrigger( string assertion, string targetValue) { @@ -46,32 +55,21 @@ public async Task DoesNotSignalForNonFailure( } [Fact] - public async Task DoesNotSignalForNonConstantInvocation() + public async Task NonConstantInvocation_DoesNotTrigger() { - var source = @" -public class TestClass { - [Xunit.Fact] - public void TestMethod() { - var value = (1 != 2); - Xunit.Assert.False(value, ""failure message""); - } -}"; + var source = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + public void TestMethod() { + var value = (1 != 2); + Xunit.Assert.False(value, "failure message"); + } + } + """; await Verify.VerifyAnalyzer(source); } - [Theory] - [InlineData(Constants.Asserts.True, "false")] - [InlineData(Constants.Asserts.False, "true")] - public async Task DoNotSignalForPre25( - string assertion, - string targetValue) - { - var source = string.Format(codeTemplate, assertion, targetValue); - - await Verify_Unsupported.VerifyAnalyzer(source); - } - internal class Analyzer_Pre25 : UseAssertFailInsteadOfBooleanAssert { protected override XunitContext CreateXunitContext(Compilation compilation) => diff --git a/src/xunit.analyzers.tests/Analyzers/X3000/CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.cs b/src/xunit.analyzers.tests/Analyzers/X3000/CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.cs index ad8230dd..6fc15052 100644 --- a/src/xunit.analyzers.tests/Analyzers/X3000/CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X3000/CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Xunit; @@ -12,45 +10,43 @@ public class CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests { public class WithAbstractions { - readonly static string Template = @" -using Xunit.Abstractions; - -public class MyClass: {0} {{ }}"; - - public static IEnumerable Interfaces - { - get - { - // Discovery and execution messages - yield return new object[] { MemberCount("IMessageSink", 1) }; - yield return new object[] { MemberCount("IMessageSinkMessage", 0) }; - - // Reflection - yield return new object[] { MemberCount("IAssemblyInfo", 5) }; - yield return new object[] { MemberCount("IAttributeInfo", 3) }; - yield return new object[] { MemberCount("IMethodInfo", 11) }; - yield return new object[] { MemberCount("IParameterInfo", 2) }; - yield return new object[] { MemberCount("ITypeInfo", 13) }; - - // Test cases - yield return new object[] { MemberCount("ITest", 2) }; - yield return new object[] { MemberCount("ITestAssembly", 4) }; - yield return new object[] { MemberCount("ITestCase", 9) }; - yield return new object[] { MemberCount("ITestClass", 4) }; - yield return new object[] { MemberCount("ITestCollection", 6) }; - yield return new object[] { MemberCount("ITestMethod", 4) }; - - // Test frameworks - yield return new object[] { MemberCount("ISourceInformation", 4) }; - yield return new object[] { MemberCount("ISourceInformationProvider", 2) }; - yield return new object[] { MemberCount("ITestFramework", 4) }; - yield return new object[] { MemberCount("ITestFrameworkDiscoverer", 6) }; - yield return new object[] { MemberCount("ITestFrameworkExecutor", 4) }; - } - } + readonly static string Template = /* lang=c#-test */ """ + using Xunit.Abstractions; + + public class {{|#0:MyClass|}}: {0} {{ }} + """; + + public static TheoryData Interfaces = + [ + // Discovery and execution messages + MemberCount("IMessageSink", 1), + MemberCount("IMessageSinkMessage", 0), + + // Reflection + MemberCount("IAssemblyInfo", 5), + MemberCount("IAttributeInfo", 3), + MemberCount("IMethodInfo", 11), + MemberCount("IParameterInfo", 2), + MemberCount("ITypeInfo", 13), + + // Test cases + MemberCount("ITest", 2), + MemberCount("ITestAssembly", 4), + MemberCount("ITestCase", 9), + MemberCount("ITestClass", 4), + MemberCount("ITestCollection", 6), + MemberCount("ITestMethod", 4), + + // Test frameworks + MemberCount("ISourceInformation", 4), + MemberCount("ISourceInformationProvider", 2), + MemberCount("ITestFramework", 4), + MemberCount("ITestFrameworkDiscoverer", 6), + MemberCount("ITestFrameworkExecutor", 4), + ]; [Fact] - public async Task SuccessCase_NoInterfaces() + public async Task NoInterfaces_DoesNotTrigger() { var source = "public class Foo { }"; @@ -59,14 +55,10 @@ public async Task SuccessCase_NoInterfaces() [Theory] [MemberData(nameof(Interfaces))] - public async Task FailureCase_InterfaceWithoutBaseClass(string @interface) + public async Task InterfaceWithoutBaseClass_Triggers(string @interface) { var source = string.Format(Template, @interface); - var expected = - Verify_WithAbstractions - .Diagnostic() - .WithSpan(4, 14, 4, 21) - .WithArguments("MyClass"); + var expected = Verify_WithAbstractions.Diagnostic().WithLocation(0).WithArguments("MyClass"); await Verify_WithAbstractions.VerifyAnalyzerV2(source, expected); } @@ -80,23 +72,15 @@ protected override XunitContext CreateXunitContext(Compilation compilation) => public class WithExecution { - readonly static string Template = @" -using Xunit.Abstractions; + readonly static string Template = /* lang=c#-test */ """ + using Xunit.Abstractions; -public class Foo {{ }} -public class MyLLMBRO: Xunit.LongLivedMarshalByRefObject {{ }} -public class MyClass: {0} {{ }}"; + public class Foo {{ }} + public class MyLLMBRO: Xunit.LongLivedMarshalByRefObject {{ }} + public class {{|#0:MyClass|}}: {0} {{ }} + """; - public static IEnumerable Interfaces - { - get - { - foreach (var @interface in WithAbstractions.Interfaces) - yield return @interface; - - yield return new object[] { MemberCount("Xunit.Sdk.IXunitTestCase", 13) }; - } - } + public static TheoryData Interfaces = new(WithAbstractions.Interfaces) { MemberCount("Xunit.Sdk.IXunitTestCase", 13) }; public static TheoryData InterfacesWithBaseClasses { @@ -104,7 +88,7 @@ public static TheoryData InterfacesWithBaseClasses { var result = new TheoryData(); - foreach (var @interface in Interfaces.Select(x => (string)x[0])) + foreach (var @interface in Interfaces) { result.Add(@interface, "MyLLMBRO"); result.Add(@interface, "Xunit.LongLivedMarshalByRefObject"); @@ -115,15 +99,15 @@ public static TheoryData InterfacesWithBaseClasses } [Fact] - public async Task SuccessCase_NoInterfaces() + public async Task NoInterfaces_DoesNotTrigger() { - var source = "public class Foo { }"; + var source = /* lang=c#-test */ "public class Foo { }"; await Verify_WithExecution.VerifyAnalyzerV2(source); } [Fact] - public async Task SuccessCase_WithXunitTestCase() + public async Task WithXunitTestCase_DoesNotTrigger() { var source = string.Format(Template, "Xunit.Sdk.XunitTestCase"); @@ -132,7 +116,7 @@ public async Task SuccessCase_WithXunitTestCase() [Theory] [MemberData(nameof(InterfacesWithBaseClasses))] - public async Task SuccessCase_CompatibleBaseClass( + public async Task CompatibleBaseClass_DoesNotTrigger( string @interface, string baseClass) { @@ -143,28 +127,20 @@ public async Task SuccessCase_CompatibleBaseClass( [Theory] [MemberData(nameof(Interfaces))] - public async Task FailureCase_InterfaceWithoutBaseClass(string @interface) + public async Task InterfaceWithoutBaseClass_Triggers(string @interface) { var source = string.Format(Template, @interface); - var expected = - Verify_WithExecution - .Diagnostic() - .WithSpan(6, 14, 6, 21) - .WithArguments("MyClass"); + var expected = Verify_WithExecution.Diagnostic().WithLocation(0).WithArguments("MyClass"); await Verify_WithExecution.VerifyAnalyzerV2(source, expected); } [Theory] [MemberData(nameof(Interfaces))] - public async Task FailureCase_IncompatibleBaseClass(string @interface) + public async Task IncompatibleBaseClass_Triggers(string @interface) { var source = string.Format(Template, $"Foo, {@interface}"); - var expected = - Verify_WithExecution - .Diagnostic() - .WithSpan(6, 14, 6, 21) - .WithArguments("MyClass"); + var expected = Verify_WithExecution.Diagnostic().WithLocation(0).WithArguments("MyClass"); await Verify_WithExecution.VerifyAnalyzerV2(source, expected); } @@ -178,14 +154,15 @@ protected override XunitContext CreateXunitContext(Compilation compilation) => public class WithRunnerUtility { - readonly static string Template = @" -using Xunit.Abstractions; + readonly static string Template = /* lang=c#-test */ """ + using Xunit.Abstractions; -public class Foo {{ }} -public class MyLLMBRO: Xunit.Sdk.LongLivedMarshalByRefObject {{ }} -public class MyClass: {0} {{ }}"; + public class Foo {{ }} + public class MyLLMBRO: Xunit.Sdk.LongLivedMarshalByRefObject {{ }} + public class {{|#0:MyClass|}}: {0} {{ }} + """; - public static IEnumerable Interfaces => + public static TheoryData Interfaces = WithAbstractions.Interfaces; public static TheoryData InterfacesWithBaseClasses @@ -194,7 +171,7 @@ public static TheoryData InterfacesWithBaseClasses { var result = new TheoryData(); - foreach (var @interface in Interfaces.Select(x => (string)x[0])) + foreach (var @interface in Interfaces) { result.Add(@interface, "MyLLMBRO"); result.Add(@interface, "Xunit.Sdk.LongLivedMarshalByRefObject"); @@ -205,16 +182,16 @@ public static TheoryData InterfacesWithBaseClasses } [Fact] - public async Task SuccessCase_NoInterfaces() + public async Task NoInterfaces_DoesNotTrigger() { - var source = "public class Foo { }"; + var source = /* lang=c#-test */ "public class Foo { }"; await Verify_WithRunnerUtility.VerifyAnalyzerV2RunnerUtility(source); } [Theory] [MemberData(nameof(InterfacesWithBaseClasses))] - public async Task SuccessCase_CompatibleBaseClass( + public async Task CompatibleBaseClass_DoesNotTrigger( string @interface, string baseClass) { @@ -225,28 +202,20 @@ public async Task SuccessCase_CompatibleBaseClass( [Theory] [MemberData(nameof(Interfaces))] - public async Task FailureCase_InterfaceWithoutBaseClass(string @interface) + public async Task InterfaceWithoutBaseClass_Triggers(string @interface) { var source = string.Format(Template, @interface); - var expected = - Verify_WithRunnerUtility - .Diagnostic() - .WithSpan(6, 14, 6, 21) - .WithArguments("MyClass"); + var expected = Verify_WithRunnerUtility.Diagnostic().WithLocation(0).WithArguments("MyClass"); await Verify_WithRunnerUtility.VerifyAnalyzerV2RunnerUtility(source, expected); } [Theory] [MemberData(nameof(Interfaces))] - public async Task FailureCase_IncompatibleBaseClass(string @interface) + public async Task IncompatibleBaseClass_Triggers(string @interface) { var source = string.Format(Template, $"Foo, {@interface}"); - var expected = - Verify_WithRunnerUtility - .Diagnostic() - .WithSpan(6, 14, 6, 21) - .WithArguments("MyClass"); + var expected = Verify_WithRunnerUtility.Diagnostic().WithLocation(0).WithArguments("MyClass"); await Verify_WithRunnerUtility.VerifyAnalyzerV2RunnerUtility(source, expected); } diff --git a/src/xunit.analyzers.tests/Analyzers/X3000/SerializableClassMustHaveParameterlessConstructorTests.cs b/src/xunit.analyzers.tests/Analyzers/X3000/SerializableClassMustHaveParameterlessConstructorTests.cs index 55e7d67c..5302e42e 100644 --- a/src/xunit.analyzers.tests/Analyzers/X3000/SerializableClassMustHaveParameterlessConstructorTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X3000/SerializableClassMustHaveParameterlessConstructorTests.cs @@ -7,92 +7,67 @@ public class SerializableClassMustHaveParameterlessConstructorTests { - static readonly string Template = @" -using {2}; - -public interface IMySerializer : IXunitSerializable {{ }} -public class Foo : {0} -{{ - {1} - public void Deserialize(IXunitSerializationInfo info) {{ }} - public void Serialize(IXunitSerializationInfo info) {{ }} -}}"; - public static TheoryData Interfaces = new() - { + static readonly string Template = /* lang=c#-test */ """ + using {2}; + + public interface IMySerializer : IXunitSerializable {{ }} + public class {{|#0:Foo|}} : {0} + {{ + {1} + public void Deserialize(IXunitSerializationInfo info) {{ }} + public void Serialize(IXunitSerializationInfo info) {{ }} + }} + """; + public static TheoryData Interfaces = + [ "IXunitSerializable", "IMySerializer" - }; + ]; [Theory] [MemberData(nameof(Interfaces))] - public async Task ImplicitConstructors_NoDiagnostics(string @interface) + public async Task ImplicitConstructors_DoesNotTrigger(string @interface) { - var v2Source = string.Format(Template, @interface, "", "Xunit.Abstractions"); - - await VerifyV2.VerifyAnalyzerV2(v2Source); - - var v3Source = string.Format(Template, @interface, "", "Xunit.Sdk"); - - await VerifyV3.VerifyAnalyzerV3(v3Source); + await VerifyV2.VerifyAnalyzerV2(string.Format(Template, @interface, "", "Xunit.Abstractions")); + await VerifyV3.VerifyAnalyzerV3(string.Format(Template, @interface, "", "Xunit.Sdk")); } [Theory] [MemberData(nameof(Interfaces))] - public async Task WrongConstructor_ReturnsError(string @interface) + public async Task WrongConstructor_Triggers(string @interface) { - var v2Source = string.Format(Template, @interface, "public Foo(int x) { }", "Xunit.Abstractions"); - var v2Expected = - VerifyV2 - .Diagnostic() - .WithSpan(5, 14, 5, 17) - .WithArguments("Foo"); + var v2Source = string.Format(Template, @interface, /* lang=c#-test */ "public Foo(int x) { }", "Xunit.Abstractions"); + var v2Expected = VerifyV2.Diagnostic().WithLocation(0).WithArguments("Foo"); await VerifyV2.VerifyAnalyzerV2(v2Source, v2Expected); - var v3Source = string.Format(Template, @interface, "public Foo(int x) { }", "Xunit.Sdk"); - var v3Expected = - VerifyV3 - .Diagnostic() - .WithSpan(5, 14, 5, 17) - .WithArguments("Foo"); + var v3Source = string.Format(Template, @interface, /* lang=c#-test */ "public Foo(int x) { }", "Xunit.Sdk"); + var v3Expected = VerifyV3.Diagnostic().WithLocation(0).WithArguments("Foo"); await VerifyV3.VerifyAnalyzerV3(v3Source, v3Expected); } [Theory] [MemberData(nameof(Interfaces))] - public async Task NonPublicConstructor_ReturnsError(string @interface) + public async Task NonPublicConstructor_Triggers(string @interface) { - var v2Source = string.Format(Template, @interface, "protected Foo() { }", "Xunit.Abstractions"); - var v2Expected = - VerifyV2 - .Diagnostic() - .WithSpan(5, 14, 5, 17) - .WithArguments("Foo"); + var v2Source = string.Format(Template, @interface, /* lang=c#-test */ "protected Foo() { }", "Xunit.Abstractions"); + var v2Expected = VerifyV2.Diagnostic().WithLocation(0).WithArguments("Foo"); await VerifyV2.VerifyAnalyzerV2(v2Source, v2Expected); - var v3Source = string.Format(Template, @interface, "protected Foo() { }", "Xunit.Sdk"); - var v3Expected = - VerifyV3 - .Diagnostic() - .WithSpan(5, 14, 5, 17) - .WithArguments("Foo"); + var v3Source = string.Format(Template, @interface, /* lang=c#-test */ "protected Foo() { }", "Xunit.Sdk"); + var v3Expected = VerifyV3.Diagnostic().WithLocation(0).WithArguments("Foo"); await VerifyV3.VerifyAnalyzerV3(v3Source, v3Expected); } [Theory] [MemberData(nameof(Interfaces))] - public async Task PublicParameterlessConstructor_NoDiagnostics(string @interface) + public async Task PublicParameterlessConstructor_DoesNotTrigger(string @interface) { - var v2Source = string.Format(Template, @interface, "public Foo() { }", "Xunit.Abstractions"); - - await VerifyV2.VerifyAnalyzerV2(v2Source); - - var v3Source = string.Format(Template, @interface, "public Foo() { }", "Xunit.Sdk"); - - await VerifyV3.VerifyAnalyzerV3(v3Source); + await VerifyV2.VerifyAnalyzerV2(string.Format(Template, @interface, "public Foo() { }", "Xunit.Abstractions")); + await VerifyV3.VerifyAnalyzerV3(string.Format(Template, @interface, "public Foo() { }", "Xunit.Sdk")); } public class V2Analyzer : SerializableClassMustHaveParameterlessConstructor diff --git a/src/xunit.analyzers.tests/Fixes/X1000/ClassDataAttributeMustPointAtValidClassFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/ClassDataAttributeMustPointAtValidClassFixerTests.cs index f839dd6d..0a9e3fe8 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/ClassDataAttributeMustPointAtValidClassFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/ClassDataAttributeMustPointAtValidClassFixerTests.cs @@ -8,31 +8,33 @@ public class ClassDataAttributeMustPointAtValidClassFixerTests [Fact] public async Task AddsIEnumerable() { - var before = @" -using System.Collections.Generic; -using Xunit; - -public class TestData { -} - -public class TestClass { - [Theory] - [{|xUnit1007:ClassData(typeof(TestData))|}] - public void TestMethod(int _) { } -}"; - var afterV2 = @" -using System.Collections.Generic; -using Xunit; - -public class TestData : {|CS0535:{|CS0535:IEnumerable|}|} -{ -} - -public class TestClass { - [Theory] - [ClassData(typeof(TestData))] - public void TestMethod(int _) { } -}"; + var before = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; + + public class TestData { + } + + public class TestClass { + [Theory] + [{|xUnit1007:ClassData(typeof(TestData))|}] + public void TestMethod(int _) { } + } + """; + var afterV2 = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; + + public class TestData : {|CS0535:{|CS0535:IEnumerable|}|} + { + } + + public class TestClass { + [Theory] + [ClassData(typeof(TestData))] + public void TestMethod(int _) { } + } + """; var afterV3 = afterV2.Replace("ClassData(typeof(TestData))", "{|xUnit1050:ClassData(typeof(TestData))|}"); await Verify.VerifyCodeFixV2(before, afterV2, ClassDataAttributeMustPointAtValidClassFixer.Key_FixDataClass); @@ -42,40 +44,42 @@ public void TestMethod(int _) { } [Fact] public async Task ConvertsParameterlessConstructorToPublic() { - var before = @" -using System.Collections; -using System.Collections.Generic; -using Xunit; - -public class TestData : IEnumerable { - TestData() { } - - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -} - -public class TestClass { - [Theory] - [{|xUnit1007:ClassData(typeof(TestData))|}] - public void TestMethod(int _) { } -}"; - var afterV2 = @" -using System.Collections; -using System.Collections.Generic; -using Xunit; - -public class TestData : IEnumerable { - public TestData() { } - - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -} - -public class TestClass { - [Theory] - [ClassData(typeof(TestData))] - public void TestMethod(int _) { } -}"; + var before = /* lang=c#-test */ """ + using System.Collections; + using System.Collections.Generic; + using Xunit; + + public class TestData : IEnumerable { + TestData() { } + + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + + public class TestClass { + [Theory] + [{|xUnit1007:ClassData(typeof(TestData))|}] + public void TestMethod(int _) { } + } + """; + var afterV2 = /* lang=c#-test */ """ + using System.Collections; + using System.Collections.Generic; + using Xunit; + + public class TestData : IEnumerable { + public TestData() { } + + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + + public class TestClass { + [Theory] + [ClassData(typeof(TestData))] + public void TestMethod(int _) { } + } + """; var afterV3 = afterV2.Replace("ClassData(typeof(TestData))", "{|xUnit1050:ClassData(typeof(TestData))|}"); await Verify.VerifyCodeFixV2(before, afterV2, ClassDataAttributeMustPointAtValidClassFixer.Key_FixDataClass); @@ -85,44 +89,46 @@ public void TestMethod(int _) { } [Fact] public async Task AddsPublicParameterlessConstructor() { - var before = @" -using System.Collections; -using System.Collections.Generic; -using Xunit; - -public class TestData : IEnumerable { - TestData(int _) { } - - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -} - -public class TestClass { - [Theory] - [{|xUnit1007:ClassData(typeof(TestData))|}] - public void TestMethod(int _) { } -}"; - var afterV2 = @" -using System.Collections; -using System.Collections.Generic; -using Xunit; - -public class TestData : IEnumerable { - TestData(int _) { } - - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; - - public TestData() - { - } -} - -public class TestClass { - [Theory] - [ClassData(typeof(TestData))] - public void TestMethod(int _) { } -}"; + var before = /* lang=c#-test */ """ + using System.Collections; + using System.Collections.Generic; + using Xunit; + + public class TestData : IEnumerable { + TestData(int _) { } + + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + + public class TestClass { + [Theory] + [{|xUnit1007:ClassData(typeof(TestData))|}] + public void TestMethod(int _) { } + } + """; + var afterV2 = """ + using System.Collections; + using System.Collections.Generic; + using Xunit; + + public class TestData : IEnumerable { + TestData(int _) { } + + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + + public TestData() + { + } + } + + public class TestClass { + [Theory] + [ClassData(typeof(TestData))] + public void TestMethod(int _) { } + } + """; var afterV3 = afterV2.Replace("ClassData(typeof(TestData))", "{|xUnit1050:ClassData(typeof(TestData))|}"); await Verify.VerifyCodeFixV2(before, afterV2, ClassDataAttributeMustPointAtValidClassFixer.Key_FixDataClass); @@ -132,36 +138,38 @@ public void TestMethod(int _) { } [Fact] public async Task RemovesAbstractModifierFromDataClass() { - var before = @" -using System.Collections; -using System.Collections.Generic; -using Xunit; - -public abstract class TestData : IEnumerable { - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -} - -public class TestClass { - [Theory] - [{|xUnit1007:ClassData(typeof(TestData))|}] - public void TestMethod(int _) { } -}"; - var afterV2 = @" -using System.Collections; -using System.Collections.Generic; -using Xunit; - -public class TestData : IEnumerable { - public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; -} - -public class TestClass { - [Theory] - [ClassData(typeof(TestData))] - public void TestMethod(int _) { } -}"; + var before = /* lang=c#-test */ """ + using System.Collections; + using System.Collections.Generic; + using Xunit; + + public abstract class TestData : IEnumerable { + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + + public class TestClass { + [Theory] + [{|xUnit1007:ClassData(typeof(TestData))|}] + public void TestMethod(int _) { } + } + """; + var afterV2 = /* lang=c#-test */ """ + using System.Collections; + using System.Collections.Generic; + using Xunit; + + public class TestData : IEnumerable { + public IEnumerator GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; + } + + public class TestClass { + [Theory] + [ClassData(typeof(TestData))] + public void TestMethod(int _) { } + } + """; var afterV3 = afterV2.Replace("ClassData(typeof(TestData))", "{|xUnit1050:ClassData(typeof(TestData))|}"); await Verify.VerifyCodeFixV2(before, afterV2, ClassDataAttributeMustPointAtValidClassFixer.Key_FixDataClass); diff --git a/src/xunit.analyzers.tests/Fixes/X1000/CollectionDefinitionClassesMustBePublicFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/CollectionDefinitionClassesMustBePublicFixerTests.cs index bd5e8335..263161d3 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/CollectionDefinitionClassesMustBePublicFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/CollectionDefinitionClassesMustBePublicFixerTests.cs @@ -10,13 +10,14 @@ public class CollectionDefinitionClassesMustBePublicFixerTests [InlineData("internal ")] public async Task MakesClassPublic(string modifier) { - var before = $@" -[Xunit.CollectionDefinition(""MyCollection"")] -{modifier}class [|CollectionDefinitionClass|] {{ }}"; - - var after = @" -[Xunit.CollectionDefinition(""MyCollection"")] -public class CollectionDefinitionClass { }"; + var before = string.Format(/* lang=c#-test */ """ + [Xunit.CollectionDefinition("MyCollection")] + {0}class [|CollectionDefinitionClass|] {{ }} + """, modifier); + var after = /* lang=c#-test */ """ + [Xunit.CollectionDefinition("MyCollection")] + public class CollectionDefinitionClass { } + """; await Verify.VerifyCodeFix(before, after, CollectionDefinitionClassesMustBePublicFixer.Key_MakeCollectionDefinitionClassPublic); } @@ -26,17 +27,18 @@ public class CollectionDefinitionClass { }"; [InlineData("internal ")] public async Task ForPartialClassDeclarations_MakesSingleDeclarationPublic(string modifier) { - var before = $@" -[Xunit.CollectionDefinition(""MyCollection"")] -{modifier}partial class [|CollectionDefinitionClass|] {{ }} - -partial class CollectionDefinitionClass {{ }}"; - - var after = @" -[Xunit.CollectionDefinition(""MyCollection"")] -public partial class CollectionDefinitionClass { } - -partial class CollectionDefinitionClass { }"; + var before = string.Format(/* lang=c#-test */ """ + [Xunit.CollectionDefinition("MyCollection")] + {0}partial class [|CollectionDefinitionClass|] {{ }} + + partial class CollectionDefinitionClass {{ }} + """, modifier); + var after = /* lang=c#-test */ """ + [Xunit.CollectionDefinition("MyCollection")] + public partial class CollectionDefinitionClass { } + + partial class CollectionDefinitionClass { } + """; await Verify.VerifyCodeFix(before, after, CollectionDefinitionClassesMustBePublicFixer.Key_MakeCollectionDefinitionClassPublic); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/ConvertToFactFixTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/ConvertToFactFixTests.cs index 651abb0d..95d28f2a 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/ConvertToFactFixTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/ConvertToFactFixTests.cs @@ -9,21 +9,22 @@ public class ConvertToFactFixTests [Fact] public async Task From_X1003() { - var before = @" -using Xunit; - -public class TestClass { - [Theory] - public void [|TestMethod|](int a) { } -}"; - - var after = @" -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod(int a) { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + public void [|TestMethod|](int a) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod(int a) { } + } + """; await Verify_X1003.VerifyCodeFix(before, after, ConvertToFactFix.Key_ConvertToFact); } @@ -31,21 +32,22 @@ public void TestMethod(int a) { } [Fact] public async Task From_X1006() { - var before = @" -using Xunit; - -public class TestClass { - [Theory] - public void [|TestMethod|]() { } -}"; - - var after = @" -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + public void [|TestMethod|]() { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { } + } + """; await Verify_X1006.VerifyCodeFix(before, after, ConvertToFactFix.Key_ConvertToFact); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/ConvertToTheoryFixTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/ConvertToTheoryFixTests.cs index b48706d8..48182208 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/ConvertToTheoryFixTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/ConvertToTheoryFixTests.cs @@ -9,21 +9,22 @@ public class ConvertToTheoryFixTests [Fact] public async Task From_X1001() { - var before = @" -using Xunit; - -public class TestClass { - [Fact] - public void [|TestMethod|](int a) { } -}"; - - var after = @" -using Xunit; - -public class TestClass { - [Theory] - public void TestMethod(int a) { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Fact] + public void [|TestMethod|](int a) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + public void TestMethod(int a) { } + } + """; await Verify_X1001.VerifyCodeFix(before, after, ConvertToTheoryFix.Key_ConvertToTheory); } @@ -31,23 +32,24 @@ public void TestMethod(int a) { } [Fact] public async Task From_X1005() { - var before = @" -using Xunit; - -public class TestClass { - [Fact] - [InlineData(42)] - public void [|TestMethod|]() { } -}"; - - var after = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(42)] - public void TestMethod() { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Fact] + [InlineData(42)] + public void [|TestMethod|]() { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + [InlineData(42)] + public void TestMethod() { } + } + """; await Verify_X1005.VerifyCodeFix(before, after, ConvertToTheoryFix.Key_ConvertToTheory); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/DataAttributeShouldBeUsedOnATheoryFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/DataAttributeShouldBeUsedOnATheoryFixerTests.cs index d4860acc..e20ee09c 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/DataAttributeShouldBeUsedOnATheoryFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/DataAttributeShouldBeUsedOnATheoryFixerTests.cs @@ -8,22 +8,23 @@ public class DataAttributeShouldBeUsedOnATheoryFixerTests [Fact] public async Task AddsMissingTheoryAttribute() { - var before = @" -using Xunit; - -public class TestClass { - [InlineData] - public void [|TestMethod|]() { } -}"; - - var after = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData] - public void TestMethod() { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [InlineData] + public void [|TestMethod|]() { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + [InlineData] + public void TestMethod() { } + } + """; await Verify.VerifyCodeFix(before, after, DataAttributeShouldBeUsedOnATheoryFixer.Key_MarkAsTheory); } @@ -31,20 +32,21 @@ public void TestMethod() { } [Fact] public async Task RemovesDataAttributes() { - var before = @" -using Xunit; - -public class TestClass { - [InlineData] - public void [|TestMethod|]() { } -}"; - - var after = @" -using Xunit; - -public class TestClass { - public void TestMethod() { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [InlineData] + public void [|TestMethod|]() { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + public void TestMethod() { } + } + """; await Verify.VerifyCodeFix(before, after, DataAttributeShouldBeUsedOnATheoryFixer.Key_RemoveDataAttributes); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/DoNotUseAsyncVoidForTestMethodsFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/DoNotUseAsyncVoidForTestMethodsFixerTests.cs index f14c5659..607b67a9 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/DoNotUseAsyncVoidForTestMethodsFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/DoNotUseAsyncVoidForTestMethodsFixerTests.cs @@ -9,33 +9,27 @@ public class DoNotUseAsyncVoidForTestMethodsFixerTests [Fact] public async Task WithoutNamespace_ConvertsToTask() { - var beforeV2 = @" -using Xunit; - -public class TestClass { - [Fact] - public async void {|xUnit1048:TestMethod|}() { - await System.Threading.Tasks.Task.Yield(); - } -}"; - var beforeV3 = @" -using Xunit; - -public class TestClass { - [Fact] - public async void {|xUnit1049:TestMethod|}() { - await System.Threading.Tasks.Task.Yield(); - } -}"; - var after = @" -using Xunit; - -public class TestClass { - [Fact] - public async System.Threading.Tasks.Task TestMethod() { - await System.Threading.Tasks.Task.Yield(); - } -}"; + var beforeV2 = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Fact] + public async void {|xUnit1048:TestMethod|}() { + await System.Threading.Tasks.Task.Yield(); + } + } + """; + var beforeV3 = beforeV2.Replace("xUnit1048", "xUnit1049"); + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Fact] + public async System.Threading.Tasks.Task TestMethod() { + await System.Threading.Tasks.Task.Yield(); + } + } + """; await Verify.VerifyCodeFixV2(beforeV2, after, DoNotUseAsyncVoidForTestMethodsFixer.Key_ConvertToTask); await Verify.VerifyCodeFixV3(beforeV3, after, DoNotUseAsyncVoidForTestMethodsFixer.Key_ConvertToTask); @@ -44,36 +38,29 @@ public async System.Threading.Tasks.Task TestMethod() { [Fact] public async Task WithNamespace_ConvertsToTask() { - var beforeV2 = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async void {|xUnit1048:TestMethod|}() { - await Task.Yield(); - } -}"; - var beforeV3 = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async void {|xUnit1049:TestMethod|}() { - await Task.Yield(); - } -}"; - var after = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - await Task.Yield(); - } -}"; + var beforeV2 = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async void {|xUnit1048:TestMethod|}() { + await Task.Yield(); + } + } + """; + var beforeV3 = beforeV2.Replace("xUnit1048", "xUnit1049"); + var after = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + await Task.Yield(); + } + } + """; await Verify.VerifyCodeFixV2(beforeV2, after, DoNotUseAsyncVoidForTestMethodsFixer.Key_ConvertToTask); await Verify.VerifyCodeFixV3(beforeV3, after, DoNotUseAsyncVoidForTestMethodsFixer.Key_ConvertToTask); @@ -82,24 +69,26 @@ public async Task TestMethod() { [Fact] public async Task WithoutNamespace_ConvertsToValueTask() { - var before = @" -using Xunit; - -public class TestClass { - [Fact] - public async void {|xUnit1049:TestMethod|}() { - await System.Threading.Tasks.Task.Yield(); - } -}"; - var after = @" -using Xunit; - -public class TestClass { - [Fact] - public async System.Threading.Tasks.ValueTask TestMethod() { - await System.Threading.Tasks.Task.Yield(); - } -}"; + var before = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Fact] + public async void {|xUnit1049:TestMethod|}() { + await System.Threading.Tasks.Task.Yield(); + } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Fact] + public async System.Threading.Tasks.ValueTask TestMethod() { + await System.Threading.Tasks.Task.Yield(); + } + } + """; await Verify.VerifyCodeFixV3(before, after, DoNotUseAsyncVoidForTestMethodsFixer.Key_ConvertToValueTask); } @@ -107,26 +96,28 @@ public async System.Threading.Tasks.ValueTask TestMethod() { [Fact] public async Task WithNamespace_ConvertsToValueTask() { - var before = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async void {|xUnit1049:TestMethod|}() { - await Task.Yield(); - } -}"; - var after = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async ValueTask TestMethod() { - await Task.Yield(); - } -}"; + var before = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async void {|xUnit1049:TestMethod|}() { + await Task.Yield(); + } + } + """; + var after = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async ValueTask TestMethod() { + await Task.Yield(); + } + } + """; await Verify.VerifyCodeFixV3(before, after, DoNotUseAsyncVoidForTestMethodsFixer.Key_ConvertToValueTask); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/DoNotUseConfigureAwaitFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/DoNotUseConfigureAwaitFixerTests.cs index 13cff60e..4de4addd 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/DoNotUseConfigureAwaitFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/DoNotUseConfigureAwaitFixerTests.cs @@ -7,13 +7,13 @@ public class DoNotUseConfigureAwaitFixerTests { public class ConfigureAwait_Boolean { - public static TheoryData InvalidValues = new() - { + public static TheoryData InvalidValues = + [ "false", // Literal false "1 == 2", // Logical false (we don't compute) "1 == 1", // Logical true (we don't compute) "booleanVar", // Reference value (we don't do lookup) - }; + ]; public class RemoveConfigureAwait { @@ -21,29 +21,30 @@ public class RemoveConfigureAwait [MemberData(nameof(InvalidValues), MemberType = typeof(ConfigureAwait_Boolean))] public async Task Task_Async(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - await Task.Delay(1).[|ConfigureAwait({argumentValue})|]; - }} -}}"; - - var after = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - var booleanVar = true; - await Task.Delay(1); - } -}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + await Task.Delay(1).[|ConfigureAwait({0})|]; + }} + }} + """, argumentValue); + var after = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + var booleanVar = true; + await Task.Delay(1); + } + } + """; await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_RemoveConfigureAwait); } @@ -52,29 +53,30 @@ public async Task TestMethod() { [MemberData(nameof(InvalidValues), MemberType = typeof(ConfigureAwait_Boolean))] public async Task Task_NonAsync(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var booleanVar = true; - Task.Delay(1).[|ConfigureAwait({argumentValue})|].GetAwaiter().GetResult(); - }} -}}"; - - var after = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - var booleanVar = true; - Task.Delay(1).GetAwaiter().GetResult(); - } -}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var booleanVar = true; + Task.Delay(1).[|ConfigureAwait({0})|].GetAwaiter().GetResult(); + }} + }} + """, argumentValue); + var after = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + var booleanVar = true; + Task.Delay(1).GetAwaiter().GetResult(); + } + } + """; await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_RemoveConfigureAwait); } @@ -83,31 +85,32 @@ public void TestMethod() { [MemberData(nameof(InvalidValues), MemberType = typeof(ConfigureAwait_Boolean))] public async Task TaskOfT(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - var task = Task.FromResult(42); - await task.[|ConfigureAwait({argumentValue})|]; - }} -}}"; - - var after = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - var booleanVar = true; - var task = Task.FromResult(42); - await task; - } -}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + var task = Task.FromResult(42); + await task.[|ConfigureAwait({0})|]; + }} + }} + """, argumentValue); + var after = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + var booleanVar = true; + var task = Task.FromResult(42); + await task; + } + } + """; await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_RemoveConfigureAwait); } @@ -116,31 +119,32 @@ public async Task TestMethod() { [MemberData(nameof(InvalidValues), MemberType = typeof(ConfigureAwait_Boolean))] public async Task ValueTask(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - var valueTask = default(ValueTask); - await valueTask.[|ConfigureAwait({argumentValue})|]; - }} -}}"; - - var after = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - var booleanVar = true; - var valueTask = default(ValueTask); - await valueTask; - } -}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + var valueTask = default(ValueTask); + await valueTask.[|ConfigureAwait({0})|]; + }} + }} + """, argumentValue); + var after = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + var booleanVar = true; + var valueTask = default(ValueTask); + await valueTask; + } + } + """; await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_RemoveConfigureAwait); } @@ -149,31 +153,32 @@ public async Task TestMethod() { [MemberData(nameof(InvalidValues), MemberType = typeof(ConfigureAwait_Boolean))] public async Task ValueTaskOfT(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - var valueTask = default(ValueTask); - await valueTask.[|ConfigureAwait({argumentValue})|]; - }} -}}"; - - var after = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - var booleanVar = true; - var valueTask = default(ValueTask); - await valueTask; - } -}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + var valueTask = default(ValueTask); + await valueTask.[|ConfigureAwait({0})|]; + }} + }} + """, argumentValue); + var after = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + var booleanVar = true; + var valueTask = default(ValueTask); + await valueTask; + } + } + """; await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_RemoveConfigureAwait); } @@ -185,29 +190,30 @@ public class ReplaceConfigureAwait [MemberData(nameof(InvalidValues), MemberType = typeof(ConfigureAwait_Boolean))] public async Task Task_Async(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - await Task.Delay(1).[|ConfigureAwait({argumentValue})|]; - }} -}}"; - - var after = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - var booleanVar = true; - await Task.Delay(1).ConfigureAwait(true); - } -}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + await Task.Delay(1).[|ConfigureAwait({0})|]; + }} + }} + """, argumentValue); + var after = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + var booleanVar = true; + await Task.Delay(1).ConfigureAwait(true); + } + } + """; await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_ReplaceArgumentValue); } @@ -216,29 +222,30 @@ public async Task TestMethod() { [MemberData(nameof(InvalidValues), MemberType = typeof(ConfigureAwait_Boolean))] public async Task Task_NonAsync(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var booleanVar = true; - Task.Delay(1).[|ConfigureAwait({argumentValue})|].GetAwaiter().GetResult(); - }} -}}"; - - var after = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - var booleanVar = true; - Task.Delay(1).ConfigureAwait(true).GetAwaiter().GetResult(); - } -}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var booleanVar = true; + Task.Delay(1).[|ConfigureAwait({0})|].GetAwaiter().GetResult(); + }} + }} + """, argumentValue); + var after = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + var booleanVar = true; + Task.Delay(1).ConfigureAwait(true).GetAwaiter().GetResult(); + } + } + """; await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_ReplaceArgumentValue); } @@ -247,31 +254,32 @@ public void TestMethod() { [MemberData(nameof(InvalidValues), MemberType = typeof(ConfigureAwait_Boolean))] public async Task TaskOfT(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - var task = Task.FromResult(42); - await task.[|ConfigureAwait({argumentValue})|]; - }} -}}"; - - var after = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - var booleanVar = true; - var task = Task.FromResult(42); - await task.ConfigureAwait(true); - } -}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + var task = Task.FromResult(42); + await task.[|ConfigureAwait({0})|]; + }} + }} + """, argumentValue); + var after = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + var booleanVar = true; + var task = Task.FromResult(42); + await task.ConfigureAwait(true); + } + } + """; await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_ReplaceArgumentValue); } @@ -280,31 +288,32 @@ public async Task TestMethod() { [MemberData(nameof(InvalidValues), MemberType = typeof(ConfigureAwait_Boolean))] public async Task ValueTask(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - var valueTask = default(ValueTask); - await valueTask.[|ConfigureAwait({argumentValue})|]; - }} -}}"; - - var after = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - var booleanVar = true; - var valueTask = default(ValueTask); - await valueTask.ConfigureAwait(true); - } -}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + var valueTask = default(ValueTask); + await valueTask.[|ConfigureAwait({0})|]; + }} + }} + """, argumentValue); + var after = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + var booleanVar = true; + var valueTask = default(ValueTask); + await valueTask.ConfigureAwait(true); + } + } + """; await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_ReplaceArgumentValue); } @@ -313,31 +322,32 @@ public async Task TestMethod() { [MemberData(nameof(InvalidValues), MemberType = typeof(ConfigureAwait_Boolean))] public async Task ValueTaskOfT(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var booleanVar = true; - var valueTask = default(ValueTask); - await valueTask.[|ConfigureAwait({argumentValue})|]; - }} -}}"; - - var after = @" -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public async Task TestMethod() { - var booleanVar = true; - var valueTask = default(ValueTask); - await valueTask.ConfigureAwait(true); - } -}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var booleanVar = true; + var valueTask = default(ValueTask); + await valueTask.[|ConfigureAwait({0})|]; + }} + }} + """, argumentValue); + var after = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public async Task TestMethod() { + var booleanVar = true; + var valueTask = default(ValueTask); + await valueTask.ConfigureAwait(true); + } + } + """; await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_ReplaceArgumentValue); } @@ -348,43 +358,45 @@ public async Task TestMethod() { public class ConfigureAwait_ConfigureAwaitOptions { - public static TheoryData InvalidValues = new() - { + public static TheoryData InvalidValues = + [ // Literal values - "ConfigureAwaitOptions.None", - "ConfigureAwaitOptions.SuppressThrowing", - "ConfigureAwaitOptions.ForceYielding | ConfigureAwaitOptions.SuppressThrowing", + /* lang=c#-test */ "ConfigureAwaitOptions.None", + /* lang=c#-test */ "ConfigureAwaitOptions.SuppressThrowing", + /* lang=c#-test */ "ConfigureAwaitOptions.ForceYielding | ConfigureAwaitOptions.SuppressThrowing", + // Reference values (we don't do lookup) - "enumVar", - }; + /* lang=c#-test */ "enumVar", + ]; [Theory] [MemberData(nameof(InvalidValues))] public async Task Task_Async(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; - await Task.Delay(1).[|ConfigureAwait({argumentValue})|]; - }} -}}"; - - var after = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; - await Task.Delay(1).ConfigureAwait({argumentValue} | ConfigureAwaitOptions.ContinueOnCapturedContext); - }} -}}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; + await Task.Delay(1).[|ConfigureAwait({0})|]; + }} + }} + """, argumentValue); + var after = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; + await Task.Delay(1).ConfigureAwait({0} | ConfigureAwaitOptions.ContinueOnCapturedContext); + }} + }} + """, argumentValue); await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_ReplaceArgumentValue); } @@ -393,29 +405,30 @@ public async Task TestMethod() {{ [MemberData(nameof(InvalidValues))] public async Task Task_NonAsync(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; - Task.Delay(1).[|ConfigureAwait({argumentValue})|].GetAwaiter().GetResult(); - }} -}}"; - - var after = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; - Task.Delay(1).ConfigureAwait({argumentValue} | ConfigureAwaitOptions.ContinueOnCapturedContext).GetAwaiter().GetResult(); - }} -}}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; + Task.Delay(1).[|ConfigureAwait({0})|].GetAwaiter().GetResult(); + }} + }} + """, argumentValue); + var after = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; + Task.Delay(1).ConfigureAwait({0} | ConfigureAwaitOptions.ContinueOnCapturedContext).GetAwaiter().GetResult(); + }} + }} + """, argumentValue); await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_ReplaceArgumentValue); } @@ -424,31 +437,32 @@ public void TestMethod() {{ [MemberData(nameof(InvalidValues))] public async Task TaskOfT(string argumentValue) { - var before = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; - var task = Task.FromResult(42); - await task.[|ConfigureAwait({argumentValue})|]; - }} -}}"; - - var after = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [Fact] - public async Task TestMethod() {{ - var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; - var task = Task.FromResult(42); - await task.ConfigureAwait({argumentValue} | ConfigureAwaitOptions.ContinueOnCapturedContext); - }} -}}"; + var before = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; + var task = Task.FromResult(42); + await task.[|ConfigureAwait({0})|]; + }} + }} + """, argumentValue); + var after = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [Fact] + public async Task TestMethod() {{ + var enumVar = ConfigureAwaitOptions.ContinueOnCapturedContext; + var task = Task.FromResult(42); + await task.ConfigureAwait({0} | ConfigureAwaitOptions.ContinueOnCapturedContext); + }} + }} + """, argumentValue); await Verify.VerifyCodeFix(before, after, DoNotUseConfigureAwaitFixer.Key_ReplaceArgumentValue); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/FactMethodMustNotHaveParametersFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/FactMethodMustNotHaveParametersFixerTests.cs index 3f24e755..5a234f3c 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/FactMethodMustNotHaveParametersFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/FactMethodMustNotHaveParametersFixerTests.cs @@ -8,21 +8,22 @@ public class FactMethodMustNotHaveParametersFixerTests [Fact] public async Task RemovesParameter() { - var before = @" -using Xunit; - -public class TestClass { - [Fact] - public void [|TestMethod|](int x) { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; - var after = @" -using Xunit; + public class TestClass { + [Fact] + public void [|TestMethod|](int x) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Fact] - public void TestMethod() { } -}"; + public class TestClass { + [Fact] + public void TestMethod() { } + } + """; await Verify.VerifyCodeFix(before, after, FactMethodMustNotHaveParametersFixer.Key_RemoveParameters); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/FactMethodShouldNotHaveTestDataFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/FactMethodShouldNotHaveTestDataFixerTests.cs index 9eb2dc31..3f81641d 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/FactMethodShouldNotHaveTestDataFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/FactMethodShouldNotHaveTestDataFixerTests.cs @@ -8,22 +8,23 @@ public class FactMethodShouldNotHaveTestDataFixerTests [Fact] public async Task RemovesDataAttribute() { - var before = @" -using Xunit; - -public class TestClass { - [Fact] - [InlineData(1)] - public void [|TestMethod|](int x) { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; - var after = @" -using Xunit; + public class TestClass { + [Fact] + [InlineData(1)] + public void [|TestMethod|](int x) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Fact] - public void TestMethod(int x) { } -}"; + public class TestClass { + [Fact] + public void TestMethod(int x) { } + } + """; await Verify.VerifyCodeFix(before, after, FactMethodShouldNotHaveTestDataFixer.Key_RemoveDataAttributes); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/InlineDataMustMatchTheoryParameters_ExtraValueFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/InlineDataMustMatchTheoryParameters_ExtraValueFixerTests.cs index d210cb78..2202e113 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/InlineDataMustMatchTheoryParameters_ExtraValueFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/InlineDataMustMatchTheoryParameters_ExtraValueFixerTests.cs @@ -8,23 +8,24 @@ public class InlineDataMustMatchTheoryParameters_ExtraValueFixerTests [Fact] public async Task RemovesUnusedData() { - var before = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(42, {|xUnit1011:21.12|})] - public void TestMethod(int a) { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; - var after = @" -using Xunit; + public class TestClass { + [Theory] + [InlineData(42, {|xUnit1011:21.12|})] + public void TestMethod(int a) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Theory] - [InlineData(42)] - public void TestMethod(int a) { } -}"; + public class TestClass { + [Theory] + [InlineData(42)] + public void TestMethod(int a) { } + } + """; await Verify.VerifyCodeFix(before, after, InlineDataMustMatchTheoryParameters_ExtraValueFixer.Key_RemoveExtraDataValue); } @@ -36,23 +37,24 @@ public async Task AddsParameterWithCorrectType( string value, string valueType) { - var before = $@" -using Xunit; + var before = string.Format(/* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Theory] - [InlineData(42, {{|xUnit1011:{value}|}})] - public void TestMethod(int a) {{ }} -}}"; + public class TestClass {{ + [Theory] + [InlineData(42, {{|xUnit1011:{0}|}})] + public void TestMethod(int a) {{ }} + }} + """, value); + var after = string.Format(/* lang=c#-test */ """ + using Xunit; - var after = $@" -using Xunit; - -public class TestClass {{ - [Theory] - [InlineData(42, {value})] - public void TestMethod(int a, {valueType} p) {{ }} -}}"; + public class TestClass {{ + [Theory] + [InlineData(42, {0})] + public void TestMethod(int a, {1} p) {{ }} + }} + """, value, valueType); await Verify.VerifyCodeFix(before, after, InlineDataMustMatchTheoryParameters_ExtraValueFixer.Key_AddTheoryParameter); } @@ -60,23 +62,24 @@ public void TestMethod(int a, {valueType} p) {{ }} [Fact] public async Task AddsParameterWithNonConflictingName() { - var before = $@" -using Xunit; + var before = /* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Theory] - [InlineData(42, {{|xUnit1011:21.12|}})] - public void TestMethod(int p) {{ }} -}}"; - - var after = $@" -using Xunit; + public class TestClass { + [Theory] + [InlineData(42, {|xUnit1011:21.12|})] + public void TestMethod(int p) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Theory] - [InlineData(42, 21.12)] - public void TestMethod(int p, double p_2) {{ }} -}}"; + public class TestClass { + [Theory] + [InlineData(42, 21.12)] + public void TestMethod(int p, double p_2) { } + } + """; await Verify.VerifyCodeFix(before, after, InlineDataMustMatchTheoryParameters_ExtraValueFixer.Key_AddTheoryParameter); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/InlineDataMustMatchTheoryParameters_NullShouldNotBeUsedForIncompatibleParameterFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/InlineDataMustMatchTheoryParameters_NullShouldNotBeUsedForIncompatibleParameterFixerTests.cs index 7525c4f3..7b3620cf 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/InlineDataMustMatchTheoryParameters_NullShouldNotBeUsedForIncompatibleParameterFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/InlineDataMustMatchTheoryParameters_NullShouldNotBeUsedForIncompatibleParameterFixerTests.cs @@ -9,23 +9,24 @@ public class InlineDataMustMatchTheoryParameters_NullShouldNotBeUsedForIncompati [Fact] public async Task MakesParameterNullable() { - var before = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(42, {|xUnit1012:null|})] - public void TestMethod(int a, int b) { } -}"; - - var after = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(42, null)] - public void TestMethod(int a, int? b) { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + [InlineData(42, {|xUnit1012:null|})] + public void TestMethod(int a, int b) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + [InlineData(42, null)] + public void TestMethod(int a, int? b) { } + } + """; await Verify.VerifyCodeFix(before, after, InlineDataMustMatchTheoryParameters_NullShouldNotBeUsedForIncompatibleParameterFixer.Key_MakeParameterNullable); } @@ -33,27 +34,28 @@ public void TestMethod(int a, int? b) { } [Fact] public async Task MakesReferenceParameterNullable() { - var before = @" -using Xunit; - -#nullable enable -public class TestClass { - [Theory] - [InlineData(42, {|xUnit1012:null|})] - public void TestMethod(int a, object b) { } -#nullable restore -}"; - - var after = @" -using Xunit; - -#nullable enable -public class TestClass { - [Theory] - [InlineData(42, null)] - public void TestMethod(int a, object? b) { } -#nullable restore -}"; + var before = /* lang=c#-test */ """ + #nullable enable + + using Xunit; + + public class TestClass { + [Theory] + [InlineData(42, {|xUnit1012:null|})] + public void TestMethod(int a, object b) { } + } + """; + var after = /* lang=c#-test */ """ + #nullable enable + + using Xunit; + + public class TestClass { + [Theory] + [InlineData(42, null)] + public void TestMethod(int a, object? b) { } + } + """; await Verify.VerifyCodeFix(LanguageVersion.CSharp8, before, after, InlineDataMustMatchTheoryParameters_NullShouldNotBeUsedForIncompatibleParameterFixer.Key_MakeParameterNullable); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/InlineDataMustMatchTheoryParameters_TooFewValuesFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/InlineDataMustMatchTheoryParameters_TooFewValuesFixerTests.cs index 328bed28..a4b731c7 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/InlineDataMustMatchTheoryParameters_TooFewValuesFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/InlineDataMustMatchTheoryParameters_TooFewValuesFixerTests.cs @@ -18,27 +18,28 @@ public async Task MakesParameterNullable( string valueType, string defaultValue) { - var before = $@" -using Xunit; - -public enum Color {{ Red, Green, Blue }} + var before = string.Format(/* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Theory] - [{{|xUnit1009:InlineData|}}] - public void TestMethod({valueType} p) {{ }} -}}"; + public enum Color {{ Red, Green, Blue }} - var after = $@" -using Xunit; + public class TestClass {{ + [Theory] + [{{|xUnit1009:InlineData|}}] + public void TestMethod({0} p) {{ }} + }} + """, valueType); + var after = string.Format(/* lang=c#-test */ """ + using Xunit; -public enum Color {{ Red, Green, Blue }} + public enum Color {{ Red, Green, Blue }} -public class TestClass {{ - [Theory] - [InlineData({defaultValue})] - public void TestMethod({valueType} p) {{ }} -}}"; + public class TestClass {{ + [Theory] + [InlineData({1})] + public void TestMethod({0} p) {{ }} + }} + """, valueType, defaultValue); await Verify.VerifyCodeFix(before, after, InlineDataMustMatchTheoryParameters_TooFewValuesFixer.Key_AddDefaultValues); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/InlineDataShouldBeUniqueWithinTheoryFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/InlineDataShouldBeUniqueWithinTheoryFixerTests.cs index 7adbd740..66abda92 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/InlineDataShouldBeUniqueWithinTheoryFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/InlineDataShouldBeUniqueWithinTheoryFixerTests.cs @@ -8,24 +8,25 @@ public class InlineDataShouldBeUniqueWithinTheoryFixerTests [Fact] public async Task RemovesDuplicateData() { - var before = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(1)] - [[|InlineData(1)|]] - public void TestMethod(int x) { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; - var after = @" -using Xunit; + public class TestClass { + [Theory] + [InlineData(1)] + [[|InlineData(1)|]] + public void TestMethod(int x) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Theory] - [InlineData(1)] - public void TestMethod(int x) { } -}"; + public class TestClass { + [Theory] + [InlineData(1)] + public void TestMethod(int x) { } + } + """; await Verify.VerifyCodeFix(before, after, InlineDataShouldBeUniqueWithinTheoryFixer.Key_RemoveDuplicateInlineData); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/LocalFunctionsCannotBeTestFunctionsFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/LocalFunctionsCannotBeTestFunctionsFixerTests.cs index 63637751..9de0dd50 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/LocalFunctionsCannotBeTestFunctionsFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/LocalFunctionsCannotBeTestFunctionsFixerTests.cs @@ -11,25 +11,27 @@ public class LocalFunctionsCannotBeTestFunctionsFixerTests [InlineData("Theory")] public async Task LocalFunctionsCannotHaveTestAttributes(string attribute) { - var before = $@" -using Xunit; + var before = string.Format(/* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - public void Method() {{ - [[|{attribute}|]] - void LocalFunction() {{ - }} - }} -}}"; - var after = @" -using Xunit; + public class TestClass {{ + public void Method() {{ + [[|{0}|]] + void LocalFunction() {{ + }} + }} + }} + """, attribute); + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - public void Method() { - void LocalFunction() { - } - } -}"; + public class TestClass { + public void Method() { + void LocalFunction() { + } + } + } + """; await Verify.VerifyCodeFix(LanguageVersion.CSharp9, before, after, LocalFunctionsCannotBeTestFunctionsFixer.Key_RemoveAttribute); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_ExtraValueFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_ExtraValueFixerTests.cs index 5fbdc172..617c1ceb 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_ExtraValueFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_ExtraValueFixerTests.cs @@ -8,27 +8,28 @@ public class MemberDataShouldReferenceValidMember_ExtraValueFixerTests [Fact] public async Task RemovesUnusedData() { - var before = @" -using Xunit; - -public class TestClass { - public static TheoryData TestData(int n) => new TheoryData(); + var before = /* lang=c#-test */ """ + using Xunit; - [Theory] - [MemberData(nameof(TestData), 42, {|xUnit1036:21.12|})] - public void TestMethod(int a) { } -}"; + public class TestClass { + public static TheoryData TestData(int n) => new TheoryData(); - var after = @" -using Xunit; + [Theory] + [MemberData(nameof(TestData), 42, {|xUnit1036:21.12|})] + public void TestMethod(int a) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - public static TheoryData TestData(int n) => new TheoryData(); + public class TestClass { + public static TheoryData TestData(int n) => new TheoryData(); - [Theory] - [MemberData(nameof(TestData), 42)] - public void TestMethod(int a) { } -}"; + [Theory] + [MemberData(nameof(TestData), 42)] + public void TestMethod(int a) { } + } + """; await Verify.VerifyCodeFix(before, after, MemberDataShouldReferenceValidMember_ExtraValueFixer.Key_RemoveExtraDataValue); } @@ -40,27 +41,28 @@ public async Task AddsParameterWithCorrectType( string value, string valueType) { - var before = $@" -using Xunit; + var before = string.Format(/* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - public static TheoryData TestData(int n) => new TheoryData(); + public class TestClass {{ + public static TheoryData TestData(int n) => new TheoryData(); - [Theory] - [MemberData(nameof(TestData), 42, {{|xUnit1036:{value}|}})] - public void TestMethod(int a) {{ }} -}}"; + [Theory] + [MemberData(nameof(TestData), 42, {{|xUnit1036:{0}|}})] + public void TestMethod(int a) {{ }} + }} + """, value); + var after = string.Format(/* lang=c#-test */ """ + using Xunit; - var after = $@" -using Xunit; - -public class TestClass {{ - public static TheoryData TestData(int n, {valueType} p) => new TheoryData(); + public class TestClass {{ + public static TheoryData TestData(int n, {1} p) => new TheoryData(); - [Theory] - [MemberData(nameof(TestData), 42, {value})] - public void TestMethod(int a) {{ }} -}}"; + [Theory] + [MemberData(nameof(TestData), 42, {0})] + public void TestMethod(int a) {{ }} + }} + """, value, valueType); await Verify.VerifyCodeFix(before, after, MemberDataShouldReferenceValidMember_ExtraValueFixer.Key_AddMethodParameter); } @@ -68,27 +70,28 @@ public void TestMethod(int a) {{ }} [Fact] public async Task AddsParameterWithNonConflictingName() { - var before = $@" -using Xunit; - -public class TestClass {{ - public static TheoryData TestData(int p) => new TheoryData(); - - [Theory] - [MemberData(nameof(TestData), 42, {{|xUnit1036:21.12|}})] - public void TestMethod(int n) {{ }} -}}"; - - var after = $@" -using Xunit; - -public class TestClass {{ - public static TheoryData TestData(int p, double p_2) => new TheoryData(); - - [Theory] - [MemberData(nameof(TestData), 42, 21.12)] - public void TestMethod(int n) {{ }} -}}"; + var before = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + public static TheoryData TestData(int p) => new TheoryData(); + + [Theory] + [MemberData(nameof(TestData), 42, {|xUnit1036:21.12|})] + public void TestMethod(int n) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + public static TheoryData TestData(int p, double p_2) => new TheoryData(); + + [Theory] + [MemberData(nameof(TestData), 42, 21.12)] + public void TestMethod(int n) { } + } + """; await Verify.VerifyCodeFix(before, after, MemberDataShouldReferenceValidMember_ExtraValueFixer.Key_AddMethodParameter); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_NameOfFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_NameOfFixerTests.cs index 604c6b3f..08bb389b 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_NameOfFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_NameOfFixerTests.cs @@ -8,31 +8,32 @@ public class MemberDataShouldReferenceValidMember_NameOfFixerTests [Fact] public async Task ConvertStringToNameOf() { - var before = @" -using System; -using System.Collections.Generic; -using Xunit; - -public class TestClass { - public static TheoryData DataSource; + var before = /* lang=c#-test */ """ + using System; + using System.Collections.Generic; + using Xunit; - [Theory] - [MemberData({|xUnit1014:""DataSource""|})] - public void TestMethod(int a) { } -}"; + public class TestClass { + public static TheoryData DataSource; - var after = @" -using System; -using System.Collections.Generic; -using Xunit; + [Theory] + [MemberData({|xUnit1014:"DataSource"|})] + public void TestMethod(int a) { } + } + """; + var after = /* lang=c#-test */ """ + using System; + using System.Collections.Generic; + using Xunit; -public class TestClass { - public static TheoryData DataSource; + public class TestClass { + public static TheoryData DataSource; - [Theory] - [MemberData(nameof(DataSource))] - public void TestMethod(int a) { } -}"; + [Theory] + [MemberData(nameof(DataSource))] + public void TestMethod(int a) { } + } + """; await Verify.VerifyCodeFix(before, after, MemberDataShouldReferenceValidMember_NameOfFixer.Key_UseNameof); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_NullShouldNotBeUsedForIncompatibleParameterFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_NullShouldNotBeUsedForIncompatibleParameterFixerTests.cs index c4afdda4..e66d5e68 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_NullShouldNotBeUsedForIncompatibleParameterFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_NullShouldNotBeUsedForIncompatibleParameterFixerTests.cs @@ -9,27 +9,28 @@ public class MemberDataShouldReferenceValidMember_NullShouldNotBeUsedForIncompat [Fact] public async Task MakesParameterNullable() { - var before = @" -using Xunit; - -public class TestClass { - public static TheoryData TestData(int n, int k) => new TheoryData(); + var before = /* lang=c#-test */ """ + using Xunit; - [Theory] - [MemberData(nameof(TestData), 42, {|xUnit1034:null|})] - public void TestMethod(int a) { } -}"; + public class TestClass { + public static TheoryData TestData(int n, int k) => new TheoryData(); - var after = @" -using Xunit; + [Theory] + [MemberData(nameof(TestData), 42, {|xUnit1034:null|})] + public void TestMethod(int a) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - public static TheoryData TestData(int n, int? k) => new TheoryData(); + public class TestClass { + public static TheoryData TestData(int n, int? k) => new TheoryData(); - [Theory] - [MemberData(nameof(TestData), 42, null)] - public void TestMethod(int a) { } -}"; + [Theory] + [MemberData(nameof(TestData), 42, null)] + public void TestMethod(int a) { } + } + """; await Verify.VerifyCodeFix(before, after, MemberDataShouldReferenceValidMember_NullShouldNotBeUsedForIncompatibleParameterFixer.Key_MakeParameterNullable); } @@ -37,31 +38,32 @@ public void TestMethod(int a) { } [Fact] public async Task MakesReferenceParameterNullable() { - var before = @" -#nullable enable + var before = /* lang=c#-test */ """ + #nullable enable -using Xunit; - -public class TestClass { - public static TheoryData TestData(int n, string k) => new TheoryData { n }; + using Xunit; - [Theory] - [MemberData(nameof(TestData), 42, {|xUnit1034:null|})] - public void TestMethod(int a) { } -}"; + public class TestClass { + public static TheoryData TestData(int n, string k) => new TheoryData { n }; - var after = @" -#nullable enable + [Theory] + [MemberData(nameof(TestData), 42, {|xUnit1034:null|})] + public void TestMethod(int a) { } + } + """; + var after = /* lang=c#-test */ """ + #nullable enable -using Xunit; + using Xunit; -public class TestClass { - public static TheoryData TestData(int n, string? k) => new TheoryData { n }; + public class TestClass { + public static TheoryData TestData(int n, string? k) => new TheoryData { n }; - [Theory] - [MemberData(nameof(TestData), 42, null)] - public void TestMethod(int a) { } -}"; + [Theory] + [MemberData(nameof(TestData), 42, null)] + public void TestMethod(int a) { } + } + """; await Verify.VerifyCodeFix(LanguageVersion.CSharp8, before, after, MemberDataShouldReferenceValidMember_NullShouldNotBeUsedForIncompatibleParameterFixer.Key_MakeParameterNullable); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_ParamsForNonMethodFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_ParamsForNonMethodFixerTests.cs index 04a60889..3f137ad8 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_ParamsForNonMethodFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_ParamsForNonMethodFixerTests.cs @@ -8,33 +8,34 @@ public class MemberDataShouldReferenceValidMember_ParamsForNonMethodFixerTests [Fact] public async Task RemovesParametersFromNonMethodMemberData() { - var before = @" -using System; -using System.Collections.Generic; -using Xunit; + var before = /* lang=c#-test */ """ + using System; + using System.Collections.Generic; + using Xunit; -public class TestClass -{ - public static TheoryData DataSource = new TheoryData(); + public class TestClass + { + public static TheoryData DataSource = new TheoryData(); - [Theory] - [MemberData(nameof(DataSource), {|xUnit1021:""abc"", 123|})] - public void TestMethod(int a) { } -}"; + [Theory] + [MemberData(nameof(DataSource), {|xUnit1021:"abc", 123|})] + public void TestMethod(int a) { } + } + """; + var after = /* lang=c#-test */ """ + using System; + using System.Collections.Generic; + using Xunit; - var after = @" -using System; -using System.Collections.Generic; -using Xunit; - -public class TestClass -{ - public static TheoryData DataSource = new TheoryData(); + public class TestClass + { + public static TheoryData DataSource = new TheoryData(); - [Theory] - [MemberData(nameof(DataSource))] - public void TestMethod(int a) { } -}"; + [Theory] + [MemberData(nameof(DataSource))] + public void TestMethod(int a) { } + } + """; await Verify.VerifyCodeFix(before, after, MemberDataShouldReferenceValidMember_ParamsForNonMethodFixer.Key_RemoveArgumentsFromMemberData); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_ReturnTypeFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_ReturnTypeFixerTests.cs index 383b9ca4..244e6ddd 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_ReturnTypeFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_ReturnTypeFixerTests.cs @@ -8,29 +8,30 @@ public class MemberDataShouldReferenceValidMember_ReturnTypeFixerTests [Fact] public async Task ChangesReturnType_ObjectArray() { - var before = @" -using System.Collections.Generic; -using Xunit; - -public class TestClass { - public static IEnumerable Data => null; + var before = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; - [Theory] - [{|xUnit1019:MemberData(nameof(Data))|}] - public void TestMethod(int a) { } -}"; + public class TestClass { + public static IEnumerable Data => null; - var after = @" -using System.Collections.Generic; -using Xunit; + [Theory] + [{|xUnit1019:MemberData(nameof(Data))|}] + public void TestMethod(int a) { } + } + """; + var after = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass { - public static IEnumerable Data => null; + public class TestClass { + public static IEnumerable Data => null; - [Theory] - [{|xUnit1042:MemberData(nameof(Data))|}] - public void TestMethod(int a) { } -}"; + [Theory] + [{|xUnit1042:MemberData(nameof(Data))|}] + public void TestMethod(int a) { } + } + """; await Verify.VerifyCodeFix(before, after, MemberDataShouldReferenceValidMember_ReturnTypeFixer.Key_ChangeMemberReturnType_ObjectArray); } @@ -38,29 +39,30 @@ public void TestMethod(int a) { } [Fact] public async Task ChangesReturnType_TheoryDataRow() { - var before = @" -using System.Collections.Generic; -using Xunit; - -public class TestClass { - public static IEnumerable Data => null; + var before = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; - [Theory] - [{|xUnit1019:MemberData(nameof(Data))|}] - public void TestMethod(int a) { } -}"; + public class TestClass { + public static IEnumerable Data => null; - var after = @" -using System.Collections.Generic; -using Xunit; + [Theory] + [{|xUnit1019:MemberData(nameof(Data))|}] + public void TestMethod(int a) { } + } + """; + var after = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass { - public static IEnumerable Data => null; + public class TestClass { + public static IEnumerable Data => null; - [Theory] - [{|xUnit1042:MemberData(nameof(Data))|}] - public void TestMethod(int a) { } -}"; + [Theory] + [{|xUnit1042:MemberData(nameof(Data))|}] + public void TestMethod(int a) { } + } + """; await Verify.VerifyCodeFixV3(before, after, MemberDataShouldReferenceValidMember_ReturnTypeFixer.Key_ChangeMemberReturnType_ITheoryDataRow); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_StaticFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_StaticFixerTests.cs index 1a2c5ca5..f85ab4d3 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_StaticFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_StaticFixerTests.cs @@ -8,29 +8,30 @@ public class MemberDataShouldReferenceValidMember_StaticFixerTests [Fact] public async Task MarksDataMemberAsStatic() { - var before = @" -using System.Collections.Generic; -using Xunit; - -public class TestClass { - public TheoryData TestData => null; + var before = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; - [Theory] - [{|xUnit1017:MemberData(nameof(TestData))|}] - public void TestMethod(int x) { } -}"; + public class TestClass { + public TheoryData TestData => null; - var after = @" -using System.Collections.Generic; -using Xunit; + [Theory] + [{|xUnit1017:MemberData(nameof(TestData))|}] + public void TestMethod(int x) { } + } + """; + var after = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass { - public static TheoryData TestData => null; + public class TestClass { + public static TheoryData TestData => null; - [Theory] - [MemberData(nameof(TestData))] - public void TestMethod(int x) { } -}"; + [Theory] + [MemberData(nameof(TestData))] + public void TestMethod(int x) { } + } + """; await Verify.VerifyCodeFix(before, after, MemberDataShouldReferenceValidMember_StaticFixer.Key_MakeMemberStatic); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_VisibilityFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_VisibilityFixerTests.cs index 43d5916e..e183daff 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_VisibilityFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/MemberDataShouldReferenceValidMember_VisibilityFixerTests.cs @@ -11,29 +11,30 @@ public class MemberDataShouldReferenceValidMember_VisibilityFixerTests [InlineData("internal ")] public async Task SetsPublicModifier(string badModifier) { - var before = $@" -using System.Collections.Generic; -using Xunit; - -public class TestClass {{ - {badModifier}static TheoryData TestData => null; + var before = string.Format(/* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; - [Theory] - [{{|xUnit1016:MemberData(nameof(TestData))|}}] - public void TestMethod(int x) {{ }} -}}"; + public class TestClass {{ + {0}static TheoryData TestData => null; - var after = @" -using System.Collections.Generic; -using Xunit; + [Theory] + [{{|xUnit1016:MemberData(nameof(TestData))|}}] + public void TestMethod(int x) {{ }} + }} + """, badModifier); + var after = /* lang=c#-test */ """ + using System.Collections.Generic; + using Xunit; -public class TestClass { - public static TheoryData TestData => null; + public class TestClass { + public static TheoryData TestData => null; - [Theory] - [MemberData(nameof(TestData))] - public void TestMethod(int x) { } -}"; + [Theory] + [MemberData(nameof(TestData))] + public void TestMethod(int x) { } + } + """; await Verify.VerifyCodeFix(before, after, MemberDataShouldReferenceValidMember_VisibilityFixer.Key_MakeMemberPublic); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/PublicMethodShouldBeMarkedAsTestFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/PublicMethodShouldBeMarkedAsTestFixerTests.cs index 4cac3900..97ba1c88 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/PublicMethodShouldBeMarkedAsTestFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/PublicMethodShouldBeMarkedAsTestFixerTests.cs @@ -5,38 +5,41 @@ public class PublicMethodShouldBeMarkedAsTestFixerTests { - const string beforeNoParams = @" -using Xunit; + const string beforeNoParams = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Fact] - public void TestMethod() { } + public class TestClass { + [Fact] + public void TestMethod() { } - public void [|TestMethod2|]() { } -}"; - const string beforeWithParams = @" -using Xunit; + public void [|TestMethod2|]() { } + } + """; + const string beforeWithParams = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Fact] - public void TestMethod() { } + public class TestClass { + [Fact] + public void TestMethod() { } - public void [|TestMethod2|](int _) { } -}"; + public void [|TestMethod2|](int _) { } + } + """; [Fact] public async Task AddsFactToPublicMethodWithoutParameters() { - var after = @" -using Xunit; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Fact] - public void TestMethod() { } + public class TestClass { + [Fact] + public void TestMethod() { } - [Fact] - public void TestMethod2() { } -}"; + [Fact] + public void TestMethod2() { } + } + """; await Verify.VerifyCodeFix(beforeNoParams, after, PublicMethodShouldBeMarkedAsTestFixer.Key_ConvertToFact); } @@ -44,16 +47,17 @@ public void TestMethod2() { } [Fact] public async Task AddsFactToPublicMethodWithParameters() { - var after = @" -using Xunit; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Fact] - public void TestMethod() { } + public class TestClass { + [Fact] + public void TestMethod() { } - [Theory] - public void TestMethod2(int _) { } -}"; + [Theory] + public void TestMethod2(int _) { } + } + """; await Verify.VerifyCodeFix(beforeWithParams, after, PublicMethodShouldBeMarkedAsTestFixer.Key_ConvertToTheory); } @@ -63,7 +67,7 @@ public void TestMethod2(int _) { } [InlineData(beforeWithParams)] public async Task MarksMethodAsInternal(string before) { - var after = before.Replace("public void [|TestMethod2|]", "internal void TestMethod2"); + var after = before.Replace(/* lang=c#-test */ "public void [|TestMethod2|]", /* lang=c#-test */ "internal void TestMethod2"); await Verify.VerifyCodeFix(before, after, PublicMethodShouldBeMarkedAsTestFixer.Key_MakeMethodInternal); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/RemoveMethodParameterFixTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/RemoveMethodParameterFixTests.cs index 5598d8de..35b5b8ae 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/RemoveMethodParameterFixTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/RemoveMethodParameterFixTests.cs @@ -12,23 +12,24 @@ public class RemoveMethodParameterFixTests [Fact] public async Task X1022_RemoveParamsArray() { - var before = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(1, 2, 3)] - public void TestMethod([|params int[] values|]) { } -}"; - - var after = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(1, 2, 3)] - public void TestMethod() { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + [InlineData(1, 2, 3)] + public void TestMethod([|params int[] values|]) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + [InlineData(1, 2, 3)] + public void TestMethod() { } + } + """; await Verify_X1022.VerifyCodeFix(before, after, RemoveMethodParameterFix.Key_RemoveParameter); } @@ -36,23 +37,24 @@ public void TestMethod() { } [Fact] public async Task X1026_RemovesUnusedParameter() { - var before = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(1)] - public void TestMethod(int [|arg|]) { } -}"; - - var after = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(1)] - public void TestMethod() { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + [InlineData(1)] + public void TestMethod(int [|arg|]) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + [InlineData(1)] + public void TestMethod() { } + } + """; await Verify_X1026.VerifyCodeFix(before, after, RemoveMethodParameterFix.Key_RemoveParameter); } @@ -60,48 +62,32 @@ public void TestMethod() { } [Fact] public async Task X1026_DoesNotCrashWhenParameterDeclarationIsMissing() { - var before = @" -using Xunit; + var before = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + [InlineData(1, 1)] + public void Test1(int x, {|CS1001:{|CS1031:{|xUnit1026:|})|}|} + { + var x1 = x; + } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Theory] + [InlineData(1, 1)] + public void Test1(int x, {|CS1001:{|CS1031:{|xUnit1026:|})|}|} + { + var x1 = x; + } + } + """; -public class TestClass { - [Theory] - [InlineData(1, 1)] - public void Test1(int x, ) - { - var x1 = x; - } -}"; - - var after = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(1, 1)] - public void Test1(int x, ) - { - var x1 = x; - } -}"; - - var expected = new[] - { - Verify_X1026 - .Diagnostic() - .WithSpan(7, 27, 7, 27) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Test1", "TestClass", ""), - Verify_X1026 - .CompilerError("CS1001") - .WithSpan(7, 27, 7, 28) - .WithMessage("Identifier expected"), - Verify_X1026 - .CompilerError("CS1031") - .WithSpan(7, 27, 7, 28) - .WithMessage("Type expected"), - }; - - await Verify_X1026.VerifyCodeFix(before, after, RemoveMethodParameterFix.Key_RemoveParameter, expected); + await Verify_X1026.VerifyCodeFix(before, after, RemoveMethodParameterFix.Key_RemoveParameter); } internal class Analyzer_X1022 : TheoryMethodCannotHaveParamsArray diff --git a/src/xunit.analyzers.tests/Fixes/X1000/TestClassCannotBeNestedInGenericClassFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/TestClassCannotBeNestedInGenericClassFixerTests.cs index e2eb4e48..6c317b45 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/TestClassCannotBeNestedInGenericClassFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/TestClassCannotBeNestedInGenericClassFixerTests.cs @@ -8,25 +8,27 @@ public class TestClassCannotBeNestedInGenericClassFixerTests [Fact] public async Task MovesTestClassOutOfGenericParent() { - const string before = @" -public abstract class OpenGenericType -{ - public class [|NestedTestClass|] - { - [Xunit.Fact] - public void TestMethod() { } - } -}"; - const string after = @" -public abstract class OpenGenericType -{ -} + const string before = /* lang=c#-test */ """ + public abstract class OpenGenericType + { + public class [|NestedTestClass|] + { + [Xunit.Fact] + public void TestMethod() { } + } + } + """; + const string after = /* lang=c#-test */ """ + public abstract class OpenGenericType + { + } -public class NestedTestClass -{ - [Xunit.Fact] - public void TestMethod() { } -}"; + public class NestedTestClass + { + [Xunit.Fact] + public void TestMethod() { } + } + """; await Verify.VerifyCodeFix(before, after, TestClassCannotBeNestedInGenericClassFixer.Key_ExtractTestClass); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/TestClassMustBePublicFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/TestClassMustBePublicFixerTests.cs index 6fa3ed18..c553ad4a 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/TestClassMustBePublicFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/TestClassMustBePublicFixerTests.cs @@ -7,20 +7,21 @@ public class TestClassMustBePublicFixerTests { [Theory] [InlineData("")] - [InlineData("internal")] + [InlineData("internal ")] public async Task MakesClassPublic(string nonPublicAccessModifier) { - var before = $@" -{nonPublicAccessModifier} class [|TestClass|] {{ - [Xunit.Fact] - public void TestMethod() {{ }} -}}"; - - var after = @" -public class TestClass { - [Xunit.Fact] - public void TestMethod() { } -}"; + var before = string.Format(/* lang=c#-test */ """ + {0}class [|TestClass|] {{ + [Xunit.Fact] + public void TestMethod() {{ }} + }} + """, nonPublicAccessModifier); + var after = /* lang=c#-test */ """ + public class TestClass { + [Xunit.Fact] + public void TestMethod() { } + } + """; await Verify.VerifyCodeFix(before, after, TestClassMustBePublicFixer.Key_MakeTestClassPublic); } @@ -28,27 +29,28 @@ public void TestMethod() { } [Fact] public async Task ForPartialClassDeclarations_MakesSingleDeclarationPublic() { - var before = @" -partial class [|TestClass|] { - [Xunit.Fact] - public void TestMethod1() {} -} - -partial class TestClass { - [Xunit.Fact] - public void TestMethod2() {} -}"; - - var after = @" -public partial class TestClass { - [Xunit.Fact] - public void TestMethod1() {} -} - -partial class TestClass { - [Xunit.Fact] - public void TestMethod2() {} -}"; + var before = /* lang=c#-test */ """ + partial class [|TestClass|] { + [Xunit.Fact] + public void TestMethod1() {} + } + + partial class TestClass { + [Xunit.Fact] + public void TestMethod2() {} + } + """; + var after = /* lang=c#-test */ """ + public partial class TestClass { + [Xunit.Fact] + public void TestMethod1() {} + } + + partial class TestClass { + [Xunit.Fact] + public void TestMethod2() {} + } + """; await Verify.VerifyCodeFix(before, after, TestClassMustBePublicFixer.Key_MakeTestClassPublic); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/TestClassShouldHaveTFixtureArgumentFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/TestClassShouldHaveTFixtureArgumentFixerTests.cs index 2f1aef7c..3e8ee87a 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/TestClassShouldHaveTFixtureArgumentFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/TestClassShouldHaveTFixtureArgumentFixerTests.cs @@ -8,28 +8,29 @@ public class TestClassShouldHaveTFixtureArgumentFixerTests [Fact] public async Task ForClassWithoutField_GenerateFieldAndConstructor() { - var before = @" -public class FixtureData { } + var before = /* lang=c#-test */ """ + public class FixtureData { } -public class [|TestClass|]: Xunit.IClassFixture { - [Xunit.Fact] - public void TestMethod() { } -}"; + public class [|TestClass|]: Xunit.IClassFixture { + [Xunit.Fact] + public void TestMethod() { } + } + """; + var after = /* lang=c#-test */ """ + public class FixtureData { } - var after = @" -public class FixtureData { } + public class TestClass: Xunit.IClassFixture { + private readonly FixtureData _fixtureData; -public class [|TestClass|]: Xunit.IClassFixture { - private readonly FixtureData _fixtureData; + public TestClass(FixtureData fixtureData) + { + _fixtureData = fixtureData; + } - public TestClass(FixtureData fixtureData) - { - _fixtureData = fixtureData; - } - - [Xunit.Fact] - public void TestMethod() { } -}"; + [Xunit.Fact] + public void TestMethod() { } + } + """; await Verify.VerifyCodeFix(before, after, TestClassShouldHaveTFixtureArgumentFixer.Key_GenerateConstructor); } @@ -37,28 +38,29 @@ public void TestMethod() { } [Fact] public async Task ForGenericTFixture_GenerateFieldAndConstructor() { - var before = @" -public class FixtureData { } - -public class [|TestClass|]: Xunit.IClassFixture> { - [Xunit.Fact] - public void TestMethod() { } -}"; + var before = /* lang=c#-test */ """ + public class FixtureData { } - var after = @" -public class FixtureData { } + public class [|TestClass|]: Xunit.IClassFixture> { + [Xunit.Fact] + public void TestMethod() { } + } + """; + var after = /* lang=c#-test */ """ + public class FixtureData { } -public class [|TestClass|]: Xunit.IClassFixture> { - private readonly FixtureData _fixtureData; + public class TestClass: Xunit.IClassFixture> { + private readonly FixtureData _fixtureData; - public TestClass(FixtureData fixtureData) - { - _fixtureData = fixtureData; - } + public TestClass(FixtureData fixtureData) + { + _fixtureData = fixtureData; + } - [Xunit.Fact] - public void TestMethod() { } -}"; + [Xunit.Fact] + public void TestMethod() { } + } + """; await Verify.VerifyCodeFix(before, after, TestClassShouldHaveTFixtureArgumentFixer.Key_GenerateConstructor); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/TestMethodMustNotHaveMultipleFactAttributesFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/TestMethodMustNotHaveMultipleFactAttributesFixerTests.cs index b470f2c7..f8c97373 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/TestMethodMustNotHaveMultipleFactAttributesFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/TestMethodMustNotHaveMultipleFactAttributesFixerTests.cs @@ -8,26 +8,27 @@ public class TestMethodMustNotHaveMultipleFactAttributesFixerTests [Fact] public async Task RemovesSecondAttribute() { - var before = $@" -using Xunit; - -public class FactDerivedAttribute : FactAttribute {{ }} + var before = /* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Fact] - [{{|CS0579:Fact|}}] - public void [|TestMethod|]() {{ }} -}}"; + public class FactDerivedAttribute : FactAttribute { } - var after = @" -using Xunit; + public class TestClass { + [Fact] + [{|CS0579:Fact|}] + public void [|TestMethod|]() { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; -public class FactDerivedAttribute : FactAttribute { } + public class FactDerivedAttribute : FactAttribute { } -public class TestClass { - [Fact] - public void TestMethod() { } -}"; + public class TestClass { + [Fact] + public void TestMethod() { } + } + """; await Verify.VerifyCodeFix(before, after, TestMethodMustNotHaveMultipleFactAttributesFixer.Key_KeepAttribute("Fact")); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/TestMethodShouldNotBeSkippedFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/TestMethodShouldNotBeSkippedFixerTests.cs index a8a48925..5e52ed53 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/TestMethodShouldNotBeSkippedFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/TestMethodShouldNotBeSkippedFixerTests.cs @@ -8,21 +8,22 @@ public class TestMethodShouldNotBeSkippedFixerTests [Fact] public async Task RemovesSkipProperty() { - var before = @" -using Xunit; - -public class TestClass { - [Fact([|Skip = ""Don't run this""|])] - public void TestMethod() { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; - var after = @" -using Xunit; + public class TestClass { + [Fact([|Skip = "Don't run this"|])] + public void TestMethod() { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Fact] - public void TestMethod() { } -}"; + public class TestClass { + [Fact] + public void TestMethod() { } + } + """; await Verify.VerifyCodeFix(before, after, TestMethodShouldNotBeSkippedFixer.Key_RemoveSkipArgument); } diff --git a/src/xunit.analyzers.tests/Fixes/X1000/TheoryMethodCannotHaveDefaultParameterFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X1000/TheoryMethodCannotHaveDefaultParameterFixerTests.cs index 74b3ecb5..4423d6c5 100644 --- a/src/xunit.analyzers.tests/Fixes/X1000/TheoryMethodCannotHaveDefaultParameterFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X1000/TheoryMethodCannotHaveDefaultParameterFixerTests.cs @@ -11,23 +11,24 @@ public class TheoryMethodCannotHaveDefaultParameterFixerTests [Fact] public async Task RemovesDefaultParameterValue() { - var before = @" -using Xunit; - -public class TestClass { - [Theory] - [InlineData(1)] - public void TestMethod(int _ [|= 0|]) { } -}"; + var before = /* lang=c#-test */ """ + using Xunit; - var after = @" -using Xunit; + public class TestClass { + [Theory] + [InlineData(1)] + public void TestMethod(int _ [|= 0|]) { } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Theory] - [InlineData(1)] - public void TestMethod(int _) { } -}"; + public class TestClass { + [Theory] + [InlineData(1)] + public void TestMethod(int _) { } + } + """; await Verify_v2_Pre220.VerifyCodeFix(before, after, TheoryMethodCannotHaveDefaultParameterFixer.Key_RemoveParameterDefault); } diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertCollectionContainsShouldNotUseBoolCheckFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertCollectionContainsShouldNotUseBoolCheckFixerTests.cs index 97f05408..8983b1d0 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertCollectionContainsShouldNotUseBoolCheckFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertCollectionContainsShouldNotUseBoolCheckFixerTests.cs @@ -5,33 +5,34 @@ public class AssertCollectionContainsShouldNotUseBoolCheckFixerTests { - const string template = @" -using System; -using System.Linq; -using Xunit; + const string template = /* lang=c#-test */ """ + using System; + using System.Linq; + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var items = new[] {{ ""a"", ""b"", ""c"" }}; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var items = new[] {{ "a", "b", "c" }}; - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] [InlineData( - @"[|Assert.True(items.Contains(""b""))|]", - @"Assert.Contains(""b"", items)")] + /* lang=c#-test */ @"[|Assert.True(items.Contains(""b""))|]", + /* lang=c#-test */ @"Assert.Contains(""b"", items)")] [InlineData( - @"[|Assert.True(items.Contains(""b"", StringComparer.Ordinal))|]", - @"Assert.Contains(""b"", items, StringComparer.Ordinal)")] + /* lang=c#-test */ @"[|Assert.True(items.Contains(""b"", StringComparer.Ordinal))|]", + /* lang=c#-test */ @"Assert.Contains(""b"", items, StringComparer.Ordinal)")] [InlineData( - @"[|Assert.False(items.Contains(""b""))|]", - @"Assert.DoesNotContain(""b"", items)")] + /* lang=c#-test */ @"[|Assert.False(items.Contains(""b""))|]", + /* lang=c#-test */ @"Assert.DoesNotContain(""b"", items)")] [InlineData( - @"[|Assert.False(items.Contains(""b"", StringComparer.Ordinal))|]", - @"Assert.DoesNotContain(""b"", items, StringComparer.Ordinal)")] + /* lang=c#-test */ @"[|Assert.False(items.Contains(""b"", StringComparer.Ordinal))|]", + /* lang=c#-test */ @"Assert.DoesNotContain(""b"", items, StringComparer.Ordinal)")] public async Task ReplacesBooleanAssert( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertEmptyCollectionCheckShouldNotBeUsedFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertEmptyCollectionCheckShouldNotBeUsedFixerTests.cs index a54f01ba..8cc9e076 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertEmptyCollectionCheckShouldNotBeUsedFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertEmptyCollectionCheckShouldNotBeUsedFixerTests.cs @@ -5,32 +5,34 @@ public class AssertEmptyCollectionCheckShouldNotBeUsedFixerTests { - readonly string before = @" -using Xunit; + const string before = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Fact] - public void TestMethod() { - var collection = new[] { 1, 2, 3 }; + public class TestClass { + [Fact] + public void TestMethod() { + var collection = new[] { 1, 2, 3 }; - [|Assert.Collection(collection)|]; - } -}"; + [|Assert.Collection(collection)|]; + } + } + """; [Fact] public async Task UseEmptyCheck() { - var after = @" -using Xunit; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Fact] - public void TestMethod() { - var collection = new[] { 1, 2, 3 }; + public class TestClass { + [Fact] + public void TestMethod() { + var collection = new[] { 1, 2, 3 }; - Assert.Empty(collection); - } -}"; + Assert.Empty(collection); + } + } + """; await Verify.VerifyCodeFix(before, after, AssertEmptyCollectionCheckShouldNotBeUsedFixer.Key_UseAssertEmpty); } @@ -38,17 +40,18 @@ public void TestMethod() { [Fact] public async Task AddElementInspector() { - var after = @" -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - var collection = new[] { 1, 2, 3 }; - - Assert.Collection(collection, x => { }); - } -}"; + var after = /* lang=c#-test */ """ + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + var collection = new[] { 1, 2, 3 }; + + Assert.Collection(collection, x => { }); + } + } + """; await Verify.VerifyCodeFix(before, after, AssertEmptyCollectionCheckShouldNotBeUsedFixer.Key_AddElementInspector); } diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheckFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheckFixerTests.cs index 3e317a83..efe54c55 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheckFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheckFixerTests.cs @@ -5,25 +5,32 @@ public class AssertEmptyShouldNotBeUsedForCollectionDoesNotContainCheckFixerTests { - const string template = @" -using System.Linq; -using Xunit; + const string template = /* lang=c#-test */ """ + using System.Linq; + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var list = new[] {{ -1, 0, 1, 2 }}; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var list = new[] {{ -1, 0, 1, 2 }}; - {0}; - }} + {0}; + }} - public bool IsEven(int num) => num % 2 == 0; -}}"; + public bool IsEven(int num) => num % 2 == 0; + }} + """; [Theory] - [InlineData("[|Assert.Empty(list.Where(f => f > 0))|]", "Assert.DoesNotContain(list, f => f > 0)")] - [InlineData("[|Assert.Empty(list.Where(n => n == 1))|]", "Assert.DoesNotContain(list, n => n == 1)")] - [InlineData("[|Assert.Empty(list.Where(IsEven))|]", "Assert.DoesNotContain(list, IsEven)")] + [InlineData( + /* lang=c#-test */ "[|Assert.Empty(list.Where(f => f > 0))|]", + /* lang=c#-test */ "Assert.DoesNotContain(list, f => f > 0)")] + [InlineData( + /* lang=c#-test */ "[|Assert.Empty(list.Where(n => n == 1))|]", + /* lang=c#-test */ "Assert.DoesNotContain(list, n => n == 1)")] + [InlineData( + /* lang=c#-test */ "[|Assert.Empty(list.Where(IsEven))|]", + /* lang=c#-test */ "Assert.DoesNotContain(list, IsEven)")] public async Task FixerReplacesAssertEmptyWithAssertDoesNotContain( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheckFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheckFixerTests.cs index 066191c3..b69ff610 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheckFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheckFixerTests.cs @@ -5,26 +5,27 @@ public class AssertEnumerableAnyCheckShouldNotBeUsedForCollectionContainsCheckFixerTests { - const string template = @" -using System.Linq; -using Xunit; + const string template = /* lang=c#-test */ """ + using System.Linq; + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var collection = new[] {{ 1, 2, 3 }}; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var collection = new[] {{ 1, 2, 3 }}; - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] [InlineData( - "[|Assert.True(collection.Any(x => x == 2))|]", - "Assert.Contains(collection, x => x == 2)")] + /* lang=c#-test */ "[|Assert.True(collection.Any(x => x == 2))|]", + /* lang=c#-test */ "Assert.Contains(collection, x => x == 2)")] [InlineData( - "[|Assert.False(collection.Any(x => x == 2))|]", - "Assert.DoesNotContain(collection, x => x == 2)")] + /* lang=c#-test */ "[|Assert.False(collection.Any(x => x == 2))|]", + /* lang=c#-test */ "Assert.DoesNotContain(collection, x => x == 2)")] public async Task ReplacesAssert( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualGenericShouldNotBeUsedForStringValueFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualGenericShouldNotBeUsedForStringValueFixerTests.cs index ac93006b..826ed162 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualGenericShouldNotBeUsedForStringValueFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualGenericShouldNotBeUsedForStringValueFixerTests.cs @@ -6,17 +6,18 @@ public class AssertEqualGenericShouldNotBeUsedForStringValueFixerTests { - const string template = @" -using Xunit; + const string template = /* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - string result = ""foo""; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + string result = "foo"; - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] [InlineData(Constants.Asserts.Equal)] diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualLiteralValueShouldBeFirstFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualLiteralValueShouldBeFirstFixerTests.cs index 95f16a18..4c676191 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualLiteralValueShouldBeFirstFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualLiteralValueShouldBeFirstFixerTests.cs @@ -6,24 +6,38 @@ public class AssertEqualLiteralValueShouldBeFirstFixerTests { - static readonly string Template = @" -using System.Collections.Generic; + const string Template = /* lang=c#-test */ """ + using System.Collections.Generic; -public class TestClass {{ - [Xunit.Fact] - public void TestMethod() {{ - var i = 0; - [|Xunit.{0}|]; - }} -}}"; + public class TestClass {{ + [Xunit.Fact] + public void TestMethod() {{ + var i = 0; + [|Xunit.{0}|]; + }} + }} + """; [Theory] - [InlineData("Assert.Equal(i, 0)", "Assert.Equal(0, i)")] - [InlineData("Assert.Equal(actual: 0, expected: i)", "Assert.Equal(actual: i, expected: 0)")] - [InlineData("Assert.Equal(expected: i, actual: 0)", "Assert.Equal(expected: 0, actual: i)")] - [InlineData("Assert.Equal(comparer: default(IEqualityComparer), actual: 0, expected: i)", "Assert.Equal(comparer: default(IEqualityComparer), actual: i, expected: 0)")] - [InlineData("Assert.Equal(comparer: (x, y) => true, actual: 0, expected: i)", "Assert.Equal(comparer: (x, y) => true, actual: i, expected: 0)")] - [InlineData("Assert.Equal(expected: i, 0)", "Assert.Equal(expected: 0, i)", LanguageVersion.CSharp7_2)] + [InlineData( + /* lang=c#-test */ "Assert.Equal(i, 0)", + /* lang=c#-test */ "Assert.Equal(0, i)")] + [InlineData( + /* lang=c#-test */ "Assert.Equal(actual: 0, expected: i)", + /* lang=c#-test */ "Assert.Equal(actual: i, expected: 0)")] + [InlineData( + /* lang=c#-test */ "Assert.Equal(expected: i, actual: 0)", + /* lang=c#-test */ "Assert.Equal(expected: 0, actual: i)")] + [InlineData( + /* lang=c#-test */ "Assert.Equal(comparer: default(IEqualityComparer), actual: 0, expected: i)", + /* lang=c#-test */ "Assert.Equal(comparer: default(IEqualityComparer), actual: i, expected: 0)")] + [InlineData( + /* lang=c#-test */ "Assert.Equal(comparer: (x, y) => true, actual: 0, expected: i)", + /* lang=c#-test */ "Assert.Equal(comparer: (x, y) => true, actual: i, expected: 0)")] + [InlineData( + /* lang=c#-test */ "Assert.Equal(expected: i, 0)", + /* lang=c#-test */ "Assert.Equal(expected: 0, i)", + LanguageVersion.CSharp7_2)] public async Task SwapArguments( string beforeAssert, string afterAssert, diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualPrecisionShouldBeInRangeFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualPrecisionShouldBeInRangeFixerTests.cs index 034f11aa..be8df4a8 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualPrecisionShouldBeInRangeFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualPrecisionShouldBeInRangeFixerTests.cs @@ -5,23 +5,32 @@ public class AssertEqualPrecisionShouldBeInRangeFixerTests { - const string template = @" -using Xunit; + const string template = /* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - {0}; - }} -}}"; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + {0}; + }} + }} + """; [Theory] // double = [0..15] - [InlineData("Assert.Equal(10.1d, 10.2d, [|-1|])", "Assert.Equal(10.1d, 10.2d, 0)")] - [InlineData("Assert.Equal(10.1d, 10.2d, [|16|])", "Assert.Equal(10.1d, 10.2d, 15)")] + [InlineData( + /* lang=c#-test */ "Assert.Equal(10.1d, 10.2d, [|-1|])", + /* lang=c#-test */ "Assert.Equal(10.1d, 10.2d, 0)")] + [InlineData( + /* lang=c#-test */ "Assert.Equal(10.1d, 10.2d, [|16|])", + /* lang=c#-test */ "Assert.Equal(10.1d, 10.2d, 15)")] // decimal = [0..28] - [InlineData("Assert.Equal(10.1m, 10.2m, [|-1|])", "Assert.Equal(10.1m, 10.2m, 0)")] - [InlineData("Assert.Equal(10.1m, 10.2m, [|29|])", "Assert.Equal(10.1m, 10.2m, 28)")] + [InlineData( + /* lang=c#-test */ "Assert.Equal(10.1m, 10.2m, [|-1|])", + /* lang=c#-test */ "Assert.Equal(10.1m, 10.2m, 0)")] + [InlineData( + /* lang=c#-test */ "Assert.Equal(10.1m, 10.2m, [|29|])", + /* lang=c#-test */ "Assert.Equal(10.1m, 10.2m, 28)")] public async Task ChangesPrecisionToZero( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualShouldNotBeUsedForBoolLiteralCheckFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualShouldNotBeUsedForBoolLiteralCheckFixerTests.cs index 9fe17243..746b1b39 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualShouldNotBeUsedForBoolLiteralCheckFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualShouldNotBeUsedForBoolLiteralCheckFixerTests.cs @@ -5,27 +5,44 @@ public class AssertEqualShouldNotBeUsedForBoolLiteralCheckFixerTests { - const string template = @" -using Xunit; + const string template = /* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var actual = true; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var actual = true; - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] - [InlineData("[|Assert.Equal(false, actual)|]", "Assert.False(actual)")] - [InlineData("[|Assert.Equal(true, actual)|]", "Assert.True(actual)")] - [InlineData("[|Assert.StrictEqual(false, actual)|]", "Assert.False(actual)")] - [InlineData("[|Assert.StrictEqual(true, actual)|]", "Assert.True(actual)")] - [InlineData("[|Assert.NotEqual(false, actual)|]", "Assert.True(actual)")] - [InlineData("[|Assert.NotEqual(true, actual)|]", "Assert.False(actual)")] - [InlineData("[|Assert.NotStrictEqual(false, actual)|]", "Assert.True(actual)")] - [InlineData("[|Assert.NotStrictEqual(true, actual)|]", "Assert.False(actual)")] + [InlineData( + /* lang=c#-test */ "[|Assert.Equal(false, actual)|]", + /* lang=c#-test */ "Assert.False(actual)")] + [InlineData( + /* lang=c#-test */ "[|Assert.Equal(true, actual)|]", + /* lang=c#-test */ "Assert.True(actual)")] + [InlineData( + /* lang=c#-test */ "[|Assert.StrictEqual(false, actual)|]", + /* lang=c#-test */ "Assert.False(actual)")] + [InlineData( + /* lang=c#-test */ "[|Assert.StrictEqual(true, actual)|]", + /* lang=c#-test */ "Assert.True(actual)")] + [InlineData( + /* lang=c#-test */ "[|Assert.NotEqual(false, actual)|]", + /* lang=c#-test */ "Assert.True(actual)")] + [InlineData( + /* lang=c#-test */ "[|Assert.NotEqual(true, actual)|]", + /* lang=c#-test */ "Assert.False(actual)")] + [InlineData( + /* lang=c#-test */ "[|Assert.NotStrictEqual(false, actual)|]", + /* lang=c#-test */ "Assert.True(actual)")] + [InlineData( + /* lang=c#-test */ "[|Assert.NotStrictEqual(true, actual)|]", + /* lang=c#-test */ "Assert.False(actual)")] public async Task ConvertsToBooleanAssert( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualShouldNotBeUsedForCollectionSizeCheckFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualShouldNotBeUsedForCollectionSizeCheckFixerTests.cs index ba493b1c..f3efd68f 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualShouldNotBeUsedForCollectionSizeCheckFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualShouldNotBeUsedForCollectionSizeCheckFixerTests.cs @@ -5,23 +5,30 @@ public class AssertEqualShouldNotBeUsedForCollectionSizeCheckFixerTests { - const string template = @" -using System.Linq; -using Xunit; + const string template = /* lang=c#-test */ """ + using System.Linq; + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var data = new[] {{ 1, 2, 3 }}; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var data = new[] {{ 1, 2, 3 }}; - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] - [InlineData("[|Assert.Equal(1, data.Count())|]", "Assert.Single(data)")] - [InlineData("[|Assert.Equal(0, data.Count())|]", "Assert.Empty(data)")] - [InlineData("[|Assert.NotEqual(0, data.Count())|]", "Assert.NotEmpty(data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.Equal(1, data.Count())|]", + /* lang=c#-test */ "Assert.Single(data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.Equal(0, data.Count())|]", + /* lang=c#-test */ "Assert.Empty(data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.NotEqual(0, data.Count())|]", + /* lang=c#-test */ "Assert.NotEmpty(data)")] public async Task ReplacesCollectionCountWithAppropriateAssert( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualShouldNotBeUsedForNullCheckFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualShouldNotBeUsedForNullCheckFixerTests.cs index f73c5d6e..8621a9a5 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualShouldNotBeUsedForNullCheckFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualShouldNotBeUsedForNullCheckFixerTests.cs @@ -5,23 +5,32 @@ public class AssertEqualShouldNotBeUsedForNullCheckFixerTests { - const string template = @" -using Xunit; + const string template = /* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - int? data = 1; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + int? data = 1; - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] - [InlineData("[|Assert.Equal(null, data)|]", "Assert.Null(data)")] - [InlineData("[|Assert.StrictEqual(null, data)|]", "Assert.Null(data)")] - [InlineData("[|Assert.NotEqual(null, data)|]", "Assert.NotNull(data)")] - [InlineData("[|Assert.NotStrictEqual(null, data)|]", "Assert.NotNull(data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.Equal(null, data)|]", + /* lang=c#-test */ "Assert.Null(data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.StrictEqual(null, data)|]", + /* lang=c#-test */ "Assert.Null(data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.NotEqual(null, data)|]", + /* lang=c#-test */ "Assert.NotNull(data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.NotStrictEqual(null, data)|]", + /* lang=c#-test */ "Assert.NotNull(data)")] public async Task ConvertsToAppropriateNullAssert( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualsShouldNotBeUsedFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualsShouldNotBeUsedFixerTests.cs index 99e150d4..054dc878 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualsShouldNotBeUsedFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertEqualsShouldNotBeUsedFixerTests.cs @@ -5,21 +5,26 @@ public class AssertEqualsShouldNotBeUsedFixerTests { - const string template = @" -using Xunit; + const string template = /* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var data = 1; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var data = 1; - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] - [InlineData("{|CS0619:[|Assert.Equals(1, data)|]|}", "Assert.Equal(1, data)")] - [InlineData("{|CS0619:[|Assert.ReferenceEquals(1, data)|]|}", "Assert.Same(1, data)")] + [InlineData( + /* lang=c#-test */ "{|CS0619:[|Assert.Equals(1, data)|]|}", + /* lang=c#-test */ "Assert.Equal(1, data)")] + [InlineData( + /* lang=c#-test */ "{|CS0619:[|Assert.ReferenceEquals(1, data)|]|}", + /* lang=c#-test */ "Assert.Same(1, data)")] public async Task ConvertsObjectCallToAssert( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertIsTypeShouldNotBeUsedForAbstractTypeFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertIsTypeShouldNotBeUsedForAbstractTypeFixerTests.cs index 90da2c57..20e0a383 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertIsTypeShouldNotBeUsedForAbstractTypeFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertIsTypeShouldNotBeUsedForAbstractTypeFixerTests.cs @@ -5,24 +5,33 @@ public class AssertIsTypeShouldNotBeUsedForAbstractTypeFixerTests { - const string template = @" -using System; -using Xunit; + const string template = /* lang=c#-test */ """ + using System; + using Xunit; -public abstract class TestClass {{ - [Fact] - public void TestMethod() {{ - var data = new object(); + public abstract class TestClass {{ + [Fact] + public void TestMethod() {{ + var data = new object(); - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] - [InlineData("[|Assert.IsType(data)|]", "Assert.IsAssignableFrom(data)")] - [InlineData("[|Assert.IsType(data)|]", "Assert.IsAssignableFrom(data)")] - [InlineData("[|Assert.IsNotType(data)|]", "Assert.IsNotAssignableFrom(data)")] - [InlineData("[|Assert.IsNotType(data)|]", "Assert.IsNotAssignableFrom(data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.IsType(data)|]", + /* lang=c#-test */ "Assert.IsAssignableFrom(data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.IsType(data)|]", + /* lang=c#-test */ "Assert.IsAssignableFrom(data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.IsNotType(data)|]", + /* lang=c#-test */ "Assert.IsNotAssignableFrom(data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.IsNotType(data)|]", + /* lang=c#-test */ "Assert.IsNotAssignableFrom(data)")] public async Task Conversions( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertNullShouldNotBeCalledOnValueTypesFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertNullShouldNotBeCalledOnValueTypesFixerTests.cs index ab2cc807..7324379b 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertNullShouldNotBeCalledOnValueTypesFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertNullShouldNotBeCalledOnValueTypesFixerTests.cs @@ -8,67 +8,71 @@ public class AssertNullShouldNotBeCalledOnValueTypesFixerTests [Fact] public async Task ForValueTypeNullAssert_RemovesAssertion() { - const string before = @" -using Xunit; + const string before = /* lang=c#-test */ """ + using Xunit; -public class Tests { - [Fact] - public void TestMethod() { - int i = 1; + public class Tests { + [Fact] + public void TestMethod() { + int i = 1; - [|Assert.NotNull(i)|]; - } -}"; - const string after = @" -using Xunit; + [|Assert.NotNull(i)|]; + } + } + """; + const string after = /* lang=c#-test */ """ + using Xunit; -public class Tests { - [Fact] - public void TestMethod() { - int i = 1; - } -}"; + public class Tests { + [Fact] + public void TestMethod() { + int i = 1; + } + } + """; await Verify.VerifyCodeFix(before, after, AssertNullShouldNotBeCalledOnValueTypesFixer.Key_RemoveAssert); } - [Fact] // https://github.com/xunit/xunit/issues/1753 + [Fact] public async Task ForAssertionWithTrivia_RemovesAssertionAndLeavesLeadingTriviaInPlace() { - const string before = @" -using System; -using Xunit; + const string before = /* lang=c#-test */ """ + using System; + using Xunit; -namespace XUnitTestProject1 { - public class UnitTest1 { - [Fact] - public void Test1() { - int i = 1; + namespace XUnitTestProject1 { + public class UnitTest1 { + [Fact] + public void Test1() { + int i = 1; - // I am a comment which gets deleted by the quick fix - // Assert - [|Assert.NotNull(i)|]; - Assert.Null(null); - } - } -}"; - const string after = @" -using System; -using Xunit; + // I am a comment which gets deleted by the quick fix + // Assert + [|Assert.NotNull(i)|]; + Assert.Null(null); + } + } + } + """; + const string after = /* lang=c#-test */ """ + using System; + using Xunit; -namespace XUnitTestProject1 { - public class UnitTest1 { - [Fact] - public void Test1() { - int i = 1; + namespace XUnitTestProject1 { + public class UnitTest1 { + [Fact] + public void Test1() { + int i = 1; - // I am a comment which gets deleted by the quick fix - // Assert - Assert.Null(null); - } - } -}"; + // I am a comment which gets deleted by the quick fix + // Assert + Assert.Null(null); + } + } + } + """; await Verify.VerifyCodeFix(before, after, AssertNullShouldNotBeCalledOnValueTypesFixer.Key_RemoveAssert); } diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertRegexMatchShouldNotUseBoolLiteralCheckFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertRegexMatchShouldNotUseBoolLiteralCheckFixerTests.cs index 6a984669..cb658e88 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertRegexMatchShouldNotUseBoolLiteralCheckFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertRegexMatchShouldNotUseBoolLiteralCheckFixerTests.cs @@ -5,22 +5,27 @@ public class AssertRegexMatchShouldNotUseBoolLiteralCheckFixerTests { - const string template = @" -using System.Text.RegularExpressions; -using Xunit; + const string template = /* lang=c#-test */ """ + using System.Text.RegularExpressions; + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var result = ""foo bar baz""; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var result = "foo bar baz"; - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] - [InlineData(@"[|Assert.True(Regex.IsMatch(result, ""foo (.*?) baz""))|]", @"Assert.Matches(""foo (.*?) baz"", result)")] - [InlineData(@"[|Assert.False(Regex.IsMatch(result, ""foo (.*?) baz""))|]", @"Assert.DoesNotMatch(""foo (.*?) baz"", result)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.True(Regex.IsMatch(result, ""foo (.*?) baz""))|]", + /* lang=c#-test */ @"Assert.Matches(""foo (.*?) baz"", result)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.False(Regex.IsMatch(result, ""foo (.*?) baz""))|]", + /* lang=c#-test */ @"Assert.DoesNotMatch(""foo (.*?) baz"", result)")] public async Task ConvertsBooleanAssertToRegexAssert( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertSameShouldNotBeCalledOnValueTypesFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertSameShouldNotBeCalledOnValueTypesFixerTests.cs index cc18e7e8..b779fe2d 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertSameShouldNotBeCalledOnValueTypesFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertSameShouldNotBeCalledOnValueTypesFixerTests.cs @@ -5,21 +5,26 @@ public class AssertSameShouldNotBeCalledOnValueTypesFixerTests { - const string template = @" -using Xunit; + const string template = /* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var data = 1; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var data = 1; - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] - [InlineData("[|Assert.Same(1, data)|]", "Assert.Equal(1, data)")] - [InlineData("[|Assert.NotSame(1, data)|]", "Assert.NotEqual(1, data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.Same(1, data)|]", + /* lang=c#-test */ "Assert.Equal(1, data)")] + [InlineData( + /* lang=c#-test */ "[|Assert.NotSame(1, data)|]", + /* lang=c#-test */ "Assert.NotEqual(1, data)")] public async Task ConvertsSameToEqual( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertSingleShouldBeUsedForSingleParameterFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertSingleShouldBeUsedForSingleParameterFixerTests.cs index ffebbb4e..442de3b0 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertSingleShouldBeUsedForSingleParameterFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertSingleShouldBeUsedForSingleParameterFixerTests.cs @@ -9,118 +9,160 @@ public class AssertSingleShouldBeUsedForSingleParameterFixerTests public static TheoryData Statements = new() { { - "[|Assert.Collection(collection, item => Assert.NotNull(item))|]", - @"var item = Assert.Single(collection); - Assert.NotNull(item);" + /* lang=c#-test */ """ + [|Assert.Collection(collection, item => Assert.NotNull(item))|] + """, + /* lang=c#-test */ """ + var item = Assert.Single(collection); + Assert.NotNull(item); + """ }, { - @"var item = 42; - [|Assert.Collection(collection, item => Assert.NotNull(item))|]", - @"var item = 42; - var item_2 = Assert.Single(collection); - Assert.NotNull(item_2);" + /* lang=c#-test */ """ + var item = 42; + [|Assert.Collection(collection, item => Assert.NotNull(item))|] + """, + /* lang=c#-test */ """ + var item = 42; + var item_2 = Assert.Single(collection); + Assert.NotNull(item_2); + """ }, { - "[|Assert.Collection(collection, item => { Assert.NotNull(item); })|]", - @"var item = Assert.Single(collection); - Assert.NotNull(item);" + /* lang=c#-test */ """ + [|Assert.Collection(collection, item => { Assert.NotNull(item); })|] + """, + /* lang=c#-test */ """ + var item = Assert.Single(collection); + Assert.NotNull(item); + """ }, { - @"var item = 42; - [|Assert.Collection(collection, item => { Assert.NotNull(item); })|]", - @"var item = 42; - var item_2 = Assert.Single(collection); - Assert.NotNull(item_2);" + /* lang=c#-test */ """ + var item = 42; + [|Assert.Collection(collection, item => { Assert.NotNull(item); })|] + """, + /* lang=c#-test */ """ + var item = 42; + var item_2 = Assert.Single(collection); + Assert.NotNull(item_2); + """ }, { - "[|Assert.Collection(collection, item => { Assert.NotNull(item); Assert.NotNull(item); })|]", - @"var item = Assert.Single(collection); - Assert.NotNull(item); Assert.NotNull(item);" + /* lang=c#-test */ """ + [|Assert.Collection(collection, item => { Assert.NotNull(item); Assert.NotNull(item); })|] + """, + /* lang=c#-test */ """ + var item = Assert.Single(collection); + Assert.NotNull(item); Assert.NotNull(item); + """ }, { - @"var item = 42; - [|Assert.Collection(collection, item => { Assert.NotNull(item); Assert.NotNull(item); })|]", - @"var item = 42; - var item_2 = Assert.Single(collection); - Assert.NotNull(item_2); Assert.NotNull(item_2);" + /* lang=c#-test */ """ + var item = 42; + [|Assert.Collection(collection, item => { Assert.NotNull(item); Assert.NotNull(item); })|] + """, + /* lang=c#-test */ """ + var item = 42; + var item_2 = Assert.Single(collection); + Assert.NotNull(item_2); Assert.NotNull(item_2); + """ }, { - @"[|Assert.Collection(collection, item => { - if (item != null) { - Assert.NotNull(item); - Assert.NotNull(item); - } - })|]", - @"var item = Assert.Single(collection); - if (item != null) - { - Assert.NotNull(item); - Assert.NotNull(item); - }" + /* lang=c#-test */ """ + [|Assert.Collection(collection, item => { + if (item != null) { + Assert.NotNull(item); + Assert.NotNull(item); + } + })|] + """, + /* lang=c#-test */ """ + var item = Assert.Single(collection); + if (item != null) + { + Assert.NotNull(item); + Assert.NotNull(item); + } + """ }, { - @"var item = 42; - [|Assert.Collection(collection, item => { - if (item != null) { - Assert.NotNull(item); - Assert.NotNull(item); - } - })|]", - @"var item = 42; - var item_2 = Assert.Single(collection); - if (item_2 != null) - { - Assert.NotNull(item_2); - Assert.NotNull(item_2); - }" + /* lang=c#-test */ """ + var item = 42; + [|Assert.Collection(collection, item => { + if (item != null) { + Assert.NotNull(item); + Assert.NotNull(item); + } + })|] + """, + /* lang=c#-test */ """ + var item = 42; + var item_2 = Assert.Single(collection); + if (item_2 != null) + { + Assert.NotNull(item_2); + Assert.NotNull(item_2); + } + """ }, { - "[|Assert.Collection(collection, ElementInspector)|]", - @"var item = Assert.Single(collection); - ElementInspector(item);" + /* lang=c#-test */ """ + [|Assert.Collection(collection, ElementInspector)|] + """, + /* lang=c#-test */ """ + var item = Assert.Single(collection); + ElementInspector(item); + """ }, { - @"var item = 42; - var item_2 = 21.12; - [|Assert.Collection(collection, ElementInspector)|]", - @"var item = 42; - var item_2 = 21.12; - var item_3 = Assert.Single(collection); - ElementInspector(item_3);" + /* lang=c#-test */ """ + var item = 42; + var item_2 = 21.12; + [|Assert.Collection(collection, ElementInspector)|] + """, + /* lang=c#-test */ """ + var item = 42; + var item_2 = 21.12; + var item_3 = Assert.Single(collection); + ElementInspector(item_3); + """ }, }; - const string beforeTemplate = @" -using Xunit; -using System.Collections.Generic; + const string beforeTemplate = /* lang=c#-test */ """ + using Xunit; + using System.Collections.Generic; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - IEnumerable collection = new List() {{ new object() }}; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + IEnumerable collection = new List() {{ new object() }}; - {0}; - }} + {0}; + }} - private void ElementInspector(object obj) - {{ }} -}}"; + private void ElementInspector(object obj) + {{ }} + }} + """; - const string afterTemplate = @" -using Xunit; -using System.Collections.Generic; + const string afterTemplate = /* lang=c#-test */ """ + using Xunit; + using System.Collections.Generic; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - IEnumerable collection = new List() {{ new object() }}; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + IEnumerable collection = new List() {{ new object() }}; - {0} - }} + {0} + }} - private void ElementInspector(object obj) - {{ }} -}}"; + private void ElementInspector(object obj) + {{ }} + }} + """; [Theory] [MemberData(nameof(Statements))] diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertStringEqualityCheckShouldNotUseBoolCheckFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertStringEqualityCheckShouldNotUseBoolCheckFixerTests.cs index 8f04cf04..e9f9a839 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertStringEqualityCheckShouldNotUseBoolCheckFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertStringEqualityCheckShouldNotUseBoolCheckFixerTests.cs @@ -5,32 +5,49 @@ public class AssertStringEqualityCheckShouldNotUseBoolCheckFixerTests { - const string template = @" -using System; -using Xunit; + const string template = /* lang=c#-test */ """ + using System; + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var data = ""foo bar baz""; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var data = "foo bar baz"; - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] // Instance Equals (true) - [InlineData(@"[|Assert.True(""foo bar baz"".Equals(data))|]", @"Assert.Equal(""foo bar baz"", data)")] - [InlineData(@"[|Assert.True(""foo bar baz"".Equals(data, StringComparison.Ordinal))|]", @"Assert.Equal(""foo bar baz"", data)")] - [InlineData(@"[|Assert.True(""foo bar baz"".Equals(data, StringComparison.OrdinalIgnoreCase))|]", @"Assert.Equal(""foo bar baz"", data, ignoreCase: true)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.True(""foo bar baz"".Equals(data))|]", + /* lang=c#-test */ @"Assert.Equal(""foo bar baz"", data)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.True(""foo bar baz"".Equals(data, StringComparison.Ordinal))|]", + /* lang=c#-test */ @"Assert.Equal(""foo bar baz"", data)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.True(""foo bar baz"".Equals(data, StringComparison.OrdinalIgnoreCase))|]", + /* lang=c#-test */ @"Assert.Equal(""foo bar baz"", data, ignoreCase: true)")] // Static Equals (true) - [InlineData(@"[|Assert.True(string.Equals(""foo bar baz"", data))|]", @"Assert.Equal(""foo bar baz"", data)")] - [InlineData(@"[|Assert.True(string.Equals(""foo bar baz"", data, StringComparison.Ordinal))|]", @"Assert.Equal(""foo bar baz"", data)")] - [InlineData(@"[|Assert.True(string.Equals(""foo bar baz"", data, StringComparison.OrdinalIgnoreCase))|]", @"Assert.Equal(""foo bar baz"", data, ignoreCase: true)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.True(string.Equals(""foo bar baz"", data))|]", + /* lang=c#-test */ @"Assert.Equal(""foo bar baz"", data)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.True(string.Equals(""foo bar baz"", data, StringComparison.Ordinal))|]", + /* lang=c#-test */ @"Assert.Equal(""foo bar baz"", data)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.True(string.Equals(""foo bar baz"", data, StringComparison.OrdinalIgnoreCase))|]", + /* lang=c#-test */ @"Assert.Equal(""foo bar baz"", data, ignoreCase: true)")] // Instance Equals (false) - [InlineData(@"[|Assert.False(""foo bar baz"".Equals(data))|]", @"Assert.NotEqual(""foo bar baz"", data)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.False(""foo bar baz"".Equals(data))|]", + /* lang=c#-test */ @"Assert.NotEqual(""foo bar baz"", data)")] // Static Equals (false) - [InlineData(@"[|Assert.False(string.Equals(""foo bar baz"", data))|]", @"Assert.NotEqual(""foo bar baz"", data)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.False(string.Equals(""foo bar baz"", data))|]", + /* lang=c#-test */ @"Assert.NotEqual(""foo bar baz"", data)")] public async Task ConvertsBooleanAssertToEqualityAssert( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertSubstringCheckShouldNotUseBoolCheckFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertSubstringCheckShouldNotUseBoolCheckFixerTests.cs index 8ec7c6c2..cda371ae 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertSubstringCheckShouldNotUseBoolCheckFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertSubstringCheckShouldNotUseBoolCheckFixerTests.cs @@ -5,26 +5,39 @@ public class AssertSubstringCheckShouldNotUseBoolCheckFixerTests { - const string template = @" -using System; -using Xunit; + const string template = /* lang=c#-test */ """ + using System; + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - var data = ""foo bar baz""; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + var data = "foo bar baz"; - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] - [InlineData(@"[|Assert.True(data.Contains(""foo""))|]", @"Assert.Contains(""foo"", data)")] - [InlineData(@"[|Assert.True(data.StartsWith(""foo""))|]", @"Assert.StartsWith(""foo"", data)")] - [InlineData(@"[|Assert.True(data.StartsWith(""foo"", StringComparison.Ordinal))|]", @"Assert.StartsWith(""foo"", data, StringComparison.Ordinal)")] - [InlineData(@"[|Assert.True(data.EndsWith(""foo""))|]", @"Assert.EndsWith(""foo"", data)")] - [InlineData(@"[|Assert.True(data.EndsWith(""foo"", StringComparison.OrdinalIgnoreCase))|]", @"Assert.EndsWith(""foo"", data, StringComparison.OrdinalIgnoreCase)")] - [InlineData(@"[|Assert.False(data.Contains(""foo""))|]", @"Assert.DoesNotContain(""foo"", data)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.True(data.Contains(""foo""))|]", + /* lang=c#-test */ @"Assert.Contains(""foo"", data)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.True(data.StartsWith(""foo""))|]", + /* lang=c#-test */ @"Assert.StartsWith(""foo"", data)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.True(data.StartsWith(""foo"", StringComparison.Ordinal))|]", + /* lang=c#-test */ @"Assert.StartsWith(""foo"", data, StringComparison.Ordinal)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.True(data.EndsWith(""foo""))|]", + /* lang=c#-test */ @"Assert.EndsWith(""foo"", data)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.True(data.EndsWith(""foo"", StringComparison.OrdinalIgnoreCase))|]", + /* lang=c#-test */ @"Assert.EndsWith(""foo"", data, StringComparison.OrdinalIgnoreCase)")] + [InlineData( + /* lang=c#-test */ @"[|Assert.False(data.Contains(""foo""))|]", + /* lang=c#-test */ @"Assert.DoesNotContain(""foo"", data)")] public async Task ConvertsBooleanAssertToStringSpecificAssert( string beforeAssert, string afterAssert) diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AssertThrowsShouldNotBeUsedForAsyncThrowsCheckFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AssertThrowsShouldNotBeUsedForAsyncThrowsCheckFixerTests.cs index d395cb69..916cab3a 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AssertThrowsShouldNotBeUsedForAsyncThrowsCheckFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AssertThrowsShouldNotBeUsedForAsyncThrowsCheckFixerTests.cs @@ -8,48 +8,59 @@ public class AssertThrowsShouldNotBeUsedForAsyncThrowsCheckFixerTests { public static readonly TheoryData Assertions = GenerateAssertions(); - static readonly string template = @" -using System; -using System.Threading.Tasks; -using Xunit; + const string template = /* lang=c#-test */ """ + using System; + using System.Threading.Tasks; + using Xunit; -public class TestClass {{ - Task ThrowingMethod() {{ - throw new NotImplementedException(); - }} + public class TestClass {{ + Task ThrowingMethod() {{ + throw new NotImplementedException(); + }} - [Fact]{0} -}}"; + [Fact]{0} + }} + """; static TheoryData GenerateAssertions() { var templates = new (string, string)[] { - ("Assert.Throws(typeof(Exception), {0})", "Assert.ThrowsAsync(typeof(Exception), {0})"), - ("Assert.Throws({0})", "Assert.ThrowsAsync({0})"), - ("Assert.Throws(\"parameter\", {0})", "Assert.ThrowsAsync(\"parameter\", {0})"), - ("Assert.ThrowsAny({0})", "Assert.ThrowsAnyAsync({0})"), + ( + /* lang=c#-test */ "Assert.Throws(typeof(Exception), {0})", + /* lang=c#-test */ "Assert.ThrowsAsync(typeof(Exception), {0})" + ), + ( + /* lang=c#-test */ "Assert.Throws({0})", + /* lang=c#-test */ "Assert.ThrowsAsync({0})" + ), + ( + /* lang=c#-test */ "Assert.Throws(\"parameter\", {0})", + /* lang=c#-test */ "Assert.ThrowsAsync(\"parameter\", {0})" + ), + ( + /* lang=c#-test */ "Assert.ThrowsAny({0})", + /* lang=c#-test */ "Assert.ThrowsAnyAsync({0})" + ), }; var lambdas = new[] { - "(Func)ThrowingMethod", - "() => Task.Delay(0)", - "(Func)(async () => await Task.Delay(0))", - "(Func)(async () => await Task.Delay(0).ConfigureAwait(false))", + /* lang=c#-test */ "(Func)ThrowingMethod", + /* lang=c#-test */ "() => Task.Delay(0)", + /* lang=c#-test */ "(Func)(async () => await Task.Delay(0))", + /* lang=c#-test */ "(Func)(async () => await Task.Delay(0).ConfigureAwait(false))", }; var assertions = new TheoryData(); foreach ((var assertionTemplate, var replacementTemplate) in templates) - { foreach (var lambda in lambdas) { var assertion = string.Format(assertionTemplate, lambda); var replacement = string.Format(replacementTemplate, lambda); assertions.Add(assertion, replacement); } - } return assertions; } @@ -60,15 +71,16 @@ public async Task GivenAssertionInMethod_ReplacesWithAsyncAssertion( string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - {{|CS0619:[|{assertion}|]|}}; - }}"; - - var afterMethod = $@" - public async Task TestMethod() {{ - await {replacement}; - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + {{|CS0619:[|{0}|]|}}; + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public async Task TestMethod() {{ + await {0}; + }} + """, replacement); await VerifyCodeFix(beforeMethod, afterMethod); } @@ -79,27 +91,28 @@ public async Task GivenAssertionInInvokedAnonymousFunction_ReplacesWithAsyncAsse string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - Func function = () => {{ - {{|CS0619:[|{assertion}|]|}}; - return 0; - }}; - - int number = function(); - function(); - }}"; - - var afterMethod = $@" - public async Task TestMethod() {{ - Func> function = async () => {{ - await {replacement}; - return 0; - }}; - - int number = {{|CS0029:function()|}}; - function(); - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + Func function = () => {{ + {{|CS0619:[|{0}|]|}}; + return 0; + }}; + + int number = function(); + function(); + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public async Task TestMethod() {{ + Func> function = async () => {{ + await {0}; + return 0; + }}; + + int number = {{|CS0029:function()|}}; + function(); + }} + """, replacement); await VerifyCodeFix(beforeMethod, afterMethod); } @@ -110,34 +123,35 @@ public async Task GivenAssertionInInvokedAnonymousFunctionWithAssignment_Replace string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - Func function = () => 0; - function = () => {{ - {{|CS0619:[|{assertion}|]|}}; - return 0; - }}; - - int number = function(); - function(); - }}"; - - var afterMethod = $@" - public async Task TestMethod() {{ - Func> function = () => {{|CS0029:{{|CS1662:0|}}|}}; - function = async () => {{ - await {replacement}; - return 0; - }}; - - int number = {{|CS0029:function()|}}; - function(); - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + Func function = () => 0; + function = () => {{ + {{|CS0619:[|{0}|]|}}; + return 0; + }}; + + int number = function(); + function(); + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public async Task TestMethod() {{ + Func> function = () => {{|CS0029:{{|CS1662:0|}}|}}; + function = async () => {{ + await {0}; + return 0; + }}; + + int number = {{|CS0029:function()|}}; + function(); + }} + """, replacement); await VerifyCodeFix(beforeMethod, afterMethod); } -#if ROSLYN_4_4_OR_GREATER +#if ROSLYN_4_4_OR_GREATER // No C# 10 in Roslyn 3.11, so no anonymous lambda types [Theory] [MemberData(nameof(Assertions))] @@ -145,27 +159,28 @@ public async Task GivenAssertionInInvokedAnonymousFunctionWithVar_ReplacesWithAs string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - var function = () => {{ - {{|CS0619:[|{assertion}|]|}}; - return 0; - }}; - - int number = function(); - function(); - }}"; - - var afterMethod = $@" - public async Task TestMethod() {{ - var function = async () => {{ - await {replacement}; - return 0; - }}; - - int number = {{|CS0029:function()|}}; - function(); - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + var function = () => {{ + {{|CS0619:[|{0}|]|}}; + return 0; + }}; + + int number = function(); + function(); + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public async Task TestMethod() {{ + var function = async () => {{ + await {0}; + return 0; + }}; + + int number = {{|CS0029:function()|}}; + function(); + }} + """, replacement); await VerifyCodeFix(LanguageVersion.CSharp10, beforeMethod, afterMethod); } @@ -178,21 +193,22 @@ public async Task GivenAssertionInUninvokedAnonymousFunction_ReplacesWithAsyncAs string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - Func function = () => {{ - {{|CS0619:[|{assertion}|]|}}; - return 0; - }}; - }}"; - - var afterMethod = $@" - public void TestMethod() {{ - Func> function = async () => {{ - await {replacement}; - return 0; - }}; - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + Func function = () => {{ + {{|CS0619:[|{0}|]|}}; + return 0; + }}; + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + Func> function = async () => {{ + await {0}; + return 0; + }}; + }} + """, replacement); await VerifyCodeFix(beforeMethod, afterMethod); } @@ -203,35 +219,36 @@ public async Task GivenAssertionInInvokedNestedAnonymousFunction_ReplacesWithAsy string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - Action outerFunction = (number) => {{ - Func innerFunction = delegate () {{ - {{|CS0619:[|{assertion}|]|}}; - return string.Empty; - }}; - - var message = innerFunction().ToLower(); - innerFunction(); - }}; - - outerFunction(0); - }}"; - - var afterMethod = $@" - public async Task TestMethod() {{ - Func outerFunction = async (number) => {{ - Func> innerFunction = async delegate () {{ - await {replacement}; - return string.Empty; - }}; - - var message = innerFunction().{{|CS7036:ToLower|}}(); - innerFunction(); - }}; - - outerFunction(0); - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + Action outerFunction = (number) => {{ + Func innerFunction = delegate () {{ + {{|CS0619:[|{0}|]|}}; + return string.Empty; + }}; + + var message = innerFunction().ToLower(); + innerFunction(); + }}; + + outerFunction(0); + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public async Task TestMethod() {{ + Func outerFunction = async (number) => {{ + Func> innerFunction = async delegate () {{ + await {0}; + return string.Empty; + }}; + + var message = innerFunction().{{|CS7036:ToLower|}}(); + innerFunction(); + }}; + + outerFunction(0); + }} + """, replacement); await VerifyCodeFix(beforeMethod, afterMethod); } @@ -242,33 +259,34 @@ public async Task GivenAssertionInExplicitlyInvokedNestedAnonymousFunction_Repla string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - Action outerFunction = (number) => {{ - Func innerFunction = delegate () {{ - {{|CS0619:[|{assertion}|]|}}; - return string.Empty; - }}; - - var message = innerFunction.Invoke().ToLower(); - }}; - - outerFunction.Invoke(0); - }}"; - - var afterMethod = $@" - public async Task TestMethod() {{ - Func outerFunction = async (number) => {{ - Func> innerFunction = async delegate () {{ - await {replacement}; - return string.Empty; - }}; - - var message = innerFunction.Invoke().{{|CS7036:ToLower|}}(); - }}; - - outerFunction.Invoke(0); - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + Action outerFunction = (number) => {{ + Func innerFunction = delegate () {{ + {{|CS0619:[|{0}|]|}}; + return string.Empty; + }}; + + var message = innerFunction.Invoke().ToLower(); + }}; + + outerFunction.Invoke(0); + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public async Task TestMethod() {{ + Func outerFunction = async (number) => {{ + Func> innerFunction = async delegate () {{ + await {0}; + return string.Empty; + }}; + + var message = innerFunction.Invoke().{{|CS7036:ToLower|}}(); + }}; + + outerFunction.Invoke(0); + }} + """, replacement); await VerifyCodeFix(beforeMethod, afterMethod); } @@ -279,33 +297,34 @@ public async Task GivenAssertionInConditionallyInvokedNestedAnonymousFunction_Re string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - Action outerFunction = (number) => {{ - Func innerFunction = delegate () {{ - {{|CS0619:[|{assertion}|]|}}; - return string.Empty; - }}; - - var message = innerFunction?.Invoke().ToLower(); - }}; - - outerFunction?.Invoke(0); - }}"; - - var afterMethod = $@" - public async Task TestMethod() {{ - Func outerFunction = async (number) => {{ - Func> innerFunction = async delegate () {{ - await {replacement}; - return string.Empty; - }}; - - var message = innerFunction?.Invoke().{{|CS7036:ToLower|}}(); - }}; - - outerFunction?.Invoke(0); - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + Action outerFunction = (number) => {{ + Func innerFunction = delegate () {{ + {{|CS0619:[|{0}|]|}}; + return string.Empty; + }}; + + var message = innerFunction?.Invoke().ToLower(); + }}; + + outerFunction?.Invoke(0); + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public async Task TestMethod() {{ + Func outerFunction = async (number) => {{ + Func> innerFunction = async delegate () {{ + await {0}; + return string.Empty; + }}; + + var message = innerFunction?.Invoke().{{|CS7036:ToLower|}}(); + }}; + + outerFunction?.Invoke(0); + }} + """, replacement); await VerifyCodeFix(beforeMethod, afterMethod); } @@ -316,25 +335,26 @@ public async Task GivenAssertionInUninvokedNestedAnonymousFunction_ReplacesWithA string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - Action outerFunction = (number) => {{ - Func innerFunction = () => {{ - {{|CS0619:[|{assertion}|]|}}; - return string.Empty; - }}; - }}; - }}"; - - var afterMethod = $@" - public void TestMethod() {{ - Action outerFunction = (number) => {{ - Func> innerFunction = async () => {{ - await {replacement}; - return string.Empty; - }}; - }}; - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + Action outerFunction = (number) => {{ + Func innerFunction = () => {{ + {{|CS0619:[|{0}|]|}}; + return string.Empty; + }}; + }}; + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + Action outerFunction = (number) => {{ + Func> innerFunction = async () => {{ + await {0}; + return string.Empty; + }}; + }}; + }} + """, replacement); await VerifyCodeFix(beforeMethod, afterMethod); } @@ -345,27 +365,28 @@ public async Task GivenAssertionInInvokedLocalFunction_ReplacesWithAsyncAssertio string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - int number = Function(); - Function(); - - int Function() {{ - {{|CS0619:[|{assertion}|]|}}; - return 0; - }} - }}"; - - var afterMethod = $@" - public async Task TestMethod() {{ - int number = {{|CS0029:Function()|}}; - Function(); - - async Task Function() {{ - await {replacement}; - return 0; - }} - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + int number = Function(); + Function(); + + int Function() {{ + {{|CS0619:[|{0}|]|}}; + return 0; + }} + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public async Task TestMethod() {{ + int number = {{|CS0029:Function()|}}; + Function(); + + async Task Function() {{ + await {0}; + return 0; + }} + }} + """, replacement); await VerifyCodeFix(LanguageVersion.CSharp7, beforeMethod, afterMethod); } @@ -376,21 +397,22 @@ public async Task GivenAssertionInUninvokedLocalFunction_ReplacesWithAsyncAssert string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - int Function() {{ - {{|CS0619:[|{assertion}|]|}}; - return 0; - }} - }}"; - - var afterMethod = $@" - public void TestMethod() {{ - async Task Function() {{ - await {replacement}; - return 0; - }} - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + int Function() {{ + {{|CS0619:[|{0}|]|}}; + return 0; + }} + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + async Task Function() {{ + await {0}; + return 0; + }} + }} + """, replacement); await VerifyCodeFix(LanguageVersion.CSharp7, beforeMethod, afterMethod); } @@ -401,39 +423,40 @@ public async Task GivenAssertionInInvokedNestedLocalFunction_ReplacesWithAsyncAs string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - int number = OuterFunction(); - OuterFunction(); - - int OuterFunction() {{ - var message = InnerFunction().ToLower(); - InnerFunction(); - return 0; - - string InnerFunction() {{ - {{|CS0619:[|{assertion}|]|}}; - return string.Empty; - }} - }} - }}"; - - var afterMethod = $@" - public async Task TestMethod() {{ - int number = {{|CS0029:OuterFunction()|}}; - OuterFunction(); - - async Task OuterFunction() {{ - var message = InnerFunction().{{|CS7036:ToLower|}}(); - InnerFunction(); - return 0; - - async Task InnerFunction() {{ - await {replacement}; - return string.Empty; - }} - }} - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + int number = OuterFunction(); + OuterFunction(); + + int OuterFunction() {{ + var message = InnerFunction().ToLower(); + InnerFunction(); + return 0; + + string InnerFunction() {{ + {{|CS0619:[|{0}|]|}}; + return string.Empty; + }} + }} + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public async Task TestMethod() {{ + int number = {{|CS0029:OuterFunction()|}}; + OuterFunction(); + + async Task OuterFunction() {{ + var message = InnerFunction().{{|CS7036:ToLower|}}(); + InnerFunction(); + return 0; + + async Task InnerFunction() {{ + await {0}; + return string.Empty; + }} + }} + }} + """, replacement); await VerifyCodeFix(LanguageVersion.CSharp7, beforeMethod, afterMethod); } @@ -444,29 +467,30 @@ public async Task GivenAssertionInUninvokedNestedLocalFunction_ReplacesWithAsync string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - int OuterFunction() {{ - return 0; - - string InnerFunction() {{ - {{|CS0619:[|{assertion}|]|}}; - return string.Empty; - }} - }} - }}"; - - var afterMethod = $@" - public void TestMethod() {{ - int OuterFunction() {{ - return 0; - - async Task InnerFunction() {{ - await {replacement}; - return string.Empty; - }} - }} - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + int OuterFunction() {{ + return 0; + + string InnerFunction() {{ + {{|CS0619:[|{0}|]|}}; + return string.Empty; + }} + }} + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + int OuterFunction() {{ + return 0; + + async Task InnerFunction() {{ + await {0}; + return string.Empty; + }} + }} + }} + """, replacement); await VerifyCodeFix(LanguageVersion.CSharp7, beforeMethod, afterMethod); } @@ -477,59 +501,60 @@ public async Task GivenAssertionInMixedNestedFunctions_ReplacesWithAsyncAssertio string assertion, string replacement) { - var beforeMethod = $@" - public void TestMethod() {{ - int OuterLocalFunction() {{ - Func outerAnonymousFunction = () => {{ - string InnerLocalFunction() {{ - Action innerAnonymousFunction = () => {{ - {{|CS0619:[|{assertion}|]|}}; - }}; - - innerAnonymousFunction(); - return string.Empty; - }} - - string message = InnerLocalFunction(); - InnerLocalFunction(); - return false; - }}; - - bool condition = outerAnonymousFunction(); - outerAnonymousFunction(); - return 0; - }} - - int number = OuterLocalFunction(); - OuterLocalFunction(); - }}"; - - var afterMethod = $@" - public async Task TestMethod() {{ - async Task OuterLocalFunction() {{ - Func> outerAnonymousFunction = async () => {{ - async Task InnerLocalFunction() {{ - Func innerAnonymousFunction = async () => {{ - await {replacement}; - }}; - - innerAnonymousFunction(); - return string.Empty; - }} - - string message = {{|CS0029:InnerLocalFunction()|}}; - InnerLocalFunction(); - return false; - }}; - - bool condition = {{|CS0029:outerAnonymousFunction()|}}; - outerAnonymousFunction(); - return 0; - }} - - int number = {{|CS0029:OuterLocalFunction()|}}; - OuterLocalFunction(); - }}"; + var beforeMethod = string.Format(/* lang=c#-test */ """ + public void TestMethod() {{ + int OuterLocalFunction() {{ + Func outerAnonymousFunction = () => {{ + string InnerLocalFunction() {{ + Action innerAnonymousFunction = () => {{ + {{|CS0619:[|{0}|]|}}; + }}; + + innerAnonymousFunction(); + return string.Empty; + }} + + string message = InnerLocalFunction(); + InnerLocalFunction(); + return false; + }}; + + bool condition = outerAnonymousFunction(); + outerAnonymousFunction(); + return 0; + }} + + int number = OuterLocalFunction(); + OuterLocalFunction(); + }} + """, assertion); + var afterMethod = string.Format(/* lang=c#-test */ """ + public async Task TestMethod() {{ + async Task OuterLocalFunction() {{ + Func> outerAnonymousFunction = async () => {{ + async Task InnerLocalFunction() {{ + Func innerAnonymousFunction = async () => {{ + await {0}; + }}; + + innerAnonymousFunction(); + return string.Empty; + }} + + string message = {{|CS0029:InnerLocalFunction()|}}; + InnerLocalFunction(); + return false; + }}; + + bool condition = {{|CS0029:outerAnonymousFunction()|}}; + outerAnonymousFunction(); + return 0; + }} + + int number = {{|CS0029:OuterLocalFunction()|}}; + OuterLocalFunction(); + }} + """, replacement); await VerifyCodeFix(LanguageVersion.CSharp7, beforeMethod, afterMethod); } diff --git a/src/xunit.analyzers.tests/Fixes/X2000/AsyncAssertsShouldBeAwaitedFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/AsyncAssertsShouldBeAwaitedFixerTests.cs index aa015570..9d3543c6 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/AsyncAssertsShouldBeAwaitedFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/AsyncAssertsShouldBeAwaitedFixerTests.cs @@ -6,31 +6,32 @@ public class AsyncAssertsShouldBeAwaitedFixerTests { - string codeTemplate = @" -using System; -using System.ComponentModel; -using System.Threading.Tasks; -using Xunit; - -public class TestClass : INotifyPropertyChanged {{ - public int Property {{ get; set; }} - - public event PropertyChangedEventHandler? PropertyChanged; - public event EventHandler? SimpleEvent; - public event EventHandler? SimpleIntEvent; - - [Fact] - public void TestMethod() {{ - {0} - }} -}} - -public static class MyTaskExtensions {{ - public static void ConsumeTask(this Task t) {{ }} -}}"; - - public static TheoryData AsyncAssertions = new() - { + const string codeTemplate = /* lang=c#-test */ """ + using System; + using System.ComponentModel; + using System.Threading.Tasks; + using Xunit; + + public class TestClass : INotifyPropertyChanged {{ + public int Property {{ get; set; }} + + public event PropertyChangedEventHandler? PropertyChanged; + public event EventHandler? SimpleEvent; + public event EventHandler? SimpleIntEvent; + + [Fact] + public void TestMethod() {{ + {0} + }} + }} + + public static class MyTaskExtensions {{ + public static void ConsumeTask(this Task t) {{ }} + }} + """; + + public static TheoryData AsyncAssertions = + [ "Assert.PropertyChangedAsync(this, nameof(Property), async () => throw new DivideByZeroException())", "Assert.RaisesAnyAsync(eh => SimpleEvent += eh, eh => SimpleEvent -= eh, async () => throw new DivideByZeroException())", "Assert.RaisesAnyAsync(eh => SimpleIntEvent += eh, eh => SimpleIntEvent -= eh, async () => throw new DivideByZeroException())", @@ -39,7 +40,7 @@ public static void ConsumeTask(this Task t) {{ }} "Assert.ThrowsAsync(typeof(DivideByZeroException), async () => throw new DivideByZeroException())", "Assert.ThrowsAsync(async () => throw new DivideByZeroException())", "Assert.ThrowsAsync(\"argName\", async () => throw new DivideByZeroException())", - }; + ]; [Theory] [MemberData(nameof(AsyncAssertions))] diff --git a/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeNegatedFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeNegatedFixerTests.cs index 06073e90..0c14f905 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeNegatedFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeNegatedFixerTests.cs @@ -5,17 +5,18 @@ public class BooleanAssertsShouldNotBeNegatedFixerTests { - const string template = @" -using Xunit; + const string template = /* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - bool condition = true; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + bool condition = true; - {0}; - }} -}}"; + {0}; + }} + }} + """; [Theory] [InlineData("False", "True")] diff --git a/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckBooleanFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckBooleanFixerTests.cs index a326bcca..f82a26ad 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckBooleanFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckBooleanFixerTests.cs @@ -5,39 +5,40 @@ public class BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckBooleanFixerTests { - const string template = @" -using Xunit; + const string template = /* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - bool condition = true; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + bool condition = true; - {0}; - }} -}}"; + {0}; + }} + }} + """; public static TheoryData AssertExpressionReplacement = new() { - { "True", "condition == true", "True" }, - { "True", "condition != true", "False" }, - { "True", "true == condition", "True" }, - { "True", "true != condition", "False" }, + /* lang=c#-test */ { "True", "condition == true", "True" }, + /* lang=c#-test */ { "True", "condition != true", "False" }, + /* lang=c#-test */ { "True", "true == condition", "True" }, + /* lang=c#-test */ { "True", "true != condition", "False" }, - { "True", "condition == false", "False" }, - { "True", "condition != false", "True" }, - { "True", "false == condition", "False" }, - { "True", "false != condition", "True" }, + /* lang=c#-test */ { "True", "condition == false", "False" }, + /* lang=c#-test */ { "True", "condition != false", "True" }, + /* lang=c#-test */ { "True", "false == condition", "False" }, + /* lang=c#-test */ { "True", "false != condition", "True" }, - { "False", "condition == true", "False" }, - { "False", "condition != true", "True" }, - { "False", "true == condition", "False" }, - { "False", "true != condition", "True" }, + /* lang=c#-test */ { "False", "condition == true", "False" }, + /* lang=c#-test */ { "False", "condition != true", "True" }, + /* lang=c#-test */ { "False", "true == condition", "False" }, + /* lang=c#-test */ { "False", "true != condition", "True" }, - { "False", "condition == false", "True" }, - { "False", "condition != false", "False" }, - { "False", "false == condition", "True" }, - { "False", "false != condition", "False" }, + /* lang=c#-test */ { "False", "condition == false", "True" }, + /* lang=c#-test */ { "False", "condition != false", "False" }, + /* lang=c#-test */ { "False", "false == condition", "True" }, + /* lang=c#-test */ { "False", "false != condition", "False" }, }; [Theory] diff --git a/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckNonBooleanFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckNonBooleanFixerTests.cs index 44c51e3b..37410f78 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckNonBooleanFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckNonBooleanFixerTests.cs @@ -7,25 +7,26 @@ public class BooleanAssertsShouldNotBeUsedForSimpleEqualityCheckNonBooleanFixerTests { - const string template = @" -using Xunit; + const string template = /* lang=c#-test */ """ + using Xunit; -public enum MyEnum {{ None, Bacon, Veggie }} + public enum MyEnum {{ None, Bacon, Veggie }} -public class TestClass {{ - [Fact] - public void TestMethod() {{ - {0} value = {1}; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + {0} value = {1}; - {2}; - }} -}}"; + {2}; + }} + }} + """; public static MatrixTheoryData MethodOperatorValue = new( - new[] { Constants.Asserts.True, Constants.Asserts.False }, - new[] { "==", "!=" }, - new[] { "\"bacon\"", "'5'", "5", "5l", "5.0d", "5.0f", "5.0m", "MyEnum.Bacon" } + [Constants.Asserts.True, Constants.Asserts.False], + ["==", "!="], + ["\"bacon\"", "'5'", "5", "5l", "5.0d", "5.0f", "5.0m", "MyEnum.Bacon"] ); [Theory] @@ -59,9 +60,9 @@ await Verify.VerifyCodeFix( public static MatrixTheoryData MethodOperatorType = new( - new[] { Constants.Asserts.True, Constants.Asserts.False }, - new[] { "==", "!=" }, - new[] { "string", "int", "object", "MyEnum" } + [Constants.Asserts.True, Constants.Asserts.False], + ["==", "!="], + ["string", "int", "object", "MyEnum"] ); [Theory] diff --git a/src/xunit.analyzers.tests/Fixes/X2000/UseAssertFailInsteadOfBooleanAssertFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/UseAssertFailInsteadOfBooleanAssertFixerTests.cs index ac7f6612..3c4b1507 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/UseAssertFailInsteadOfBooleanAssertFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/UseAssertFailInsteadOfBooleanAssertFixerTests.cs @@ -5,19 +5,21 @@ public class UseAssertFailInsteadOfBooleanAssertFixerTests { - const string template = @" -using Xunit; + const string template = /* lang=c#-test */ """ + + using Xunit; -public class TestClass {{ - [Fact] - public void TestMethod() {{ - {0}; - }} -}}"; + public class TestClass {{ + [Fact] + public void TestMethod() {{ + {0}; + }} + }} + """; [Theory] - [InlineData(@"[|Assert.True(false, ""message"")|]")] - [InlineData(@"[|Assert.False(true, ""message"")|]")] + [InlineData(/* lang=c#-test */ @"[|Assert.True(false, ""message"")|]")] + [InlineData(/* lang=c#-test */ @"[|Assert.False(true, ""message"")|]")] public async Task ReplacesBooleanAssert(string badAssert) { var before = string.Format(template, badAssert); diff --git a/src/xunit.analyzers.tests/Fixes/X2000/UseGenericOverloadFixTests.cs b/src/xunit.analyzers.tests/Fixes/X2000/UseGenericOverloadFixTests.cs index ebeb600e..3baea676 100644 --- a/src/xunit.analyzers.tests/Fixes/X2000/UseGenericOverloadFixTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X2000/UseGenericOverloadFixTests.cs @@ -9,29 +9,30 @@ public class UseGenericOverloadFixTests [Fact] public async Task X2007_SwitchesToGenericIsType() { - var before = @" -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - var result = 123; + var before = /* lang=c#-test */ """ + using Xunit; - [|Assert.IsType(typeof(int), result)|]; - } -}"; + public class TestClass { + [Fact] + public void TestMethod() { + var result = 123; - var after = @" -using Xunit; + [|Assert.IsType(typeof(int), result)|]; + } + } + """; + var after = /* lang=c#-test */ """ + using Xunit; -public class TestClass { - [Fact] - public void TestMethod() { - var result = 123; + public class TestClass { + [Fact] + public void TestMethod() { + var result = 123; - Assert.IsType(result); - } -}"; + Assert.IsType(result); + } + } + """; await Verify_X2007.VerifyCodeFix(before, after, UseGenericOverloadFix.Key_UseAlternateAssert); } @@ -39,31 +40,32 @@ public void TestMethod() { [Fact] public async Task X2015_SwitchesToGenericThrows() { - var before = @" -using System; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - Action func = () => { }; + var before = /* lang=c#-test */ """ + using System; + using Xunit; - [|Assert.Throws(typeof(DivideByZeroException), func)|]; - } -}"; + public class TestClass { + [Fact] + public void TestMethod() { + Action func = () => { }; - var after = @" -using System; -using Xunit; + [|Assert.Throws(typeof(DivideByZeroException), func)|]; + } + } + """; + var after = /* lang=c#-test */ """ + using System; + using Xunit; -public class TestClass { - [Fact] - public void TestMethod() { - Action func = () => { }; + public class TestClass { + [Fact] + public void TestMethod() { + Action func = () => { }; - Assert.Throws(func); - } -}"; + Assert.Throws(func); + } + } + """; await Verify_X2015.VerifyCodeFix(before, after, UseGenericOverloadFix.Key_UseAlternateAssert); } diff --git a/src/xunit.analyzers.tests/Fixes/X3000/CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X3000/CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectFixerTests.cs index ed55c51f..cbd3c7e0 100644 --- a/src/xunit.analyzers.tests/Fixes/X3000/CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X3000/CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectFixerTests.cs @@ -11,13 +11,13 @@ public class CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectFixerTests { public class WithAbstractions : CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectFixerTests { - readonly static string Template = "using Xunit.Abstractions; public class {0}: {1} {{ }}"; + const string Template = /* lang=c#-test */ "using Xunit.Abstractions; public class {0}: {1} {{ }}"; [Theory] [MemberData(nameof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithAbstractions.Interfaces), MemberType = typeof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithAbstractions))] public async Task DoesNotAttemptToFix(string @interface) { - var source = string.Format(Template, "[|MyClass|]", @interface); + var source = string.Format(Template, /* lang=c#-test */ "[|MyClass|]", @interface); await Verify_WithAbstractions.VerifyCodeFixV2( source, @@ -35,23 +35,25 @@ protected override XunitContext CreateXunitContext(Compilation compilation) => public class WithExecution { - static string Template_WithoutUsing = @" -using Xunit.Abstractions; + const string Template_WithoutUsing = /* lang=c#-test */ """ + using Xunit.Abstractions; -public class Foo {{ }} -public class {0}: {1} {{ }}"; - static string Template_WithUsing = @" -using Xunit; -using Xunit.Abstractions; + public class Foo {{ }} + public class {0}: {1} {{ }} + """; + const string Template_WithUsing = /* lang=c#-test */ """ + using Xunit; + using Xunit.Abstractions; -public class Foo {{ }} -public class {0}: {1} {{ }}"; + public class Foo {{ }} + public class {0}: {1} {{ }} + """; [Theory] [MemberData(nameof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithExecution.Interfaces), MemberType = typeof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithExecution))] public async Task WithNoBaseClass_WithoutUsing_AddsBaseClass(string @interface) { - var before = string.Format(Template_WithoutUsing, "[|MyClass|]", @interface); + var before = string.Format(Template_WithoutUsing, /* lang=c#-test */ "[|MyClass|]", @interface); var after = string.Format(Template_WithoutUsing, "MyClass", $"Xunit.LongLivedMarshalByRefObject, {@interface}"); await Verify_WithExecution.VerifyCodeFixV2( @@ -65,7 +67,7 @@ await Verify_WithExecution.VerifyCodeFixV2( [MemberData(nameof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithExecution.Interfaces), MemberType = typeof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithExecution))] public async Task WithNoBaseClass_WithUsing_AddsBaseClass(string @interface) { - var before = string.Format(Template_WithUsing, "[|MyClass|]", @interface); + var before = string.Format(Template_WithUsing, /* lang=c#-test */ "[|MyClass|]", @interface); var after = string.Format(Template_WithUsing, "MyClass", $"LongLivedMarshalByRefObject, {@interface}"); await Verify_WithExecution.VerifyCodeFixV2( @@ -79,7 +81,7 @@ await Verify_WithExecution.VerifyCodeFixV2( [MemberData(nameof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithExecution.Interfaces), MemberType = typeof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithExecution))] public async Task WithBadBaseClass_WithoutUsing_ReplacesBaseClass(string @interface) { - var before = string.Format(Template_WithoutUsing, "[|MyClass|]", $"Foo, {@interface}"); + var before = string.Format(Template_WithoutUsing, /* lang=c#-test */ "[|MyClass|]", $"Foo, {@interface}"); var after = string.Format(Template_WithoutUsing, "MyClass", $"Xunit.LongLivedMarshalByRefObject, {@interface}"); await Verify_WithExecution.VerifyCodeFixV2( @@ -93,7 +95,7 @@ await Verify_WithExecution.VerifyCodeFixV2( [MemberData(nameof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithExecution.Interfaces), MemberType = typeof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithExecution))] public async Task WithBadBaseClass_WithUsing_ReplacesBaseClass(string @interface) { - var before = string.Format(Template_WithUsing, "[|MyClass|]", $"Foo, {@interface}"); + var before = string.Format(Template_WithUsing, /* lang=c#-test */ "[|MyClass|]", $"Foo, {@interface}"); var after = string.Format(Template_WithUsing, "MyClass", $"LongLivedMarshalByRefObject, {@interface}"); await Verify_WithExecution.VerifyCodeFixV2( @@ -112,23 +114,25 @@ protected override XunitContext CreateXunitContext(Compilation compilation) => public class WithRunnerUtility { - static string Template_WithoutUsing = @" -using Xunit.Abstractions; + const string Template_WithoutUsing = /* lang=c#-test */ """ + using Xunit.Abstractions; -public class Foo {{ }} -public class {0}: {1} {{ }}"; - static string Template_WithUsing = @" -using Xunit.Abstractions; -using Xunit.Sdk; + public class Foo {{ }} + public class {0}: {1} {{ }} + """; + const string Template_WithUsing = /* lang=c#-test */ """ + using Xunit.Abstractions; + using Xunit.Sdk; -public class Foo {{ }} -public class {0}: {1} {{ }}"; + public class Foo {{ }} + public class {0}: {1} {{ }} + """; [Theory] [MemberData(nameof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithRunnerUtility.Interfaces), MemberType = typeof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithRunnerUtility))] public async Task WithNoBaseClass_WithoutUsing_AddsBaseClass(string @interface) { - var before = string.Format(Template_WithoutUsing, "[|MyClass|]", @interface); + var before = string.Format(Template_WithoutUsing, /* lang=c#-test */ "[|MyClass|]", @interface); var after = string.Format(Template_WithoutUsing, "MyClass", $"Xunit.Sdk.LongLivedMarshalByRefObject, {@interface}"); await Verify_WithRunnerUtility.VerifyCodeFixV2RunnerUtility( @@ -142,7 +146,7 @@ await Verify_WithRunnerUtility.VerifyCodeFixV2RunnerUtility( [MemberData(nameof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithRunnerUtility.Interfaces), MemberType = typeof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithRunnerUtility))] public async Task WithNoBaseClass_WithUsing_AddsBaseClass(string @interface) { - var before = string.Format(Template_WithUsing, "[|MyClass|]", @interface); + var before = string.Format(Template_WithUsing, /* lang=c#-test */ "[|MyClass|]", @interface); var after = string.Format(Template_WithUsing, "MyClass", $"LongLivedMarshalByRefObject, {@interface}"); await Verify_WithRunnerUtility.VerifyCodeFixV2RunnerUtility( @@ -156,7 +160,7 @@ await Verify_WithRunnerUtility.VerifyCodeFixV2RunnerUtility( [MemberData(nameof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithRunnerUtility.Interfaces), MemberType = typeof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithRunnerUtility))] public async Task WithBadBaseClass_WithoutUsing_ReplacesBaseClass(string @interface) { - var before = string.Format(Template_WithoutUsing, "[|MyClass|]", $"Foo, {@interface}"); + var before = string.Format(Template_WithoutUsing, /* lang=c#-test */ "[|MyClass|]", $"Foo, {@interface}"); var after = string.Format(Template_WithoutUsing, "MyClass", $"Xunit.Sdk.LongLivedMarshalByRefObject, {@interface}"); await Verify_WithRunnerUtility.VerifyCodeFixV2RunnerUtility( @@ -170,7 +174,7 @@ await Verify_WithRunnerUtility.VerifyCodeFixV2RunnerUtility( [MemberData(nameof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithRunnerUtility.Interfaces), MemberType = typeof(CrossAppDomainClassesMustBeLongLivedMarshalByRefObjectTests.WithRunnerUtility))] public async Task WithBadBaseClass_WithUsing_ReplacesBaseClass(string @interface) { - var before = string.Format(Template_WithUsing, "[|MyClass|]", $"Foo, {@interface}"); + var before = string.Format(Template_WithUsing, /* lang=c#-test */ "[|MyClass|]", $"Foo, {@interface}"); var after = string.Format(Template_WithUsing, "MyClass", $"LongLivedMarshalByRefObject, {@interface}"); await Verify_WithRunnerUtility.VerifyCodeFixV2RunnerUtility( diff --git a/src/xunit.analyzers.tests/Fixes/X3000/SerializableClassMustHaveParameterlessConstructorFixerTests.cs b/src/xunit.analyzers.tests/Fixes/X3000/SerializableClassMustHaveParameterlessConstructorFixerTests.cs index 66970f81..39482163 100644 --- a/src/xunit.analyzers.tests/Fixes/X3000/SerializableClassMustHaveParameterlessConstructorFixerTests.cs +++ b/src/xunit.analyzers.tests/Fixes/X3000/SerializableClassMustHaveParameterlessConstructorFixerTests.cs @@ -8,26 +8,27 @@ public class SerializableClassMustHaveParameterlessConstructorFixerTests [Fact] public async Task WithPublicParameteredConstructor_AddsNewConstructor() { - var beforeTemplate = @" -public class [|MyTestCase|]: {0}.IXunitSerializable {{ - public MyTestCase(int x) {{ }} - - void {0}.IXunitSerializable.Deserialize({0}.IXunitSerializationInfo _) {{ }} - void {0}.IXunitSerializable.Serialize({0}.IXunitSerializationInfo _) {{ }} -}}"; - - var afterTemplate = @" -public class MyTestCase: {0}.IXunitSerializable {{ - [System.Obsolete(""Called by the de-serializer; should only be called by deriving classes for de-serialization purposes"")] - public MyTestCase() - {{ - }} - - public MyTestCase(int x) {{ }} - - void {0}.IXunitSerializable.Deserialize({0}.IXunitSerializationInfo _) {{ }} - void {0}.IXunitSerializable.Serialize({0}.IXunitSerializationInfo _) {{ }} -}}"; + var beforeTemplate = /* lang=c#-test */ """ + public class [|MyTestCase|]: {0}.IXunitSerializable {{ + public MyTestCase(int x) {{ }} + + void {0}.IXunitSerializable.Deserialize({0}.IXunitSerializationInfo _) {{ }} + void {0}.IXunitSerializable.Serialize({0}.IXunitSerializationInfo _) {{ }} + }} + """; + var afterTemplate = /* lang=c#-test */ """ + public class MyTestCase: {0}.IXunitSerializable {{ + [System.Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")] + public MyTestCase() + {{ + }} + + public MyTestCase(int x) {{ }} + + void {0}.IXunitSerializable.Deserialize({0}.IXunitSerializationInfo _) {{ }} + void {0}.IXunitSerializable.Serialize({0}.IXunitSerializationInfo _) {{ }} + }} + """; var v2Before = string.Format(beforeTemplate, "Xunit.Abstractions"); var v2After = string.Format(afterTemplate, "Xunit.Abstractions"); @@ -43,26 +44,27 @@ public MyTestCase(int x) {{ }} [Fact] public async Task WithNonPublicParameterlessConstructor_ChangesVisibility_WithoutUsing() { - var beforeTemplate = @" -using {0}; + var beforeTemplate = /* lang=c#-test */ """ + using {0}; -public class [|MyTestCase|]: IXunitSerializable {{ - protected MyTestCase() {{ throw new System.DivideByZeroException(); }} + public class [|MyTestCase|]: IXunitSerializable {{ + protected MyTestCase() {{ throw new System.DivideByZeroException(); }} - void IXunitSerializable.Deserialize(IXunitSerializationInfo _) {{ }} - void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} -}}"; + void IXunitSerializable.Deserialize(IXunitSerializationInfo _) {{ }} + void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} + }} + """; + var afterTemplate = /* lang=c#-test */ """ + using {0}; - var afterTemplate = @" -using {0}; + public class MyTestCase: IXunitSerializable {{ + [System.Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")] + public MyTestCase() {{ throw new System.DivideByZeroException(); }} -public class MyTestCase: IXunitSerializable {{ - [System.Obsolete(""Called by the de-serializer; should only be called by deriving classes for de-serialization purposes"")] - public MyTestCase() {{ throw new System.DivideByZeroException(); }} - - void IXunitSerializable.Deserialize(IXunitSerializationInfo _) {{ }} - void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} -}}"; + void IXunitSerializable.Deserialize(IXunitSerializationInfo _) {{ }} + void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} + }} + """; var v2Before = string.Format(beforeTemplate, "Xunit.Abstractions"); var v2After = string.Format(afterTemplate, "Xunit.Abstractions"); @@ -78,28 +80,29 @@ void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} [Fact] public async Task WithNonPublicParameterlessConstructor_ChangesVisibility_WithUsing() { - var beforeTemplate = @" -using System; -using {0}; - -public class [|MyTestCase|]: IXunitSerializable {{ - protected MyTestCase() {{ throw new DivideByZeroException(); }} - - void IXunitSerializable.Deserialize(IXunitSerializationInfo _) {{ }} - void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} -}}"; - - var afterTemplate = @" -using System; -using {0}; - -public class MyTestCase: IXunitSerializable {{ - [Obsolete(""Called by the de-serializer; should only be called by deriving classes for de-serialization purposes"")] - public MyTestCase() {{ throw new DivideByZeroException(); }} - - void IXunitSerializable.Deserialize(IXunitSerializationInfo _) {{ }} - void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} -}}"; + var beforeTemplate = /* lang=c#-test */ """ + using System; + using {0}; + + public class [|MyTestCase|]: IXunitSerializable {{ + protected MyTestCase() {{ throw new DivideByZeroException(); }} + + void IXunitSerializable.Deserialize(IXunitSerializationInfo _) {{ }} + void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} + }} + """; + var afterTemplate = /* lang=c#-test */ """ + using System; + using {0}; + + public class MyTestCase: IXunitSerializable {{ + [Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")] + public MyTestCase() {{ throw new DivideByZeroException(); }} + + void IXunitSerializable.Deserialize(IXunitSerializationInfo _) {{ }} + void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} + }} + """; var v2Before = string.Format(beforeTemplate, "Xunit.Abstractions"); var v2After = string.Format(afterTemplate, "Xunit.Abstractions"); @@ -115,29 +118,30 @@ void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} [Fact] public async Task PreservesExistingObsoleteAttribute() { - var beforeTemplate = @" -using {0}; -using obo = System.ObsoleteAttribute; - -public class [|MyTestCase|]: IXunitSerializable {{ - [obo(""This is my custom obsolete message"")] - protected MyTestCase() {{ throw new System.DivideByZeroException(); }} - - void IXunitSerializable.Deserialize(IXunitSerializationInfo _) {{ }} - void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} -}}"; - - var afterTemplate = @" -using {0}; -using obo = System.ObsoleteAttribute; - -public class MyTestCase: IXunitSerializable {{ - [obo(""This is my custom obsolete message"")] - public MyTestCase() {{ throw new System.DivideByZeroException(); }} - - void IXunitSerializable.Deserialize(IXunitSerializationInfo _) {{ }} - void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} -}}"; + var beforeTemplate = /* lang=c#-test */ """ + using {0}; + using obo = System.ObsoleteAttribute; + + public class [|MyTestCase|]: IXunitSerializable {{ + [obo("This is my custom obsolete message")] + protected MyTestCase() {{ throw new System.DivideByZeroException(); }} + + void IXunitSerializable.Deserialize(IXunitSerializationInfo _) {{ }} + void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} + }} + """; + var afterTemplate = /* lang=c#-test */ """ + using {0}; + using obo = System.ObsoleteAttribute; + + public class MyTestCase: IXunitSerializable {{ + [obo("This is my custom obsolete message")] + public MyTestCase() {{ throw new System.DivideByZeroException(); }} + + void IXunitSerializable.Deserialize(IXunitSerializationInfo _) {{ }} + void IXunitSerializable.Serialize(IXunitSerializationInfo _) {{ }} + }} + """; var v2Before = string.Format(beforeTemplate, "Xunit.Abstractions"); var v2After = string.Format(afterTemplate, "Xunit.Abstractions"); diff --git a/src/xunit.analyzers.tests/Suppressors/ConsiderCallingConfigureAwaitSuppressorTests.cs b/src/xunit.analyzers.tests/Suppressors/ConsiderCallingConfigureAwaitSuppressorTests.cs index 4b246269..4c6d0a69 100644 --- a/src/xunit.analyzers.tests/Suppressors/ConsiderCallingConfigureAwaitSuppressorTests.cs +++ b/src/xunit.analyzers.tests/Suppressors/ConsiderCallingConfigureAwaitSuppressorTests.cs @@ -1,7 +1,6 @@ #if NETCOREAPP using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Testing; using Xunit; @@ -13,14 +12,15 @@ public sealed class ConsiderCallingConfigureAwaitSuppressorTests [Fact] public async Task NonTestMethod_DoesNotSuppress() { - var code = @" -using System.Threading.Tasks; + var code = /* lang=c#-test */ """ + using System.Threading.Tasks; -public class NonTestClass { - public async Task NonTestMethod() { - await {|CA2007:Task.Delay(1)|}; - } -}"; + public class NonTestClass { + public async Task NonTestMethod() { + await {|CA2007:Task.Delay(1)|}; + } + } + """; await Verify.VerifySuppressor(code, CodeAnalysisNetAnalyzers.CA2007()); } @@ -32,22 +32,18 @@ public async Task NonTestMethod() { [InlineData("TheoryAttribute")] public async Task StandardTestMethod_Suppresses(string attribute) { - var code = @$" -using System.Threading.Tasks; -using Xunit; - -public class TestClass {{ - [{attribute}] - public async Task TestMethod() {{ - await Task.Delay(1); - }} -}}"; - - // Roslyn 3.11 still surfaces the diagnostic that has been suppressed - var expected = - new DiagnosticResult("CA2007", DiagnosticSeverity.Warning) - .WithSpan(8, 15, 8, 28) - .WithIsSuppressed(true); + var code = string.Format(/* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; + + public class TestClass {{ + [{0}] + public async Task TestMethod() {{ + await {{|#0:Task.Delay(1)|}}; + }} + }} + """, attribute); + var expected = DiagnosticResult.CompilerWarning("CA2007").WithLocation(0).WithIsSuppressed(true); await Verify.VerifySuppressor(code, CodeAnalysisNetAnalyzers.CA2007(), expected); } @@ -55,18 +51,19 @@ public async Task TestMethod() {{ [Fact] public async Task CustomFactTestMethod_DoesNotSuppress() { - var code = @" -using System.Threading.Tasks; -using Xunit; + var code = /* lang=c#-test */ """ + using System.Threading.Tasks; + using Xunit; -internal class CustomFactAttribute : FactAttribute { } + internal class CustomFactAttribute : FactAttribute { } -public class TestClass { - [CustomFact] - public async Task TestMethod() { - await {|CA2007:Task.Delay(1)|}; - } -}"; + public class TestClass { + [CustomFact] + public async Task TestMethod() { + await {|CA2007:Task.Delay(1)|}; + } + } + """; await Verify.VerifySuppressor(code, CodeAnalysisNetAnalyzers.CA2007()); } @@ -74,19 +71,20 @@ public async Task TestMethod() { [Fact] public async Task CodeInsideFunctions_DoesNotSuppress() { - var code = @" -using System; -using System.Threading.Tasks; -using Xunit; - -public class TestClass { - [Fact] - public void TestMethod() { - async Task InnerMethod1() { await {|CA2007:Task.Delay(1)|}; } - async Task InnerMethod2() => await {|CA2007:Task.Delay(1)|}; - Func Lambda = async () => await {|CA2007:Task.Delay(1)|}; - } -}"; + var code = /* lang=c#-test */ """ + using System; + using System.Threading.Tasks; + using Xunit; + + public class TestClass { + [Fact] + public void TestMethod() { + async Task InnerMethod1() { await {|CA2007:Task.Delay(1)|}; } + async Task InnerMethod2() => await {|CA2007:Task.Delay(1)|}; + Func Lambda = async () => await {|CA2007:Task.Delay(1)|}; + } + } + """; await Verify.VerifySuppressor(LanguageVersion.CSharp7, code, CodeAnalysisNetAnalyzers.CA2007()); } diff --git a/src/xunit.analyzers.tests/Suppressors/MakeTypesInternalSuppressorTests.cs b/src/xunit.analyzers.tests/Suppressors/MakeTypesInternalSuppressorTests.cs index 92514ea4..7bf207d5 100644 --- a/src/xunit.analyzers.tests/Suppressors/MakeTypesInternalSuppressorTests.cs +++ b/src/xunit.analyzers.tests/Suppressors/MakeTypesInternalSuppressorTests.cs @@ -12,17 +12,13 @@ public sealed class MakeTypesInternalSuppressorTests [Fact] public async Task NonTestClass_DoesNotSuppress() { - var code = @" -public class NonTestClass { - public void NonTestMethod() { } -}"; + var code = /* lang=c#-test */ """ + public class {|CA1515:NonTestClass|} { + public void NonTestMethod() { } + } + """; - var expected = - new DiagnosticResult("CA1515", DiagnosticSeverity.Warning) - .WithSpan(2, 14, 2, 26) - .WithIsSuppressed(false); - - await Verify.VerifySuppressor(code, CodeAnalysisNetAnalyzers.CA1515(), expected); + await Verify.VerifySuppressor(code, CodeAnalysisNetAnalyzers.CA1515()); } [Theory] @@ -34,21 +30,17 @@ public void NonTestMethod() { } [InlineData("CustomFactAttribute")] public async Task TestClass_Suppresses(string attribute) { - var code = @$" -using Xunit; - -internal class CustomFactAttribute : FactAttribute {{ }} + var code = string.Format(/* lang=c#-test */ """ + using Xunit; -public class TestClass {{ - [{attribute}] - public void TestMethod() {{ }} -}}"; + internal class CustomFactAttribute : FactAttribute {{ }} - // Roslyn 3.11 still surfaces the diagnostic that has been suppressed - var expected = - new DiagnosticResult("CA1515", DiagnosticSeverity.Warning) - .WithSpan(6, 14, 6, 23) - .WithIsSuppressed(true); + public class {{|#0:TestClass|}} {{ + [{0}] + public void TestMethod() {{ }} + }} + """, attribute); + var expected = new DiagnosticResult("CA1515", DiagnosticSeverity.Warning).WithLocation(0).WithIsSuppressed(true); await Verify.VerifySuppressor(code, CodeAnalysisNetAnalyzers.CA1515(), expected); } diff --git a/src/xunit.analyzers.tests/Utility/CodeAnalyzerHelper.cs b/src/xunit.analyzers.tests/Utility/CodeAnalyzerHelper.cs index a2a6328c..de066b80 100644 --- a/src/xunit.analyzers.tests/Utility/CodeAnalyzerHelper.cs +++ b/src/xunit.analyzers.tests/Utility/CodeAnalyzerHelper.cs @@ -39,8 +39,8 @@ static CodeAnalyzerHelper() new PackageIdentity("System.Collections.Immutable", "1.6.0"), new PackageIdentity("System.Threading.Tasks.Extensions", "4.5.4"), new PackageIdentity("xunit.abstractions", "2.0.3"), - new PackageIdentity("xunit.assert", "2.8.2-pre.19"), - new PackageIdentity("xunit.core", "2.8.2-pre.19") + new PackageIdentity("xunit.assert", "2.9.1-pre.5"), + new PackageIdentity("xunit.core", "2.9.1-pre.5") ) ); @@ -51,7 +51,7 @@ static CodeAnalyzerHelper() new PackageIdentity("System.Collections.Immutable", "1.6.0"), new PackageIdentity("System.Threading.Tasks.Extensions", "4.5.4"), new PackageIdentity("xunit.abstractions", "2.0.3"), - new PackageIdentity("xunit.runner.utility", "2.8.2-pre.19") + new PackageIdentity("xunit.runner.utility", "2.9.1-pre.5") ) ); diff --git a/src/xunit.analyzers.tests/xunit.analyzers.tests.csproj b/src/xunit.analyzers.tests/xunit.analyzers.tests.csproj index 888f4179..ac19a533 100644 --- a/src/xunit.analyzers.tests/xunit.analyzers.tests.csproj +++ b/src/xunit.analyzers.tests/xunit.analyzers.tests.csproj @@ -12,8 +12,8 @@ - - + + diff --git a/src/xunit.analyzers/X1000/PublicMethodShouldBeMarkedAsTest.cs b/src/xunit.analyzers/X1000/PublicMethodShouldBeMarkedAsTest.cs index c5baa6f9..b021d756 100644 --- a/src/xunit.analyzers/X1000/PublicMethodShouldBeMarkedAsTest.cs +++ b/src/xunit.analyzers/X1000/PublicMethodShouldBeMarkedAsTest.cs @@ -84,7 +84,7 @@ public override void AnalyzeCompilation( var shouldIgnore = false; while (!shouldIgnore || method.IsOverride) { - if (methodsToIgnore.Any(m => SymbolEqualityComparer.Default.Equals(method, m))) + if (methodsToIgnore.Any(m => SymbolEqualityComparer.Default.Equals(method, m)) || !method.ReceiverType.IsTestClass(xunitContext, strict: true)) shouldIgnore = true; if (!method.IsOverride) diff --git a/tools/builder/common b/tools/builder/common index 90dba1f5..1faa6934 160000 --- a/tools/builder/common +++ b/tools/builder/common @@ -1 +1 @@ -Subproject commit 90dba1f5638a4f00d4978a73e23edde5b85061d9 +Subproject commit 1faa6934a6c163aa377b1bcc96ff65cbc3a9eac4