diff --git a/Directory.Packages.props b/Directory.Packages.props
index 4eccf82..1cb9f40 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -6,6 +6,7 @@
true
+
@@ -18,4 +19,4 @@
-
+
\ No newline at end of file
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 727008f..a5e3cbb 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -13,6 +13,10 @@ trigger:
- azure-pipelines/release.yml
parameters:
+- name: includeMacOS
+ displayName: Build on macOS
+ type: boolean
+ default: false # macOS is often bogged down in Azure Pipelines
- name: RunTests
displayName: Run tests
type: boolean
@@ -22,10 +26,11 @@ variables:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
BuildConfiguration: Release
codecov_token: 4dc9e7e2-6b01-4932-a180-847b52b43d35 # Get a new one from https://codecov.io/
- ci_feed: https://pkgs.dev.azure.com/andrewarnott/_packaging/CI/nuget/v3/index.json # Azure Artifacts feed URL
+ ci_feed: https://pkgs.dev.azure.com/andrewarnott/OSS/_packaging/PublicCI/nuget/v3/index.json # Azure Artifacts feed URL
NUGET_PACKAGES: $(Agent.TempDirectory)/.nuget/packages/
jobs:
- template: azure-pipelines/build.yml
parameters:
+ includeMacOS: ${{ parameters.includeMacOS }}
RunTests: ${{ parameters.RunTests }}
diff --git a/azure-pipelines/build.yml b/azure-pipelines/build.yml
index ae6767e..36da37c 100644
--- a/azure-pipelines/build.yml
+++ b/azure-pipelines/build.yml
@@ -1,12 +1,17 @@
parameters:
+- name: windowsPool
+ type: object
+ default:
+ vmImage: windows-2022
+- name: includeMacOS
+ type: boolean
- name: RunTests
type: boolean
default: true
jobs:
-- job: Linux
- pool:
- vmImage: Ubuntu 20.04
+- job: Windows
+ pool: ${{ parameters.windowsPool }}
steps:
- checkout: self
fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
@@ -20,5 +25,52 @@ jobs:
parameters:
RunTests: ${{ parameters.RunTests }}
+- job: Linux
+ pool:
+ vmImage: Ubuntu 20.04
+ steps:
+ - checkout: self
+ fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
+ clean: true
+ - template: install-dependencies.yml
+ - template: dotnet.yml
+ parameters:
+ RunTests: ${{ parameters.RunTests }}
+ - script: dotnet format --verify-no-changes --no-restore
+ displayName: 💅 Verify formatted code
+
+- job: macOS
+ condition: ${{ parameters.includeMacOS }}
+ pool:
+ vmImage: macOS-12
+ steps:
+ - checkout: self
+ fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
+ clean: true
+ - template: install-dependencies.yml
+ - template: dotnet.yml
+ parameters:
+ RunTests: ${{ parameters.RunTests }}
+
+- job: WrapUp
+ dependsOn:
+ - Windows
+ - Linux
+ - macOS
+ pool: ${{ parameters.windowsPool }} # Use Windows agent because PublishSymbols task requires it (https://github.com/microsoft/azure-pipelines-tasks/issues/13821).
+ condition: succeededOrFailed()
+ steps:
+ - checkout: self
+ fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
+ clean: true
+ - template: install-dependencies.yml
+ parameters:
+ initArgs: -NoRestore
- template: publish-symbols.yml
+ parameters:
+ includeMacOS: ${{ parameters.includeMacOS }}
+ - ${{ if parameters.RunTests }}:
+ - template: publish-codecoverage.yml
+ parameters:
+ includeMacOS: ${{ parameters.includeMacOS }}
- template: publish-deployables.yml
diff --git a/azure-pipelines/publish-deployables.yml b/azure-pipelines/publish-deployables.yml
index 20c6567..0cbd140 100644
--- a/azure-pipelines/publish-deployables.yml
+++ b/azure-pipelines/publish-deployables.yml
@@ -1,4 +1,8 @@
steps:
-- powershell: dotnet nuget push "$(Resolve-Path '$(Build.ArtifactStagingDirectory)\deployables-Linux\')*.nupkg" -s $(ci_feed) -k azdo --skip-duplicate
+- download: current
+ displayName: 🔻 Download deployables
+ artifact: deployables-Linux
+
+- powershell: dotnet nuget push "$(Resolve-Path '$(Pipeline.Workspace)\deployables-Linux\')*.nupkg" -s $(ci_feed) -k azdo --skip-duplicate
displayName: 📦 Push packages to CI feed
condition: and(succeeded(), ne(variables['ci_feed'], ''), ne(variables['Build.Reason'], 'PullRequest'))
diff --git a/azure-pipelines/publish-symbols.yml b/azure-pipelines/publish-symbols.yml
index 65ac10c..00c188f 100644
--- a/azure-pipelines/publish-symbols.yml
+++ b/azure-pipelines/publish-symbols.yml
@@ -1,8 +1,50 @@
+parameters:
+ includeMacOS:
+
steps:
+- task: DownloadPipelineArtifact@2
+ inputs:
+ artifact: symbols-Windows
+ path: $(Pipeline.Workspace)/symbols/Windows
+ displayName: 🔻 Download Windows symbols
+ continueOnError: true
+- task: DownloadPipelineArtifact@2
+ inputs:
+ artifact: symbols-Linux
+ path: $(Pipeline.Workspace)/symbols/Linux
+ displayName: 🔻 Download Linux symbols
+ continueOnError: true
+- task: DownloadPipelineArtifact@2
+ inputs:
+ artifact: symbols-macOS
+ path: $(Pipeline.Workspace)/symbols/macOS
+ displayName: 🔻 Download macOS symbols
+ continueOnError: true
+ condition: ${{ parameters.includeMacOS }}
+
+- task: DownloadPipelineArtifact@2
+ inputs:
+ artifact: test_symbols-Windows
+ path: $(Pipeline.Workspace)/test_symbols/Windows
+ displayName: 🔻 Download Windows test symbols
+ continueOnError: true
+- task: DownloadPipelineArtifact@2
+ inputs:
+ artifact: test_symbols-Linux
+ path: $(Pipeline.Workspace)/test_symbols/Linux
+ displayName: 🔻 Download Linux test symbols
+ continueOnError: true
+- task: DownloadPipelineArtifact@2
+ inputs:
+ artifact: test_symbols-macOS
+ path: $(Pipeline.Workspace)/test_symbols/macOS
+ displayName: 🔻 Download macOS test symbols
+ continueOnError: true
+ condition: ${{ parameters.includeMacOS }}
- task: PublishSymbols@2
inputs:
- SymbolsFolder: $(Build.ArtifactStagingDirectory)/symbols
+ SymbolsFolder: $(Pipeline.Workspace)/symbols
SearchPattern: '**/*.pdb'
IndexSources: false
SymbolServerType: TeamServices
@@ -10,7 +52,7 @@ steps:
- task: PublishSymbols@2
inputs:
- SymbolsFolder: $(Build.ArtifactStagingDirectory)/test_symbols
+ SymbolsFolder: $(Pipeline.Workspace)/test_symbols
SearchPattern: '**/*.pdb'
IndexSources: false
SymbolServerType: TeamServices
diff --git a/src/Xunit.Combinatorial/CombinatorialMemberDataAttribute.cs b/src/Xunit.Combinatorial/CombinatorialMemberDataAttribute.cs
index c3058e1..668354d 100644
--- a/src/Xunit.Combinatorial/CombinatorialMemberDataAttribute.cs
+++ b/src/Xunit.Combinatorial/CombinatorialMemberDataAttribute.cs
@@ -75,10 +75,19 @@ public CombinatorialMemberDataAttribute(string memberName, params object?[]? arg
/// The generic type argument for (one of) the interface)s) implemented by the .
private static TypeInfo? GetEnumeratedType(Type enumerableType)
{
- if (enumerableType.IsGenericType && enumerableType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
+ if (enumerableType.IsGenericType)
{
- Type[] enumerableGenericTypeArgs = enumerableType.GetTypeInfo().GetGenericArguments();
- return enumerableGenericTypeArgs[0].GetTypeInfo();
+ if (enumerableType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
+ {
+ Type[] enumerableGenericTypeArgs = enumerableType.GetTypeInfo().GetGenericArguments();
+ return enumerableGenericTypeArgs[0].GetTypeInfo();
+ }
+
+ if (enumerableType.GetGenericTypeDefinition() == typeof(TheoryData<>))
+ {
+ Type[] enumerableGenericTypeArgs = enumerableType.GetTypeInfo().GetGenericArguments();
+ return enumerableGenericTypeArgs[0].GetTypeInfo();
+ }
}
foreach (Type implementedInterface in enumerableType.GetTypeInfo().ImplementedInterfaces)
diff --git a/test/Xunit.Combinatorial.Tests/CombinatorialMemberDataSampleUses.cs b/test/Xunit.Combinatorial.Tests/CombinatorialMemberDataSampleUses.cs
index 762553d..f91320a 100644
--- a/test/Xunit.Combinatorial.Tests/CombinatorialMemberDataSampleUses.cs
+++ b/test/Xunit.Combinatorial.Tests/CombinatorialMemberDataSampleUses.cs
@@ -12,6 +12,10 @@ public class CombinatorialMemberDataSampleUses
public static readonly IEnumerable GuidFieldValues = Enumerable.Range(0, 5).Select(_ => Guid.NewGuid());
#pragma warning restore SA1202 // Elements should be ordered by access
+ public static readonly TheoryData MyTestCases = new(
+ new MyTestCase(1, "Foo"),
+ new MyTestCase(2, "Bar"));
+
public static IEnumerable IntPropertyValues => GetIntMethodValues();
public static IEnumerable GuidPropertyValues => GetGuidMethodValues();
@@ -84,4 +88,18 @@ public void CombinatorialMemberDataFromFields(
{
Assert.True(true);
}
+
+ [Theory, CombinatorialData]
+ public void TheoryDataOfT([CombinatorialMemberData(nameof(MyTestCases))] MyTestCase testCase, bool flag)
+ {
+ /*
+ This will give you:
+ testCase(1, "Foo"), true
+ testCase(1, "Foo"), false
+ testCase(2, "Bar"), true
+ testCase(2, "Bar"), false
+ */
+ }
+
+ public record MyTestCase(int Number, string Text);
}
diff --git a/test/Xunit.Combinatorial.Tests/Xunit.Combinatorial.Tests.csproj b/test/Xunit.Combinatorial.Tests/Xunit.Combinatorial.Tests.csproj
index bd96fa0..c24da0c 100644
--- a/test/Xunit.Combinatorial.Tests/Xunit.Combinatorial.Tests.csproj
+++ b/test/Xunit.Combinatorial.Tests/Xunit.Combinatorial.Tests.csproj
@@ -1,11 +1,13 @@

- net462;net6.0
+ net6.0;net8.0
+ $(TargetFrameworks);net462
+