diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml
index 13146357..875f8f50 100644
--- a/.github/workflows/ci-pipeline.yml
+++ b/.github/workflows/ci-pipeline.yml
@@ -12,6 +12,10 @@ on:
options:
- Debug
- Release
+ run_mac_tests:
+ type: boolean
+ description: Run the macOS test matrix despite the additional cost and runtime.
+ default: false
permissions:
contents: read
@@ -22,6 +26,7 @@ jobs:
runs-on: ubuntu-24.04
outputs:
run-privileged-jobs: ${{ steps.vars.outputs.run-privileged-jobs }}
+ run-mac-tests: ${{ steps.vars.outputs.run-mac-tests }}
strong-name-key-filename: ${{ steps.vars.outputs.strong-name-key-filename }}
build-switches: ${{ steps.vars.outputs.build-switches }}
steps:
@@ -29,6 +34,12 @@ jobs:
name: calculate workflow variables
shell: bash
run: |
+ if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ inputs.run_mac_tests }}" == "true" ]]; then
+ echo "run-mac-tests=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "run-mac-tests=false" >> "$GITHUB_OUTPUT"
+ fi
+
if [[ "${{ github.event_name }}" == "pull_request" && "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]]; then
echo "run-privileged-jobs=false" >> "$GITHUB_OUTPUT"
echo "strong-name-key-filename=" >> "$GITHUB_OUTPUT"
@@ -130,8 +141,9 @@ jobs:
download-pattern: build-${{ matrix.configuration }}-${{ matrix.arch }}
test_mac:
+ if: ${{ needs.init.outputs.run-mac-tests == 'true' }}
name: call-test-mac
- needs: [build, prepare_test]
+ needs: [init, build, prepare_test]
strategy:
fail-fast: false
matrix:
@@ -256,10 +268,61 @@ jobs:
docker stop nats
docker rm nats
+ test_qualitygate:
+ if: ${{ always() }}
+ name: test-qualitygate
+ needs: [init, test_linux, test_windows, test_mac, integration_test, integration_test_rabbitmq, integration_test_nats]
+ runs-on: ubuntu-24.04
+ steps:
+ - name: Evaluate test results
+ shell: bash
+ env:
+ RUN_MAC_TESTS: ${{ needs.init.outputs.run-mac-tests }}
+ RUN_PRIVILEGED_JOBS: ${{ needs.init.outputs.run-privileged-jobs }}
+ TEST_LINUX_RESULT: ${{ needs.test_linux.result }}
+ TEST_WINDOWS_RESULT: ${{ needs.test_windows.result }}
+ TEST_MAC_RESULT: ${{ needs.test_mac.result }}
+ INTEGRATION_TEST_RESULT: ${{ needs.integration_test.result }}
+ INTEGRATION_TEST_RABBITMQ_RESULT: ${{ needs.integration_test_rabbitmq.result }}
+ INTEGRATION_TEST_NATS_RESULT: ${{ needs.integration_test_nats.result }}
+ run: |
+ require_success() {
+ local job_name="$1"
+ local job_result="$2"
+
+ if [[ "$job_result" != "success" ]]; then
+ echo "::error::$job_name finished with '$job_result'."
+ exit 1
+ fi
+ }
+
+ require_success_or_skip() {
+ local job_name="$1"
+ local job_enabled="$2"
+ local job_result="$3"
+
+ if [[ "$job_enabled" == "true" ]]; then
+ require_success "$job_name" "$job_result"
+ return
+ fi
+
+ if [[ "$job_result" != "success" && "$job_result" != "skipped" ]]; then
+ echo "::error::$job_name finished with '$job_result' while disabled."
+ exit 1
+ fi
+ }
+
+ require_success "test_linux" "$TEST_LINUX_RESULT"
+ require_success "test_windows" "$TEST_WINDOWS_RESULT"
+ require_success_or_skip "test_mac" "$RUN_MAC_TESTS" "$TEST_MAC_RESULT"
+ require_success_or_skip "integration_test" "$RUN_PRIVILEGED_JOBS" "$INTEGRATION_TEST_RESULT"
+ require_success "integration_test_rabbitmq" "$INTEGRATION_TEST_RABBITMQ_RESULT"
+ require_success "integration_test_nats" "$INTEGRATION_TEST_NATS_RESULT"
+
sonarcloud:
- if: ${{ needs.init.outputs.run-privileged-jobs == 'true' }}
+ if: ${{always() && needs.init.outputs.run-privileged-jobs == 'true' && needs.build.result == 'success' && needs.test_qualitygate.result == 'success'}}
name: call-sonarcloud
- needs: [init, build, test_linux, test_windows, test_mac, integration_test, integration_test_rabbitmq, integration_test_nats]
+ needs: [init, build, test_qualitygate]
uses: codebeltnet/jobs-sonarcloud/.github/workflows/default.yml@v3
with:
organization: geekle
@@ -268,18 +331,18 @@ jobs:
secrets: inherit
codecov:
- if: ${{ needs.init.outputs.run-privileged-jobs == 'true' }}
+ if: ${{always() && needs.init.outputs.run-privileged-jobs == 'true' && needs.build.result == 'success' && needs.test_qualitygate.result == 'success'}}
name: call-codecov
- needs: [init, build, test_linux, test_windows, test_mac, integration_test, integration_test_rabbitmq, integration_test_nats]
+ needs: [init, build, test_qualitygate]
uses: codebeltnet/jobs-codecov/.github/workflows/default.yml@v1
with:
repository: codebeltnet/savvyio
secrets: inherit
codeql:
- if: ${{ needs.init.outputs.run-privileged-jobs == 'true' }}
+ if: ${{always() && needs.init.outputs.run-privileged-jobs == 'true' && needs.build.result == 'success' && needs.test_qualitygate.result == 'success'}}
name: call-codeql
- needs: [init, build, test_linux, test_windows, test_mac, integration_test, integration_test_rabbitmq, integration_test_nats]
+ needs: [init, build, test_qualitygate]
uses: codebeltnet/jobs-codeql/.github/workflows/default.yml@v3
permissions:
security-events: write
@@ -287,7 +350,7 @@ jobs:
deploy:
if: github.event_name != 'pull_request'
name: call-nuget
- needs: [build, pack, test_linux, test_windows, test_mac, integration_test, integration_test_rabbitmq, integration_test_nats, sonarcloud, codecov, codeql]
+ needs: [build, pack, test_qualitygate, sonarcloud, codecov, codeql]
uses: codebeltnet/jobs-nuget-push/.github/workflows/default.yml@v3
with:
version: ${{ needs.build.outputs.version }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0f4c942d..2442871d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,29 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
For more details, please refer to `PackageReleaseNotes.txt` on a per assembly basis in the `.nuget` folder.
+## [Unreleased]
+
+This is a patch release focused on consolidating the internal `AssemblyContext` reflection utility into the upstream `Cuemon.Reflection` package and tightening the CI pipeline structure.
+
+> [!TIP]
+> The `Savvyio.Reflection.AssemblyContext` class has been removed from the `Savvyio.Core` assembly. Consumers referencing it directly must migrate to `Cuemon.Reflection.AssemblyContext` and replace the `CurrentDomainAssemblies` property with the `GetCurrentDomainAssemblies()` method.
+
+### Changed
+
+- `SavvyioOptionsExtensions` in `Savvyio.Extensions.Dispatchers` now calls `Cuemon.Reflection.AssemblyContext.GetCurrentDomainAssemblies()` to replace the removed `Savvyio.Reflection.AssemblyContext.CurrentDomainAssemblies` property,
+- `MessageConverter` in `Savvyio.Extensions.Newtonsoft.Json` updated to use `Cuemon.Reflection.AssemblyContext.GetCurrentDomainAssemblies()`,
+- `MessageConverter` in `Savvyio.Extensions.Text.Json` updated to use `Cuemon.Reflection.AssemblyContext.GetCurrentDomainAssemblies()`,
+- LocalStack Docker image bumped from `4.14.0` to `2026.05.0` in `Dockerfile.localstack` and `docker-compose.yml`,
+- CI pipeline now supports an opt-in `run_mac_tests` workflow dispatch boolean (default `false`) to run the macOS test matrix on demand rather than always,
+- macOS test job (`test_mac`) is now guarded by the `run-mac-tests` output and requires `init` as an explicit dependency,
+- New `test_qualitygate` job centralises evaluation of all test results (Linux, Windows, macOS, integration, RabbitMQ, NATS) using `require_success` and `require_success_or_skip` helper functions,
+- `sonarcloud`, `codecov`, `codeql`, and `deploy` jobs now depend on `test_qualitygate` instead of enumerating each individual test job.
+
+### Removed
+
+- `AssemblyContext` class from the `Savvyio.Core` assembly (`Savvyio.Reflection` namespace); functionality is consolidated into `Cuemon.Reflection.AssemblyContext`,
+- `AssemblyContextTest` unit tests removed alongside the deleted class.
+
## [5.0.7] - 2026-05-26
This is a patch release focused on Azure.Identity compatibility across target frameworks, RabbitMQ queue durability correction, comprehensive test coverage expansion across multiple extensions, testability improvements with protected virtual methods and constructors for extensibility, dependency updates including LocalStack, NATS.Client, and Microsoft utility packages, and test reliability hardening for distributed mediator scenarios.
diff --git a/Dockerfile.localstack b/Dockerfile.localstack
index f6343dfd..ae292d29 100644
--- a/Dockerfile.localstack
+++ b/Dockerfile.localstack
@@ -1,5 +1,5 @@
# Use the LocalStack base image
-FROM localstack/localstack:4.14.0
+FROM localstack/localstack:2026.05.0
# Expose the port for LocalStack
EXPOSE 4566
diff --git a/docker-compose.yml b/docker-compose.yml
index cbb26967..14f2544a 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,6 +1,6 @@
services:
localstack:
- image: localstack/localstack:4.14.0
+ image: localstack/localstack:2026.05.0
environment:
- SERVICES=sns,sqs
- DEBUG=0
diff --git a/src/Savvyio.Core/Reflection/AssemblyContext.cs b/src/Savvyio.Core/Reflection/AssemblyContext.cs
deleted file mode 100644
index ee95d3b1..00000000
--- a/src/Savvyio.Core/Reflection/AssemblyContext.cs
+++ /dev/null
@@ -1 +0,0 @@
-using Cuemon.Extensions.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Cuemon;
namespace Savvyio.Reflection
{
///
/// Provides a set of static methods and properties to manage and filter assemblies in the current application domain.
///
public static class AssemblyContext
{
private static readonly Lazy> AssemblyLoadFactory = new(() => AppDomain
.CurrentDomain
.GetAssemblies()
.Where(AssemblyFilterCallback)
.SelectMany(AssemblyDependenciesCallback)
.Distinct()
.Except(typeof(AssemblyContext).Assembly.Yield())
.ToList()
.AsReadOnly());
private static Func _assemblyFilterCallback = DefaultAssemblyFilter;
private static Func> _assemblyDependenciesCallback = DefaultAssemblyDependencies;
private static Func _assemblyDependenciesFilterCallback = DefaultAssemblyDependenciesFilter;
///
/// Gets or sets the function delegate that filters assemblies from the current application domain.
///
/// The function delegate that filters assemblies from the current application domain.
/// The default implementation filters away assemblies that suggest being part of the .NET runtime themselves.
///
/// cannot be null.
///
public static Func AssemblyFilterCallback
{
get => _assemblyFilterCallback;
set => _assemblyFilterCallback = value ?? throw new ArgumentNullException(nameof(value));
}
///
/// Gets or sets the function delegate that recursively discover dependencies for an assembly in the current application domain.
///
/// The function delegate that recursively discover dependencies for an assembly in the current application domain.
///
/// cannot be null.
///
public static Func> AssemblyDependenciesCallback
{
get => _assemblyDependenciesCallback;
set => _assemblyDependenciesCallback = value ?? throw new ArgumentNullException(nameof(value));
}
///
/// Gets or sets the function delegate that filters assembly dependencies from the current application domain.
///
/// The function delegate that filters assembly dependencies from the current application domain.
/// The default implementation filters away assembly dependencies that suggest being part of the .NET runtime themselves.
///
/// cannot be null.
///
public static Func AssemblyDependenciesFilterCallback
{
get => _assemblyDependenciesFilterCallback;
set => _assemblyDependenciesFilterCallback = value ?? throw new ArgumentNullException(nameof(value));
}
///
/// Gets the qualified assemblies from the current application domain.
///
/// The qualified assemblies from the current application domain.
/// This result of this property is coupled with and .
public static IReadOnlyList CurrentDomainAssemblies => AssemblyLoadFactory.Value;
private static bool DefaultAssemblyFilter(Assembly assembly)
{
return assembly.FullName != null &&
!assembly.FullName.StartsWith(nameof(System)) &&
!assembly.FullName.StartsWith(nameof(Microsoft));
}
private static bool DefaultAssemblyDependenciesFilter(AssemblyName assemblyName)
{
return !assemblyName.FullName.StartsWith(nameof(System)) &&
!assemblyName.FullName.StartsWith(nameof(Microsoft));
}
private static IEnumerable DefaultAssemblyDependencies(Assembly assembly)
{
var stack = new Stack();
var guard = new HashSet();
yield return assembly;
stack.Push(assembly);
guard.Add(assembly.FullName);
while (stack.TryPop(out var assemblyToTraverse))
{
foreach (var assemblyName in assemblyToTraverse.GetReferencedAssemblies().Where(AssemblyDependenciesFilterCallback))
{
if (!guard.Add(assemblyName.FullName)) { continue; }
if (Patterns.TryInvoke(() => Assembly.Load(assemblyName), out var referencedAssembly) && referencedAssembly != null)
{
stack.Push(referencedAssembly);
yield return referencedAssembly;
}
}
}
}
}
}
\ No newline at end of file
diff --git a/src/Savvyio.Extensions.Dispatchers/SavvyioOptionsExtensions.cs b/src/Savvyio.Extensions.Dispatchers/SavvyioOptionsExtensions.cs
index dd49abf1..f92e3428 100644
--- a/src/Savvyio.Extensions.Dispatchers/SavvyioOptionsExtensions.cs
+++ b/src/Savvyio.Extensions.Dispatchers/SavvyioOptionsExtensions.cs
@@ -1,11 +1,11 @@
-using Savvyio.Commands;
+using Cuemon.Reflection;
+using Savvyio.Commands;
using Savvyio.Dispatchers;
using Savvyio.Domain;
using Savvyio.EventDriven;
using Savvyio.Queries;
using System.Linq;
using System.Reflection;
-using Savvyio.Reflection;
using System.Runtime.CompilerServices;
namespace Savvyio.Extensions
@@ -43,7 +43,7 @@ public static SavvyioOptions UseAutomaticDispatcherDiscovery(this SavvyioOptions
{
if (bruteAssemblyScanning)
{
- options.AddDispatchers(AssemblyContext.CurrentDomainAssemblies.ToArray());
+ options.AddDispatchers(AssemblyContext.GetCurrentDomainAssemblies().ToArray());
}
else
{
@@ -63,7 +63,7 @@ public static SavvyioOptions UseAutomaticHandlerDiscovery(this SavvyioOptions op
{
if (bruteAssemblyScanning)
{
- options.AddHandlers(AssemblyContext.CurrentDomainAssemblies.ToArray());
+ options.AddHandlers(AssemblyContext.GetCurrentDomainAssemblies().ToArray());
}
else
{
diff --git a/src/Savvyio.Extensions.Newtonsoft.Json/Converters/MessageConverter.cs b/src/Savvyio.Extensions.Newtonsoft.Json/Converters/MessageConverter.cs
index 5c58c1a3..380c3098 100644
--- a/src/Savvyio.Extensions.Newtonsoft.Json/Converters/MessageConverter.cs
+++ b/src/Savvyio.Extensions.Newtonsoft.Json/Converters/MessageConverter.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Reflection;
using Cuemon.Extensions;
+using Cuemon.Reflection;
using Codebelt.Extensions.Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -11,7 +12,6 @@
using Savvyio.EventDriven.Messaging.CloudEvents.Cryptography;
using Savvyio.Messaging;
using Savvyio.Messaging.Cryptography;
-using Savvyio.Reflection;
namespace Savvyio.Extensions.Newtonsoft.Json.Converters
{
@@ -21,7 +21,7 @@ namespace Savvyio.Extensions.Newtonsoft.Json.Converters
///
public class MessageConverter : JsonConverter
{
- internal static readonly Lazy> CloudEventTypes = new(() => AssemblyContext.CurrentDomainAssemblies.SelectMany(a => a.DefinedTypes.Where(ti => ti.HasInterfaces(typeof(ICloudEvent<>)) &&
+ internal static readonly Lazy> CloudEventTypes = new(() => AssemblyContext.GetCurrentDomainAssemblies().SelectMany(a => a.DefinedTypes.Where(ti => ti.HasInterfaces(typeof(ICloudEvent<>)) &&
ti is { IsAbstract: false, IsInterface: false })).ToList());
///
diff --git a/src/Savvyio.Extensions.Text.Json/Converters/MessageConverter.cs b/src/Savvyio.Extensions.Text.Json/Converters/MessageConverter.cs
index 37929a37..167706f4 100644
--- a/src/Savvyio.Extensions.Text.Json/Converters/MessageConverter.cs
+++ b/src/Savvyio.Extensions.Text.Json/Converters/MessageConverter.cs
@@ -6,13 +6,13 @@
using System.Text.Json.Serialization;
using Cuemon.Extensions;
using Cuemon.Extensions.Reflection;
+using Cuemon.Reflection;
using Cuemon.Extensions.Text.Json;
using Savvyio.EventDriven;
using Savvyio.EventDriven.Messaging.CloudEvents;
using Savvyio.EventDriven.Messaging.CloudEvents.Cryptography;
using Savvyio.Messaging;
using Savvyio.Messaging.Cryptography;
-using Savvyio.Reflection;
namespace Savvyio.Extensions.Text.Json.Converters
{
@@ -22,7 +22,7 @@ namespace Savvyio.Extensions.Text.Json.Converters
///
public class MessageConverter : JsonConverterFactory
{
- internal static readonly Lazy> CloudEventTypes = new(() => AssemblyContext.CurrentDomainAssemblies.SelectMany(a => a.DefinedTypes.Where(ti => ti.HasInterfaces(typeof(ICloudEvent<>)) &&
+ internal static readonly Lazy> CloudEventTypes = new(() => AssemblyContext.GetCurrentDomainAssemblies().SelectMany(a => a.DefinedTypes.Where(ti => ti.HasInterfaces(typeof(ICloudEvent<>)) &&
ti is { IsAbstract: false, IsInterface: false })).ToList());
///
diff --git a/test/Savvyio.Core.Tests/Reflection/AssemblyContextTest.cs b/test/Savvyio.Core.Tests/Reflection/AssemblyContextTest.cs
deleted file mode 100644
index 48f23786..00000000
--- a/test/Savvyio.Core.Tests/Reflection/AssemblyContextTest.cs
+++ /dev/null
@@ -1,185 +0,0 @@
-using System;
-using System.Linq;
-using System.Reflection;
-using Codebelt.Extensions.Xunit;
-using Savvyio.Reflection;
-using Xunit;
-
-namespace Savvyio.Reflection
-{
- public class AssemblyContextTest : Test
- {
- public AssemblyContextTest(ITestOutputHelper output) : base(output)
- {
- }
-
- [Fact]
- public void CurrentDomainAssemblies_ShouldReturnNonEmptyList()
- {
- var assemblies = AssemblyContext.CurrentDomainAssemblies;
-
- Assert.NotNull(assemblies);
- Assert.NotEmpty(assemblies);
- }
-
- [Fact]
- public void CurrentDomainAssemblies_ShouldNotContainSavvyioCoreAssembly()
- {
- var savvyioCoreAssembly = typeof(AssemblyContext).Assembly;
-
- Assert.DoesNotContain(savvyioCoreAssembly, AssemblyContext.CurrentDomainAssemblies);
- }
-
- [Fact]
- public void CurrentDomainAssemblies_ShouldNotContainSystemOrMicrosoftAssemblies()
- {
- foreach (var assembly in AssemblyContext.CurrentDomainAssemblies)
- {
- Assert.False(assembly.FullName?.StartsWith(nameof(System), StringComparison.Ordinal),
- $"Assembly '{assembly.FullName}' should have been filtered out.");
- Assert.False(assembly.FullName?.StartsWith(nameof(Microsoft), StringComparison.Ordinal),
- $"Assembly '{assembly.FullName}' should have been filtered out.");
- }
- }
-
- [Fact]
- public void AssemblyFilterCallback_ShouldReturnDefaultNonNullDelegate()
- {
- var callback = AssemblyContext.AssemblyFilterCallback;
-
- Assert.NotNull(callback);
- }
-
- [Fact]
- public void AssemblyFilterCallback_ShouldAcceptCustomDelegate()
- {
- var original = AssemblyContext.AssemblyFilterCallback;
- try
- {
- Func custom = _ => true;
- AssemblyContext.AssemblyFilterCallback = custom;
-
- Assert.Same(custom, AssemblyContext.AssemblyFilterCallback);
- }
- finally
- {
- AssemblyContext.AssemblyFilterCallback = original;
- }
- }
-
- [Fact]
- public void AssemblyFilterCallback_ShouldThrowArgumentNullException_WhenAssignedNull()
- {
- Assert.Throws(() => AssemblyContext.AssemblyFilterCallback = null);
- }
-
- [Fact]
- public void AssemblyDependenciesCallback_ShouldReturnDefaultNonNullDelegate()
- {
- var callback = AssemblyContext.AssemblyDependenciesCallback;
-
- Assert.NotNull(callback);
- }
-
- [Fact]
- public void AssemblyDependenciesCallback_ShouldAcceptCustomDelegate()
- {
- var original = AssemblyContext.AssemblyDependenciesCallback;
- try
- {
- Func> custom = a => Enumerable.Repeat(a, 1);
- AssemblyContext.AssemblyDependenciesCallback = custom;
-
- Assert.Same(custom, AssemblyContext.AssemblyDependenciesCallback);
- }
- finally
- {
- AssemblyContext.AssemblyDependenciesCallback = original;
- }
- }
-
- [Fact]
- public void AssemblyDependenciesCallback_ShouldThrowArgumentNullException_WhenAssignedNull()
- {
- Assert.Throws(() => AssemblyContext.AssemblyDependenciesCallback = null);
- }
-
- [Fact]
- public void AssemblyDependenciesFilterCallback_ShouldReturnDefaultNonNullDelegate()
- {
- var callback = AssemblyContext.AssemblyDependenciesFilterCallback;
-
- Assert.NotNull(callback);
- }
-
- [Fact]
- public void AssemblyDependenciesFilterCallback_ShouldAcceptCustomDelegate()
- {
- var original = AssemblyContext.AssemblyDependenciesFilterCallback;
- try
- {
- Func custom = _ => true;
- AssemblyContext.AssemblyDependenciesFilterCallback = custom;
-
- Assert.Same(custom, AssemblyContext.AssemblyDependenciesFilterCallback);
- }
- finally
- {
- AssemblyContext.AssemblyDependenciesFilterCallback = original;
- }
- }
-
- [Fact]
- public void AssemblyDependenciesFilterCallback_ShouldThrowArgumentNullException_WhenAssignedNull()
- {
- Assert.Throws(() => AssemblyContext.AssemblyDependenciesFilterCallback = null);
- }
-
- [Fact]
- public void AssemblyFilterCallback_DefaultFilter_ShouldIncludeNonSystemAssembly()
- {
- var callback = AssemblyContext.AssemblyFilterCallback;
- var savvyioAssembly = typeof(AssemblyContext).Assembly;
-
- Assert.True(callback(savvyioAssembly));
- }
-
- [Fact]
- public void AssemblyFilterCallback_DefaultFilter_ShouldExcludeSystemAssembly()
- {
- var callback = AssemblyContext.AssemblyFilterCallback;
- var systemAssembly = typeof(string).Assembly;
-
- Assert.False(callback(systemAssembly));
- }
-
- [Fact]
- public void AssemblyDependenciesFilterCallback_DefaultFilter_ShouldIncludeNonSystemAssemblyName()
- {
- var callback = AssemblyContext.AssemblyDependenciesFilterCallback;
- var assemblyName = typeof(AssemblyContext).Assembly.GetName();
-
- Assert.True(callback(assemblyName));
- }
-
- [Fact]
- public void AssemblyDependenciesFilterCallback_DefaultFilter_ShouldExcludeSystemAssemblyName()
- {
- var callback = AssemblyContext.AssemblyDependenciesFilterCallback;
- var assemblyName = typeof(string).Assembly.GetName();
-
- Assert.False(callback(assemblyName));
- }
-
- [Fact]
- public void AssemblyDependenciesCallback_DefaultCallback_ShouldYieldAtLeastTheInputAssembly()
- {
- var callback = AssemblyContext.AssemblyDependenciesCallback;
- var assembly = typeof(AssemblyContext).Assembly;
-
- var result = callback(assembly).ToList();
-
- Assert.Contains(assembly, result);
- }
- }
-}