using System.Reflection;
using NetArchTest.Rules;
using Xunit;
using FluentAssertions;
namespace StellaOps.Architecture.Tests;
///
/// Architecture tests for lattice engine placement rules.
/// Ensures lattice algorithms are only in Scanner.WebService, not in Concelier or Excititor.
///
[Trait("Category", "Architecture")]
public sealed class LatticeEngineRulesTests
{
private const string ScannerLatticeNamespace = "StellaOps.Scanner.Lattice";
///
/// Concelier modules must not reference Scanner lattice engine.
/// Lattice decisions are made in Scanner, not in Concelier.
///
[Fact]
public void Concelier_MustNot_Reference_ScannerLattice()
{
var concelierAssemblies = GetAssembliesByPattern("StellaOps.Concelier");
if (!concelierAssemblies.Any())
{
// Skip if assemblies not loaded (test discovery phase)
return;
}
var result = Types.InAssemblies(concelierAssemblies)
.ShouldNot()
.HaveDependencyOn(ScannerLatticeNamespace)
.GetResult();
result.IsSuccessful.Should().BeTrue(
$"Concelier assemblies must not reference Scanner lattice. " +
$"Violations: {string.Join(", ", result.FailingTypeNames ?? Enumerable.Empty())}");
}
///
/// Excititor modules must not reference Scanner lattice engine.
/// Excititor preserves prune source - does not evaluate lattice decisions.
///
[Fact]
public void Excititor_MustNot_Reference_ScannerLattice()
{
var excititorAssemblies = GetAssembliesByPattern("StellaOps.Excititor");
if (!excititorAssemblies.Any())
{
return;
}
var result = Types.InAssemblies(excititorAssemblies)
.ShouldNot()
.HaveDependencyOn(ScannerLatticeNamespace)
.GetResult();
result.IsSuccessful.Should().BeTrue(
$"Excititor assemblies must not reference Scanner lattice. " +
$"Violations: {string.Join(", ", result.FailingTypeNames ?? Enumerable.Empty())}");
}
///
/// Scanner.WebService MAY reference Scanner lattice engine (it's the authorized host).
/// This test documents the allowed dependency.
///
[Fact]
public void ScannerWebService_May_Reference_ScannerLattice()
{
// This is a documentation test - Scanner.WebService is allowed to use lattice
// The test validates that the architectural rule is correctly documented
var allowedAssemblies = new[] { "StellaOps.Scanner.WebService" };
// Positive assertion: these assemblies ARE allowed to reference lattice
allowedAssemblies.Should().Contain("StellaOps.Scanner.WebService",
"Scanner.WebService is the authorized host for lattice algorithms");
}
private static IEnumerable GetAssembliesByPattern(string pattern)
{
return AppDomain.CurrentDomain.GetAssemblies()
.Where(a => a.GetName().Name?.StartsWith(pattern) == true);
}
}