118 lines
4.2 KiB
C#
118 lines
4.2 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",
|
|
[],
|
|
["System.Text.Json"]);
|
|
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",
|
|
"Microsoft.AspNetCore.OpenApi",
|
|
"Microsoft.Extensions.ApiDescription.Server",
|
|
]);
|
|
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);
|
|
}
|