Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
88 changes: 14 additions & 74 deletions .github/workflows/pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,87 +125,27 @@ jobs:
buildSwitches: -p:SkipSignAssembly=true

sonarcloud:
name: 🔬 Code Quality Analysis
name: call-sonarcloud
needs: [build,test]
runs-on: ubuntu-22.04
timeout-minutes: 15
steps:
- name: Checkout
uses: codebeltnet/git-checkout@v1

- name: Install .NET
uses: codebeltnet/install-dotnet@v1
with:
includePreview: true

- name: Install .NET Tool - Sonar Scanner
uses: codebeltnet/dotnet-tool-install-sonarscanner@v1

- name: Restore Dependencies
uses: codebeltnet/dotnet-restore@v2

- name: Run SonarCloud Analysis
uses: codebeltnet/sonarcloud-scan@v1
with:
token: ${{ secrets.SONAR_TOKEN }}
organization: geekle
projectKey: xunit
version: ${{ needs.build.outputs.version }}

- name: Build
uses: codebeltnet/dotnet-build@v2
with:
buildSwitches: -p:SkipSignAssembly=true
uploadBuildArtifact: false

- name: Finalize SonarCloud Analysis
uses: codebeltnet/sonarcloud-scan-finalize@v1
with:
token: ${{ secrets.SONAR_TOKEN }}
uses: codebeltnet/jobs-sonarcloud/.github/workflows/default.yml@v1
with:
organization: geekle
projectKey: xunit
version: ${{ needs.build.outputs.version }}
secrets: inherit

codecov:
name: 📊 Code Coverage Analysis
name: call-codecov
needs: [build,test]
runs-on: ubuntu-22.04
timeout-minutes: 15
steps:
- name: Checkout
uses: codebeltnet/git-checkout@v1
uses: codebeltnet/jobs-codecov/.github/workflows/default.yml@v1
with:
repository: codebeltnet/xunit
secrets: inherit

- name: Run CodeCov Analysis
uses: codebeltnet/codecov-scan@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
repository: codebeltnet/xunit

codeql:
name: 🛡️ Security Analysis
name: call-codeql
needs: [build,test]
runs-on: ubuntu-22.04
timeout-minutes: 15
steps:
- name: Checkout
uses: codebeltnet/git-checkout@v1

- name: Install .NET
uses: codebeltnet/install-dotnet@v1
with:
includePreview: true

- name: Restore Dependencies
uses: codebeltnet/dotnet-restore@v2

- name: Prepare CodeQL SAST Analysis
uses: codebeltnet/codeql-scan@v1

- name: Build
uses: codebeltnet/dotnet-build@v2
with:
buildSwitches: -p:SkipSignAssembly=true
uploadBuildArtifact: false

- name: Finalize CodeQL SAST Analysis
uses: codebeltnet/codeql-scan-finalize@v1
uses: codebeltnet/jobs-codeql/.github/workflows/default.yml@v1

deploy:
if: github.event_name != 'pull_request'
Expand Down
14 changes: 13 additions & 1 deletion .nuget/Codebelt.Extensions.Xunit.App/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
Version 9.0.0
Version 9.1.0
Availability: .NET 9 and .NET 8

# ALM
- CHANGED Dependencies to latest and greatest with respect to TFMs

Version 9.0.1
Availability: .NET 9 and .NET 8

# ALM
- CHANGED Dependencies to latest and greatest with respect to TFMs

Version 9.0.0
Availability: .NET 9 and .NET 8

# ALM
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
Version 9.0.1
Version 9.1.0
Availability: .NET 9 and .NET 8

# ALM
- CHANGED Dependencies to latest and greatest with respect to TFMs

# New Features
- ADDED AspNetCoreHostFixtureExtensions class in the Codebelt.Extensions.Xunit.Hosting.AspNetCore namespace that consist of one extension method for the IAspNetCoreHostFixture interface: HasValidState
- ADDED BlockingAspNetCoreHostFixture class in the Codebelt.Extensions.Xunit.Hosting.AspNetCore namespace that provides a blocking implementation of the AspNetCoreHostFixture implementation

# Improvements
- CHANGED WebHostTestFactory class in the Codebelt.Extensions.Xunit.Hosting.AspNetCore namespace to accept an optional argument taking a custom implementation of IAspNetCoreHostFixture (promote DIP)

Version 9.0.1
Availability: .NET 9 and .NET 8

