|
18 | 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
19 | 19 | */
|
20 | 20 |
|
21 |
| -namespace SonarAnalyzer.Helpers |
| 21 | +namespace SonarAnalyzer.Helpers; |
| 22 | + |
| 23 | +// Note: useful comparison of the differing syntax across unit test frameworks at https://xunit.net/docs/comparisons |
| 24 | +internal static class UnitTestHelper |
22 | 25 | {
|
23 |
| - // Note: useful comparison of the differing syntax across unit test frameworks at https://xunit.net/docs/comparisons |
24 |
| - internal static class UnitTestHelper |
25 |
| - { |
26 |
| - public static readonly ImmutableArray<KnownType> KnownTestMethodAttributesOfMSTest = ImmutableArray.Create( |
27 |
| - KnownType.Microsoft_VisualStudio_TestTools_UnitTesting_TestMethodAttribute, |
28 |
| - KnownType.Microsoft_VisualStudio_TestTools_UnitTesting_DataTestMethodAttribute); |
29 |
| - |
30 |
| - public static readonly ImmutableArray<KnownType> KnownTestMethodAttributesOfNUnit = ImmutableArray.Create( |
31 |
| - KnownType.NUnit_Framework_TestAttribute, |
32 |
| - KnownType.NUnit_Framework_TestCaseAttribute, |
33 |
| - KnownType.NUnit_Framework_TestCaseSourceAttribute, |
34 |
| - KnownType.NUnit_Framework_TheoryAttribute, |
35 |
| - KnownType.NUnit_Framework_ITestBuilderInterface); |
36 |
| - |
37 |
| - public static readonly ImmutableArray<KnownType> KnownTestMethodAttributesOfxUnit = ImmutableArray.Create( |
38 |
| - KnownType.Xunit_TheoryAttribute, |
39 |
| - KnownType.LegacyXunit_TheoryAttribute, |
40 |
| - // In order for the FindFirstTestMethodType to work, FactAttribute should go last as the Theory attribute derives from it. |
41 |
| - KnownType.Xunit_FactAttribute); |
42 |
| - |
43 |
| - public static readonly ImmutableArray<KnownType> KnownExpectedExceptionAttributes = ImmutableArray.Create( |
44 |
| - // Note: XUnit doesn't have a exception attribute |
45 |
| - KnownType.Microsoft_VisualStudio_TestTools_UnitTesting_ExpectedExceptionAttribute, |
46 |
| - KnownType.NUnit_Framework_ExpectedExceptionAttribute); |
47 |
| - |
48 |
| - public static readonly ImmutableArray<KnownType> KnownIgnoreAttributes = ImmutableArray.Create( |
49 |
| - // Note: XUnit doesn't have a separate "Ignore" attribute. It has a "Skip" parameter |
50 |
| - // on the test attribute |
51 |
| - KnownType.Microsoft_VisualStudio_TestTools_UnitTesting_IgnoreAttribute, |
52 |
| - KnownType.NUnit_Framework_IgnoreAttribute); |
53 |
| - |
54 |
| - /// <summary> |
55 |
| - /// List of partial names that are assumed to indicate an assertion method. |
56 |
| - /// </summary> |
57 |
| - public static readonly ImmutableArray<string> KnownAssertionMethodParts = ImmutableArray.Create( |
58 |
| - "ASSERT", |
59 |
| - "CHECK", |
60 |
| - "EXPECT", |
61 |
| - "MUST", |
62 |
| - "SHOULD", |
63 |
| - "VERIFY", |
64 |
| - "VALIDATE"); |
65 |
| - |
66 |
| - private static readonly ImmutableArray<KnownType> KnownTestMethodAttributes = ImmutableArray.Create( |
67 |
| - KnownTestMethodAttributesOfMSTest |
68 |
| - .Concat(KnownTestMethodAttributesOfNUnit) |
69 |
| - .Concat(KnownTestMethodAttributesOfxUnit) |
70 |
| - .ToArray()); |
71 |
| - |
72 |
| - private static readonly ImmutableArray<KnownType> KnownTestClassAttributes = ImmutableArray.Create( |
73 |
| - // xUnit does not have have attributes to identity test classes |
74 |
| - KnownType.Microsoft_VisualStudio_TestTools_UnitTesting_TestClassAttribute, |
75 |
| - KnownType.NUnit_Framework_TestFixtureAttribute); |
76 |
| - |
77 |
| - private static readonly ImmutableArray<KnownType> NoExpectedResultTestMethodReturnTypes = ImmutableArray.Create( |
78 |
| - KnownType.Void, |
79 |
| - KnownType.System_Threading_Tasks_Task); |
80 |
| - |
81 |
| - /// <summary> |
82 |
| - /// Returns whether the class has an attribute that marks the class |
83 |
| - /// as an MSTest or NUnit test class (xUnit doesn't have any such attributes). |
84 |
| - /// </summary> |
85 |
| - public static bool IsTestClass(this INamedTypeSymbol classSymbol) => |
86 |
| - classSymbol.AnyAttributeDerivesFromAny(KnownTestClassAttributes); |
87 |
| - |
88 |
| - public static bool IsTestMethod(this IMethodSymbol method) => |
89 |
| - method.AnyAttributeDerivesFromOrImplementsAny(KnownTestMethodAttributes); |
90 |
| - |
91 |
| - public static bool HasExpectedExceptionAttribute(this IMethodSymbol method) => |
92 |
| - method.GetAttributes().Any(a => |
93 |
| - a.AttributeClass.IsAny(KnownExpectedExceptionAttributes) |
94 |
| - || a.AttributeClass.DerivesFrom(KnownType.Microsoft_VisualStudio_TestTools_UnitTesting_ExpectedExceptionBaseAttribute)); |
95 |
| - |
96 |
| - public static bool HasAssertionInAttribute(this IMethodSymbol method) => |
97 |
| - !NoExpectedResultTestMethodReturnTypes.Any(method.ReturnType.Is) |
98 |
| - && method.GetAttributes().Any(IsAnyTestCaseAttributeWithExpectedResult); |
99 |
| - |
100 |
| - public static bool IsMsTestOrNUnitTestIgnored(this IMethodSymbol method) => |
101 |
| - method.GetAttributes().Any(a => a.AttributeClass.IsAny(KnownIgnoreAttributes)); |
102 |
| - |
103 |
| - public static AttributeData FindXUnitTestAttribute(this IMethodSymbol method) => |
104 |
| - method.GetAttributes().FirstOrDefault(a => |
105 |
| - a.AttributeClass.Is(KnownType.Xunit_FactAttribute) |
106 |
| - || a.AttributeClass.Is(KnownType.Xunit_TheoryAttribute) |
107 |
| - || a.AttributeClass.Is(KnownType.LegacyXunit_TheoryAttribute)); |
108 |
| - |
109 |
| - /// <summary> |
110 |
| - /// Returns the <see cref="KnownType"/> that indicates the type of the test method or |
111 |
| - /// null if the method is not decorated with a known type. |
112 |
| - /// </summary> |
113 |
| - /// <remarks>We assume that a test is only marked with a single test attribute e.g. |
114 |
| - /// not both [Fact] and [Theory]. If there are multiple attributes only one will be |
115 |
| - /// returned.</remarks> |
116 |
| - public static KnownType FindFirstTestMethodType(this IMethodSymbol method) => |
117 |
| - KnownTestMethodAttributes.FirstOrDefault(known => |
118 |
| - method.GetAttributes().Any(att => att.AttributeClass.DerivesFrom(known))); |
119 |
| - |
120 |
| - private static bool IsAnyTestCaseAttributeWithExpectedResult(AttributeData a) => |
121 |
| - IsTestAttributeWithExpectedResult(a) |
122 |
| - || a.AttributeClass.Is(KnownType.NUnit_Framework_TestCaseSourceAttribute); |
123 |
| - |
124 |
| - private static bool IsTestAttributeWithExpectedResult(AttributeData a) => |
125 |
| - a.AttributeClass.IsAny(KnownType.NUnit_Framework_TestCaseAttribute, KnownType.NUnit_Framework_TestAttribute) |
126 |
| - && a.NamedArguments.Any(arg => arg.Key == "ExpectedResult"); |
127 |
| - } |
| 26 | + public static readonly ImmutableArray<KnownType> KnownTestMethodAttributesOfMSTest = ImmutableArray.Create( |
| 27 | + KnownType.Microsoft_VisualStudio_TestTools_UnitTesting_TestMethodAttribute, |
| 28 | + KnownType.Microsoft_VisualStudio_TestTools_UnitTesting_DataTestMethodAttribute); |
| 29 | + |
| 30 | + public static readonly ImmutableArray<KnownType> KnownTestMethodAttributesOfNUnit = ImmutableArray.Create( |
| 31 | + KnownType.NUnit_Framework_TestAttribute, |
| 32 | + KnownType.NUnit_Framework_TestCaseAttribute, |
| 33 | + KnownType.NUnit_Framework_TestCaseSourceAttribute, |
| 34 | + KnownType.NUnit_Framework_TheoryAttribute, |
| 35 | + KnownType.NUnit_Framework_ITestBuilderInterface); |
| 36 | + |
| 37 | + public static readonly ImmutableArray<KnownType> KnownTestMethodAttributesOfxUnit = ImmutableArray.Create( |
| 38 | + KnownType.Xunit_TheoryAttribute, |
| 39 | + KnownType.LegacyXunit_TheoryAttribute, |
| 40 | + // In order for the FindFirstTestMethodType to work, FactAttribute should go last as the Theory attribute derives from it. |
| 41 | + KnownType.Xunit_FactAttribute); |
| 42 | + |
| 43 | + public static readonly ImmutableArray<KnownType> KnownExpectedExceptionAttributes = ImmutableArray.Create( |
| 44 | + // Note: XUnit doesn't have a exception attribute |
| 45 | + KnownType.Microsoft_VisualStudio_TestTools_UnitTesting_ExpectedExceptionAttribute, |
| 46 | + KnownType.NUnit_Framework_ExpectedExceptionAttribute); |
| 47 | + |
| 48 | + public static readonly ImmutableArray<KnownType> KnownIgnoreAttributes = ImmutableArray.Create( |
| 49 | + // Note: XUnit doesn't have a separate "Ignore" attribute. It has a "Skip" parameter |
| 50 | + // on the test attribute |
| 51 | + KnownType.Microsoft_VisualStudio_TestTools_UnitTesting_IgnoreAttribute, |
| 52 | + KnownType.NUnit_Framework_IgnoreAttribute); |
| 53 | + |
| 54 | + /// <summary> |
| 55 | + /// List of partial names that are assumed to indicate an assertion method. |
| 56 | + /// </summary> |
| 57 | + public static readonly ImmutableArray<string> KnownAssertionMethodParts = ImmutableArray.Create( |
| 58 | + "ASSERT", |
| 59 | + "CHECK", |
| 60 | + "EXPECT", |
| 61 | + "MUST", |
| 62 | + "SHOULD", |
| 63 | + "VERIFY", |
| 64 | + "VALIDATE"); |
| 65 | + |
| 66 | + private static readonly ImmutableArray<KnownType> KnownTestMethodAttributes = ImmutableArray.Create( |
| 67 | + KnownTestMethodAttributesOfMSTest |
| 68 | + .Concat(KnownTestMethodAttributesOfNUnit) |
| 69 | + .Concat(KnownTestMethodAttributesOfxUnit) |
| 70 | + .ToArray()); |
| 71 | + |
| 72 | + private static readonly ImmutableArray<KnownType> KnownTestClassAttributes = ImmutableArray.Create( |
| 73 | + // xUnit does not have have attributes to identity test classes |
| 74 | + KnownType.Microsoft_VisualStudio_TestTools_UnitTesting_TestClassAttribute, |
| 75 | + KnownType.NUnit_Framework_TestFixtureAttribute); |
| 76 | + |
| 77 | + private static readonly ImmutableArray<KnownType> NoExpectedResultTestMethodReturnTypes = ImmutableArray.Create( |
| 78 | + KnownType.Void, |
| 79 | + KnownType.System_Threading_Tasks_Task); |
| 80 | + |
| 81 | + /// <summary> |
| 82 | + /// Returns whether the class has an attribute that marks the class |
| 83 | + /// as an MSTest or NUnit test class (xUnit doesn't have any such attributes). |
| 84 | + /// </summary> |
| 85 | + public static bool IsTestClass(this INamedTypeSymbol classSymbol) => |
| 86 | + classSymbol.AnyAttributeDerivesFromAny(KnownTestClassAttributes); |
| 87 | + |
| 88 | + public static bool IsTestMethod(this IMethodSymbol method) => |
| 89 | + method.MethodKind.HasFlag(MethodKindEx.LocalFunction) |
| 90 | + ? method.IsXunitTestMethod() |
| 91 | + : method.AnyAttributeDerivesFromOrImplementsAny(KnownTestMethodAttributes); |
| 92 | + |
| 93 | + public static bool IsIgnoredTestMethod(this IMethodSymbol method) => |
| 94 | + method.IsMsTestOrNUnitTestIgnored() |
| 95 | + || method.FindXUnitTestAttribute().NamedArguments.Any(arg => arg.Key == "Skip"); |
| 96 | + |
| 97 | + public static bool HasExpectedExceptionAttribute(this IMethodSymbol method) => |
| 98 | + method.GetAttributes().Any(a => |
| 99 | + a.AttributeClass.IsAny(KnownExpectedExceptionAttributes) |
| 100 | + || a.AttributeClass.DerivesFrom(KnownType.Microsoft_VisualStudio_TestTools_UnitTesting_ExpectedExceptionBaseAttribute)); |
| 101 | + |
| 102 | + public static bool HasAssertionInAttribute(this IMethodSymbol method) => |
| 103 | + !NoExpectedResultTestMethodReturnTypes.Any(method.ReturnType.Is) |
| 104 | + && method.GetAttributes().Any(IsAnyTestCaseAttributeWithExpectedResult); |
| 105 | + |
| 106 | + public static AttributeData FindXUnitTestAttribute(this IMethodSymbol method) => |
| 107 | + method.GetAttributes().FirstOrDefault(a => |
| 108 | + a.AttributeClass.Is(KnownType.Xunit_FactAttribute) |
| 109 | + || a.AttributeClass.Is(KnownType.Xunit_TheoryAttribute) |
| 110 | + || a.AttributeClass.Is(KnownType.LegacyXunit_TheoryAttribute)); |
| 111 | + |
| 112 | + /// <summary> |
| 113 | + /// Returns the <see cref="KnownType"/> that indicates the type of the test method or |
| 114 | + /// null if the method is not decorated with a known type. |
| 115 | + /// </summary> |
| 116 | + /// <remarks>We assume that a test is only marked with a single test attribute e.g. |
| 117 | + /// not both [Fact] and [Theory]. If there are multiple attributes only one will be |
| 118 | + /// returned.</remarks> |
| 119 | + public static KnownType FindFirstTestMethodType(this IMethodSymbol method) => |
| 120 | + KnownTestMethodAttributes.FirstOrDefault(known => |
| 121 | + method.GetAttributes().Any(att => att.AttributeClass.DerivesFrom(known))); |
| 122 | + |
| 123 | + private static bool IsAnyTestCaseAttributeWithExpectedResult(AttributeData a) => |
| 124 | + IsTestAttributeWithExpectedResult(a) |
| 125 | + || a.AttributeClass.Is(KnownType.NUnit_Framework_TestCaseSourceAttribute); |
| 126 | + |
| 127 | + private static bool IsTestAttributeWithExpectedResult(AttributeData a) => |
| 128 | + a.AttributeClass.IsAny(KnownType.NUnit_Framework_TestCaseAttribute, KnownType.NUnit_Framework_TestAttribute) |
| 129 | + && a.NamedArguments.Any(arg => arg.Key == "ExpectedResult"); |
| 130 | + |
| 131 | + private static bool IsXunitTestMethod(this IMethodSymbol methodSymbol) => |
| 132 | + methodSymbol.AnyAttributeDerivesFromAny(KnownTestMethodAttributesOfxUnit); |
| 133 | + |
| 134 | + private static bool IsMsTestOrNUnitTestIgnored(this IMethodSymbol method) => |
| 135 | + method.GetAttributes().Any(a => a.AttributeClass.IsAny(KnownIgnoreAttributes)); |
128 | 136 | }
|
0 commit comments