Files
Rendezvous/tests/FinalFactory.Rendezvous.Tests/Architecture/DependencyBoundaryTests.cs
T
KyuubiYoru e626b89909
quality-gate / quality (push) Successful in 58s
build: bootstrap solution and quality gates (#3)
Closes #3
2026-07-16 04:25:54 +02:00

114 lines
4.0 KiB
C#

using System.Reflection;
using System.Xml.Linq;
namespace FinalFactory.Rendezvous.Tests.Architecture;
public sealed class DependencyBoundaryTests
{
[Fact]
public void ContractsAreTransportAndEngineIndependent()
{
string[] references = GetReferences("FinalFactory.Rendezvous.Contracts");
Assert.DoesNotContain(references, IsGodotAssembly);
Assert.DoesNotContain(references, IsServerAssembly);
Assert.DoesNotContain(references, IsLiteNetLibAssembly);
}
[Fact]
public void ClientIsGodotAndServerIndependent()
{
string[] references = GetReferences("FinalFactory.Rendezvous.Client");
Assert.DoesNotContain(references, IsGodotAssembly);
Assert.DoesNotContain(references, IsServerAssembly);
}
[Fact]
public void TestClientUsesOnlyPublicRendezvousDependencies()
{
string[] references = GetReferences("FinalFactory.Rendezvous.TestClient");
Assert.DoesNotContain(references, IsGodotAssembly);
Assert.DoesNotContain(references, IsServerAssembly);
}
[Fact]
public void DeclaredDependencyGraphMatchesTheArchitecture()
{
AssertDeclaredDependencies(
"src/FinalFactory.Rendezvous.Contracts/FinalFactory.Rendezvous.Contracts.csproj",
[],
[]);
AssertDeclaredDependencies(
"src/FinalFactory.Rendezvous.Client/FinalFactory.Rendezvous.Client.csproj",
["FinalFactory.Rendezvous.Contracts"],
["LiteNetLib"]);
AssertDeclaredDependencies(
"src/FinalFactory.Rendezvous.Server/FinalFactory.Rendezvous.Server.csproj",
["FinalFactory.Rendezvous.Contracts"],
["LiteNetLib"]);
AssertDeclaredDependencies(
"src/FinalFactory.Rendezvous.TestClient/FinalFactory.Rendezvous.TestClient.csproj",
["FinalFactory.Rendezvous.Client", "FinalFactory.Rendezvous.Contracts"],
["LiteNetLib"]);
}
private static void AssertDeclaredDependencies(
string projectPath,
string[] expectedProjects,
string[] expectedPackages)
{
XDocument project = XDocument.Load(Path.Combine(FindRepositoryRoot(), projectPath));
string[] projects = project
.Descendants("ProjectReference")
.Select(static element =>
Path.GetFileNameWithoutExtension(element.Attribute("Include")?.Value) ?? string.Empty)
.Order(StringComparer.Ordinal)
.ToArray();
string[] packages = project
.Descendants("PackageReference")
.Select(static element => element.Attribute("Include")?.Value ?? string.Empty)
.Order(StringComparer.Ordinal)
.ToArray();
Assert.Equal(expectedProjects.Order(StringComparer.Ordinal), projects);
Assert.Equal(expectedPackages.Order(StringComparer.Ordinal), packages);
}
private static string FindRepositoryRoot()
{
DirectoryInfo? directory = new(AppContext.BaseDirectory);
while (directory is not null)
{
if (File.Exists(Path.Combine(directory.FullName, "Rendezvous.slnx")))
{
return directory.FullName;
}
directory = directory.Parent;
}
throw new DirectoryNotFoundException("Could not locate the Rendezvous repository root.");
}
private static string[] GetReferences(string assemblyName) => Assembly
.Load(assemblyName)
.GetReferencedAssemblies()
.Select(static reference => reference.Name ?? string.Empty)
.ToArray();
private static bool IsGodotAssembly(string assemblyName) =>
assemblyName.StartsWith("Godot", StringComparison.OrdinalIgnoreCase);
private static bool IsLiteNetLibAssembly(string assemblyName) =>
string.Equals(assemblyName, "LiteNetLib", StringComparison.Ordinal);
private static bool IsServerAssembly(string assemblyName) =>
string.Equals(
assemblyName,
"FinalFactory.Rendezvous.Server",
StringComparison.Ordinal);
}