Forge
csharp4405de34
1using System.Collections.Immutable;
2using Basic.Reference.Assemblies;
3using Microsoft.CodeAnalysis;
4using Microsoft.CodeAnalysis.CSharp;
5using Microsoft.CodeAnalysis.Diagnostics;
6using Xunit;
7
8namespace CascadeIDE.ArchitectureAnalyzers.Tests;
9
10public sealed class CockpitComputeUnitBoundaryAnalyzerTests
11{
12 private static async Task<ImmutableArray<Diagnostic>> RunAnalyzerAsync(params (string Path, string Text)[] files)
13 {
14 var trees = new List<SyntaxTree>(files.Length);
15 foreach (var (path, text) in files)
16 trees.Add(CSharpSyntaxTree.ParseText(text, path: path));
17
18 var compilation = CSharpCompilation.Create(
19 "TestAssembly",
20 trees,
21 Net80.References.All,
22 new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
23
24 var analyzer = new CockpitComputeUnitBoundaryAnalyzer();
25 return await compilation
26 .WithAnalyzers(ImmutableArray.Create<DiagnosticAnalyzer>(analyzer))
27 .GetAnalyzerDiagnosticsAsync();
28 }
29
30 [Fact]
31 public async Task CASCOPE020_FileRead_InComputingUnit_Reports()
32 {
33 var diags = await RunAnalyzerAsync((
34 @"D:\repo\Cockpit\ComputingUnits\Launch\Bad.cs",
35 """
36 namespace CascadeIDE.Cockpit.ComputingUnits.Launch;
37
38 public static class Bad
39 {
40 public static string Read(string path) => File.ReadAllText(path);
41 }
42 """));
43
44 var d = Assert.Single(diags);
45 Assert.Equal(CockpitComputeUnitBoundaryAnalyzer.ForbiddenExternalAccessId, d.Id);
46 }
47
48 [Fact]
49 public async Task CASCOPE020_HttpClientCreation_InComputingUnit_Reports()
50 {
51 var diags = await RunAnalyzerAsync((
52 @"D:\repo\Cockpit\ComputingUnits\Launch\Bad.cs",
53 """
54 namespace CascadeIDE.Cockpit.ComputingUnits.Launch;
55
56 public sealed class Bad
57 {
58 public object Build() => new HttpClient();
59 }
60 """));
61
62 var d = Assert.Single(diags);
63 Assert.Equal(CockpitComputeUnitBoundaryAnalyzer.ForbiddenExternalAccessId, d.Id);
64 }
65
66 [Fact]
67 public async Task CASCOPE021_UsingViewModels_InComputingUnit_Reports()
68 {
69 var diags = await RunAnalyzerAsync((
70 @"D:\repo\Cockpit\ComputingUnits\Launch\Bad.cs",
71 """
72 using CascadeIDE.ViewModels;
73 namespace CascadeIDE.Cockpit.ComputingUnits.Launch;
74
75 public static class Bad { }
76 """));
77
78 var d = Assert.Single(diags);
79 Assert.Equal(CockpitComputeUnitBoundaryAnalyzer.ForbiddenLayerDependencyId, d.Id);
80 }
81
82 [Fact]
83 public async Task NonComputingUnit_FileAccess_DoesNotReport()
84 {
85 var diags = await RunAnalyzerAsync((
86 @"D:\repo\Services\Ok.cs",
87 """
88 namespace CascadeIDE.Services;
89
90 public static class Ok
91 {
92 public static string Read(string path) => File.ReadAllText(path);
93 }
94 """));
95
96 Assert.Empty(diags);
97 }
98}
99
View only · write via MCP/CIDE