Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for xunit v3 #115

Merged
merged 20 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d8df5c8
Activate GitHub Actions test reporting
AArnott Dec 18, 2024
01eeb1a
Merge pull request #319 from AArnott/betterTestingLibTemplate
AArnott Dec 18, 2024
d2f4c5e
Revert "Merge pull request #319 from AArnott/betterTestingLibTemplate"
AArnott Dec 18, 2024
b1fa3bc
Merge pull request #321 from AArnott/betterTestingLibTemplate
AArnott Dec 18, 2024
7b18fd0
Resolve schema validation error in VS Code for docfx yml files
AArnott Dec 20, 2024
ad4ff0f
Bump xunit.runner.visualstudio to 3.0.0
AArnott Dec 20, 2024
2e9751f
Bump .NET SDK to 9.0.101
AArnott Dec 20, 2024
3459e45
Merge pull request #322 from AArnott/depUpdates
AArnott Dec 20, 2024
0c33c69
Organize Directory.Packages.props to reduce merge conflicts going for…
AArnott Dec 20, 2024
99ee1fc
Bump to Xunit v3
AArnott Dec 23, 2024
867012d
Merge pull request #323 from AArnott/xunitv3
AArnott Dec 23, 2024
531f1fb
Merge the main branch from https://github.com/aarnott/Library.Template
AArnott Dec 23, 2024
7f29978
Update to work against xunit v3
AArnott Dec 23, 2024
29fbe46
Bump version to 2.0-alpha
AArnott Dec 23, 2024
37cf2e5
Add package README
AArnott Dec 23, 2024
a9ee2b0
Merge branch 'main' into xunitv3
AArnott Dec 23, 2024
0060ffb
Merge the main branch from https://github.com/aarnott/Library.Template
AArnott Dec 23, 2024
01b7acf
Merge pull request #114 from AArnott/dev/andarno/libtemplateUpdate
AArnott Dec 23, 2024
a93e302
Build stabilization branches
AArnott Dec 23, 2024
9162ed7
Merge branch 'v1.7' into xunitv3
AArnott Dec 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- main
- v*.*
- validate/*
pull_request:
workflow_dispatch:
Expand Down
12 changes: 9 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="Validation" Version="2.5.51" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageVersion Include="xunit" Version="2.9.2" />
</ItemGroup>
<ItemGroup Label="Library.Template">
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.0" />
<PackageVersion Include="xunit.v3" Version="1.0.0" />
<PackageVersion Include="xunit.v3.extensibility.core" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<!-- Put repo-specific GlobalPackageReference items in this group. -->
</ItemGroup>
<ItemGroup Label="Library.Template">
<GlobalPackageReference Include="CSharpIsNullAnalyzer" Version="0.1.593" />
<GlobalPackageReference Include="DotNetAnalyzers.DocumentationAnalyzers" Version="1.0.0-beta.59" />
<!-- The condition works around https://github.com/dotnet/sdk/issues/44951 -->
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ you have more than two parameters.

This project is available as a [NuGet package][NuPkg].

The v1.x versions of this package support xunit 2.
The v2.x versions of this package support xunit 3.

## Examples

### Auto-generated values
Expand Down
2 changes: 1 addition & 1 deletion docfx/docs/toc.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
items:
- name: Features
href: features.md
- name: Getting Started
href: getting-started.md

1 change: 1 addition & 0 deletions docfx/toc.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
items:
- name: Docs
href: docs/
- name: API
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "9.0.100",
"version": "9.0.101",
"rollForward": "patch",
"allowPrerelease": false
}
Expand Down
11 changes: 8 additions & 3 deletions src/Xunit.Combinatorial/CombinatorialDataAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Reflection;
using Xunit.Sdk;
using Xunit.v3;

namespace Xunit;

Expand All @@ -22,14 +23,17 @@ public CombinatorialDataAttribute()
}

/// <inheritdoc />
public override IEnumerable<object?[]> GetData(MethodInfo testMethod)
public override bool SupportsDiscoveryEnumeration() => true;

/// <inheritdoc />
public override ValueTask<IReadOnlyCollection<ITheoryDataRow>> GetData(MethodInfo testMethod, DisposalTracker disposalTracker)
{
Requires.NotNull(testMethod, nameof(testMethod));

ParameterInfo[]? parameters = testMethod.GetParameters();
if (parameters.Length == 0)
{
return Enumerable.Empty<object[]>();
return new([]);
}

var values = new List<object?>[parameters.Length];
Expand All @@ -39,7 +43,8 @@ public CombinatorialDataAttribute()
}

object[]? currentValues = new object[parameters.Length];
return this.FillCombinations(parameters, values, currentValues, 0);
return new(
[.. this.FillCombinations(parameters, values, currentValues, 0).Select(v => new TheoryDataRow(v))]);
}

/// <summary>
Expand Down
20 changes: 13 additions & 7 deletions src/Xunit.Combinatorial/PairwiseDataAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Reflection;
using Xunit.Sdk;
using Xunit.v3;

namespace Xunit;

Expand All @@ -14,24 +15,29 @@ namespace Xunit;
public class PairwiseDataAttribute : DataAttribute
{
/// <inheritdoc />
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
public override bool SupportsDiscoveryEnumeration() => true;

/// <inheritdoc />
public override ValueTask<IReadOnlyCollection<ITheoryDataRow>> GetData(MethodInfo testMethod, DisposalTracker disposalTracker)
{
Requires.NotNull(testMethod, nameof(testMethod));

ParameterInfo[]? parameters = testMethod.GetParameters();
if (parameters.Length == 0)
{
return Enumerable.Empty<object[]>();
return new([]);
}

var values = new List<object?>[parameters.Length];
object?[][] values = new object?[parameters.Length][];
for (int i = 0; i < parameters.Length; i++)
{
values[i] = ValuesUtilities.GetValuesFor(parameters[i]).ToList();
values[i] = ValuesUtilities.GetValuesFor(parameters[i]).ToArray();
}

List<int[]>? testCaseInfo = PairwiseStrategy.GetTestCases(values.Select(v => v.Count).ToArray());
return from testCase in testCaseInfo
select testCase.Select((j, i) => values[i][j]).ToArray();
int[][] testCaseInfo = PairwiseStrategy.GetTestCases([.. values.Select(v => v.Length)]);
AArnott marked this conversation as resolved.
Show resolved Hide resolved
IEnumerable<TheoryDataRow> intermediate =
from testCase in testCaseInfo
select new TheoryDataRow(testCase.Select((j, i) => values[i][j]).ToArray());
return new ValueTask<IReadOnlyCollection<ITheoryDataRow>>([.. intermediate]);
AArnott marked this conversation as resolved.
Show resolved Hide resolved
}
}
4 changes: 2 additions & 2 deletions src/Xunit.Combinatorial/PairwiseStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ internal static class PairwiseStrategy
/// <returns>
/// A set of test cases.
/// </returns>
public static List<int[]> GetTestCases(int[] dimensions)
public static int[][] GetTestCases(int[] dimensions)
{
return (from testCase in new PairwiseTestCaseGenerator().GetTestCases(dimensions)
select testCase.Features).ToList();
select testCase.Features).ToArray();
}

private static bool IsTupleCovered(this TestCaseInfo testCaseInfo, FeatureTuple tuple)
Expand Down
6 changes: 6 additions & 0 deletions src/Xunit.Combinatorial/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Xunit.Combinatorial

The v1.x versions of this package support xunit 2.
The v2.x versions of this package support xunit 3.

Check out the documentation at [the GitHub README](https://github.com/AArnott/Xunit.Combinatorial?tab=readme-ov-file#readme).
4 changes: 2 additions & 2 deletions src/Xunit.Combinatorial/Xunit.Combinatorial.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
<RootNamespace>Xunit</RootNamespace>

<Title>Combinatorial testing with Xunit</Title>
Expand All @@ -15,7 +15,7 @@
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="xunit.extensibility.core" VersionOverride="2.2.0" />
<PackageReference Include="xunit.v3.extensibility.core" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Strings.resx">
Expand Down
63 changes: 32 additions & 31 deletions test/Xunit.Combinatorial.Tests/CombinatorialDataAttributeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,30 @@
using Validation;
using Xunit;
using Xunit.Sdk;
using Xunit.v3;

public class CombinatorialDataAttributeTests
{
[Fact]
public void GetData_NoArguments()
public async Task GetData_NoArguments()
{
AssertData([]);
await AssertData([]);
}

[Fact]
public void GetData_Bool()
public async Task GetData_Bool()
{
AssertData(
[
[true],
await AssertData(
[
[true],
[false],
]);
}

[Fact]
public void GetData_BoolBool()
public async Task GetData_BoolBool()
{
AssertData(
await AssertData(
[
[true, true],
[true, false],
Expand All @@ -38,19 +39,19 @@ public void GetData_BoolBool()
}

[Fact]
public void GetData_Int()
public async Task GetData_Int()
{
AssertData(
await AssertData(
[
[0],
[1],
]);
}

[Fact]
public void GetData_NullableInt()
public async Task GetData_NullableInt()
{
AssertData(
await AssertData(
[
[null],
[0],
Expand All @@ -59,19 +60,19 @@ public void GetData_NullableInt()
}

[Fact]
public void GetData_Int_35()
public async Task GetData_Int_35()
{
AssertData(
await AssertData(
[
[3],
[5],
]);
}

[Fact]
public void GetData_string_int_bool_Values()
public async Task GetData_string_int_bool_Values()
{
AssertData(
await AssertData(
[
["a", 2, true],
["a", 2, false],
Expand All @@ -89,9 +90,9 @@ public void GetData_string_int_bool_Values()
}

[Fact]
public void GetData_DateTimeKind()
public async Task GetData_DateTimeKind()
{
AssertData(
await AssertData(
[
[DateTimeKind.Unspecified],
[DateTimeKind.Utc],
Expand All @@ -100,9 +101,9 @@ public void GetData_DateTimeKind()
}

[Fact]
public void GetData_NullableDateTimeKind()
public async Task GetData_NullableDateTimeKind()
{
AssertData(
await AssertData(
[
[null],
[DateTimeKind.Unspecified],
Expand All @@ -126,18 +127,18 @@ public void GetData_UnsupportedNullableType()
}

[Fact]
public void GetData_CustomDataFromDerivedAttriute()
public async Task GetData_CustomDataFromDerivedAttriute()
{
var att = new CombinatorialDataAttribute();
MethodInfo testhelperMethodInfo = this.GetType().GetMethod(nameof(this.SomeTestWithCustomValues), BindingFlags.Instance | BindingFlags.NonPublic)!;
IEnumerable<object?[]> actual = att.GetData(testhelperMethodInfo);
IReadOnlyCollection<ITheoryDataRow> actual = await att.GetData(testhelperMethodInfo, new DisposalTracker());
Assert.Equal(
[
[5],
[10],
[15],
],
actual);
actual.Select(r => r.GetData()));
}

private static void Suppose_NoArguments()
Expand Down Expand Up @@ -184,13 +185,13 @@ private static void Suppose_UnsupportedNullableType(Guid? p1)
{
}

private static void AssertData(IEnumerable<object?[]> expectedCombinatorial, [CallerMemberName] string? testMethodName = null)
private static async Task AssertData(IReadOnlyCollection<object?[]> expectedCombinatorial, [CallerMemberName] string? testMethodName = null)
{
IEnumerable<object[]> actualCombinatorial = GetData(new CombinatorialDataAttribute(), testMethodName).ToArray();
IEnumerable<object[]> actualPairwise = GetData(new PairwiseDataAttribute(), testMethodName).ToArray();
IReadOnlyCollection<ITheoryDataRow> actualCombinatorial = await GetData(new CombinatorialDataAttribute(), testMethodName);
IReadOnlyCollection<ITheoryDataRow> actualPairwise = await GetData(new PairwiseDataAttribute(), testMethodName);

// Verify that the combinatorial result is as expected.
Assert.Equal(expectedCombinatorial, actualCombinatorial);
Assert.Equal(expectedCombinatorial, actualCombinatorial.Select(row => row.GetData()).ToArray());

if (expectedCombinatorial.Any())
{
Expand All @@ -208,8 +209,8 @@ private static void AssertData(IEnumerable<object?[]> expectedCombinatorial, [Ca
Assert.Contains(
actualPairwise,
testCase =>
EqualityComparer<object?>.Default.Equals(testCase[i], iValue) &&
EqualityComparer<object?>.Default.Equals(testCase[j], jValue));
EqualityComparer<object?>.Default.Equals(testCase.GetData()[i], iValue) &&
EqualityComparer<object?>.Default.Equals(testCase.GetData()[j], jValue));
}
}
}
Expand Down Expand Up @@ -238,15 +239,15 @@ private static void AssertData(IEnumerable<object?[]> expectedCombinatorial, [Ca
return possibleValues;
}

private static IEnumerable<object[]> GetData(DataAttribute dataAttribute, [CallerMemberName] string? testMethodName = null)
private static ValueTask<IReadOnlyCollection<ITheoryDataRow>> GetData(DataAttribute dataAttribute, [CallerMemberName] string? testMethodName = null)
{
Requires.NotNull(dataAttribute, nameof(dataAttribute));
Requires.NotNullOrEmpty(testMethodName!, nameof(testMethodName));

string supposeMethodName = testMethodName.Replace("GetData_", "Suppose_");
MethodInfo? methodInfo = typeof(CombinatorialDataAttributeTests).GetTypeInfo()
.DeclaredMethods.First(m => m.Name == supposeMethodName);
return dataAttribute.GetData(methodInfo);
return dataAttribute.GetData(methodInfo, new DisposalTracker());
}

private void SomeTestWithCustomValues([CustomValues] int a)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net462</TargetFrameworks>
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net472</TargetFrameworks>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Xunit.Combinatorial\Xunit.Combinatorial.csproj" />
Expand All @@ -10,6 +11,6 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Validation" />
<PackageReference Include="xunit.runner.visualstudio" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.v3" />
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions version.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json",
"version": "1.8-alpha",
"version": "2.0-alpha",
"publicReleaseRefSpec": [
"^refs/heads/main$",
"^refs/heads/v\\d+\\.\\d+"
]
}
}