# ALM
Expand Down
15 changes: 14 additions & 1 deletion .nuget/Codebelt.Extensions.Xunit.Hosting/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
Version 9.0.1
Version 9.1.0
Availability: .NET 9, .NET 8 and .NET Standard 2.0

# ALM
- CHANGED Dependencies to latest and greatest with respect to TFMs

# New Features
- ADDED HostFixtureExtensions class in the Codebelt.Extensions.Xunit.Hosting namespace that consist of one extension method for the IHostFixture interface: HasValidState

# Improvements
- CHANGED HostFixture class in the Codebelt.Extensions.Xunit.Hosting namespace to have an additional virtual method: StartConfiguredHost, which is called from the ConfigureHost method, to allow for custom implementations of the host startup process
- CHANGED GenericHostTestFactory class in the Codebelt.Extensions.Xunit.Hosting namespace to accept an optional argument taking a custom implementation of IHostFixture (promote DIP)

Version 9.0.1
Availability: .NET 9, .NET 8 and .NET Standard 2.0

# ALM
Expand Down
8 changes: 7 additions & 1 deletion .nuget/Codebelt.Extensions.Xunit/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
Version 9.0.1
Version 9.1.0
Availability: .NET 9, .NET 8 and .NET Standard 2.0

# ALM
- CHANGED Dependencies to latest and greatest with respect to TFMs

Version 9.0.1
Availability: .NET 9, .NET 8 and .NET Standard 2.0

# ALM
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@ For more details, please refer to `PackageReleaseNotes.txt` on a per assembly ba
> [!NOTE]
> Changelog entries prior to version 8.4.0 was migrated from previous versions of Cuemon.Extensions.Xunit, Cuemon.Extensions.Xunit.Hosting, and Cuemon.Extensions.Xunit.Hosting.AspNetCore.

## [9.1.0] - 2025-03-31

This is a service update that primarily focuses on package dependencies including DIP improvements and a new blocking implementation of the AspNetCoreHostFixture.

> [!WARNING]
> Although this release is backward compatible, do expect some design-time incompatibility due to changes in `GenericHostTestFactory` and `WebHostTestFactory`.

### Added

- HostFixtureExtensions class in the Codebelt.Extensions.Xunit.Hosting namespace that consist of one extension method for the IHostFixture interface: HasValidState
- AspNetCoreHostFixtureExtensions class in the Codebelt.Extensions.Xunit.Hosting.AspNetCore namespace that consist of one extension method for the IAspNetCoreHostFixture interface: HasValidState
- BlockingAspNetCoreHostFixture class in the Codebelt.Extensions.Xunit.Hosting.AspNetCore namespace that provides a blocking implementation of the AspNetCoreHostFixture implementation

### Changed

- HostFixture class in the Codebelt.Extensions.Xunit.Hosting namespace to have an additional virtual method: StartConfiguredHost, which is called from the ConfigureHost method, to allow for custom implementations of the host startup process
- GenericHostTestFactory class in the Codebelt.Extensions.Xunit.Hosting namespace to accept an optional argument taking a custom implementation of IHostFixture (promote DIP)
- WebHostTestFactory class in the Codebelt.Extensions.Xunit.Hosting.AspNetCore namespace to accept an optional argument taking a custom implementation of IAspNetCoreHostFixture (promote DIP)

## [9.0.1] - 2025-01-25

This is a service update that primarily focuses on package dependencies and minor improvements.
Expand Down
1 change: 0 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
</ItemGroup>

