profileShare

rasmusjy / splitapp-backend-microservices

Read-only snapshot

No repository description.

main default branch 501 files Expires Sep 13, 2026, 9:06 AM
ModuleBoundaryTests.cs 3,142 bytes
1 using System.IO;
2 using System.Linq;
3 using System.Xml.Linq;
4
5 namespace SplitApp.WebApp.IntegrationTests.Architecture;
6
7 /// <summary>
8 /// Compile-time invariant: no module project may reference another module's project.
9 /// Modules can only depend on Shared.Kernel and Shared.Contracts.
10 /// </summary>
11 public class ModuleBoundaryTests
12 {
13 private static string SolutionRoot()
14 {
15 var dir = new DirectoryInfo(AppContext.BaseDirectory);
16 while (dir != null && !File.Exists(Path.Combine(dir.FullName, "SplitApp.sln")))
17 {
18 dir = dir.Parent;
19 }
20 Assert.NotNull(dir);
21 return dir!.FullName;
22 }
23
24 [Fact]
25 public void NoModuleReferencesAnotherModuleProject()
26 {
27 var modulesDir = Path.Combine(SolutionRoot(), "src", "Modules");
28 Assert.True(Directory.Exists(modulesDir), $"Modules dir not found at {modulesDir}");
29
30 var moduleNames = Directory.GetDirectories(modulesDir).Select(Path.GetFileName).ToList();
31 Assert.Equal(3, moduleNames.Count);
32
33 var csprojFiles = Directory.GetFiles(modulesDir, "*.csproj", SearchOption.AllDirectories);
34 var failures = new List<string>();
35
36 foreach (var csproj in csprojFiles)
37 {
38 var owningModule = moduleNames.First(m => csproj.Contains($"Modules{Path.DirectorySeparatorChar}{m}{Path.DirectorySeparatorChar}"));
39 var doc = XDocument.Load(csproj);
40 var refs = doc.Descendants("ProjectReference")
41 .Select(r => (string?)r.Attribute("Include"))
42 .Where(r => r != null)
43 .ToList();
44
45 foreach (var refPath in refs)
46 {
47 foreach (var otherModule in moduleNames.Where(m => m != owningModule))
48 {
49 if (refPath!.Contains($"Modules{Path.DirectorySeparatorChar}{otherModule}{Path.DirectorySeparatorChar}")
50 || refPath.Contains($"Modules\\{otherModule}\\")
51 || refPath.Contains($"Modules/{otherModule}/"))
52 {
53 failures.Add($"{Path.GetFileName(csproj)} (module {owningModule}) references {refPath} (module {otherModule})");
54 }
55 }
56 }
57 }
58
59 Assert.Empty(failures);
60 }
61
62 [Fact]
63 public void SharedProjectsDoNotReferenceModules()
64 {
65 var sharedDir = Path.Combine(SolutionRoot(), "src", "Shared");
66 var csprojFiles = Directory.GetFiles(sharedDir, "*.csproj", SearchOption.AllDirectories);
67
68 var failures = new List<string>();
69 foreach (var csproj in csprojFiles)
70 {
71 var doc = XDocument.Load(csproj);
72 var refs = doc.Descendants("ProjectReference")
73 .Select(r => (string?)r.Attribute("Include"))
74 .Where(r => r != null);
75
76 foreach (var refPath in refs)
77 {
78 if (refPath!.Contains("Modules"))
79 {
80 failures.Add($"{Path.GetFileName(csproj)} references {refPath}");
81 }
82 }
83 }
84
85 Assert.Empty(failures);
86 }
87 }
88