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 +