<ItemGroup Condition="'$(IsTestProject)' == 'false'">
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="all" />
<PackageReference Include="MinVer" PrivateAssets="all" />
<None Include="..\..\.nuget\$(MSBuildProjectName)\icon.png" Pack="true" Visible="false" PackagePath="\" />
<None Include="..\..\.nuget\$(MSBuildProjectName)\README.md" Pack="true" PackagePath="\" />
Expand Down
29 changes: 14 additions & 15 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Cuemon.Core" Version="9.0.0" />
<PackageVersion Include="Cuemon.Extensions.AspNetCore" Version="9.0.0" />
<PackageVersion Include="Cuemon.Extensions.IO" Version="9.0.0" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="Cuemon.Core" Version="9.0.3" />
<PackageVersion Include="Cuemon.Extensions.AspNetCore" Version="9.0.3" />
<PackageVersion Include="Cuemon.Extensions.IO" Version="9.0.3" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.3" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageVersion Include="MinVer" Version="6.0.0" />
<PackageVersion Include="NativeLibraryLoader" Version="1.0.13" />
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.6.0" />
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.6.2" />
<PackageVersion Include="Xunit.Priority" Version="1.1.6" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.4" />
Expand All @@ -21,23 +20,23 @@
<PackageVersion Include="xunit.assert" Version="2.9.3" />
<PackageVersion Include="xunit.extensibility.core" Version="2.9.3" />
<PackageVersion Include="xunit.runner.console" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.2" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('net9'))">
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration.FileExtensions" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="9.0.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="9.0.3" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.3" />
<PackageVersion Include="Microsoft.Extensions.Configuration.FileExtensions" Version="9.0.3" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="9.0.3" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="9.0.3" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('net8')) OR $(TargetFramework.StartsWith('netstandard2'))">
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="8.0.12" />
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="8.0.14" />
</ItemGroup>
</Project>
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

