Skip to content

Commit 4bb7855

Browse files
authored
Support xunit.v3 in Microsoft.DotNet.XUnitExtensions (#15668)
1 parent bef5823 commit 4bb7855

File tree

72 files changed

+1036
-221
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1036
-221
lines changed

Arcade.sln

+21
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.MacOsPkg.T
153153
EndProject
154154
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DotNet.StrongName", "src\Microsoft.DotNet.StrongName\Microsoft.DotNet.StrongName.csproj", "{B65809A4-C6DB-4994-BBDE-D5B8396958A6}"
155155
EndProject
156+
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.DotNet.XUnitExtensions.Shared", "src\Microsoft.DotNet.XUnitExtensions.Shared\Microsoft.DotNet.XUnitExtensions.Shared.shproj", "{3A0BC9CF-F9BF-4961-8615-1919C99FDD27}"
157+
EndProject
158+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DotNet.XUnitV3Extensions", "src\Microsoft.DotNet.XUnitV3Extensions\src\Microsoft.DotNet.XUnitV3Extensions.csproj", "{B6625157-A06A-431F-8424-7CC41EE7038E}"
159+
EndProject
156160
Global
157161
GlobalSection(SolutionConfigurationPlatforms) = preSolution
158162
Debug|Any CPU = Debug|Any CPU
@@ -1015,6 +1019,18 @@ Global
10151019
{B65809A4-C6DB-4994-BBDE-D5B8396958A6}.Release|x64.Build.0 = Release|Any CPU
10161020
{B65809A4-C6DB-4994-BBDE-D5B8396958A6}.Release|x86.ActiveCfg = Release|Any CPU
10171021
{B65809A4-C6DB-4994-BBDE-D5B8396958A6}.Release|x86.Build.0 = Release|Any CPU
1022+
{B6625157-A06A-431F-8424-7CC41EE7038E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1023+
{B6625157-A06A-431F-8424-7CC41EE7038E}.Debug|Any CPU.Build.0 = Debug|Any CPU
1024+
{B6625157-A06A-431F-8424-7CC41EE7038E}.Debug|x64.ActiveCfg = Debug|Any CPU
1025+
{B6625157-A06A-431F-8424-7CC41EE7038E}.Debug|x64.Build.0 = Debug|Any CPU
1026+
{B6625157-A06A-431F-8424-7CC41EE7038E}.Debug|x86.ActiveCfg = Debug|Any CPU
1027+
{B6625157-A06A-431F-8424-7CC41EE7038E}.Debug|x86.Build.0 = Debug|Any CPU
1028+
{B6625157-A06A-431F-8424-7CC41EE7038E}.Release|Any CPU.ActiveCfg = Release|Any CPU
1029+
{B6625157-A06A-431F-8424-7CC41EE7038E}.Release|Any CPU.Build.0 = Release|Any CPU
1030+
{B6625157-A06A-431F-8424-7CC41EE7038E}.Release|x64.ActiveCfg = Release|Any CPU
1031+
{B6625157-A06A-431F-8424-7CC41EE7038E}.Release|x64.Build.0 = Release|Any CPU
1032+
{B6625157-A06A-431F-8424-7CC41EE7038E}.Release|x86.ActiveCfg = Release|Any CPU
1033+
{B6625157-A06A-431F-8424-7CC41EE7038E}.Release|x86.Build.0 = Release|Any CPU
10181034
EndGlobalSection
10191035
GlobalSection(SolutionProperties) = preSolution
10201036
HideSolutionNode = FALSE
@@ -1053,4 +1069,9 @@ Global
10531069
GlobalSection(ExtensibilityGlobals) = postSolution
10541070
SolutionGuid = {32B9C883-432E-4FC8-A1BF-090EB033DD5B}
10551071
EndGlobalSection
1072+
GlobalSection(SharedMSBuildProjectFiles) = preSolution
1073+
src\Microsoft.DotNet.XUnitExtensions.Shared\Microsoft.DotNet.XUnitExtensions.Shared.projitems*{3a0bc9cf-f9bf-4961-8615-1919c99fdd27}*SharedItemsImports = 13
1074+
src\Microsoft.DotNet.XUnitExtensions.Shared\Microsoft.DotNet.XUnitExtensions.Shared.projitems*{b6625157-a06a-431f-8424-7cc41ee7038e}*SharedItemsImports = 5
1075+
src\Microsoft.DotNet.XUnitExtensions.Shared\Microsoft.DotNet.XUnitExtensions.Shared.projitems*{f8e7fec3-b9e0-4a08-8608-f48379204f3a}*SharedItemsImports = 5
1076+
EndGlobalSection
10561077
EndGlobal

Directory.Packages.props

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<!-- Overwrite XUnitVersion/XUnitAnalyzersVersion/XUnitRunnerConsoleVersion/XUnitRunnerVisualStudioVersion that comes from the Arcade SDK to be in sync as Arcade doesn't use a live Arcade SDK.
1515
Keep in sync with DefaultVersions.props. -->
1616
<XUnitVersion>2.9.2</XUnitVersion>
17+
<XUnitV3Version>2.0.0</XUnitV3Version>
1718
<XUnitAnalyzersVersion>1.16.0</XUnitAnalyzersVersion>
1819
<XUnitRunnerConsoleVersion>$(XUnitVersion)</XUnitRunnerConsoleVersion>
1920
<XUnitRunnerVisualStudioVersion>3.0.2</XUnitRunnerVisualStudioVersion>
@@ -103,6 +104,7 @@
103104
<PackageVersion Include="xunit.abstractions" Version="2.0.3" />
104105
<PackageVersion Include="xunit.extensibility.core" Version="$(XUnitVersion)" />
105106
<PackageVersion Include="xunit.extensibility.execution" Version="$(XUnitVersion)" />
107+
<PackageVersion Include="xunit.v3.extensibility.core" Version="$(XUnitV3Version)" />
106108
<PackageVersion Include="xunit.runner.reporters" Version="$(XUnitVersion)" />
107109
<PackageVersion Include="nsubstitute" Version="5.1.0" />
108110
</ItemGroup>

src/Microsoft.DotNet.XUnitExtensions/src/Attributes/ActiveIssueAttribute.cs src/Microsoft.DotNet.XUnitExtensions.Shared/Attributes/ActiveIssueAttribute.cs

+47-4
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,71 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using Microsoft.DotNet.XUnitExtensions;
58
using Xunit.Sdk;
69

710
namespace Xunit
811
{
912
/// <summary>
1013
/// Apply this attribute to your test method to specify an active issue.
1114
/// </summary>
15+
#if !USES_XUNIT_3
1216
[TraitDiscoverer("Microsoft.DotNet.XUnitExtensions.ActiveIssueDiscoverer", "Microsoft.DotNet.XUnitExtensions")]
17+
#endif
1318
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]
1419
public class ActiveIssueAttribute : Attribute, ITraitAttribute
1520
{
21+
#if USES_XUNIT_3
22+
private readonly IEnumerable<object> _ctorArgs;
23+
#endif
24+
1625
public Type CalleeType { get; private set; }
1726
public string[] ConditionMemberNames { get; private set; }
1827

19-
public ActiveIssueAttribute(string issue, TestPlatforms platforms) { }
20-
public ActiveIssueAttribute(string issue, TargetFrameworkMonikers framework) { }
21-
public ActiveIssueAttribute(string issue, TestRuntimes runtimes) { }
22-
public ActiveIssueAttribute(string issue, TestPlatforms platforms = TestPlatforms.Any, TargetFrameworkMonikers framework = TargetFrameworkMonikers.Any, TestRuntimes runtimes = TestRuntimes.Any) { }
28+
public ActiveIssueAttribute(string issue, TestPlatforms platforms)
29+
{
30+
#if USES_XUNIT_3
31+
_ctorArgs = [issue, platforms];
32+
#endif
33+
}
34+
35+
public ActiveIssueAttribute(string issue, TargetFrameworkMonikers framework)
36+
{
37+
#if USES_XUNIT_3
38+
_ctorArgs = [issue, framework];
39+
#endif
40+
}
41+
42+
public ActiveIssueAttribute(string issue, TestRuntimes runtimes)
43+
{
44+
#if USES_XUNIT_3
45+
_ctorArgs = [issue, runtimes];
46+
#endif
47+
}
48+
49+
public ActiveIssueAttribute(string issue, TestPlatforms platforms = TestPlatforms.Any, TargetFrameworkMonikers framework = TargetFrameworkMonikers.Any, TestRuntimes runtimes = TestRuntimes.Any)
50+
{
51+
#if USES_XUNIT_3
52+
_ctorArgs = [issue, platforms, framework, runtimes];
53+
#endif
54+
}
55+
2356
public ActiveIssueAttribute(string issue, Type calleeType, params string[] conditionMemberNames)
2457
{
58+
#if USES_XUNIT_3
59+
_ctorArgs = [issue, calleeType, conditionMemberNames];
60+
#endif
2561
CalleeType = calleeType;
2662
ConditionMemberNames = conditionMemberNames;
2763
}
64+
65+
#if USES_XUNIT_3
66+
public IReadOnlyCollection<KeyValuePair<string, string>> GetTraits()
67+
{
68+
return DiscovererHelpers.EvaluateArguments(_ctorArgs, XunitConstants.Failing).ToArray();
69+
}
70+
#endif
2871
}
2972
}

src/Microsoft.DotNet.XUnitExtensions/src/Attributes/ConditionalClassAttribute.cs src/Microsoft.DotNet.XUnitExtensions.Shared/Attributes/ConditionalClassAttribute.cs

+32
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Collections.Generic;
6+
using System.Diagnostics;
57
using System.Diagnostics.CodeAnalysis;
8+
using System.Linq;
9+
using Microsoft.DotNet.XUnitExtensions;
610
using Xunit.Sdk;
711

812
namespace Xunit
913
{
14+
#if !USES_XUNIT_3
1015
[TraitDiscoverer("Microsoft.DotNet.XUnitExtensions.ConditionalClassDiscoverer", "Microsoft.DotNet.XUnitExtensions")]
16+
#endif
1117
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
1218
public sealed class ConditionalClassAttribute : Attribute, ITraitAttribute
1319
{
@@ -23,5 +29,31 @@ public ConditionalClassAttribute(
2329
CalleeType = calleeType;
2430
ConditionMemberNames = conditionMemberNames;
2531
}
32+
33+
#if USES_XUNIT_3
34+
public IReadOnlyCollection<KeyValuePair<string, string>> GetTraits()
35+
{
36+
// If evaluated to false, skip the test class entirely.
37+
if (!EvaluateParameterHelper())
38+
{
39+
return [new KeyValuePair<string, string>(XunitConstants.Category, XunitConstants.Failing)];
40+
}
41+
42+
return [];
43+
}
44+
45+
internal bool EvaluateParameterHelper()
46+
{
47+
Type calleeType = null;
48+
string[] conditionMemberNames = null;
49+
50+
if (ConditionalTestDiscoverer.CheckInputToSkipExecution([CalleeType, ConditionMemberNames], ref calleeType, ref conditionMemberNames))
51+
{
52+
return true;
53+
}
54+
55+
return DiscovererHelpers.Evaluate(calleeType, conditionMemberNames);
56+
}
57+
#endif
2658
}
2759
}

src/Microsoft.DotNet.XUnitExtensions/src/Attributes/ConditionalFactAttribute.cs src/Microsoft.DotNet.XUnitExtensions.Shared/Attributes/ConditionalFactAttribute.cs

+14
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
5+
// Not adding the support for xunit.v3.
6+
// Still keeping the logic inside compatible with xunit.v3 in case we decided to add it.
7+
// For cases that used to do [ConditionalFact] in xunit.v2, they can now call Assert.Skip instead of throwing SkipTestException
8+
// In this case, [Fact] will just work because Assert.Skip is natively supported in xunit.v3
9+
// TODO: Evaluate whether or not we want to still expose this attribute in xunit.v3 for usages of CalleeType and ConditionMemberNames?
10+
#if !USES_XUNIT_3
11+
412
using System;
513
using System.Diagnostics.CodeAnalysis;
14+
using Microsoft.DotNet.XUnitExtensions;
615
using Xunit.Sdk;
716

817
namespace Xunit
918
{
19+
#if USES_XUNIT_3
20+
[XunitTestCaseDiscoverer(typeof(ConditionalFactDiscoverer))]
21+
#else
1022
[XunitTestCaseDiscoverer("Microsoft.DotNet.XUnitExtensions.ConditionalFactDiscoverer", "Microsoft.DotNet.XUnitExtensions")]
23+
#endif
1124
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
1225
public sealed class ConditionalFactAttribute : FactAttribute
1326
{
@@ -30,3 +43,4 @@ public ConditionalFactAttribute(params string[] conditionMemberNames)
3043
}
3144
}
3245
}
46+
#endif