An open-source project (MIT license) that targets and complements the [xUnit.net](https://xunit.net/) test platform. It provides a uniform and convenient way of doing unit test for all project types in .NET.

Full documentation (generated by [DocFx](https://github.com/dotnet/docfx)) located here: https://xunit.codebelt.net/

### 📦 Standalone Packages

Provides a focused API for unit-testing specific types of .NET projects.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,9 @@ public override void ConfigureHost(Test hostTest)

ConfigureHostCallback(hb);

var host = hb.Build();
Task.Run(() => host.StartAsync().ConfigureAwait(false))
.ConfigureAwait(false)
.GetAwaiter()
.GetResult();
Host = host;
Host = hb.Build();

StartConfiguredHost();
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
namespace Codebelt.Extensions.Xunit.Hosting.AspNetCore
{
internal static class AspNetCoreHostFixtureExtensions
/// <summary>
/// Extension methods for the <see cref="IAspNetCoreHostFixture"/> interface.
/// </summary>
public static class AspNetCoreHostFixtureExtensions
{
internal static bool HasValidState(this IAspNetCoreHostFixture fixture)
/// <summary>
/// Determines whether the specified <see cref="IAspNetCoreHostFixture"/> has a valid state.
/// </summary>
/// <param name="fixture">The <see cref="IAspNetCoreHostFixture"/> to check.</param>
/// <returns><c>true</c> if the specified <see cref="IAspNetCoreHostFixture"/> has a valid state; otherwise, <c>false</c>.</returns>
/// <remarks>
/// A valid state is defined as having non-null values for the following properties:
/// <see cref="IHostFixture.ConfigureServicesCallback"/>, <see cref="IHostTest.Host"/>,
/// <see cref="IServiceTest.ServiceProvider"/>, <see cref="IHostFixture.ConfigureHostCallback"/> and <see cref="IPipelineTest.Application"/>.
/// </remarks>
public static bool HasValidState(this IAspNetCoreHostFixture fixture)
{
return fixture.ConfigureServicesCallback != null && fixture.Host != null && fixture.ServiceProvider != null && fixture.Application != null && fixture.ConfigureHostCallback != null;
var hasValidState = ((IHostFixture)fixture).HasValidState();
return hasValidState && fixture.Application != null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,6 @@ protected AspNetCoreHostTest(T hostFixture, ITestOutputHelper output = null, Typ
{
}

/// <summary>
/// Initializes the specified host fixture.
/// </summary>
/// <param name="hostFixture">The host fixture to initialize.</param>
protected override void InitializeHostFixture(T hostFixture)
{
if (!hostFixture.HasValidState())
{
hostFixture.ConfigureCallback = Configure;
hostFixture.ConfigureHostCallback = ConfigureHost;
hostFixture.ConfigureServicesCallback = ConfigureServices;
hostFixture.ConfigureApplicationCallback = ConfigureApplication;
hostFixture.ConfigureHost(this);
}
Host = hostFixture.Host;
ServiceProvider = hostFixture.Host.Services;
Application = hostFixture.Application;
Configure(hostFixture.Configuration, hostFixture.HostingEnvironment);
}

/// <summary>
/// Gets the <see cref="IApplicationBuilder"/> initialized by the <see cref="IHost"/>.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.Extensions.Hosting;

namespace Codebelt.Extensions.Xunit.Hosting.AspNetCore
{
/// <summary>
/// Extends the default implementation of the <see cref="IAspNetCoreHostFixture"/> interface to be synchronous e.g., blocking where exceptions can be captured.
/// </summary>
/// <seealso cref="AspNetCoreHostFixture" />
public class BlockingAspNetCoreHostFixture : AspNetCoreHostFixture
{
/// <summary>
/// Starts the by <see cref="AspNetCoreHostFixture.ConfigureHost"/> initialized <see cref="IHost"/>.
/// </summary>
/// <remarks><see cref="AspNetCoreHostFixture.ConfigureHost"/> is responsible for configuring and setting the <see cref="Host"/> property.</remarks>
protected override void StartConfiguredHost()
{
Host.Start();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.

using System.Diagnostics.CodeAnalysis;

[assembly: SuppressMessage("Blocker Code Smell", "S3427:Method overloads with default parameter values should not overlap", Justification = "Avoid bumping major version by providing an extra overloaded member as optional argument.", Scope = "member", Target = "~M:Codebelt.Extensions.Xunit.Hosting.AspNetCore.WebHostTestFactory.Create(System.Action{Microsoft.Extensions.DependencyInjection.IServiceCollection},System.Action{Microsoft.AspNetCore.Builder.IApplicationBuilder},System.Action{Microsoft.Extensions.Hosting.IHostBuilder},Codebelt.Extensions.Xunit.Hosting.AspNetCore.IAspNetCoreHostFixture)~Codebelt.Extensions.Xunit.Hosting.AspNetCore.IWebHostTest")]
[assembly: SuppressMessage("Blocker Code Smell", "S3427:Method overloads with default parameter values should not overlap", Justification = "Avoid bumping major version by providing an extra overloaded member as optional argument.", Scope = "member", Target = "~M:Codebelt.Extensions.Xunit.Hosting.AspNetCore.WebHostTestFactory.CreateWithHostBuilderContext(System.Action{Microsoft.Extensions.Hosting.HostBuilderContext,Microsoft.Extensions.DependencyInjection.IServiceCollection},System.Action{Microsoft.Extensions.Hosting.HostBuilderContext,Microsoft.AspNetCore.Builder.IApplicationBuilder},System.Action{Microsoft.Extensions.Hosting.IHostBuilder},Codebelt.Extensions.Xunit.Hosting.AspNetCore.IAspNetCoreHostFixture)~Codebelt.Extensions.Xunit.Hosting.AspNetCore.IWebHostTest")]
[assembly: SuppressMessage("Blocker Code Smell", "S3427:Method overloads with default parameter values should not overlap", Justification = "Avoid bumping major version by providing an extra overloaded member as optional argument.", Scope = "member", Target = "~M:Codebelt.Extensions.Xunit.Hosting.AspNetCore.WebHostTestFactory.RunAsync(System.Action{Microsoft.Extensions.DependencyInjection.IServiceCollection},System.Action{Microsoft.AspNetCore.Builder.IApplicationBuilder},System.Action{Microsoft.Extensions.Hosting.IHostBuilder},System.Func{System.Net.Http.HttpClient,System.Threading.Tasks.Task{System.Net.Http.HttpResponseMessage}},Codebelt.Extensions.Xunit.Hosting.AspNetCore.IAspNetCoreHostFixture)~System.Threading.Tasks.Task{System.Net.Http.HttpResponseMessage}")]
[assembly: SuppressMessage("Blocker Code Smell", "S3427:Method overloads with default parameter values should not overlap", Justification = "Avoid bumping major version by providing an extra overloaded member as optional argument.", Scope = "member", Target = "~M:Codebelt.Extensions.Xunit.Hosting.AspNetCore.WebHostTestFactory.RunWithHostBuilderContextAsync(System.Action{Microsoft.Extensions.Hosting.HostBuilderContext,Microsoft.Extensions.DependencyInjection.IServiceCollection},System.Action{Microsoft.Extensions.Hosting.HostBuilderContext,Microsoft.AspNetCore.Builder.IApplicationBuilder},System.Action{Microsoft.Extensions.Hosting.IHostBuilder},System.Func{System.Net.Http.HttpClient,System.Threading.Tasks.Task{System.Net.Http.HttpResponseMessage}},Codebelt.Extensions.Xunit.Hosting.AspNetCore.IAspNetCoreHostFixture)~System.Threading.Tasks.Task{System.Net.Http.HttpResponseMessage}")]
Loading
Loading