src/Microsoft.DotNet.XUnitExtensions/src/Attributes/ConditionalTheoryAttribute.cs src/Microsoft.DotNet.XUnitExtensions.Shared/Attributes/ConditionalTheoryAttribute.cs

+13
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
// Not adding the support for xunit.v3.
5+
// Still keeping the logic inside compatible with xunit.v3 in case we decided to add it.
6+
// For cases that used to do [ConditionalTheory] in xunit.v2, they can now call Assert.Skip instead of throwing SkipTestException
7+
// In this case, [Fact] will just work because Assert.Skip is natively supported in xunit.v3
8+
// TODO: Evaluate whether or not we want to still expose this attribute in xunit.v3 for usages of CalleeType and ConditionMemberNames?
9+
#if !USES_XUNIT_3
10+
411
using System;
512
using System.Diagnostics.CodeAnalysis;
13+
using Microsoft.DotNet.XUnitExtensions;
614
using Xunit.Sdk;
715

816
namespace Xunit
917
{
18+
#if USES_XUNIT_3
19+
[XunitTestCaseDiscoverer(typeof(ConditionalTheoryDiscoverer))]
20+
#else
1021
[XunitTestCaseDiscoverer("Microsoft.DotNet.XUnitExtensions.ConditionalTheoryDiscoverer", "Microsoft.DotNet.XUnitExtensions")]
22+
#endif
1123
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
1224
public sealed class ConditionalTheoryAttribute : TheoryAttribute
1325
{
@@ -30,3 +42,4 @@ public ConditionalTheoryAttribute(params string[] conditionMemberNames)
3042
}
3143
}
3244
}
45+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using Microsoft.DotNet.XUnitExtensions;
8+
using Xunit.Sdk;
9+
10+
namespace Xunit
11+
{
12+
/// <summary>
13+
/// Apply this attribute to your test method to specify a outer-loop category.
14+
/// </summary>
15+
#if !USES_XUNIT_3
16+
[TraitDiscoverer("Microsoft.DotNet.XUnitExtensions.OuterLoopTestsDiscoverer", "Microsoft.DotNet.XUnitExtensions")]
17+
#endif
18+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
19+
public class OuterLoopAttribute : Attribute, ITraitAttribute
20+
{
21+
#if USES_XUNIT_3
22+
private readonly object[] _ctorArgs;
23+
#endif
24+
25+
public Type CalleeType { get; private set; }
26+
public string[] ConditionMemberNames { get; private set; }
27+
28+
public OuterLoopAttribute()
29+
{
30+
#if USES_XUNIT_3
31+
_ctorArgs = [];
32+
#endif
33+
}
34+
35+
public OuterLoopAttribute(string reason)
36+
{
37+
#if USES_XUNIT_3
38+
_ctorArgs = [reason];
39+
#endif
40+
}
41+
42+
public OuterLoopAttribute(string reason, TestPlatforms platforms)
43+
{
44+
#if USES_XUNIT_3
45+
_ctorArgs = [reason, platforms];
46+
#endif
47+
}
48+
49+
public OuterLoopAttribute(string reason, TargetFrameworkMonikers framework)
50+
{
51+
#if USES_XUNIT_3
52+
_ctorArgs = [reason, framework];
53+
#endif
54+
}
55+
56+
public OuterLoopAttribute(string reason, TestRuntimes runtimes)
57+
{
58+
#if USES_XUNIT_3
59+
_ctorArgs = [reason, runtimes];
60+
#endif
61+
}
62+
63+
public OuterLoopAttribute(string reason, TestPlatforms platforms = TestPlatforms.Any, TargetFrameworkMonikers framework = TargetFrameworkMonikers.Any, TestRuntimes runtimes = TestRuntimes.Any)
64+
{
65+
#if USES_XUNIT_3
66+
_ctorArgs = [reason, platforms, framework, runtimes];
67+
#endif
68+
}
69+
70+
public OuterLoopAttribute(string reason, Type calleeType, params string[] conditionMemberNames)
71+
{
72+
#if USES_XUNIT_3
73+
_ctorArgs = [reason, calleeType, conditionMemberNames];
74+
#endif
75+
CalleeType = calleeType;
76+
ConditionMemberNames = conditionMemberNames;
77+
}
78+
79+
#if USES_XUNIT_3
80+
public IReadOnlyCollection<KeyValuePair<string, string>> GetTraits()
81+
{
82+
if (_ctorArgs.Length < 2)
83+
{
84+
return new[] { new KeyValuePair<string, string>(XunitConstants.Category, XunitConstants.OuterLoop) };
85+
}
86+
87+
return DiscovererHelpers.EvaluateArguments(_ctorArgs, XunitConstants.OuterLoop).ToArray();
88+
}
89+
#endif
90+
}
91+
}

src/Microsoft.DotNet.XUnitExtensions/src/Attributes/ParallelTheoryAttribute.cs src/Microsoft.DotNet.XUnitExtensions.Shared/Attributes/ParallelTheoryAttribute.cs

+7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
// TODO: Not yet supported for xunit.v3
5+
#if !USES_XUNIT_3
46
using System;
57
using System.Collections.Generic;
68
using System.Text;
@@ -9,9 +11,14 @@
911

1012
namespace Microsoft.DotNet.XUnitExtensions.Attributes
1113
{
14+
#if USES_XUNIT_3
15+
[XunitTestCaseDiscoverer(typeof(ParallelTheoryDiscoverer))]
16+
#else
1217
[XunitTestCaseDiscoverer("Microsoft.DotNet.XUnitExtensions.ParallelTheoryDiscoverer", "Microsoft.DotNet.XUnitExtensions")]
18+
#endif
1319
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
1420
public sealed class ParallelTheoryAttribute : TheoryAttribute
1521
{
1622
}
1723
}
24+
#endif

0 commit comments

Comments
 (0)